158 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
159 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
160 PetscInt choice_base_value = AINSWORTH;
161 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL,
"-base", list_bases,
162 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
164 switch (choice_base_value) {
168 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
173 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
185 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-order", &
order, PETSC_NULLPTR);
190 auto project_ho_geometry = [&]() {
191 Projection10NodeCoordsOnField ent_method(
mField,
"GEOMETRY");
194 CHKERR project_ho_geometry();
196 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-use_adolc_material",
201 "ADOL-C support is not enabled. Please reconfigure with "
202 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
206 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use ADOL-C material model";
208 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use Hencky material model";
211 auto tag_meshest = [&]() {
214 auto set_block = [&](
auto name,
int dim) {
215 std::map<int, Range> map;
216 auto set_tag_impl = [&](
auto name) {
219 auto bcs = mesh_mng->getCubitMeshsetPtr(
221 std::regex((boost::format(
"%s(.*)") %
name).str())
224 std::map<int, int> ids_map;
226 for (
auto bc : bcs) {
227 int id = bc->getMeshsetId();
228 ids_map[id] = bit_id;
231 for (
auto bc : bcs) {
235 map[ids_map[bc->getMeshsetId()]] = r;
237 <<
"Block " <<
name <<
" id " << bc->getMeshsetId() <<
" : "
238 << ids_map[bc->getMeshsetId()] <<
" has " << r.size()
246 return std::make_pair(
name, map);
249 auto set_skin = [&](
auto &&map) {
250 for (
auto &
m : map.second) {
254 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
255 <<
m.second.size() <<
" entities";
260 auto set_tag = [&](
auto &&map) {
262 auto name = map.first;
263 int def_val[] = {-1};
265 name, 1, MB_TYPE_INTEGER, th,
266 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
268 for (
auto &
m : map.second) {
270 for (
auto ent :
m.second) {
275 if (current_id != -1) {
348 auto add_domain_ops_lhs = [&](
auto &pip) {
350 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(pip, {
H1},
353 HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
354 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
358 auto add_domain_ops_rhs = [&](
auto &pip) {
360 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(pip, {
H1},
363 HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
364 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
368 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
369 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
372 CHKERR add_domain_ops_rhs(pipeline_mng->getOpEvaluationPipeline());
373 auto &domain_reaction_fe = pipeline_mng->getEvaluationFE();
374 domain_reaction_fe->postProcessHook =
375 EssentialPreProcReaction<DisplacementCubitBcData>(
mField,
378 PetscBool post_proc_vol;
379 PetscBool post_proc_skin;
382 post_proc_vol = PETSC_TRUE;
383 post_proc_skin = PETSC_FALSE;
385 post_proc_vol = PETSC_FALSE;
386 post_proc_skin = PETSC_TRUE;
389 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
390 &post_proc_vol, PETSC_NULLPTR);
391 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
392 &post_proc_skin, PETSC_NULLPTR);
395 auto create_post_proc_fe = [&]() {
396 auto post_proc_ele_domain = [
this](
auto &pip_domain) {
397 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(pip_domain, {
H1},
399 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
400 mField, pip_domain,
"U",
"MAT_ELASTIC", Sev::inform);
404 auto post_proc_map = [&](
auto &pip,
auto u_ptr,
auto common_ptr) {
407 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
409 pip->getOpPtrVector().push_back(
411 new OpPPMap(pip->getPostProcMesh(), pip->getMapGaussPts(), {},
413 {{
"GRAD", common_ptr->matGradPtr},
414 {
"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
419 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
420 if (post_proc_skin == PETSC_FALSE)
421 return boost::shared_ptr<PostProcEleBdy>();
423 auto domain_fe_name =
simple->getDomainFEName();
424 auto u_ptr = boost::make_shared<MatrixDouble>();
425 pip_bdy->getOpPtrVector().push_back(
426 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
429 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
430 pip_bdy->getOpPtrVector().push_back(op_loop_side);
431 CHKERR post_proc_map(pip_bdy, u_ptr, common_ptr);
435 auto push_post_proc_domain = [&](
auto &pip_domain) {
436 if (post_proc_vol == PETSC_FALSE)
437 return boost::shared_ptr<PostProcEleDomain>();
439 auto u_ptr = boost::make_shared<MatrixDouble>();
440 pip_domain->getOpPtrVector().push_back(
441 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
442 auto common_ptr = post_proc_ele_domain(pip_domain->getOpPtrVector());
444 CHKERR post_proc_map(pip_domain, u_ptr, common_ptr);
449 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(
mField);
450 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(
mField);
452 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
453 push_post_proc_bdy(post_proc_fe_bdy));
456 auto post_proc_pair = create_post_proc_fe();
457 postProcDomainFe = post_proc_pair.first;
458 postProcBdyFe = post_proc_pair.second;
543 #ifdef WITH_ADOL_C_UMAT
545 constexpr int umat_model_type =
547 auto umat_physical_equations_ptr =
548 MatOps::createMatOpsPhysicalEquationsPtr<MatOps::UMAT, umat_model_type>(
551 CHKERR umat_physical_equations_ptr->getOptions(&
mField);
552 CHKERR umat_physical_equations_ptr->recordTape();
565 #ifdef WITH_ADOL_C_GENERIC_ELASTIC
567 auto generic_physical_equations_ptr =
575 generic_physical_equations_ptr->hookEvaluateVariable =
577 generic_physical_equations_ptr->hookEvaluateDerivatives =
579 generic_physical_equations_ptr->hookUpdateState =
582 CHKERR generic_physical_equations_ptr->getOptions(&
mField);
583 CHKERR generic_physical_equations_ptr->recordTape();
585 auto &material_map = getMetaPiolaResponseMap(
586 boost::static_pointer_cast<MatOps::MatPiolaResponse>(
588 material_map[generic_physical_equations_ptr->tAg] =
589 boost::static_pointer_cast<MatOps::MatPiolaResponse>(
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();
610 auto &material_map = getMetaPiolaResponseMap(
611 boost::static_pointer_cast<MatOps::MatPiolaResponse>(
613 material_map[generic_physical_equations_ptr->tAg] =
614 boost::static_pointer_cast<MatOps::MatPiolaResponse>(
615 generic_physical_equations_ptr);
626 ->getCubitMeshsetPtr(std::regex(
"MAT_HUHU(.*)"))
630 MatOps::createMatOpsPhysicalEquationsPtr<MatOps::HUHU, modelType>(
637 auto add_domain_ops_lhs = [&](
auto &pip) {
639 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(pip, {
H1},
643 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
648 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
654 auto add_domain_ops_rhs = [&](
auto &pip) {
656 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(pip, {
H1},
660 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
665 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
671 auto add_domain_ops_update = [&](
auto &pip) {
673 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(pip, {
H1},
682 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
683 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
689 CHKERR add_domain_ops_rhs(pipeline_mng->getOpEvaluationPipeline());
690 auto &domain_reaction_fe = pipeline_mng->getEvaluationFE();
691 domain_reaction_fe->postProcessHook =
692 EssentialPreProcReaction<DisplacementCubitBcData>(
mField,
695 PetscBool post_proc_vol;
696 PetscBool post_proc_skin;
699 post_proc_vol = PETSC_TRUE;
700 post_proc_skin = PETSC_FALSE;
702 post_proc_vol = PETSC_FALSE;
703 post_proc_skin = PETSC_TRUE;
706 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
707 &post_proc_vol, PETSC_NULLPTR);
708 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
709 &post_proc_skin, PETSC_NULLPTR);
712 auto create_post_proc_fe = [&]() {
713 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
715 auto post_proc_ele_domain = [&](
auto &pip_domain) {
717 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(pip_domain, {
H1},
726 auto post_proc_map = [&](
auto &pip,
auto u_ptr) {
731 auto first_piola_ptr =
733 pip->getOpPtrVector().push_back(
new OpPPMap(pip->getPostProcMesh(),
734 pip->getMapGaussPts(), {},
735 {{
"U", u_ptr}}, {}, {}));
736 pip->getOpPtrVector().push_back(
737 new OpPostProcMapInMoab<MAT_DIM, MAT_DIM>(
738 pip->getPostProcMesh(), pip->getMapGaussPts(), {}, {},
739 {{
"GRAD", grad_ptr}, {
"FIRST_PIOLA", first_piola_ptr}}, {}));
744 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
745 if (post_proc_skin == PETSC_FALSE)
746 return boost::shared_ptr<PostProcEleBdy>();
747 auto simple = mField.getInterface<Simple>();
748 auto domain_fe_name =
simple->getDomainFEName();
749 auto u_ptr = boost::make_shared<MatrixDouble>();
750 pip_bdy->getOpPtrVector().push_back(
751 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
753 new OpLoopSide<SideEle>(mField, domain_fe_name,
SPACE_DIM);
754 CHKERR post_proc_ele_domain(op_loop_side->getOpPtrVector());
755 pip_bdy->getOpPtrVector().push_back(op_loop_side);
756 CHKERR post_proc_map(pip_bdy, u_ptr);
760 auto push_post_proc_domain = [&](
auto &pip_domain) {
761 if (post_proc_vol == PETSC_FALSE)
762 return boost::shared_ptr<PostProcEleDomain>();
763 auto u_ptr = boost::make_shared<MatrixDouble>();
764 pip_domain->getOpPtrVector().push_back(
765 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
766 CHKERR post_proc_ele_domain(pip_domain->getOpPtrVector());
768 if (physicalEquationsPtr) {
769 auto state_tags = physicalEquationsPtr->matOpsDataPtr->getStateTags();
770 if (!state_tags.empty()) {
773 selected_state_tags.reserve(state_tags.size());
774 statev_tags.reserve(state_tags.size());
776 constexpr auto statev_prefix =
"UMAT_STATEV_";
777 constexpr auto statev_prefix_len =
sizeof(
"UMAT_STATEV_") - 1;
778 auto get_statev_index = [&](
const std::string &
name) {
779 return std::stoi(
name.substr(statev_prefix_len));
782 for (
const auto &state_tag : state_tags) {
783 const auto &
name = state_tag.name;
785 if (
name ==
"UMAT_DFGRD0" ||
name ==
"UMAT_STRESS") {
786 selected_state_tags.push_back(state_tag);
790 if (
name.rfind(statev_prefix, 0) == 0) {
791 statev_tags.push_back(state_tag);
795 std::sort(statev_tags.begin(), statev_tags.end(),
796 [&](
const auto &lhs,
const auto &rhs) {
797 return get_statev_index(lhs.name) <
798 get_statev_index(rhs.name);
800 if (statev_tags.size() > 10)
801 statev_tags.resize(10);
802 selected_state_tags.insert(selected_state_tags.end(),
803 statev_tags.begin(), statev_tags.end());
805 if (selected_state_tags.empty())
808 auto simple = mField.getInterface<Simple>();
812 auto op_loop_this =
new OpLoopThis<DomainEle>(
813 mField,
simple->getDomainFEName(), Sev::noisy);
815 pip_domain->getOpPtrVector().push_back(op_loop_this);
816 CHKERR addTagDGProjectionOps<SPACE_DIM, SPACE_DIM>(
817 mField.get_moab(), pip_domain->getOpPtrVector(),
818 op_loop_this->getThisFEPtr()->getOpPtrVector(),
819 pip_domain->getPostProcMesh(), pip_domain->getMapGaussPts(),
820 selected_state_tags, state_order, approximationBase);
824 CHKERR post_proc_map(pip_domain, u_ptr);
829 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(mField);
830 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
832 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
833 push_post_proc_bdy(post_proc_fe_bdy));
836 auto post_proc_pair = create_post_proc_fe();
837 postProcDomainFe = post_proc_pair.first;
838 postProcBdyFe = post_proc_pair.second;
842 "ADOL-C support is not enabled. Please reconfigure with "
843 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
855 auto dm =
simple->getDM();
856 auto ts = pipeline_mng->createTSIM();
858 auto add_extra_finite_elements_to_solver_pipelines = [&]() {
861 auto pre_proc_ptr = boost::make_shared<FEMethod>();
862 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
863 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
865 auto time_scale = boost::make_shared<ExampleTimeScale>();
867 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
869 CHKERR EssentialPreProc<DisplacementCubitBcData>(
mField, pre_proc_ptr,
870 {time_scale},
false)();
874 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
876 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
878 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
879 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
880 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
881 mField, post_proc_rhs_ptr, 1.)();
884 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
886 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
887 mField, post_proc_lhs_ptr, 1.)();
890 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
891 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
894 auto ts_ctx_ptr = getDMTsCtx(
simple->getDM());
895 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
896 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
897 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
898 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
904 CHKERR add_extra_finite_elements_to_solver_pipelines();
906 auto create_monitor_fe = [dm](
auto &&post_proc_fe) {
907 return boost::make_shared<Monitor>(dm.get(), post_proc_fe);
911 boost::shared_ptr<FEMethod> null_fe;
920 CHKERR DMMoFEMTSSetMonitor(dm, ts,
simple->getDomainFEName(), null_fe,
921 null_fe, monitor_ptr);
925 CHKERR TSSetMaxTime(ts, ftime);
926 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
928 auto B = createDMMatrix(dm);
929 CHKERR TSSetI2Jacobian(ts,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
930 auto D = createDMVector(
simple->getDM());
932 CHKERR TSSetFromOptions(ts);
934 PetscBool test_steps = PETSC_FALSE;
935 PetscBool test_piola_stress = PETSC_FALSE;
936 CHKERR PetscOptionsGetBool(
nullptr,
"",
"-test_piola_stress",
937 &test_piola_stress,
nullptr);
938 CHKERR PetscOptionsGetBool(
nullptr,
"",
"-test_step_monitor", &test_steps,
941 const bool check_steps = test_steps || test_piola_stress;
943 auto check_piola_stress = [
this](PetscReal time) {
952 auto displacement_ptr = boost::make_shared<MatrixDouble>();
955 const double applied_F_zz = 1. - 0.1 * time;
957 t_P_expected(
i,
J) = 0.;
958 auto set_linear_elastic_piola = [&](
const double strain_zz,
959 const double d_strain_d_F_zz) {
960 constexpr double E = 1.;
961 constexpr double nu = 0.3;
962 const double lambda =
E * nu / ((1. + nu) * (1. - 2. * nu));
963 const double mu =
E / (2. * (1. + nu));
965 t_P_expected(d, d) =
lambda * strain_zz;
967 (
lambda + 2. *
mu) * strain_zz * d_strain_d_F_zz;
971 auto set_neohookean_piola = [&](
const double F_zz,
const double J) {
972 constexpr double c10 = 1.;
973 constexpr double K = 1.;
974 double I1 = (
SPACE_DIM - 1) + F_zz * F_zz;
977 const double J_to_minus_two_thirds = std::pow(
J, -2. / 3.);
979 const double F_dd = d ==
SPACE_DIM - 1 ? F_zz : 1.;
980 const double inv_F_dd = 1. / F_dd;
982 2. * c10 * J_to_minus_two_thirds * (F_dd - (I1 / 3.) * inv_F_dd) +
983 K *
J * (
J - 1.) * inv_F_dd;
989 auto eval_piola_at_point = [&](boost::shared_ptr<MatrixDouble> &mat_p,
990 std::array<double, 3> field_eval_coords) {
993 ->addFieldEvaluator<SPACE_DIM>(
995 field_eval_coords, [&](
auto &pipeline) {
997 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
998 pipeline, {
H1},
"GEOMETRY");
1000 pipeline.push_back(
new OpCalculateVectorFieldValues<SPACE_DIM>(
1001 "U", displacement_ptr));
1005 commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1006 mField, pipeline,
"U",
"MAT_ELASTIC", Sev::inform);
1007 mat_p = common_ptr->getMatFirstPiolaStress();
1018 "ADOL-C support is not enabled. Please reconfigure with "
1019 "-DWITH_ADOL_C=ON and recompile to use MatOps material model.");
1027 boost::shared_ptr<MatrixDouble> mat_p;
1028 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
1031 std::string material_name =
"Hencky";
1035 bool found_range =
false;
1040 if (found_range && tag != material_tag)
1042 "The analytical fixture requires a homogeneous material");
1052 if (material_name !=
"MetaPiolaResponse")
1055 "The axisymmetric analytical fixture requires Neo-Hookean material");
1058 if (material_name ==
"Hencky") {
1060 set_linear_elastic_piola(std::log(applied_F_zz), 1. / applied_F_zz);
1061 }
else if (material_name ==
"MetaPiolaResponse") {
1065 const double stretch = 1. + 0.01 * time;
1066 const double jacobian = stretch * stretch * stretch;
1069 t_P_expected(
i,
J) = piola *
delta(
i,
J);
1070 CHKERR eval_piola_at_point(mat_p, {1.37, 0.41, 0.});
1071 auto t_u = MatrixSizeHelper<GetFTensor1FromMatType<2, -1, DL>, DL>::get(
1072 *displacement_ptr, 1)();
1073 const double u_err = std::hypot(t_u(0) - (stretch - 1.) * 1.37,
1074 t_u(1) - (stretch - 1.) * 0.41);
1076 ->checkError<TestType::POINTWISE>(
"axisymmetric displacement", u_err,
1079 set_neohookean_piola(applied_F_zz, applied_F_zz);
1081 }
else if (material_name ==
"Umat") {
1083 char strain_type[32] =
"small";
1084 CHKERR PetscOptionsGetString(
nullptr,
"",
"-umat_strain_type",
1085 strain_type,
sizeof(strain_type),
nullptr);
1086 if (std::string(strain_type) !=
"small")
1088 "The analytical UMAT fixture requires small strain");
1089 set_linear_elastic_piola(applied_F_zz - 1., 1.);
1092 "No analytical fixture for material %s", material_name.c_str());
1096 CHKERR eval_piola_at_point(mat_p, {0.123, -0.087, 0.193});
1098 MatrixSizeHelper<GetFTensor2FromMatType<
MAT_DIM,
MAT_DIM, -1, DL>,
1099 DL>::get(*mat_p, 1)();
1100 t_P_diff(
i,
J) = t_P(
i,
J) - t_P_expected(
i,
J);
1101 const double p_err = std::sqrt(t_P_diff(
i,
J) * t_P_diff(
i,
J));
1102 for (
int r = 0; r !=
MAT_DIM; ++r)
1105 <<
"Piola stress (" << material_name <<
") P(" << r <<
", " <<
c
1106 <<
") actual " << std::scientific << t_P(r,
c) <<
" expected "
1107 << t_P_expected(r,
c) <<
" diff " << t_P_diff(r,
c);
1108 MOFEM_LOG(
"EXAMPLE", Sev::inform) <<
"Piola stress (" << material_name
1109 <<
") error " << std::scientific << p_err;
1111 ->checkError<TestType::POINTWISE>(
"Piola stress", p_err, 0.,
1119 ts, [
this, check_piola_stress](TS, PetscInt step, PetscReal time,
1123 CHKERR VecGhostUpdateBegin(solution, INSERT_VALUES, SCATTER_FORWARD);
1124 CHKERR VecGhostUpdateEnd(solution, INSERT_VALUES, SCATTER_FORWARD);
1125 CHKERR DMoFEMMeshToLocalVector(
simple->getDM(), solution,
1126 INSERT_VALUES, SCATTER_REVERSE);
1127 CHKERR check_piola_stress(time);
1129 <<
"Numerical checks passed at TS step " << step <<
", time "
1138 const auto solve_error = TSSolve(ts,
nullptr);
1146 PetscReal expected_time;
1147 CHKERR TSGetMaxTime(ts, &expected_time);
1149 CHKERR testing->checkSolver(ts, expected_time, {1e-12, 1e-12},
1150 "nonlinear elasticity");
1153 CHKERR TSGetTime(ts, &ftime);
1155 PetscInt steps, snesfails, rejects, nonlinits, linits;
1156 CHKERR TSGetStepNumber(ts, &steps);
1157 CHKERR TSGetSNESFailures(ts, &snesfails);
1158 CHKERR TSGetStepRejections(ts, &rejects);
1159 CHKERR TSGetSNESIterations(ts, &nonlinits);
1160 CHKERR TSGetKSPIterations(ts, &linits);
1162 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
1164 steps, rejects, snesfails, ftime, nonlinits, linits);
1175 auto dm =
simple->getDM();
1177 auto T = createDMVector(
simple->getDM());
1178 CHKERR DMoFEMMeshToLocalVector(
simple->getDM(), T, INSERT_VALUES,
1181 CHKERR VecNorm(T, NORM_2, &nrm2);
1182 MOFEM_LOG(
"EXAMPLE", Sev::inform) <<
"Solution norm " << nrm2;
1184 auto post_proc_norm_fe = boost::make_shared<DomainEle>(
mField);
1186 auto post_proc_norm_rule_hook = [](int, int,
int p) ->
int {
return 2 * p; };
1187 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
1189 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
1190 post_proc_norm_fe->getOpPtrVector(), {H1},
"GEOMETRY");
1192 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
1196 CHKERR VecZeroEntries(norms_vec);
1198 auto u_ptr = boost::make_shared<MatrixDouble>();
1199 post_proc_norm_fe->getOpPtrVector().push_back(
1200 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
1202 post_proc_norm_fe->getOpPtrVector().push_back(
1203 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
1212 post_proc_norm_fe->getOpPtrVector().push_back(
1213 new OpCalcNormL2Tensor2<MAT_DIM, MAT_DIM>(m_P, norms_vec,
1218 "ADOL-C support is not enabled. Please reconfigure with "
1219 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
1222 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1223 mField, post_proc_norm_fe->getOpPtrVector(),
"U",
"MAT_ELASTIC",
1225 post_proc_norm_fe->getOpPtrVector().push_back(
1226 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(
1227 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
1230 CHKERR DMoFEMLoopFiniteElements(dm,
simple->getDomainFEName(),
1233 CHKERR VecAssemblyBegin(norms_vec);
1234 CHKERR VecAssemblyEnd(norms_vec);
1238 const double *norms;
1239 CHKERR VecGetArrayRead(norms_vec, &norms);
1241 <<
"norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
1243 <<
"norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
1244 CHKERR VecRestoreArrayRead(norms_vec, &norms);