159 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
160 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
161 PetscInt choice_base_value = AINSWORTH;
162 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL,
"-base", list_bases,
163 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
165 switch (choice_base_value) {
169 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
174 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
186 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-order", &
order, PETSC_NULLPTR);
191 auto project_ho_geometry = [&]() {
192 Projection10NodeCoordsOnField ent_method(
mField,
"GEOMETRY");
195 CHKERR project_ho_geometry();
197 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-use_adolc_material",
202 "ADOL-C support is not enabled. Please reconfigure with "
203 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
207 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use ADOL-C material model";
209 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use Hencky material model";
212 auto tag_meshest = [&]() {
215 auto set_block = [&](
auto name,
int dim) {
216 std::map<int, Range> map;
217 auto set_tag_impl = [&](
auto name) {
220 auto bcs = mesh_mng->getCubitMeshsetPtr(
222 std::regex((boost::format(
"%s(.*)") % name).str())
225 std::map<int, int> ids_map;
227 for (
auto bc : bcs) {
228 int id = bc->getMeshsetId();
229 ids_map[id] = bit_id;
232 for (
auto bc : bcs) {
236 map[ids_map[bc->getMeshsetId()]] = r;
238 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" : "
239 << ids_map[bc->getMeshsetId()] <<
" has " << r.size()
245 CHKERR set_tag_impl(name);
247 return std::make_pair(name, map);
250 auto set_skin = [&](
auto &&map) {
251 for (
auto &
m : map.second) {
255 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
256 <<
m.second.size() <<
" entities";
261 auto set_tag = [&](
auto &&map) {
263 auto name = map.first;
264 int def_val[] = {-1};
266 name, 1, MB_TYPE_INTEGER, th,
267 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
269 for (
auto &
m : map.second) {
271 for (
auto ent :
m.second) {
276 if (current_id != -1) {
349 auto add_domain_ops_lhs = [&](
auto &pip) {
354 HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
355 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
359 auto add_domain_ops_rhs = [&](
auto &pip) {
364 HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
365 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
369 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
370 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
373 CHKERR add_domain_ops_rhs(pipeline_mng->getOpEvaluationPipeline());
374 auto &domain_reaction_fe = pipeline_mng->getEvaluationFE();
375 domain_reaction_fe->postProcessHook =
376 EssentialPreProcReaction<DisplacementCubitBcData>(
mField,
379 PetscBool post_proc_vol;
380 PetscBool post_proc_skin;
383 post_proc_vol = PETSC_TRUE;
384 post_proc_skin = PETSC_FALSE;
386 post_proc_vol = PETSC_FALSE;
387 post_proc_skin = PETSC_TRUE;
390 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
391 &post_proc_vol, PETSC_NULLPTR);
392 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
393 &post_proc_skin, PETSC_NULLPTR);
396 auto create_post_proc_fe = [&]() {
397 auto post_proc_ele_domain = [
this](
auto &pip_domain) {
400 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
401 mField, pip_domain,
"U",
"MAT_ELASTIC", Sev::inform);
405 auto post_proc_map = [&](
auto &pip,
auto u_ptr,
auto common_ptr) {
408 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
410 pip->getOpPtrVector().push_back(
412 new OpPPMap(pip->getPostProcMesh(), pip->getMapGaussPts(), {},
414 {{
"GRAD", common_ptr->matGradPtr},
415 {
"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
420 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
421 if (post_proc_skin == PETSC_FALSE)
422 return boost::shared_ptr<PostProcEleBdy>();
424 auto domain_fe_name =
simple->getDomainFEName();
425 auto u_ptr = boost::make_shared<MatrixDouble>();
426 pip_bdy->getOpPtrVector().push_back(
427 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
430 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
431 pip_bdy->getOpPtrVector().push_back(op_loop_side);
432 CHKERR post_proc_map(pip_bdy, u_ptr, common_ptr);
436 auto push_post_proc_domain = [&](
auto &pip_domain) {
437 if (post_proc_vol == PETSC_FALSE)
438 return boost::shared_ptr<PostProcEleDomain>();
440 auto u_ptr = boost::make_shared<MatrixDouble>();
441 pip_domain->getOpPtrVector().push_back(
442 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
443 auto common_ptr = post_proc_ele_domain(pip_domain->getOpPtrVector());
445 CHKERR post_proc_map(pip_domain, u_ptr, common_ptr);
450 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(
mField);
451 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(
mField);
453 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
454 push_post_proc_bdy(post_proc_fe_bdy));
457 auto post_proc_pair = create_post_proc_fe();
458 postProcDomainFe = post_proc_pair.first;
459 postProcBdyFe = post_proc_pair.second;
545#ifdef WITH_ADOL_C_UMAT
547 constexpr int umat_model_type =
549 auto umat_physical_equations_ptr =
554 CHKERR umat_physical_equations_ptr->getOptions(&
mField);
555 CHKERR umat_physical_equations_ptr->recordTape();
568 #ifdef WITH_ADOL_C_GENERIC_ELASTIC
570 auto generic_physical_equations_ptr =
578 generic_physical_equations_ptr->hookEvaluateVariable =
580 generic_physical_equations_ptr->hookEvaluateDerivatives =
582 generic_physical_equations_ptr->hookUpdateState =
585 CHKERR generic_physical_equations_ptr->getOptions(&
mField);
586 CHKERR generic_physical_equations_ptr->recordTape();
589 material_map[generic_physical_equations_ptr->tAg] =
590 generic_physical_equations_ptr;
595 #ifdef WITH_ADOL_C_SIMPLE_DAMAGE
597 auto generic_physical_equations_ptr =
601 "GenericElasticSimpleDamage"));
604 mField, boost::dynamic_pointer_cast<MatOps::GenericElastic>(
605 generic_physical_equations_ptr));
607 CHKERR generic_physical_equations_ptr->getOptions(&
mField);
608 CHKERR generic_physical_equations_ptr->recordTape();
611 material_map[generic_physical_equations_ptr->tAg] =
612 generic_physical_equations_ptr;
624 ->getCubitMeshsetPtr(std::regex(
"MAT_HUHU(.*)"))
628 MatOps::createMatOpsPhysicalEquationsPtr<MatOps::HUHU, modelType>(
635 auto add_domain_ops_lhs = [&](
auto &pip) {
641 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
646 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
652 auto add_domain_ops_rhs = [&](
auto &pip) {
658 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
663 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
669 auto add_domain_ops_update = [&](
auto &pip) {
680 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
681 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
687 CHKERR add_domain_ops_rhs(pipeline_mng->getOpEvaluationPipeline());
688 auto &domain_reaction_fe = pipeline_mng->getEvaluationFE();
689 domain_reaction_fe->postProcessHook =
690 EssentialPreProcReaction<DisplacementCubitBcData>(
mField,
693 PetscBool post_proc_vol;
694 PetscBool post_proc_skin;
697 post_proc_vol = PETSC_TRUE;
698 post_proc_skin = PETSC_FALSE;
700 post_proc_vol = PETSC_FALSE;
701 post_proc_skin = PETSC_TRUE;
704 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
705 &post_proc_vol, PETSC_NULLPTR);
706 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
707 &post_proc_skin, PETSC_NULLPTR);
710 auto create_post_proc_fe = [&]() {
711 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
713 auto post_proc_ele_domain = [&](
auto &pip_domain) {
724 auto post_proc_map = [&](
auto &pip,
auto u_ptr) {
729 auto first_piola_ptr =
731 pip->getOpPtrVector().push_back(
new OpPPMap(
732 pip->getPostProcMesh(), pip->getMapGaussPts(), {}, {{
"U", u_ptr}},
734 pip->getOpPtrVector().push_back(
735 new OpPostProcMapInMoab<MAT_DIM, MAT_DIM>(
736 pip->getPostProcMesh(), pip->getMapGaussPts(), {}, {},
737 {{
"GRAD", grad_ptr}, {
"FIRST_PIOLA", first_piola_ptr}}, {}));
742 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
743 if (post_proc_skin == PETSC_FALSE)
744 return boost::shared_ptr<PostProcEleBdy>();
745 auto simple = mField.getInterface<Simple>();
746 auto domain_fe_name =
simple->getDomainFEName();
747 auto u_ptr = boost::make_shared<MatrixDouble>();
748 pip_bdy->getOpPtrVector().push_back(
749 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
751 new OpLoopSide<SideEle>(mField, domain_fe_name,
SPACE_DIM);
752 CHKERR post_proc_ele_domain(op_loop_side->getOpPtrVector());
753 pip_bdy->getOpPtrVector().push_back(op_loop_side);
754 CHKERR post_proc_map(pip_bdy, u_ptr);
758 auto push_post_proc_domain = [&](
auto &pip_domain) {
759 if (post_proc_vol == PETSC_FALSE)
760 return boost::shared_ptr<PostProcEleDomain>();
761 auto u_ptr = boost::make_shared<MatrixDouble>();
762 pip_domain->getOpPtrVector().push_back(
763 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
764 CHKERR post_proc_ele_domain(pip_domain->getOpPtrVector());
766 if (physicalEquationsPtr) {
767 auto state_tags = physicalEquationsPtr->matOpsDataPtr->getStateTags();
768 if (!state_tags.empty()) {
771 selected_state_tags.reserve(state_tags.size());
772 statev_tags.reserve(state_tags.size());
774 constexpr auto statev_prefix =
"UMAT_STATEV_";
775 constexpr auto statev_prefix_len =
sizeof(
"UMAT_STATEV_") - 1;
776 auto get_statev_index = [&](
const std::string &name) {
777 return std::stoi(name.substr(statev_prefix_len));
780 for (
const auto &state_tag : state_tags) {
781 const auto &name = state_tag.name;
783 if (name ==
"UMAT_DFGRD0" || name ==
"UMAT_STRESS") {
784 selected_state_tags.push_back(state_tag);
788 if (name.rfind(statev_prefix, 0) == 0) {
789 statev_tags.push_back(state_tag);
793 std::sort(statev_tags.begin(), statev_tags.end(),
794 [&](
const auto &lhs,
const auto &rhs) {
795 return get_statev_index(lhs.name) <
796 get_statev_index(rhs.name);
798 if (statev_tags.size() > 10)
799 statev_tags.resize(10);
800 selected_state_tags.insert(selected_state_tags.end(),
801 statev_tags.begin(), statev_tags.end());
803 if (selected_state_tags.empty())
806 auto simple = mField.getInterface<Simple>();
810 auto op_loop_this =
new OpLoopThis<DomainEle>(
811 mField,
simple->getDomainFEName(), Sev::noisy);
813 pip_domain->getOpPtrVector().push_back(op_loop_this);
814 CHKERR addTagDGProjectionOps<SPACE_DIM, SPACE_DIM>(
815 mField.get_moab(), pip_domain->getOpPtrVector(),
816 op_loop_this->getThisFEPtr()->getOpPtrVector(),
817 pip_domain->getPostProcMesh(), pip_domain->getMapGaussPts(),
818 selected_state_tags, state_order, approximationBase);
822 CHKERR post_proc_map(pip_domain, u_ptr);
827 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(mField);
828 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
830 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
831 push_post_proc_bdy(post_proc_fe_bdy));
834 auto post_proc_pair = create_post_proc_fe();
835 postProcDomainFe = post_proc_pair.first;
836 postProcBdyFe = post_proc_pair.second;
840 "ADOL-C support is not enabled. Please reconfigure with "
841 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
853 auto dm =
simple->getDM();
854 auto ts = pipeline_mng->createTSIM();
856 auto add_extra_finite_elements_to_solver_pipelines = [&]() {
859 auto pre_proc_ptr = boost::make_shared<FEMethod>();
860 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
861 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
863 auto time_scale = boost::make_shared<ExampleTimeScale>();
865 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
867 CHKERR EssentialPreProc<DisplacementCubitBcData>(
mField, pre_proc_ptr,
868 {time_scale},
false)();
872 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
874 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
876 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
877 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
878 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
879 mField, post_proc_rhs_ptr, 1.)();
882 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
884 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
885 mField, post_proc_lhs_ptr, 1.)();
888 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
889 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
892 auto ts_ctx_ptr = getDMTsCtx(
simple->getDM());
893 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
894 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
895 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
896 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
902 CHKERR add_extra_finite_elements_to_solver_pipelines();
904 auto create_monitor_fe = [dm](
auto &&post_proc_fe) {
905 return boost::make_shared<Monitor>(dm.get(), post_proc_fe);
909 boost::shared_ptr<FEMethod> null_fe;
918 CHKERR DMMoFEMTSSetMonitor(dm, ts,
simple->getDomainFEName(), null_fe,
919 null_fe, monitor_ptr);
923 CHKERR TSSetMaxTime(ts, ftime);
924 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
926 auto B = createDMMatrix(dm);
927 CHKERR TSSetI2Jacobian(ts,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
928 auto D = createDMVector(
simple->getDM());
930 CHKERR TSSetFromOptions(ts);
938 CHKERR TSGetTime(ts, &ftime);
940 PetscInt steps, snesfails, rejects, nonlinits, linits;
941 CHKERR TSGetStepNumber(ts, &steps);
942 CHKERR TSGetSNESFailures(ts, &snesfails);
943 CHKERR TSGetStepRejections(ts, &rejects);
944 CHKERR TSGetSNESIterations(ts, &nonlinits);
945 CHKERR TSGetKSPIterations(ts, &linits);
947 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
949 steps, rejects, snesfails, ftime, nonlinits, linits);
960 auto dm =
simple->getDM();
962 auto T = createDMVector(
simple->getDM());
963 CHKERR DMoFEMMeshToLocalVector(
simple->getDM(), T, INSERT_VALUES,
966 CHKERR VecNorm(T, NORM_2, &nrm2);
967 MOFEM_LOG(
"EXAMPLE", Sev::inform) <<
"Solution norm " << nrm2;
969 auto post_proc_norm_fe = boost::make_shared<DomainEle>(
mField);
971 auto post_proc_norm_rule_hook = [](int, int,
int p) ->
int {
return 2 * p; };
972 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
975 post_proc_norm_fe->getOpPtrVector(), {H1},
"GEOMETRY");
977 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
981 CHKERR VecZeroEntries(norms_vec);
983 auto u_ptr = boost::make_shared<MatrixDouble>();
984 post_proc_norm_fe->getOpPtrVector().push_back(
985 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
987 post_proc_norm_fe->getOpPtrVector().push_back(
988 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
997 post_proc_norm_fe->getOpPtrVector().push_back(
998 new OpCalcNormL2Tensor2<MAT_DIM, MAT_DIM>(m_P, norms_vec,
1003 "ADOL-C support is not enabled. Please reconfigure with "
1004 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
1007 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1008 mField, post_proc_norm_fe->getOpPtrVector(),
"U",
"MAT_ELASTIC",
1010 post_proc_norm_fe->getOpPtrVector().push_back(
1011 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(
1012 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
1015 CHKERR DMoFEMLoopFiniteElements(dm,
simple->getDomainFEName(),
1018 CHKERR VecAssemblyBegin(norms_vec);
1019 CHKERR VecAssemblyEnd(norms_vec);
1023 const double *norms;
1024 CHKERR VecGetArrayRead(norms_vec, &norms);
1026 <<
"norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
1028 <<
"norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
1029 CHKERR VecRestoreArrayRead(norms_vec, &norms);
1052 auto displacement_ptr = boost::make_shared<MatrixDouble>();
1054 constexpr double applied_F_zz = 0.99;
1056 t_P_expected(
i,
J) = 0.;
1057 auto set_linear_elastic_piola = [&](
const double strain_zz,
1058 const double d_strain_d_F_zz) {
1059 constexpr double E = 1.;
1060 constexpr double nu = 0.3;
1061 const double lambda =
E * nu / ((1. + nu) * (1. - 2. * nu));
1062 const double mu =
E / (2. * (1. + nu));
1063 for (
int d = 0; d !=
SPACE_DIM - 1; ++d)
1064 t_P_expected(d, d) =
lambda * strain_zz;
1066 (
lambda + 2. *
mu) * strain_zz * d_strain_d_F_zz;
1069 auto set_neohookean_piola = [&](
const double F_zz,
const double J) {
1070 const double log_J = std::log(
J);
1071 const double inv_F_zz = 1. / F_zz;
1072 constexpr double c10 = 1.;
1073 constexpr double K = 1.;
1074 for (
int d = 0; d !=
SPACE_DIM - 1; ++d)
1075 t_P_expected(d, d) = K * log_J;
1077 2. * c10 * (F_zz - inv_F_zz) + K * log_J * inv_F_zz;
1080 auto eval_piola_at_point = [&](boost::shared_ptr<MatrixDouble> &mat_p,
1081 std::array<double, 3> field_eval_coords) {
1084 auto field_eval_data = field_eval_ptr->getData<
DomainEle>();
1086 simple->getDomainFEName());
1087 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1089 auto fe = field_eval_data->feMethodPtr;
1090 fe->getRuleHook = [](int, int, int) {
return -1; };
1092 auto &pipeline = fe->getOpPtrVector();
1097 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", displacement_ptr));
1100 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1101 mField, pipeline,
"U",
"MAT_ELASTIC", Sev::inform);
1102 mat_p = common_ptr->getMatFirstPiolaStress();
1110 "ADOL-C support is not enabled. Please reconfigure with "
1111 "-DWITH_ADOL_C=ON and recompile to use MatOps material model.");
1115 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
1121 boost::shared_ptr<MatrixDouble> mat_p;
1122 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
1126 const double hencky_strain_zz = std::log(applied_F_zz);
1127 set_linear_elastic_piola(hencky_strain_zz, 1. / applied_F_zz);
1132 const double J = applied_F_zz;
1133 set_neohookean_piola(applied_F_zz,
J);
1138 const double small_strain_zz = applied_F_zz - 1.;
1139 set_linear_elastic_piola(small_strain_zz, 1.);
1145 constexpr double stretch = 1.01;
1146 const double piola = 2. * (stretch - 1. / stretch) +
1147 3. * std::log(stretch) / stretch;
1149 t_P_expected(
i,
J) = piola *
delta(
i,
J);
1150 CHKERR eval_piola_at_point(mat_p, {1.37, 0.41, 0.});
1151 auto t_u = MatrixSizeHelper<GetFTensor1FromMatType<2, -1, DL>, DL>::get(
1152 *displacement_ptr, 1)();
1153 const double u_err = std::hypot(t_u(0) - 0.0137, t_u(1) - 0.0041);
1155 <<
"Axisymmetric displacement error " << u_err;
1156 if (!std::isfinite(u_err) || u_err > 1e-8)
1158 "Wrong axisymmetric displacement. Error %6.4e", u_err);
1164 "Wrong Piola stress test number.");
1169 CHKERR eval_piola_at_point(mat_p, {0.123, -0.087, 0.193});
1171 MatrixSizeHelper<GetFTensor2FromMatType<
MAT_DIM,
MAT_DIM, -1, DL>,
1172 DL>::get(*mat_p, 1)();
1173 t_P_diff(
i,
J) = t_P(
i,
J) - t_P_expected(
i,
J);
1174 const double p_err = std::sqrt(t_P_diff(
i,
J) * t_P_diff(
i,
J));
1175 for (
int r = 0; r !=
MAT_DIM; ++r)
1178 <<
"Piola stress test " << test_nb <<
" P(" << r <<
", " <<
c
1179 <<
") actual " << std::scientific << t_P(r,
c) <<
" expected "
1180 << t_P_expected(r,
c) <<
" diff " << t_P_diff(r,
c);
1182 <<
"Piola stress test " << test_nb <<
" error " << std::scientific
1184 if (!std::isfinite(p_err) || p_err > 1e-8)
1186 "Wrong Piola stress. Error %6.4e", p_err);