22 boost::shared_ptr<HMHHencky> hencky_ptr)
25 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE],
false);
26 doEntities[MBVERTEX] =
true;
30 EntitiesFieldData::EntData &data) {
47 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
48 boost::shared_ptr<PhysicalEquations> physics_ptr) {
50 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
54 "Can not get data from block");
57 for (
const auto &b : henckyPtr->blockData) {
61 <<
"Found non-homogeneous material block: " << b.blockName;
68 data_ptr, boost::dynamic_pointer_cast<HMHHencky>(physics_ptr)));
71 data_ptr, boost::dynamic_pointer_cast<HMHHencky>(physics_ptr)));
75 template <
int STRIDEMATD = 0>
79 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
80 const double alpha_u);
95 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
96 const double alpha_u) {
107 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
108 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
109 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
120 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
121 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
122 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) {
124 external_strain_vec_ptr, smv);
127 template <
int STRIDEMATD = 0>
131 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
145 std::string row_field, std::string col_field,
146 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha) {
170 template <
int STRIDEMATD>
174 boost::shared_ptr<double> total_energy_ptr);
184 boost::shared_ptr<double> total_energy_ptr) {
193 template <
int STRIDEMATD = 0>
196 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
197 boost::shared_ptr<MatrixDouble> strain_ptr,
198 boost::shared_ptr<MatrixDouble> stress_ptr,
199 boost::shared_ptr<HMHHencky> hencky_ptr);
203 boost::shared_ptr<DataAtIntegrationPts>
211 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
212 boost::shared_ptr<PhysicalEquations> physics_ptr) {
213 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
217 "Can not get data from block");
220 for (
const auto &b : henckyPtr->blockData) {
224 <<
"Found non-homogeneous material block: " << b.blockName;
231 data_ptr, data_ptr->getLogStretchTensorAtPts(),
232 data_ptr->getApproxPAtPts(),
233 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
236 data_ptr, data_ptr->getLogStretchTensorAtPts(),
237 data_ptr->getApproxPAtPts(),
238 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
243 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
244 boost::shared_ptr<PhysicalEquations> physics_ptr) {
245 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
249 "Can not get data from block");
252 for (
const auto &b : henckyPtr->blockData) {
256 <<
"Found non-homogeneous material block: " << b.blockName;
263 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
264 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
267 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
268 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
272 MoFEMErrorCode
getOptions(boost::shared_ptr<DataAtIntegrationPts> data_ptr) {
274 PetscOptionsBegin(PETSC_COMM_WORLD,
"hencky_",
"",
"none");
276 CHKERR PetscOptionsScalar(
"-young_modulus",
"Young modulus",
"",
E, &
E,
278 CHKERR PetscOptionsScalar(
"-poisson_ratio",
"poisson ratio",
"",
nu, &
nu,
284 <<
"Hencky: E = " <<
E <<
" nu = " <<
nu;
297 (boost::format(
"(.*)%s(.*)") %
"_ELASTIC").str()
309 for (
auto m : meshset_vec_ptr) {
311 std::vector<double> block_data;
312 CHKERR m->getAttributes(block_data);
313 if (block_data.size() < 2) {
315 "Expected that block has atleast two attributes");
317 auto get_block_ents = [&]() {
331 std::string block_name =
m->getName();
333 auto block_name_heterogeneous =
"(.*)HETEROGENEOUS_ELASTIC(.*)";
334 auto block_name_analytical =
"(.*)ANALYTICAL_ELASTIC(.*)";
335 std::regex reg_name_heterogeneous(block_name_heterogeneous);
336 std::regex reg_name_analytical(block_name_analytical);
339 if (std::regex_match(block_name, reg_name_heterogeneous)) {
341 }
else if (std::regex_match(block_name, reg_name_analytical)) {
353 template <
int STRIDEMATD,
typename OP_PTR>
355 OP_PTR op_ptr, EntitiesFieldData::EntData &data,
356 boost::shared_ptr<DataAtIntegrationPts> dataAtGaussPts) {
359 auto getLamesParam = [](
double E,
double nu) {
367 auto fe_ent = op_ptr->getNumeredEntFiniteElementPtr()->getEnt();
368 int nb_integration_pts = op_ptr->getGaussPts().size2();
370 dataAtGaussPts->muAtPts.resize(nb_integration_pts,
false);
371 dataAtGaussPts->lambdaAtPts.resize(nb_integration_pts,
false);
372 dataAtGaussPts->muAtPts.clear();
373 dataAtGaussPts->lambdaAtPts.clear();
375 dataAtGaussPts->youngModulusAtPts.resize(nb_integration_pts,
false);
376 dataAtGaussPts->youngModulusAtPts.clear();
378 auto t_young_modulus =
379 getFTensor0FromVec(dataAtGaussPts->youngModulusAtPts);
380 auto t_mu = getFTensor0FromVec(dataAtGaussPts->muAtPts);
381 auto t_lambda = getFTensor0FromVec(dataAtGaussPts->lambdaAtPts);
384 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
385 DL>::size(dataAtGaussPts->matD, nb_integration_pts);
387 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
388 DL>::size(dataAtGaussPts->matAxiatorD, nb_integration_pts);
390 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
391 DL>::size(dataAtGaussPts->matDeviatorD, nb_integration_pts);
393 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
394 DL>::size(dataAtGaussPts->matInvD, nb_integration_pts);
396 dataAtGaussPts->matD.clear();
397 dataAtGaussPts->matAxiatorD.clear();
398 dataAtGaussPts->matDeviatorD.clear();
399 dataAtGaussPts->matInvD.clear();
407 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
408 dataAtGaussPts->matD);
409 auto t_axiator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
410 dataAtGaussPts->matAxiatorD);
411 auto t_deviator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
412 dataAtGaussPts->matDeviatorD);
413 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
414 dataAtGaussPts->matInvD);
430 t_deviator_D(
i,
j,
k,
l) =
432 t_D(
i,
j,
k,
l) = t_axiator_D(
i,
j,
k,
l) + t_deviator_D(
i,
j,
k,
l);
441 t_inv_D(
i,
j,
k,
l) =
449 if (b.blockEnts.find(op_ptr->getFEEntityHandle()) != b.blockEnts.end()) {
452 VectorDouble analytical_elastic;
455 auto t_analytical_elastic = getFTensor0FromVec(analytical_elastic);
457 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
458 t_young_modulus = t_analytical_elastic;
460 t_analytical_elastic / (3 * (1 - 2 * b.poissonRatio));
462 t_analytical_elastic / (2 * (1 + b.poissonRatio));
468 ++t_analytical_elastic;
473 Tag tag_heterogenous_mat;
474 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_handle(
476 tag_heterogenous_mat);
478 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_length(
479 tag_heterogenous_mat, tag_length);
480 if (tag_length != 1) {
482 "heterogeneous Young's modulus tag should be 1 but is %d",
487 double elem_young_mod = 0.0;
488 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
489 tag_heterogenous_mat, &fe_ent, 1, &elem_young_mod);
491 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
492 t_young_modulus = elem_young_mod;
493 auto [
mu,
lambda] = getLamesParam(elem_young_mod, b.poissonRatio);
497 elem_young_mod / (3 * (1 - 2 * b.poissonRatio));
499 elem_young_mod / (2 * (1 + b.poissonRatio));
509 CHKERR op_ptr->getPtrFE()->mField.get_moab().get_connectivity(
510 fe_ent, vert_conn, vert_num,
true);
512 VectorDouble vert_young_mod(vert_num);
513 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
514 tag_heterogenous_mat, vert_conn, vert_num, &vert_young_mod[0]);
516 auto t_shape_n = data.getFTensor0N();
517 int nb_shape_fn = data.getN(
NOBASE).size2();
519 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
521 auto t_vert_young_mod = getFTensor0FromVec(vert_young_mod);
522 for (
int bb = 0; bb != nb_shape_fn; ++bb) {
523 t_young_modulus += t_vert_young_mod * t_shape_n;
528 getLamesParam(t_young_modulus, b.poissonRatio);
532 t_young_modulus / (3 * (1 - 2 * b.poissonRatio));
534 t_young_modulus / (2 * (1 + b.poissonRatio));
542 "Unsupported heterogeneous Young's modulus interpolation "
548 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
549 t_young_modulus = b.youngModulus;
550 t_mu = b.shearModulusG;
551 t_lambda = b.bulkModulusK - 2 * b.shearModulusG / 3;
553 CHKERR evalMatD(b.bulkModulusK, b.shearModulusG);
554 CHKERR evalInvMatDPtr(b.bulkModulusK, b.shearModulusG);
563 const auto E = this->
E;
564 const auto nu = this->
nu;
566 double bulk_modulus_K =
E / (3 * (1 - 2 *
nu));
573 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
588 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
589 SmartPetscObj<Vec> assemble_vec,
590 boost::shared_ptr<TopologicalData> topo_ptr,
591 const double alpha_u,
592 boost::shared_ptr<double> J_ptr);
600 MoFEMErrorCode
assemble(
int row_side, EntityType row_type,
608 boost::shared_ptr<double>
JPtr;
614 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
615 SmartPetscObj<Vec> assemble_vec,
616 boost::shared_ptr<TopologicalData> topo_ptr,
617 const double alpha_u,
618 boost::shared_ptr<double> J_ptr)
override {
620 topo_ptr, alpha_u, J_ptr);
646template <
int STRIDEMATD>
649 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha_u)
652 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-poly_convex",
654 "get polyconvex option failed");
657template <
int STRIDEMATD>
663 "Polyconvex Hencky with heterogeneous material properties is not "
667 CHKERR integratePolyconvexHencky(data);
669 CHKERR integrateHencky(data);
674template <
int STRIDEMATD>
682 int nb_dofs = data.getIndices().size();
683 int nb_integration_pts = data.getN().size1();
684 auto v = getVolume();
685 auto t_w = getFTensor0IntegrationWeight();
686 auto t_approx_P_adjoint_log_du =
687 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
688 auto t_log_stretch_h1 =
689 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
690 auto t_dot_log_u = dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
692 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
698 auto get_ftensor2 = [](
auto &
v) {
700 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
703 int nb_base_functions = data.getN().size2();
704 auto t_row_base_fun = data.getFTensor0N();
706 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
708 auto t_nf = get_ftensor2(nF);
712 t_D(
i,
j,
k,
l) * (t_log_stretch_h1(
k,
l) + alphaU * t_dot_log_u(
k,
l));
715 a * (t_approx_P_adjoint_log_du(L) - t_L(
i,
j, L) * t_T(
i,
j));
718 for (; bb != nb_dofs / 6; ++bb) {
719 t_nf(L) -= t_row_base_fun * t_residual(L);
723 for (; bb != nb_base_functions; ++bb)
728 ++t_approx_P_adjoint_log_du;
736template <
int STRIDEMATD>
745 int nb_dofs = data.getIndices().size();
746 int nb_integration_pts = data.getN().size1();
747 auto v = getVolume();
748 auto t_w = getFTensor0IntegrationWeight();
749 auto t_approx_P_adjoint_log_du =
750 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
751 auto t_log_stretch_h1 =
752 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
753 auto t_dot_log_u = dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
755 auto t_D = getFTensor4DdgFromMat<3, 3, 0>(dataAtPts->matD);
761 auto get_ftensor2 = [](
auto &
v) {
763 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
766 constexpr double nohat_k = 1. / 4;
767 constexpr double hat_k = 1. / 8;
768 double mu = dataAtPts->mu;
769 double lambda = dataAtPts->lambda;
771 constexpr double third = boost::math::constants::third<double>();
775 int nb_base_functions = data.getN().size2();
776 auto t_row_base_fun = data.getFTensor0N();
777 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
779 auto t_nf = get_ftensor2(nF);
781 double log_det = t_log_stretch_h1(
i,
i);
782 double log_det2 = log_det * log_det;
785 double dev_norm2 = t_dev(
i,
j) * t_dev(
i,
j);
788 auto A = 2 *
mu * std::exp(nohat_k * dev_norm2);
789 auto B =
lambda * std::exp(hat_k * log_det2) * log_det;
792 A * (t_dev(
k,
l) * t_diff_deviator(
k,
l,
i,
j))
800 alphaU * t_D(
i,
j,
k,
l) * t_dot_log_u(
k,
l);
804 a * (t_approx_P_adjoint_log_du(L) - t_L(
i,
j, L) * t_T(
i,
j));
807 for (; bb != nb_dofs /
size_symm; ++bb) {
808 t_nf(L) -= t_row_base_fun * t_residual(L);
812 for (; bb != nb_base_functions; ++bb)
816 ++t_approx_P_adjoint_log_du;
823template <
int STRIDEMATD>
825 std::string row_field, std::string col_field,
826 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha)
831 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-poly_convex",
833 "get polyconvex option failed");
838 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
839 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
840 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
842 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap(smv) {}
858 for (
auto &ext_strain_block : (*externalStrainVecPtr)) {
860 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
863 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
864 scalingMethodsMap.end()) {
866 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
869 <<
"No scaling method found for " << ext_strain_block.blockName;
872 int nb_dofs = data.getIndices().size();
873 int nb_integration_pts = data.getN().size1();
874 auto v = getVolume();
875 auto t_w = getFTensor0IntegrationWeight();
878 double external_strain_val;
879 VectorDouble v_external_strain;
880 auto block_name =
"(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
881 std::regex reg_name(block_name);
882 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
883 VectorDouble analytical_external_strain;
884 std::string block_name_tmp;
885 std::tie(block_name_tmp, v_external_strain) =
887 ext_strain_block.blockName);
890 external_strain_val =
scale * ext_strain_block.val;
892 v_external_strain.resize(nb_integration_pts);
893 std::fill(v_external_strain.begin(), v_external_strain.end(),
894 external_strain_val);
896 auto t_external_strain = getFTensor0FromVec(v_external_strain);
904 auto get_ftensor2 = [](
auto &
v) {
906 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
909 int nb_base_functions = data.getN().size2();
910 auto t_row_base_fun = data.getFTensor0N();
911 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
912 auto tr = 3.0 * t_external_strain;
914 auto t_nf = get_ftensor2(nF);
921 t_residual(L) =
a * (t_L(
i,
j, L) * t_T(
i,
j));
924 for (; bb != nb_dofs / 6; ++bb) {
925 t_nf(L) += t_row_base_fun * t_residual(L);
929 for (; bb != nb_base_functions; ++bb)
940template <
int STRIDEMATD>
947 "Polyconvex Hencky with heterogeneous material properties is not "
951 CHKERR integratePolyconvexHencky(row_data, col_data);
953 CHKERR integrateHencky(row_data, col_data);
958template <
int STRIDEMATD>
968 int nb_integration_pts = row_data.getN().size1();
969 int row_nb_dofs = row_data.getIndices().size();
970 int col_nb_dofs = col_data.getIndices().size();
972 auto get_ftensor2 = [](MatrixDouble &
m,
const int r,
const int c) {
976 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 0,
c + 3),
977 &
m(r + 0,
c + 4), &
m(r + 0,
c + 5),
979 &
m(r + 1,
c + 0), &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 1,
c + 3),
980 &
m(r + 1,
c + 4), &
m(r + 1,
c + 5),
982 &
m(r + 2,
c + 0), &
m(r + 2,
c + 1), &
m(r + 2,
c + 2), &
m(r + 2,
c + 3),
983 &
m(r + 2,
c + 4), &
m(r + 2,
c + 5),
985 &
m(r + 3,
c + 0), &
m(r + 3,
c + 1), &
m(r + 3,
c + 2), &
m(r + 3,
c + 3),
986 &
m(r + 3,
c + 4), &
m(r + 3,
c + 5),
988 &
m(r + 4,
c + 0), &
m(r + 4,
c + 1), &
m(r + 4,
c + 2), &
m(r + 4,
c + 3),
989 &
m(r + 4,
c + 4), &
m(r + 4,
c + 5),
991 &
m(r + 5,
c + 0), &
m(r + 5,
c + 1), &
m(r + 5,
c + 2), &
m(r + 5,
c + 3),
992 &
m(r + 5,
c + 4), &
m(r + 5,
c + 5)
999 auto v = getVolume();
1000 auto t_w = getFTensor0IntegrationWeight();
1002 auto t_approx_P_adjoint__dstretch =
1003 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
1004 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(nb_integration_pts);
1005 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(nb_integration_pts);
1007 int row_nb_base_functions = row_data.getN().size2();
1008 auto t_row_base_fun = row_data.getFTensor0N();
1010 auto get_dP = [&]() {
1013 DL>::size(dP, nb_integration_pts);
1014 auto ts_a = getTSa();
1016 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
1018 if constexpr (!STRIDEMATD) {
1019 t_dP_tmp(L,
J) = -(1 + alphaU * ts_a) *
1020 (t_L(
i,
j, L) * ((t_D(
i,
j,
m,
n) * t_diff(
m,
n,
k,
l)) *
1025 L_left(
i,
j, L) = t_L(
i,
j, L);
1027 L_right(
k,
l,
J) = t_L(
k,
l,
J);
1032 auto t_approx_P_adjoint__dstretch =
1033 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
1034 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(nb_integration_pts);
1035 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(nb_integration_pts);
1036 auto &nbUniq = dataAtPts->nbUniq;
1038 auto t_dP = get_stress();
1039 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1040 if constexpr (STRIDEMATD) {
1044 -(1 + alphaU * ts_a) *
1053 t_sym(
i,
j) = (t_approx_P_adjoint__dstretch(
i,
j) ||
1054 t_approx_P_adjoint__dstretch(
j,
i));
1059 t_dP(L,
J) = t_L(
i,
j, L) *
1060 ((t_diff2_uP2(
i,
j,
k,
l) + t_diff2_uP2(
k,
l,
i,
j)) *
1066 ++t_approx_P_adjoint__dstretch;
1071 auto t_dP = get_stress();
1072 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1073 if constexpr (STRIDEMATD) {
1077 -(1 + alphaU * ts_a) *
1082 t_dP(L,
J) = t_dP_tmp(L,
J);
1088 return get_stress();
1091 auto t_dP = get_dP();
1093 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1097 for (; rr != row_nb_dofs / 6; ++rr) {
1098 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1099 auto t_m = get_ftensor2(K, 6 * rr, 0);
1100 for (
int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1101 const double b =
a * t_row_base_fun * t_col_base_fun;
1102 t_m(L,
J) -= b * t_dP(L,
J);
1109 for (; rr != row_nb_base_functions; ++rr) {
1119template <
int STRIDEMATD>
1130 int nb_integration_pts = row_data.getN().size1();
1131 int row_nb_dofs = row_data.getIndices().size();
1132 int col_nb_dofs = col_data.getIndices().size();
1134 auto get_ftensor2 = [](MatrixDouble &
m,
const int r,
const int c) {
1138 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 0,
c + 3),
1139 &
m(r + 0,
c + 4), &
m(r + 0,
c + 5),
1141 &
m(r + 1,
c + 0), &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 1,
c + 3),
1142 &
m(r + 1,
c + 4), &
m(r + 1,
c + 5),
1144 &
m(r + 2,
c + 0), &
m(r + 2,
c + 1), &
m(r + 2,
c + 2), &
m(r + 2,
c + 3),
1145 &
m(r + 2,
c + 4), &
m(r + 2,
c + 5),
1147 &
m(r + 3,
c + 0), &
m(r + 3,
c + 1), &
m(r + 3,
c + 2), &
m(r + 3,
c + 3),
1148 &
m(r + 3,
c + 4), &
m(r + 3,
c + 5),
1150 &
m(r + 4,
c + 0), &
m(r + 4,
c + 1), &
m(r + 4,
c + 2), &
m(r + 4,
c + 3),
1151 &
m(r + 4,
c + 4), &
m(r + 4,
c + 5),
1153 &
m(r + 5,
c + 0), &
m(r + 5,
c + 1), &
m(r + 5,
c + 2), &
m(r + 5,
c + 3),
1154 &
m(r + 5,
c + 4), &
m(r + 5,
c + 5)
1165 auto v = getVolume();
1166 auto t_w = getFTensor0IntegrationWeight();
1168 int row_nb_base_functions = row_data.getN().size2();
1169 auto t_row_base_fun = row_data.getFTensor0N();
1171 auto get_dP = [&]() {
1174 DL>::size(dP, nb_integration_pts);
1175 auto ts_a = getTSa();
1177 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
1179 constexpr double nohat_k = 1. / 4;
1180 constexpr double hat_k = 1. / 8;
1181 double mu = dataAtPts->mu;
1182 double lambda = dataAtPts->lambda;
1184 constexpr double third = boost::math::constants::third<double>();
1188 auto t_approx_P_adjoint__dstretch =
1189 dataAtPts->getFTensorAdjointPdstretch(getGaussPts().size2());
1190 auto t_log_stretch_h1 =
1191 dataAtPts->getFTensorLogStretchTotal(getGaussPts().size2());
1192 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(getGaussPts().size2());
1193 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(getGaussPts().size2());
1194 auto &nbUniq = dataAtPts->nbUniq;
1196 auto t_dP = get_stress();
1197 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1199 double log_det = t_log_stretch_h1(
i,
i);
1200 double log_det2 = log_det * log_det;
1202 t_dev(
i,
j) = t_log_stretch_h1(
i,
j) -
t_kd(
i,
j) * (
third * log_det);
1203 double dev_norm2 = t_dev(
i,
j) * t_dev(
i,
j);
1205 auto A = 2 *
mu * std::exp(nohat_k * dev_norm2);
1206 auto B =
lambda * std::exp(hat_k * log_det2) * log_det;
1210 (
A * 2 * nohat_k) * (t_dev(
k,
l) * t_diff_deviator(
k,
l,
i,
j));
1211 t_B_diff(
i,
j) = (
B * 2 * hat_k) * log_det *
t_kd(
i,
j) +
1215 t_A_diff(
i,
j) * (t_dev(
m,
n) * t_diff_deviator(
m,
n,
k,
l))
1219 A * t_diff_deviator(
m,
n,
i,
j) * t_diff_deviator(
m,
n,
k,
l)
1225 t_dP(L,
J) = -t_L(
i,
j, L) *
1232 (alphaU * ts_a) * (t_D(
i,
j,
m,
n) * t_diff(
m,
n,
k,
l)
1242 t_sym(
i,
j) = (t_approx_P_adjoint__dstretch(
i,
j) ||
1243 t_approx_P_adjoint__dstretch(
j,
i));
1248 t_dP(L,
J) += t_L(
i,
j, L) *
1249 ((t_diff2_uP2(
i,
j,
k,
l) + t_diff2_uP2(
k,
l,
i,
j)) *
1255 ++t_approx_P_adjoint__dstretch;
1261 return get_stress();
1264 auto t_dP = get_dP();
1265 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1269 for (; rr != row_nb_dofs / 6; ++rr) {
1270 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1271 auto t_m = get_ftensor2(K, 6 * rr, 0);
1272 for (
int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1273 const double b =
a * t_row_base_fun * t_col_base_fun;
1274 t_m(L,
J) -= b * t_dP(L,
J);
1281 for (; rr != row_nb_base_functions; ++rr) {
1291template <
int STRIDEMATD>
1293 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1294 boost::shared_ptr<double> total_energy_ptr)
1296 totalEnergyPtr(total_energy_ptr) {
1300 "dataAtPts is not allocated. Please set it before "
1301 "using this operator.");
1305template <
int STRIDEMATD>
1316 int nb_integration_pts = getGaussPts().size2();
1317 auto t_log_u = dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1320 auto &mat_d = dataAtPts->matD;
1323 "wrong matD size, number of columns should be %d but is %zu",
1326 if constexpr (STRIDEMATD != 0) {
1327 if (mat_d.size1() != nb_integration_pts) {
1329 "wrong matD size, number of rows should be %d but is %zu",
1330 nb_integration_pts, mat_d.size1());
1335 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
1337 dataAtPts->energyAtPts.resize(nb_integration_pts,
false);
1338 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1340 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1342 t_energy = 0.5 * (t_log_u(
i,
j) * (t_D(
i,
j,
k,
l) * t_log_u(
k,
l)));
1349 if (totalEnergyPtr) {
1350 auto t_w = getFTensor0IntegrationWeight();
1351 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1352 double loc_energy = 0;
1353 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1354 loc_energy += t_energy * t_w;
1358 *totalEnergyPtr += getMeasure() * loc_energy;
1364template <
int STRIDEMATD>
1367 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1368 boost::shared_ptr<MatrixDouble> strain_ptr,
1369 boost::shared_ptr<MatrixDouble> stress_ptr,
1370 boost::shared_ptr<HMHHencky> hencky_ptr)
1372 strainPtr(strain_ptr), stressPtr(stress_ptr), henckyPtr(hencky_ptr) {
1373 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE],
false);
1374 doEntities[MBVERTEX] =
true;
1377template <
int STRIDEMATD>
1389 auto nb_integration_pts = stressPtr->size1();
1391 if (nb_integration_pts != getGaussPts().size2()) {
1393 "inconsistent number of integration points");
1397 CHKERR henckyPtr->computeMaterialParamsAtPts<STRIDEMATD>(
this, data,
1401 MatrixSizeHelper<GetFTensor2SymmetricFromMatType<3, -1,
DL>,
DL>::size(
1402 *strainPtr, nb_integration_pts);
1403 auto t_strain = get_strain();
1405 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
1406 dataAtPts->matInvD);
1409 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(dataAtPts->matD);
1416 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1417 t_strain(
i,
j) = t_inv_D(
i,
j,
k,
l) * t_stress(
k,
l);
1421 t_stress_symm_debug(
i,
j) = (t_stress(
i,
j) || t_stress(
j,
i)) / 2;
1423 t_stress_symm_debug_diff(
i,
j) =
1424 t_D(
i,
j,
k,
l) * t_strain(
k,
l) - t_stress_symm_debug(
i,
j);
1426 t_stress_symm_debug_diff(
i,
j) * t_stress_symm_debug_diff(
i,
j);
1427 double nrm0 = t_stress_symm_debug(
i,
j) * t_stress_symm_debug(
i,
j) +
1428 std::numeric_limits<double>::epsilon();
1429 constexpr double eps = 1e-10;
1430 if (std::fabs(std::sqrt(nrm / nrm0)) >
eps) {
1432 <<
"Stress symmetry check failed: " << std::endl
1433 << t_stress_symm_debug_diff << std::endl
1436 "Norm is too big: " + std::to_string(nrm / nrm0));
1449template <
typename OP_PTR>
1450std::tuple<std::string, VectorDouble>
1452 const std::string block_name) {
1454 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1456 auto ts_time = op_ptr->getTStime();
1457 auto ts_time_step = op_ptr->getTStimeStep();
1463 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1466 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1469 if (v_analytical_expr.size() != nb_gauss_pts)
1471 "Wrong number of integration pts");
1474 return std::make_tuple(block_name, v_analytical_expr);
1477template <
typename OP_PTR>
1480 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1482 auto ts_time = op_ptr->getTStime();
1483 auto ts_time_step = op_ptr->getTStimeStep();
1490 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1493 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1496 if (v_analytical_expr.size() != nb_gauss_pts)
1498 "Wrong number of integration pts");
1501 return v_analytical_expr;
1508 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1509 SmartPetscObj<Vec> assemble_vec,
1510 boost::shared_ptr<TopologicalData> topo_ptr,
const double alpha_u,
1511 boost::shared_ptr<double> J_ptr)
1513 JPtr(J_ptr), topoDataPtr(topo_ptr), assembleVec(assemble_vec) {
1515 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-poly_convex",
1517 "get polyconvex option failed");
1523 CHKERR integratePolyconvexHencky(data);
1525 CHKERR integrateHencky(data);
1537 int nb_dofs = data.getIndices().size();
1538 int nb_integration_pts = data.getN().size1();
1539 auto v = getVolume();
1543 auto get_ftensor1 = [](
auto &
v) {
1545 &
v[0], &
v[1], &
v[2]);
1549 int nb_base_functions = data.getN().size2();
1551 auto integrate = [&](
auto t_D) {
1554 auto t_w = getFTensor0IntegrationWeight();
1555 auto t_det = topoDataPtr->getFTensorDetJacobian(nb_integration_pts);
1556 auto t_inv_jac = topoDataPtr->getFTensorInvJacobian(nb_integration_pts);
1558 auto t_var_log_u = dataAtPts->getFTensorVarLogStreach(nb_integration_pts);
1559 auto t_approx_P = dataAtPts->getFTensorApproxP(nb_integration_pts);
1560 auto t_approx_P_adjoint_log_du =
1561 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
1563 dataAtPts->getFTensorSmallHdLogStretch(nb_integration_pts);
1564 auto t_log_stretch_h1 =
1565 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1573 auto t_diff_base = data.getFTensor1DiffN<
SPACE_DIM>();
1574 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1575 const double a =
v * t_w;
1578 t_T(
i,
j) = t_D(
i,
j,
k,
l) *
1579 (t_log_stretch_h1(
k,
l) );
1582 t_stress_residual(L) = t_L(
i,
j, L) * t_T(
i,
j);
1585 t_residual(L) = t_approx_P_adjoint_log_du(L) - t_stress_residual(L);
1587 locJ -= (
a * t_det) * t_residual(L) * t_var_log_u(L);
1590 t_cof(
I,
J) = t_det * t_inv_jac(
J,
I);
1592 const double var_stress_residual = t_var_log_u(L) * t_stress_residual(L);
1597 t_approx_P_adjoint_log_du_dX;
1598 t_approx_P_adjoint_log_du_dX(L,
I,
J) =
1599 t_h_dlog_u(
i,
I, L) * t_approx_P(
i,
J);
1602 t_residual_dX(
I,
J) =
1603 t_var_log_u(L) * t_approx_P_adjoint_log_du_dX(L,
I,
J) -
1604 var_stress_residual * t_cof(
I,
J);
1606 auto t_nf = get_ftensor1(nF);
1608 for (; bb != nb_dofs /
SPACE_DIM; ++bb) {
1609 t_nf(
i) -=
a * t_residual_dX(
i,
j) * t_diff_base(
j);
1613 for (; bb != nb_base_functions; ++bb)
1621 ++t_approx_P_adjoint_log_du;
1632 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matD));
1635 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matD));
1645 "Polyconvex Hencky is not implemented yet");
1650 EntityType row_type,
1654 double *vec_ptr = nF.data().data();
1655 const int nb_dofs = data.getIndices().size();
1656 int *ind_ptr = data.getIndices().data().data();
1657 CHKERR VecSetValues(assembleVec, nb_dofs, ind_ptr, vec_ptr, ADD_VALUES);
1659 if (row_type == MBVERTEX) {
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEXES(DIM,...)
#define FTENSOR_INDEX(DIM, I)
static PetscErrorCode ierr
Kronecker Delta class symmetric.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, C &&t_S, const int nb)
Get the Diff Diff Mat object.
VectorDouble analytical_externalstrain_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_ref_coords, const std::string block_name)
auto diff_deviator(FTensor::Ddg< double, 3, 3 > &&t_diff_stress)
std::tuple< std::string, VectorDouble > getAnalyticalExternalStrain(OP_PTR op_ptr, VectorDouble &analytical_expr, const std::string block_name)
VectorDouble analytical_elastic_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_ref_coords, const std::string block_name)
EntitiesFieldData::EntData EntData
ForcesAndSourcesCore::UserDataOperator UserDataOperator
VectorDouble getAnalyticalElastic(OP_PTR op_ptr, const std::string block_name)
static constexpr auto size_symm
constexpr IntegrationType I
constexpr auto field_name
FTensor::Index< 'm', 3 > m
void temp(int x, int y=10)
static enum StretchSelector stretchSelector
static enum RotSelector gradApproximator
static std::string heterogeneousYoungModTagName
static int physicalStepNumber
static PetscBool physicalTimeFlg
static double currentPhysicalTime
static boost::function< double(const double)> f
static bool hasNonHomogeneousMaterialBlock
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
static int meshTransferInterpOrder
static constexpr int SizeSymm
Calculate energy density for Hencky material model.
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< double > totalEnergyPtr
OpCalculateEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_energy_ptr)
OpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< HMHHencky > hencky_ptr)
boost::shared_ptr< MatrixDouble > stressPtr
boost::shared_ptr< HMHHencky > henckyPtr
boost::shared_ptr< MatrixDouble > strainPtr
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode evaluateLhs(EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
boost::shared_ptr< DataAtIntegrationPts > dataAtGaussPts
OpHenckyJacobian(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< HMHHencky > hencky_ptr)
MoFEMErrorCode evaluateRhs(EntData &data)
boost::shared_ptr< HMHHencky > henckyPtr
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
OpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > &external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
MoFEMErrorCode integrate(EntData &data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integratePolyconvexHencky(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrateHencky(EntData &row_data, EntData &col_data)
OpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MoFEMErrorCode integrate(EntData &data)
MoFEMErrorCode integrateHencky(EntData &data)
MoFEMErrorCode integratePolyconvexHencky(EntData &data)
OpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
OpTopoSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, SmartPetscObj< Vec > assemble_vec, boost::shared_ptr< TopologicalData > topo_ptr, const double alpha_u, boost::shared_ptr< double > J_ptr)
MoFEMErrorCode assemble(int row_side, EntityType row_type, EntData &data) override
SmartPetscObj< Vec > assembleVec
boost::shared_ptr< TopologicalData > topoDataPtr
MoFEMErrorCode integratePolyconvexHencky(EntData &data)
MoFEMErrorCode integrateHencky(EntData &data)
MoFEMErrorCode integrate(EntData &data)
boost::shared_ptr< double > JPtr
MoFEMErrorCode computeMaterialParamsAtPts(OP_PTR op_ptr, EntitiesFieldData::EntData &data, boost::shared_ptr< DataAtIntegrationPts > dataAtGaussPts)
virtual VolUserDataOperator * returnOpTopoSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, SmartPetscObj< Vec > assemble_vec, boost::shared_ptr< TopologicalData > topo_ptr, const double alpha_u, boost::shared_ptr< double > J_ptr) override
virtual VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
VolUserDataOperator * returnOpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
MoFEMErrorCode extractBlockData(Sev sev)
Sev getOptionsSeverityLevels
std::vector< BlockData > blockData
static constexpr int StrideMatD
MoFEMErrorCode extractBlockData(std::vector< const CubitMeshSets * > meshset_vec_ptr, Sev sev)
HMHHencky(MoFEM::Interface &m_field, const double E, const double nu)
VolUserDataOperator * returnOpCalculateVarStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
VolUserDataOperator * returnOpCalculateEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_energy_ptr)
MoFEMErrorCode getOptions(boost::shared_ptr< DataAtIntegrationPts > data_ptr)
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MoFEM::Interface & mField
virtual VolUserDataOperator * returnOpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
virtual UserDataOperator * returnOpJacobian(const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
virtual moab::Interface & get_moab()=0
bool sYmm
If true assume that matrix is symmetric structure.
Deprecated interface functions.
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
PetscReal ts_t
Current time value.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
double young_modulus
Young modulus.
double poisson_ratio
Poisson ratio.