21 double diagonal_strain) {
22 const double c10 =
E / (4.0 * (1.0 + nu));
24 const double lambda =
E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu));
26 2.0 * c10 * std::exp(-2.0 * diagonal_strain / 3.0);
44 "Can not get data from block");
49 <<
"Found non-homogeneous material block: " << block.blockName;
60 boost::shared_ptr<HMHHencky> hencky_ptr)
63 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE],
false);
64 doEntities[MBVERTEX] =
true;
68 EntitiesFieldData::EntData &data) {
85 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
86 boost::shared_ptr<PhysicalEquations> physics_ptr)
override {
88 auto hencky_ptr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
95 template <
int STRIDEMATD = 0>
99 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
100 const double alpha_u);
112 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
113 const double alpha_u)
override {
124 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
125 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
126 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
137 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
138 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
139 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
override {
141 external_strain_vec_ptr, smv);
144 template <
int STRIDEMATD = 0>
148 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
158 std::string row_field, std::string col_field,
159 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
160 const double alpha)
override {
184 template <
int STRIDEMATD>
188 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
189 boost::shared_ptr<double> total_helmholtz_free_energy_ptr);
199 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
200 boost::shared_ptr<double> total_helmholtz_free_energy_ptr)
override {
204 data_ptr, total_helmholtz_free_energy_ptr);
207 data_ptr, total_helmholtz_free_energy_ptr);
213 template <
int STRIDEMATD = 0>
216 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
217 boost::shared_ptr<MatrixDouble> strain_ptr,
218 boost::shared_ptr<MatrixDouble> stress_ptr,
219 boost::shared_ptr<HMHHencky> hencky_ptr);
223 boost::shared_ptr<DataAtIntegrationPts>
231 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
232 boost::shared_ptr<PhysicalEquations> physics_ptr,
233 boost::shared_ptr<MatrixDouble> strain_ptr)
override {
235 std::move(data_ptr), std::move(physics_ptr), std::move(strain_ptr),
240 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
241 boost::shared_ptr<PhysicalEquations> physics_ptr,
242 boost::shared_ptr<MatrixDouble> strain_ptr,
243 boost::shared_ptr<MatrixDouble> stress_ptr,
244 VectorPtr external_pressure_ptr)
override {
245 auto hencky_ptr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
250 strain_ptr ? strain_ptr : data_ptr->getLogStretchTensorAtPts(),
251 stress_ptr ? stress_ptr : data_ptr->getApproxPAtPts(), hencky_ptr);
255 strain_ptr ? strain_ptr : data_ptr->getLogStretchTensorAtPts(),
256 stress_ptr ? stress_ptr : data_ptr->getApproxPAtPts(), hencky_ptr);
261 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
262 boost::shared_ptr<PhysicalEquations> physics_ptr)
override {
263 auto hencky_ptr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
267 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
271 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
278 PetscOptionsBegin(PETSC_COMM_WORLD,
"hencky_",
"",
"none");
280 CHKERR PetscOptionsScalar(
"-young_modulus",
"Young modulus",
"",
E, &
E,
282 CHKERR PetscOptionsScalar(
"-poisson_ratio",
"poisson ratio",
"",
nu, &
nu,
284 CHKERR PetscOptionsBool(
"-effective_neohookean_stiffness",
285 "Use effective Neo-Hookean stiffness",
"",
288 CHKERR PetscOptionsScalar(
"-effective_diagonal_strain",
289 "Diagonal logarithmic strain for effective "
290 "Neo-Hookean stiffness",
297 <<
"Hencky: E = " <<
E <<
" nu = " <<
nu
298 <<
" effective_neohookean_stiffness = "
312 (boost::format(
"(.*)%s(.*)") %
"_ELASTIC").str()
324 for (
auto m : meshset_vec_ptr) {
326 std::string block_name =
m->getName();
328 auto block_name_heterogeneous =
"(.*)HETEROGENEOUS_ELASTIC(.*)";
329 auto block_name_analytical =
"(.*)ANALYTICAL_ELASTIC(.*)";
330 std::regex reg_name_heterogeneous(block_name_heterogeneous);
331 std::regex reg_name_analytical(block_name_analytical);
332 const bool is_heterogeneous =
333 std::regex_match(block_name, reg_name_heterogeneous);
334 const bool is_analytical =
335 std::regex_match(block_name, reg_name_analytical);
337 std::vector<double> block_data;
338 CHKERR m->getAttributes(block_data);
339 if (block_data.size() < 2) {
341 "Expected that block has atleast two attributes");
343 auto get_block_ents = [&]() {
353 if (is_heterogeneous) {
355 }
else if (is_analytical) {
381 template <
int STRIDEMATD,
typename OP_PTR>
383 OP_PTR op_ptr, EntitiesFieldData::EntData &data,
384 boost::shared_ptr<DataAtIntegrationPts> dataAtGaussPts) {
387 auto getMaterialParams = [&](
double E,
double nu) {
399 auto fe_ent = op_ptr->getNumeredEntFiniteElementPtr()->getEnt();
400 int nb_integration_pts = op_ptr->getGaussPts().size2();
402 dataAtGaussPts->muAtPts.resize(nb_integration_pts,
false);
403 dataAtGaussPts->lambdaAtPts.resize(nb_integration_pts,
false);
404 dataAtGaussPts->muAtPts.clear();
405 dataAtGaussPts->lambdaAtPts.clear();
407 dataAtGaussPts->youngModulusAtPts.resize(nb_integration_pts,
false);
408 dataAtGaussPts->youngModulusAtPts.clear();
410 auto t_young_modulus =
411 getFTensor0FromVec(dataAtGaussPts->youngModulusAtPts);
412 auto t_mu = getFTensor0FromVec(dataAtGaussPts->muAtPts);
413 auto t_lambda = getFTensor0FromVec(dataAtGaussPts->lambdaAtPts);
416 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
417 DL>::size(dataAtGaussPts->matD, nb_integration_pts);
419 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
420 DL>::size(dataAtGaussPts->matAxiatorD, nb_integration_pts);
422 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
423 DL>::size(dataAtGaussPts->matDeviatorD, nb_integration_pts);
425 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
426 DL>::size(dataAtGaussPts->matInvD, nb_integration_pts);
428 dataAtGaussPts->matD.clear();
429 dataAtGaussPts->matAxiatorD.clear();
430 dataAtGaussPts->matDeviatorD.clear();
431 dataAtGaussPts->matInvD.clear();
439 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
440 dataAtGaussPts->matD);
441 auto t_axiator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
442 dataAtGaussPts->matAxiatorD);
443 auto t_deviator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
444 dataAtGaussPts->matDeviatorD);
445 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
446 dataAtGaussPts->matInvD);
462 t_deviator_D(
i,
j,
k,
l) =
464 t_D(
i,
j,
k,
l) = t_axiator_D(
i,
j,
k,
l) + t_deviator_D(
i,
j,
k,
l);
473 t_inv_D(
i,
j,
k,
l) =
481 if (b.blockEnts.find(op_ptr->getFEEntityHandle()) != b.blockEnts.end()) {
484 VectorDouble analytical_elastic;
487 auto t_analytical_elastic = getFTensor0FromVec(analytical_elastic);
489 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
490 const auto material_params =
491 getMaterialParams(t_analytical_elastic, b.poissonRatio);
492 t_young_modulus = material_params.youngModulus;
493 t_mu = material_params.shearModulusG;
494 t_lambda = material_params.lambda;
496 CHKERR evalMatD(material_params.bulkModulusK,
497 material_params.shearModulusG);
498 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
499 material_params.shearModulusG);
500 ++t_analytical_elastic;
505 Tag tag_heterogenous_mat;
506 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_handle(
508 tag_heterogenous_mat);
510 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_length(
511 tag_heterogenous_mat, tag_length);
512 if (tag_length != 1) {
514 "heterogeneous Young's modulus tag should be 1 but is %d",
519 double elem_young_mod = 0.0;
520 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
521 tag_heterogenous_mat, &fe_ent, 1, &elem_young_mod);
523 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
524 const auto material_params =
525 getMaterialParams(elem_young_mod, b.poissonRatio);
526 t_young_modulus = material_params.youngModulus;
527 t_mu = material_params.shearModulusG;
528 t_lambda = material_params.lambda;
530 CHKERR evalMatD(material_params.bulkModulusK,
531 material_params.shearModulusG);
532 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
533 material_params.shearModulusG);
538 const EntityHandle *vert_conn;
540 CHKERR op_ptr->getPtrFE()->mField.get_moab().get_connectivity(
541 fe_ent, vert_conn, vert_num,
true);
543 VectorDouble vert_young_mod(vert_num);
544 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
545 tag_heterogenous_mat, vert_conn, vert_num, &vert_young_mod[0]);
547 auto t_shape_n = data.getFTensor0N();
548 int nb_shape_fn = data.getN(
NOBASE).size2();
550 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
552 auto t_vert_young_mod = getFTensor0FromVec(vert_young_mod);
553 for (
int bb = 0; bb != nb_shape_fn; ++bb) {
554 t_young_modulus += t_vert_young_mod * t_shape_n;
558 const auto material_params =
559 getMaterialParams(t_young_modulus, b.poissonRatio);
560 t_young_modulus = material_params.youngModulus;
561 t_mu = material_params.shearModulusG;
562 t_lambda = material_params.lambda;
564 CHKERR evalMatD(material_params.bulkModulusK,
565 material_params.shearModulusG);
566 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
567 material_params.shearModulusG);
572 "Unsupported heterogeneous Young's modulus interpolation "
578 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
579 t_young_modulus = b.youngModulus;
580 t_mu = b.shearModulusG;
581 t_lambda = b.bulkModulusK - 2 * b.shearModulusG / 3;
583 CHKERR evalMatD(b.bulkModulusK, b.shearModulusG);
584 CHKERR evalInvMatDPtr(b.bulkModulusK, b.shearModulusG);
593 const auto material_params = getMaterialParams(this->E, this->
nu);
595 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
596 t_young_modulus = material_params.youngModulus;
597 t_mu = material_params.shearModulusG;
598 t_lambda = material_params.lambda;
599 CHKERR evalMatD(material_params.bulkModulusK,
600 material_params.shearModulusG);
601 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
602 material_params.shearModulusG);
612 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
613 SmartPetscObj<Vec> assemble_vec,
614 boost::shared_ptr<TopologicalData> topo_ptr,
615 const double alpha_u,
616 boost::shared_ptr<double> J_ptr);
622 MoFEMErrorCode
assemble(
int row_side, EntityType row_type,
629 boost::shared_ptr<double>
JPtr;
635 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
636 SmartPetscObj<Vec> assemble_vec,
637 boost::shared_ptr<TopologicalData> topo_ptr,
638 const double alpha_u,
639 boost::shared_ptr<double> J_ptr)
override {
641 topo_ptr, alpha_u, J_ptr);
668template <
int STRIDEMATD>
671 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha_u)
674template <
int STRIDEMATD>
678 CHKERR integrateHencky(data);
682template <
int STRIDEMATD>
688 auto t_L = FTensor::SymmLTensor<double, 3>();
690 int nb_dofs = data.getIndices().size();
691 int nb_integration_pts = data.getN().size1();
692 auto v = getVolume();
693 auto t_w = getFTensor0IntegrationWeight();
694 auto t_approx_P_adjoint_log_du =
695 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
696 auto t_log_stretch_h1 =
697 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
698 auto t_dot_log_u =
dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
699 auto t_plasticF =
dataAtPts->getFTensorPlasticF(nb_integration_pts);
701 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(
dataAtPts->matD);
707 auto get_ftensor2 = [](
auto &
v) {
709 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
712 int nb_base_functions = data.getN().size2();
713 auto t_row_base_fun = data.getFTensor0N();
715 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
716 const double det_plasticF = determinantTensor3by3(t_plasticF);
717 const double a =
v * t_w * det_plasticF;
718 auto t_nf = get_ftensor2(nF);
722 t_D(
i,
j,
k,
l) * (t_log_stretch_h1(
k,
l) +
alphaU * t_dot_log_u(
k,
l));
725 a * (t_approx_P_adjoint_log_du(L) - t_L(
i,
j, L) * t_T(
i,
j));
728 for (; bb != nb_dofs / 6; ++bb) {
729 t_nf(L) -= t_row_base_fun * t_residual(L);
733 for (; bb != nb_base_functions; ++bb)
738 ++t_approx_P_adjoint_log_du;
747template <
int STRIDEMATD>
749 std::string row_field, std::string col_field,
750 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha)
758 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
759 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
760 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
762 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap(smv) {}
778 for (
auto &ext_strain_block : (*externalStrainVecPtr)) {
780 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
783 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
784 scalingMethodsMap.end()) {
786 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
789 <<
"No scaling method found for " << ext_strain_block.blockName;
792 int nb_dofs = data.getIndices().size();
793 int nb_integration_pts = data.getN().size1();
794 auto v = getVolume();
795 auto t_w = getFTensor0IntegrationWeight();
796 auto t_plasticF =
dataAtPts->getFTensorPlasticF(nb_integration_pts);
799 double external_strain_val;
800 VectorDouble v_external_strain;
801 auto block_name =
"(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
802 std::regex reg_name(block_name);
803 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
804 VectorDouble analytical_external_strain;
805 std::string block_name_tmp;
806 std::tie(block_name_tmp, v_external_strain) =
808 ext_strain_block.blockName);
811 external_strain_val =
scale * ext_strain_block.val;
813 v_external_strain.resize(nb_integration_pts);
814 std::fill(v_external_strain.begin(), v_external_strain.end(),
815 external_strain_val);
817 auto t_external_strain = getFTensor0FromVec(v_external_strain);
819 auto t_L = FTensor::SymmLTensor<double, 3>();
825 auto get_ftensor2 = [](
auto &
v) {
827 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
830 int nb_base_functions = data.getN().size2();
831 auto t_row_base_fun = data.getFTensor0N();
832 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
833 auto tr = 3.0 * t_external_strain;
834 const double det_plasticF = determinantTensor3by3(t_plasticF);
835 const double a =
v * t_w * det_plasticF;
836 auto t_nf = get_ftensor2(nF);
843 t_residual(L) =
a * (t_L(
i,
j, L) * t_T(
i,
j));
846 for (; bb != nb_dofs / 6; ++bb) {
847 t_nf(L) += t_row_base_fun * t_residual(L);
851 for (; bb != nb_base_functions; ++bb)
863template <
int STRIDEMATD>
868 CHKERR integrateHencky(row_data, col_data);
872template <
int STRIDEMATD>
879 auto t_L = FTensor::SymmLTensor<double, 3>();
880 auto t_diff = FTensor::DiffTensor<double>();
882 int nb_integration_pts = row_data.getN().size1();
883 int row_nb_dofs = row_data.getIndices().size();
884 int col_nb_dofs = col_data.getIndices().size();
886 auto get_ftensor2 = [](MatrixDouble &
m,
const int r,
const int c) {
890 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 0,
c + 3),
891 &
m(r + 0,
c + 4), &
m(r + 0,
c + 5),
893 &
m(r + 1,
c + 0), &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 1,
c + 3),
894 &
m(r + 1,
c + 4), &
m(r + 1,
c + 5),
896 &
m(r + 2,
c + 0), &
m(r + 2,
c + 1), &
m(r + 2,
c + 2), &
m(r + 2,
c + 3),
897 &
m(r + 2,
c + 4), &
m(r + 2,
c + 5),
899 &
m(r + 3,
c + 0), &
m(r + 3,
c + 1), &
m(r + 3,
c + 2), &
m(r + 3,
c + 3),
900 &
m(r + 3,
c + 4), &
m(r + 3,
c + 5),
902 &
m(r + 4,
c + 0), &
m(r + 4,
c + 1), &
m(r + 4,
c + 2), &
m(r + 4,
c + 3),
903 &
m(r + 4,
c + 4), &
m(r + 4,
c + 5),
905 &
m(r + 5,
c + 0), &
m(r + 5,
c + 1), &
m(r + 5,
c + 2), &
m(r + 5,
c + 3),
906 &
m(r + 5,
c + 4), &
m(r + 5,
c + 5)
913 auto v = getVolume();
914 auto t_w = getFTensor0IntegrationWeight();
916 int row_nb_base_functions = row_data.getN().size2();
917 auto t_row_base_fun = row_data.getFTensor0N();
919 auto get_dP = [&]() {
922 DL>::size(dP, nb_integration_pts);
923 auto ts_a = getTSa();
925 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(
dataAtPts->matD);
927 if constexpr (!STRIDEMATD) {
928 t_dP_tmp(L,
J) = -(1 +
alphaU * ts_a) *
929 (t_L(
i,
j, L) * ((t_D(
i,
j,
m,
n) * t_diff(
m,
n,
k,
l)) *
934 L_left(
i,
j, L) = t_L(
i,
j, L);
936 L_right(
k,
l,
J) = t_L(
k,
l,
J);
941 auto t_approx_P_adjoint__dstretch =
942 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
943 auto t_eigen_vals =
dataAtPts->getFTensorEigenVals(nb_integration_pts);
944 auto t_eigen_vecs =
dataAtPts->getFTensorEigenVecs(nb_integration_pts);
947 auto t_dP = get_stress();
948 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
949 if constexpr (STRIDEMATD) {
962 t_sym(
i,
j) = (t_approx_P_adjoint__dstretch(
i,
j) ||
963 t_approx_P_adjoint__dstretch(
j,
i));
968 t_dP(L,
J) = t_L(
i,
j, L) *
969 ((t_diff2_uP2(
i,
j,
k,
l) + t_diff2_uP2(
k,
l,
i,
j)) *
975 ++t_approx_P_adjoint__dstretch;
980 auto t_dP = get_stress();
981 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
982 if constexpr (STRIDEMATD) {
991 t_dP(L,
J) = t_dP_tmp(L,
J);
1000 auto t_dP = get_dP();
1001 auto t_plasticF =
dataAtPts->getFTensorPlasticF(nb_integration_pts);
1003 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1004 const double det_plasticF = determinantTensor3by3(t_plasticF);
1005 const double a =
v * t_w * det_plasticF;
1008 for (; rr != row_nb_dofs / 6; ++rr) {
1009 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1010 auto t_m = get_ftensor2(K, 6 * rr, 0);
1011 for (
int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1012 const double b =
a * t_row_base_fun * t_col_base_fun;
1013 t_m(L,
J) -= b * t_dP(L,
J);
1020 for (; rr != row_nb_base_functions; ++rr) {
1031template <
int STRIDEMATD>
1033 STRIDEMATD>::OpCalculateHelmholtzFreeEnergy(
1034 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1035 boost::shared_ptr<double> total_helmholtz_free_energy_ptr)
1037 totalHelmholtzFreeEnergyPtr(total_helmholtz_free_energy_ptr) {
1041 "dataAtPts is not allocated. Please set it before "
1042 "using this operator.");
1046template <
int STRIDEMATD>
1057 int nb_integration_pts = getGaussPts().size2();
1058 auto t_log_u =
dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1064 "wrong matD size, number of columns should be %d but is %zu",
1067 if constexpr (STRIDEMATD != 0) {
1068 if (mat_d.size1() != nb_integration_pts) {
1070 "wrong matD size, number of rows should be %d but is %zu",
1071 nb_integration_pts, mat_d.size1());
1076 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(
dataAtPts->matD);
1078 dataAtPts->energyAtPts.resize(nb_integration_pts,
false);
1079 auto t_energy = getFTensor0FromVec(
dataAtPts->energyAtPts);
1081 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1083 t_energy = 0.5 * (t_log_u(
i,
j) * (t_D(
i,
j,
k,
l) * t_log_u(
k,
l)));
1090 if (totalHelmholtzFreeEnergyPtr) {
1091 auto t_w = getFTensor0IntegrationWeight();
1092 auto t_energy = getFTensor0FromVec(
dataAtPts->energyAtPts);
1093 double loc_energy = 0;
1094 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1095 loc_energy += t_energy * t_w;
1099 *totalHelmholtzFreeEnergyPtr += getMeasure() * loc_energy;
1105template <
int STRIDEMATD>
1108 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1109 boost::shared_ptr<MatrixDouble> strain_ptr,
1110 boost::shared_ptr<MatrixDouble> stress_ptr,
1111 boost::shared_ptr<HMHHencky> hencky_ptr)
1113 strainPtr(strain_ptr), stressPtr(stress_ptr), henckyPtr(hencky_ptr) {
1114 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE],
false);
1115 doEntities[MBVERTEX] =
true;
1118template <
int STRIDEMATD>
1130 auto nb_integration_pts = stressPtr->size1();
1132 if (nb_integration_pts != getGaussPts().size2()) {
1134 "inconsistent number of integration points");
1138 CHKERR henckyPtr->computeMaterialParamsAtPts<STRIDEMATD>(
this, data,
1142 MatrixSizeHelper<GetFTensor2SymmetricFromMatType<3, -1,
DL>,
DL>::size(
1143 *strainPtr, nb_integration_pts);
1144 auto t_strain = get_strain();
1146 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
1150 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
dataAtPts->matD);
1155 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
1156 t_strain(
i,
j) = t_inv_D(
i,
j,
k,
l) * t_stress(
k,
l);
1160 t_stress_symm_debug(
i,
j) = (t_stress(
i,
j) || t_stress(
j,
i)) / 2;
1162 t_stress_symm_debug_diff(
i,
j) =
1163 t_D(
i,
j,
k,
l) * t_strain(
k,
l) - t_stress_symm_debug(
i,
j);
1165 t_stress_symm_debug_diff(
i,
j) * t_stress_symm_debug_diff(
i,
j);
1166 double nrm0 = t_stress_symm_debug(
i,
j) * t_stress_symm_debug(
i,
j) +
1167 std::numeric_limits<double>::epsilon();
1168 constexpr double eps = 1e-10;
1169 if (std::fabs(std::sqrt(nrm / nrm0)) >
eps) {
1171 <<
"Stress symmetry check failed: " << std::endl
1172 << t_stress_symm_debug_diff << std::endl
1175 "Norm is too big: " + std::to_string(nrm / nrm0));
1188template <
typename OP_PTR>
1189std::tuple<std::string, VectorDouble>
1191 const std::string block_name) {
1193 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1195 auto ts_time = op_ptr->getTStime();
1196 auto ts_time_step = op_ptr->getTStimeStep();
1202 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1205 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1208 if (v_analytical_expr.size() != nb_gauss_pts)
1210 "Wrong number of integration pts");
1213 return std::make_tuple(block_name, v_analytical_expr);
1216template <
typename OP_PTR>
1219 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1221 auto ts_time = op_ptr->getTStime();
1222 auto ts_time_step = op_ptr->getTStimeStep();
1229 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1232 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1235 if (v_analytical_expr.size() != nb_gauss_pts)
1237 "Wrong number of integration pts");
1240 return v_analytical_expr;
1247 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1248 SmartPetscObj<Vec> assemble_vec,
1249 boost::shared_ptr<TopologicalData> topo_ptr,
const double alpha_u,
1250 boost::shared_ptr<double> J_ptr)
1252 JPtr(J_ptr), topoDataPtr(topo_ptr), assembleVec(assemble_vec) {}
1256 CHKERR integrateHencky(data);
1265 auto t_L = FTensor::SymmLTensor<double, 3>();
1267 int nb_dofs = data.getIndices().size();
1268 int nb_integration_pts = data.getN().size1();
1269 auto v = getVolume();
1273 auto get_ftensor1 = [](
auto &
v) {
1275 &
v[0], &
v[1], &
v[2]);
1279 int nb_base_functions = data.getN().size2();
1281 auto integrate = [&](
auto t_D) {
1284 auto t_w = getFTensor0IntegrationWeight();
1285 auto t_det = topoDataPtr->getFTensorDetJacobian(nb_integration_pts);
1286 auto t_inv_jac = topoDataPtr->getFTensorInvJacobian(nb_integration_pts);
1288 auto t_var_log_u =
dataAtPts->getFTensorVarLogStreach(nb_integration_pts);
1289 auto t_approx_P =
dataAtPts->getFTensorApproxP(nb_integration_pts);
1290 auto t_approx_P_adjoint_log_du =
1291 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
1293 dataAtPts->getFTensorSmallHdLogStretch(nb_integration_pts);
1294 auto t_log_stretch_h1 =
1295 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1303 auto t_diff_base = data.getFTensor1DiffN<
SPACE_DIM>();
1304 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1305 const double a =
v * t_w;
1308 t_T(
i,
j) = t_D(
i,
j,
k,
l) *
1309 (t_log_stretch_h1(
k,
l) );
1312 t_stress_residual(L) = t_L(
i,
j, L) * t_T(
i,
j);
1315 t_residual(L) = t_approx_P_adjoint_log_du(L) - t_stress_residual(L);
1317 locJ -= (
a * t_det) * t_residual(L) * t_var_log_u(L);
1320 t_cof(
I,
J) = t_det * t_inv_jac(
J,
I);
1322 const double var_stress_residual = t_var_log_u(L) * t_stress_residual(L);
1327 t_approx_P_adjoint_log_du_dX;
1328 t_approx_P_adjoint_log_du_dX(L,
I,
J) =
1329 t_h_dlog_u(
i,
I, L) * t_approx_P(
i,
J);
1332 t_residual_dX(
I,
J) =
1333 t_var_log_u(L) * t_approx_P_adjoint_log_du_dX(L,
I,
J) -
1334 var_stress_residual * t_cof(
I,
J);
1336 auto t_nf = get_ftensor1(nF);
1338 for (; bb != nb_dofs /
SPACE_DIM; ++bb) {
1339 t_nf(
i) -=
a * t_residual_dX(
i,
j) * t_diff_base(
j);
1343 for (; bb != nb_base_functions; ++bb)
1351 ++t_approx_P_adjoint_log_du;
1360 if (!
dataAtPts->physicsPtr->getFeatures().test(
1363 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(
dataAtPts->matD));
1366 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(
dataAtPts->matD));
1373 EntityType row_type,
1377 double *vec_ptr = nF.data().data();
1378 const int nb_dofs = data.getIndices().size();
1379 int *ind_ptr = data.getIndices().data().data();
1380 CHKERR VecSetValues(assembleVec, nb_dofs, ind_ptr, vec_ptr, ADD_VALUES);
1382 if (row_type == MBVERTEX) {
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
#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.
@ 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)
std::tuple< std::string, VectorDouble > getAnalyticalExternalStrain(OP_PTR op_ptr, VectorDouble &analytical_expr, const std::string block_name)
static auto calc_effective_elastic_params(double E, double nu, double diagonal_strain)
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
VectorDouble getAnalyticalElastic(OP_PTR op_ptr, const std::string block_name)
static constexpr auto size_symm
boost::shared_ptr< VectorDouble > VectorPtr
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 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.
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< double > totalHelmholtzFreeEnergyPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
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 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)
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
MoFEMErrorCode integrate(EntData &data) override
SmartPetscObj< Vec > assembleVec
boost::shared_ptr< TopologicalData > topoDataPtr
MoFEMErrorCode integrateHencky(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
PetscBool effectiveNehookeanStiffness
VolUserDataOperator * returnOpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, VectorPtr external_pressure_ptr) override
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) override
VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u) override
HMHHencky(MoFEM::Interface &m_field, const double E, const double nu, const Features features)
MoFEMErrorCode extractBlockData(Sev sev)
MoFEMErrorCode getOptions()
std::vector< BlockData > blockData
static constexpr int StrideMatD
UserDataOperator * returnOpJacobian(const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr) override
MoFEMErrorCode extractBlockData(std::vector< const CubitMeshSets * > meshset_vec_ptr, Sev sev)
bool providesHelmholtzFreeEnergy() const override
VolUserDataOperator * returnOpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr, boost::shared_ptr< MatrixDouble > strain_ptr) override
VolUserDataOperator * returnOpCalculateHelmholtzFreeEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_helmholtz_free_energy_ptr) override
double effectiveDiagonalStrain
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha) override
MoFEM::Interface & mField
VolUserDataOperator * returnOpCalculateVarStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr) override
const Features & getFeatures() const
std::bitset< LAST_FEATURE > Features
Features materialFeatures
@ NON_HOMOGENEOUS_MATERIAL
virtual moab::Interface & get_moab()=0
bool sYmm
If true assume that matrix is symmetric structure.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
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.