22 double radiusMls,
const std::string name):radiusMls(radiusMls),name(name)
24 MY_BANNER(
"Constructing Deformation Gradient using the Moving Least Square method!");
28 std::unique_ptr<const Configuration> pconfigMls;
29 if (body.
pbc.any() == 1)
31 MY_HEADING(
"Generating padding atoms for periodic boundary conditions of Moving Least Squares.")
33 std::cout <<
"Thickness of padding = radiusMls = " 34 << radiusMls << std::endl;
35 std::cout <<
"Total number of atoms including padding atoms = " << pconfigMls->
numberOfParticles << std::endl;
36 std::cout << std::endl;
43 double box_xx, box_yy, box_zz;
47 int pbc_x, pbc_y, pbc_z;
53 displacements.setZero();
123 double gridRadiusMls;
126 Vector3d rSanityI, rSanityJ, rSanityK, rSanityQ;
127 int sanityI, sanityJ, sanityK, sanityQ;
133 Matrix4d sanity, A, inverseA, dAdx, dAdy, dAdz;
134 Matrix4d inverseAXdAdx, inverseAXdAdy, inverseAXdAdz;
135 Matrix4d inverseAXdAdxXInverseA, inverseAXdAdyXInverseA, inverseAXdAdzXInverseA;
136 MatrixXd MlsDisp(4,3), dMlsDispdx(4,3), dMlsDispdy(4,3), dMlsDispdz(4,3);
137 MatrixXd fintmdx, fintmdy,fintmdz, sintmdx, sintmdy, sintmdz;
138 MatrixXd B, inverseAXB, dBdx, dBdy, dBdz;
143 std::vector<int> gridMlsAtomList;
144 int ngridMLSAtomList;
162 std::vector<std::set<int>> neighborListsOfGridsMls=pgrid->
getGridNeighborLists(subconfig,radiusMls);
165 for (
int i = 0; i != subconfig.coordinates.at(
Reference).rows(); i++)
168 if (fabs(subconfig.coordinates.at(
Current)(i,0) - subconfig.coordinates.at(
Reference)(i,0)) > 0.5 * box_xx && pbc_x)
170 displacements(i,0) = subconfig.coordinates.at(
Current)(i,0) - subconfig.coordinates.at(
Reference)(i,0) - box_xx;
174 displacements(i,0) = subconfig.coordinates.at(
Current)(i,0) - subconfig.coordinates.at(
Reference)(i,0);
177 if (fabs(subconfig.coordinates.at(
Current)(i,1) - subconfig.coordinates.at(
Reference)(i,1)) > 0.5 * box_yy && pbc_y)
179 displacements(i,1) = subconfig.coordinates.at(
Current)(i,1) - subconfig.coordinates.at(
Reference)(i,1) - box_yy;
183 displacements(i,1) = subconfig.coordinates.at(
Current)(i,1) - subconfig.coordinates.at(
Reference)(i,1);
186 if (fabs(subconfig.coordinates.at(
Current)(i,2) - subconfig.coordinates.at(
Reference)(i,2)) > 0.5 * box_zz && pbc_z)
188 displacements(i,2) = subconfig.coordinates.at(
Current)(i,2) - subconfig.coordinates.at(
Reference)(i,2) - box_zz;
192 displacements(i,2) = subconfig.coordinates.at(
Current)(i,2) - subconfig.coordinates.at(
Reference)(i,2);
199 for (
int iGrid = 0; iGrid != pgrid->
coordinates.size(); iGrid++)
203 A = Matrix4d::Zero();
208 if (cycle_count != 1)
212 MY_WARNING(
"Something is wrong and causing the A matrix singular, \ 213 Probably because there are not enough atoms in the MLS radius. Setting the deformation gradient to be identity and \ 214 pushed grid point to the grid point itself.")
215 tensorF.setIdentity();
237 MY_ERROR(
"Model degenerate to 2D. Cannot use MLS3D to generate deformation gradient!")
240 gridMlsAtomList.clear();
241 ngridMLSAtomList = 0;
242 const std::set<int>& neighborListOfGridsMls = neighborListsOfGridsMls[iGrid];
246 for (
const auto& jRefAtoms : neighborListOfGridsMls)
259 if (r.norm() <= gridRadiusMls)
266 gridMlsAtomList.push_back(jRefAtoms);
275 if (ngridMLSAtomList <= 3)
278 A = Matrix4d::Zero();
279 MY_WARNING(
"Not enough atoms in the MLS radius " + std::to_string(gridRadiusMls) +
". Doubling it.");
280 gridRadiusMls = 2.0 * gridRadiusMls;
285 for (
int i = 0; i <= ngridMLSAtomList - 4; i++)
287 sanityI = gridMlsAtomList[i];
294 for(
int j = i + 1; j <= ngridMLSAtomList - 3; j++)
296 sanityJ = gridMlsAtomList[j];
303 for (
int k = j + 1; k <= ngridMLSAtomList - 2; k++)
305 sanityK = gridMlsAtomList[k];
312 for (
int q = k + 1; q <= ngridMLSAtomList - 1; q++)
314 sanityQ = gridMlsAtomList[q];
323 sanity = Matrix4d::Constant(1.0);
324 sanity(0,0) = rSanityI(0);
325 sanity(0,1) = rSanityI(1);
326 sanity(0,2) = rSanityI(2);
327 sanity(1,0) = rSanityJ(0);
328 sanity(1,1) = rSanityJ(1);
329 sanity(1,2) = rSanityJ(2);
330 sanity(2,0) = rSanityK(0);
331 sanity(2,1) = rSanityK(1);
332 sanity(2,2) = rSanityK(2);
333 sanity(3,0) = rSanityQ(0);
334 sanity(3,1) = rSanityQ(1);
335 sanity(3,2) = rSanityQ(2);
337 if (sanity.determinant() >
epsilon)
350 A = Matrix4d::Zero();
351 MY_WARNING(
"All atoms lying on a surface for the MLS radius " + std::to_string(gridRadiusMls) +
". Doubling it.");
352 gridRadiusMls = 2.0 * gridRadiusMls;
359 sort(gridMlsAtomList.begin(), gridMlsAtomList.end());
368 P.resize(ngridMLSAtomList,4);
369 W.resize(ngridMLSAtomList);
370 dWdx.resize(ngridMLSAtomList,3);
371 B.resize(4,ngridMLSAtomList);
372 dBdx.resize(4,ngridMLSAtomList);
373 dBdy.resize(4,ngridMLSAtomList);
374 dBdz.resize(4,ngridMLSAtomList);
375 inverseAXB.resize(4,ngridMLSAtomList);
376 exactDisplacements.resize(ngridMLSAtomList,3);
377 fintmdx.resize(4,ngridMLSAtomList);
378 fintmdy.resize(4,ngridMLSAtomList);
379 fintmdz.resize(4,ngridMLSAtomList);
380 sintmdx.resize(4,ngridMLSAtomList);
381 sintmdy.resize(4,ngridMLSAtomList);
382 sintmdz.resize(4,ngridMLSAtomList);
384 tensorF = Matrix3d::Zero();
385 gptIPushedF = Vector3d::Zero();
386 P = MatrixXd::Zero(ngridMLSAtomList,4);
387 W = VectorXd::Zero(ngridMLSAtomList);
388 dWdx = MatrixXd::Zero(ngridMLSAtomList,3);
389 A = Matrix4d::Zero();
390 inverseA = Matrix4d::Zero();
391 dAdx = Matrix4d::Zero();
392 dAdy = Matrix4d::Zero();
393 dAdz = Matrix4d::Zero();
394 B = MatrixXd::Zero(4,ngridMLSAtomList);
395 dBdx = MatrixXd::Zero(4,ngridMLSAtomList);
396 dBdy = MatrixXd::Zero(4,ngridMLSAtomList);
397 dBdz = MatrixXd::Zero(4,ngridMLSAtomList);
398 inverseAXB = MatrixXd::Zero(4,ngridMLSAtomList);
399 MlsDisp = MatrixXd::Zero(4,3);
400 dMlsDispdx = MatrixXd::Zero(4,3);
401 dMlsDispdy = MatrixXd::Zero(4,3);
402 dMlsDispdz = MatrixXd::Zero(4,3);
403 exactDisplacements = MatrixXd::Zero(ngridMLSAtomList,3);
404 inverseAXdAdx = Matrix4d::Zero();
405 inverseAXdAdy = Matrix4d::Zero();
406 inverseAXdAdz = Matrix4d::Zero();
407 inverseAXdAdxXInverseA = Matrix4d::Zero();
408 inverseAXdAdyXInverseA = Matrix4d::Zero();
409 inverseAXdAdzXInverseA = Matrix4d::Zero();
410 fintmdx = MatrixXd::Zero(4,ngridMLSAtomList);
411 fintmdy = MatrixXd::Zero(4,ngridMLSAtomList);
412 fintmdz = MatrixXd::Zero(4,ngridMLSAtomList);
413 sintmdx = MatrixXd::Zero(4,ngridMLSAtomList);
414 sintmdy = MatrixXd::Zero(4,ngridMLSAtomList);
415 sintmdz = MatrixXd::Zero(4,ngridMLSAtomList);
417 for (
int i = 0; i < ngridMLSAtomList; i++)
422 r(0) = subconfig.coordinates.at(
Reference)(gridMlsAtomList[i],0) - pgrid->
coordinates[iGrid](0);
423 r(1) = subconfig.coordinates.at(
Reference)(gridMlsAtomList[i],1) - pgrid->
coordinates[iGrid](1);
424 r(2) = subconfig.coordinates.at(
Reference)(gridMlsAtomList[i],2) - pgrid->
coordinates[iGrid](2);
430 P(i,1) = subconfig.coordinates.at(
Reference)(gridMlsAtomList[i],0) - pgrid->
coordinates[iGrid](0);
431 P(i,2) = subconfig.coordinates.at(
Reference)(gridMlsAtomList[i],1) - pgrid->
coordinates[iGrid](1);
432 P(i,3) = subconfig.coordinates.at(
Reference)(gridMlsAtomList[i],2) - pgrid->
coordinates[iGrid](2);
434 r2 = r.norm() / gridRadiusMls;
437 W(i) = 2.0 / 3.0 - 4.0 * r2 * r2 + 4.0 * r2 * r2 * r2;
438 dWdx(i,0) = -8.0 * r(0) / gridRadiusMls / gridRadiusMls \
439 + 12.0 * r2 * r(0) / gridRadiusMls / gridRadiusMls;
440 dWdx(i,1) = -8.0 * r(1) / gridRadiusMls / gridRadiusMls \
441 + 12.0 * r2 * r(1) / gridRadiusMls / gridRadiusMls;
442 dWdx(i,2) = -8.0 * r(2) / gridRadiusMls / gridRadiusMls \
443 + 12.0 * r2 * r(2) / gridRadiusMls / gridRadiusMls;
445 else if (r2 >= 0.5 && r2 <= 1.0)
447 W(i) = 4.0 / 3.0 - 4.0 * r2 + 4.0 * r2 * r2 - 4.0 / 3.0 * r2 * r2 * r2;
448 dWdx(i,0) = -4.0 * r(0) / gridRadiusMls / gridRadiusMls / r2 \
449 + 8.0 * r(0) / gridRadiusMls / gridRadiusMls \
450 - 4.0 * r2 * r(0) / gridRadiusMls / gridRadiusMls;
451 dWdx(i,1) = -4.0 * r(1) / gridRadiusMls / gridRadiusMls / r2 \
452 + 8.0 * r(1) / gridRadiusMls / gridRadiusMls \
453 - 4.0 * r2 * r(1) / gridRadiusMls / gridRadiusMls;
454 dWdx(i,2) = -4.0 * r(2) / gridRadiusMls / gridRadiusMls / r2 \
455 + 8.0 * r(2) / gridRadiusMls / gridRadiusMls \
456 - 4.0 * r2 * r(2) / gridRadiusMls / gridRadiusMls;
465 exactDisplacements(i,0) = displacements(gridMlsAtomList[i],0);
466 exactDisplacements(i,1) = displacements(gridMlsAtomList[i],1);
467 exactDisplacements(i,2) = displacements(gridMlsAtomList[i],2);
470 for (
int i = 0; i < 4; i++)
472 for (
int j = 0; j < ngridMLSAtomList; j++)
474 B(i,j) = P(j,i) * W(j);
478 for (
int i = 0; i < 4; i++)
480 for (
int j = 0; j < 4; j++)
482 for (
int k = 0; k < ngridMLSAtomList; k++)
484 A(i,j) = A(i,j) + B(i,k) * P(k,j);
489 inverseA = A.inverse();
490 gridRadiusMls = 2.0 * gridRadiusMls;
561 }
while (A.determinant() <
epsilon);
563 gridRadiusMls = gridRadiusMls / 2.0;
566 for (
int i = 0; i < 4; i++)
568 for (
int j = 0; j < ngridMLSAtomList; j++)
570 for (
int k = 0; k < 4; k++)
572 inverseAXB(i,j) = inverseAXB(i,j) + inverseA(i,k) * B(k,j);
577 for (
int i = 0; i < 4; i++)
579 for (
int j = 0; j < 3; j++)
581 for (
int k = 0; k < ngridMLSAtomList; k++)
583 MlsDisp(i,j) = MlsDisp(i,j) + inverseAXB(i,k) * exactDisplacements(k,j);
591 for (
int i = 0; i < 4; i++)
593 for (
int j = 0; j < ngridMLSAtomList; j++)
595 dBdx(i,j) = P(j,i) * dWdx(j,0);
596 dBdy(i,j) = P(j,i) * dWdx(j,1);
597 dBdz(i,j) = P(j,i) * dWdx(j,2);
601 for (
int i = 0; i < 4; i++)
603 for (
int j = 0; j < 4; j++)
605 for (
int k = 0; k < ngridMLSAtomList; k++)
607 dAdx(i,j) = dAdx(i,j) + dBdx(i,k) * P(k,j);
608 dAdy(i,j) = dAdy(i,j) + dBdy(i,k) * P(k,j);
609 dAdz(i,j) = dAdz(i,j) + dBdz(i,k) * P(k,j);
614 for (
int i = 0; i < 4; i++)
616 for (
int j = 0; j < 4; j++)
618 for (
int k = 0; k < 4; k++)
620 inverseAXdAdx(i,j) = inverseAXdAdx(i,j) + inverseA(i,k) * dAdx(k,j);
621 inverseAXdAdy(i,j) = inverseAXdAdy(i,j) + inverseA(i,k) * dAdy(k,j);
622 inverseAXdAdz(i,j) = inverseAXdAdz(i,j) + inverseA(i,k) * dAdz(k,j);
627 for (
int i = 0; i < 4; i++)
629 for (
int j = 0; j < 4; j++)
631 for (
int k = 0; k < 4; k++)
633 inverseAXdAdxXInverseA(i,j) = inverseAXdAdxXInverseA(i,j) + inverseAXdAdx(i,k) * inverseA(k,j);
634 inverseAXdAdyXInverseA(i,j) = inverseAXdAdyXInverseA(i,j) + inverseAXdAdy(i,k) * inverseA(k,j);
635 inverseAXdAdzXInverseA(i,j) = inverseAXdAdzXInverseA(i,j) + inverseAXdAdz(i,k) * inverseA(k,j);
640 for (
int i = 0; i < 4; i++)
642 for (
int j = 0; j < ngridMLSAtomList; j++)
644 for (
int k = 0; k < 4; k++)
646 fintmdx(i,j) = fintmdx(i,j) + inverseAXdAdxXInverseA(i,k) * B(k,j);
647 fintmdy(i,j) = fintmdy(i,j) + inverseAXdAdyXInverseA(i,k) * B(k,j);
648 fintmdz(i,j) = fintmdz(i,j) + inverseAXdAdzXInverseA(i,k) * B(k,j);
653 for (
int i = 0; i < 4; i++)
655 for (
int j = 0; j < ngridMLSAtomList; j++)
657 for (
int k = 0; k < 4; k++)
659 sintmdx(i,j) = sintmdx(i,j) + inverseA(i,k) * dBdx(k,j);
660 sintmdy(i,j) = sintmdy(i,j) + inverseA(i,k) * dBdy(k,j);
661 sintmdz(i,j) = sintmdz(i,j) + inverseA(i,k) * dBdz(k,j);
666 for (
int i = 0; i < 4; i++)
668 for (
int j = 0; j < ngridMLSAtomList; j++)
670 fintmdx(i,j) = -fintmdx(i,j) + sintmdx(i,j);
671 fintmdy(i,j) = -fintmdy(i,j) + sintmdy(i,j);
672 fintmdz(i,j) = -fintmdz(i,j) + sintmdz(i,j);
676 for (
int i = 0; i < 4; i++)
678 for (
int j = 0; j < 3; j++)
680 for (
int k = 0; k < ngridMLSAtomList; k++)
682 dMlsDispdx(i,j) = dMlsDispdx(i,j) + fintmdx(i,k) * exactDisplacements(k,j);
683 dMlsDispdy(i,j) = dMlsDispdy(i,j) + fintmdy(i,k) * exactDisplacements(k,j);
684 dMlsDispdz(i,j) = dMlsDispdz(i,j) + fintmdz(i,k) * exactDisplacements(k,j);
713 tensorF(0,0) = 1.0 + MlsDisp(1,0) \
714 + 1.0 * dMlsDispdx(0,0);
715 tensorF(1,0) = MlsDisp(2,0) \
716 + 1.0 * dMlsDispdy(0,0);
717 tensorF(2,0) = MlsDisp(3,0) \
718 + 1.0 * dMlsDispdz(0,0);
719 tensorF(0,1) = MlsDisp(1,1) \
720 + 1.0 * dMlsDispdx(0,1);
721 tensorF(1,1) = 1.0 + MlsDisp(2,1) \
722 + 1.0 * dMlsDispdy(0,1);
723 tensorF(2,1) = MlsDisp(3,1) \
724 + 1.0 * dMlsDispdz(0,1);
725 tensorF(0,2) = MlsDisp(1,2) \
726 + 1.0 * dMlsDispdx(0,2);
727 tensorF(1,2) = MlsDisp(2,2) \
728 + 1.0 * dMlsDispdy(0,2);
729 tensorF(2,2) = 1.0 + MlsDisp(3,2) \
730 + 1.0 * dMlsDispdz(0,2);
732 gptIPushedF(0) = pgrid->
coordinates[iGrid](0) + MlsDisp(0,0);
733 gptIPushedF(1) = pgrid->
coordinates[iGrid](1) + MlsDisp(0,1);
734 gptIPushedF(2) = pgrid->
coordinates[iGrid](2) + MlsDisp(0,2);
796 void Mls::pushToCauchy(
const std::vector<Matrix3d>& piolaStress,std::vector<Matrix3d>& cauchyStress)
798 MY_HEADING(
"Pushing the Piola-Kirchhoff Stress to the Cauchy stress.");
799 for (std::vector<Matrix3d>::size_type i = 0; i != piolaStress.size(); i++)
836 std::ofstream file(
name+
".DeformationGradient");
842 Eigen::Map<Eigen::Matrix<double,1,DIM*DIM>> FRow(F.data(), F.size());
843 Eigen::IOFormat fmt(Eigen::FullPrecision, 0,
" ",
"\n",
"",
"",
"",
"");
844 file << FRow.format(fmt) <<
" " << std::setprecision(16) << F.determinant() << std::endl;
852 std::ofstream file(
name+
".pushedGrids");
857 Eigen::Map<Eigen::Matrix<double,1,DIM>> gridRow(grid.data(), grid.size());
858 Eigen::IOFormat fmt(Eigen::FullPrecision, 0,
" ",
"\n",
"",
"",
"",
"");
859 file << gridRow.format(fmt) << std::endl;
867 std::ofstream file(
name+
".CauchyPushed");
868 file << cauchyStress.size() <<
"\n";
870 for (
auto& pushedStress : cauchyStress)
872 Eigen::Map<Eigen::Matrix<double,1,DIM*DIM>> pushedStressRow(pushedStress.data(), pushedStress.size());
873 Eigen::IOFormat fmt(Eigen::FullPrecision, 0,
" ",
"\n",
"",
"",
"",
"");
874 file << pushedStressRow.format(fmt) << std::endl;
void transpose(double const *mat, double *const trans)
#define MY_HEADING(heading)
void pushToCauchy(const std::vector< Matrix3d > &piolaStress, std::vector< Matrix3d > &cauchyStress)
std::map< ConfigType, MatrixXd > coordinates
#define MY_WARNING(message)
Configuration * getConfiguration(double) const
std::vector< std::set< int > > getGridNeighborLists(const SubConfiguration &, const double &) const
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor > VectorXd
std::vector< Vector3d > coordinates
Eigen::Matrix< double, 4, 4, Eigen::RowMajor > Matrix4d
#define MY_BANNER(announcement)
void expandStencil(const Grid< configType > *pgrid, const double &contributingNeighborhoodSize, const double &noncontributingNeighborhoodSize)
void writePushedCauchyStress(std::vector< Matrix3d > &cauchyStress)
Mls(const BoxConfiguration &body, const Grid< Reference > *pgrid, double radiusMls, const std::string name)
#define MY_ERROR(message)
Eigen::Matrix< double, 1, DIM, Eigen::RowMajor > Vector3d
Eigen::Matrix< double, DIM, DIM, Eigen::RowMajor > Matrix3d
std::vector< Vector3d > gridPushed
std::vector< Matrix3d > deformationGradient
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > MatrixXd
void writeDeformationGradient()