146 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
147 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
148 PetscInt choice_base_value = AINSWORTH;
149 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL,
"-base", list_bases,
150 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
153 switch (choice_base_value) {
157 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
162 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
174 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-order", &
order, PETSC_NULLPTR);
179 auto project_ho_geometry = [&]() {
180 Projection10NodeCoordsOnField ent_method(
mField,
"GEOMETRY");
183 CHKERR project_ho_geometry();
185 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-use_adolc_material",
190 "ADOL-C support is not enabled. Please reconfigure with "
191 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
195 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use ADOL-C material model";
197 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use Hencky material model";
200 auto tag_meshest = [&]() {
203 auto set_block = [&](
auto name,
int dim) {
204 std::map<int, Range> map;
205 auto set_tag_impl = [&](
auto name) {
208 auto bcs = mesh_mng->getCubitMeshsetPtr(
210 std::regex((boost::format(
"%s(.*)") % name).str())
213 std::map<int, int> ids_map;
215 for (
auto bc : bcs) {
216 int id = bc->getMeshsetId();
217 ids_map[id] = bit_id;
220 for (
auto bc : bcs) {
224 map[ids_map[bc->getMeshsetId()]] = r;
226 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" : "
227 << ids_map[bc->getMeshsetId()] <<
" has " << r.size()
233 CHKERR set_tag_impl(name);
235 return std::make_pair(name, map);
238 auto set_skin = [&](
auto &&map) {
239 for (
auto &
m : map.second) {
243 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
244 <<
m.second.size() <<
" entities";
249 auto set_tag = [&](
auto &&map) {
251 auto name = map.first;
252 int def_val[] = {-1};
254 name, 1, MB_TYPE_INTEGER, th,
255 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
257 for (
auto &
m : map.second) {
259 for (
auto ent :
m.second) {
264 if (current_id != -1) {
336 auto add_domain_ops_lhs = [&](
auto &pip) {
341 HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
342 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
346 auto add_domain_ops_rhs = [&](
auto &pip) {
351 HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
352 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
356 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
357 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
366 PetscBool post_proc_vol;
367 PetscBool post_proc_skin;
370 post_proc_vol = PETSC_TRUE;
371 post_proc_skin = PETSC_FALSE;
373 post_proc_vol = PETSC_FALSE;
374 post_proc_skin = PETSC_TRUE;
377 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
378 &post_proc_vol, PETSC_NULLPTR);
379 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
380 &post_proc_skin, PETSC_NULLPTR);
383 auto create_post_proc_fe = [&]() {
384 auto post_proc_ele_domain = [
this](
auto &pip_domain) {
387 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
388 mField, pip_domain,
"U",
"MAT_ELASTIC", Sev::inform);
392 auto post_proc_map = [&](
auto &pip,
auto u_ptr,
auto common_ptr) {
395 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
397 pip->getOpPtrVector().push_back(
399 new OpPPMap(pip->getPostProcMesh(), pip->getMapGaussPts(), {},
401 {{
"GRAD", common_ptr->matGradPtr},
402 {
"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
407 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
408 if (post_proc_skin == PETSC_FALSE)
409 return boost::shared_ptr<PostProcEleBdy>();
411 auto domain_fe_name =
simple->getDomainFEName();
412 auto u_ptr = boost::make_shared<MatrixDouble>();
413 pip_bdy->getOpPtrVector().push_back(
414 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
417 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
418 pip_bdy->getOpPtrVector().push_back(op_loop_side);
419 CHKERR post_proc_map(pip_bdy, u_ptr, common_ptr);
423 auto push_post_proc_domain = [&](
auto &pip_domain) {
424 if (post_proc_vol == PETSC_FALSE)
425 return boost::shared_ptr<PostProcEleDomain>();
427 auto u_ptr = boost::make_shared<MatrixDouble>();
428 pip_domain->getOpPtrVector().push_back(
429 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
430 auto common_ptr = post_proc_ele_domain(pip_domain->getOpPtrVector());
432 CHKERR post_proc_map(pip_domain, u_ptr, common_ptr);
437 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(
mField);
438 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(
mField);
440 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
441 push_post_proc_bdy(post_proc_fe_bdy));
444 auto post_proc_pair = create_post_proc_fe();
445 postProcDomainFe = post_proc_pair.first;
446 postProcBdyFe = post_proc_pair.second;
462 constexpr double eps = 1e-9;
464 auto x = opt->setRandomFields(
simple->getDM(), {
470 auto dot_x = opt->setRandomFields(
simple->getDM(), {
476 auto diff_x = opt->setRandomFields(
simple->getDM(), {
482 auto test_domain_ops = [&](
auto fe_name,
auto lhs_pipeline,
486 auto diff_res = opt->checkCentralFiniteDifference(
487 simple->getDM(), fe_name, rhs_pipeline, lhs_pipeline, x, dot_x,
488 SmartPetscObj<Vec>(), diff_x, 0, 0.5,
eps);
493 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
495 "Test consistency of tangent matrix %3.4e", fnorm);
497 constexpr double err = 1e-5;
500 "Norm of directional derivative too large err = %3.4e", fnorm);
506 <<
"Test operators with finite difference of directional "
508 CHKERR test_domain_ops(
simple->getDomainFEName(), pip->getDomainLhsFE(),
509 pip->getDomainRhsFE());
538 #ifdef WITH_ADOL_C_GENERIC_ELASTIC
540 auto generic_physical_equations_ptr =
548 generic_physical_equations_ptr->hookEvaluateVariable =
550 generic_physical_equations_ptr->hookEvaluateDerivatives =
552 generic_physical_equations_ptr->hookUpdateState =
555 CHKERR generic_physical_equations_ptr->getOptions(&
mField);
556 CHKERR generic_physical_equations_ptr->recordTape();
559 material_map[generic_physical_equations_ptr->tAg] =
560 generic_physical_equations_ptr;
565 #ifdef WITH_ADOL_C_SIMPLE_DAMAGE
567 auto generic_physical_equations_ptr =
571 "GenericElasticSimpleDamage"));
574 mField, boost::dynamic_pointer_cast<MatOps::GenericElastic>(
575 generic_physical_equations_ptr));
577 CHKERR generic_physical_equations_ptr->getOptions(&
mField);
578 CHKERR generic_physical_equations_ptr->recordTape();
581 material_map[generic_physical_equations_ptr->tAg] =
582 generic_physical_equations_ptr;
595 MatOps::createMatOpsPhysicalEquationsPtr<MatOps::HUHU, modelType>(
601 auto add_domain_ops_lhs = [&](
auto &pip) {
607 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
612 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
618 auto add_domain_ops_rhs = [&](
auto &pip) {
624 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
629 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
635 auto add_domain_ops_update = [&](
auto &pip) {
646 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
647 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
659 PetscBool post_proc_vol;
660 PetscBool post_proc_skin;
663 post_proc_vol = PETSC_TRUE;
664 post_proc_skin = PETSC_FALSE;
666 post_proc_vol = PETSC_FALSE;
667 post_proc_skin = PETSC_TRUE;
670 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
671 &post_proc_vol, PETSC_NULLPTR);
672 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
673 &post_proc_skin, PETSC_NULLPTR);
676 auto create_post_proc_fe = [&]() {
677 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
679 auto post_proc_ele_domain = [&](
auto &pip_domain) {
690 auto post_proc_map = [&](
auto &pip,
auto u_ptr) {
695 auto first_piola_ptr =
697 pip->getOpPtrVector().push_back(
new OpPPMap(
698 pip->getPostProcMesh(), pip->getMapGaussPts(), {}, {{
"U", u_ptr}},
699 {{
"GRAD", grad_ptr}, {
"FIRST_PIOLA", first_piola_ptr}}, {}));
704 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
705 if (post_proc_skin == PETSC_FALSE)
706 return boost::shared_ptr<PostProcEleBdy>();
708 auto domain_fe_name =
simple->getDomainFEName();
709 auto u_ptr = boost::make_shared<MatrixDouble>();
710 pip_bdy->getOpPtrVector().push_back(
711 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
714 CHKERR post_proc_ele_domain(op_loop_side->getOpPtrVector());
715 pip_bdy->getOpPtrVector().push_back(op_loop_side);
716 CHKERR post_proc_map(pip_bdy, u_ptr);
720 auto push_post_proc_domain = [&](
auto &pip_domain) {
721 if (post_proc_vol == PETSC_FALSE)
722 return boost::shared_ptr<PostProcEleDomain>();
723 auto u_ptr = boost::make_shared<MatrixDouble>();
724 pip_domain->getOpPtrVector().push_back(
725 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
726 CHKERR post_proc_ele_domain(pip_domain->getOpPtrVector());
731 if (!state_tags.empty()) {
734 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-order", &state_order,
736 auto op_loop_this =
new OpLoopThis<DomainEle>(
739 pip_domain->getOpPtrVector().push_back(op_loop_this);
740 CHKERR addTagDGProjectionOps<SPACE_DIM, SPACE_DIM>(
742 op_loop_this->getThisFEPtr()->getOpPtrVector(),
743 pip_domain->getPostProcMesh(), pip_domain->getMapGaussPts(),
744 state_tags, state_order);
748 CHKERR post_proc_map(pip_domain, u_ptr);
753 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(
mField);
754 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(
mField);
756 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
757 push_post_proc_bdy(post_proc_fe_bdy));
760 auto post_proc_pair = create_post_proc_fe();
761 postProcDomainFe = post_proc_pair.first;
762 postProcBdyFe = post_proc_pair.second;
766 "ADOL-C support is not enabled. Please reconfigure with "
767 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
779 auto dm =
simple->getDM();
780 auto ts = pipeline_mng->createTSIM();
782 auto add_extra_finite_elements_to_solver_pipelines = [&]() {
785 auto pre_proc_ptr = boost::make_shared<FEMethod>();
786 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
787 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
789 auto time_scale = boost::make_shared<ExampleTimeScale>();
791 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
793 CHKERR EssentialPreProc<DisplacementCubitBcData>(
mField, pre_proc_ptr,
794 {time_scale},
false)();
798 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
800 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
802 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
803 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
804 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
805 mField, post_proc_rhs_ptr, 1.)();
808 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
810 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
811 mField, post_proc_lhs_ptr, 1.)();
814 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
815 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
818 auto ts_ctx_ptr = getDMTsCtx(
simple->getDM());
819 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
820 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
821 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
822 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
828 CHKERR add_extra_finite_elements_to_solver_pipelines();
830 auto create_monitor_fe = [dm](
auto &&post_proc_fe,
auto &&
reactionFe) {
831 return boost::make_shared<Monitor>(dm.get(), post_proc_fe,
reactionFe);
835 boost::shared_ptr<FEMethod> null_fe;
842 auto monitor_ptr = create_monitor_fe(
844 CHKERR DMMoFEMTSSetMonitor(dm, ts,
simple->getDomainFEName(), null_fe,
845 null_fe, monitor_ptr);
849 CHKERR TSSetMaxTime(ts, ftime);
850 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
852 auto B = createDMMatrix(dm);
853 CHKERR TSSetI2Jacobian(ts,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
854 auto D = createDMVector(
simple->getDM());
856 CHKERR TSSetFromOptions(ts);
864 CHKERR TSGetTime(ts, &ftime);
866 PetscInt steps, snesfails, rejects, nonlinits, linits;
867 CHKERR TSGetStepNumber(ts, &steps);
868 CHKERR TSGetSNESFailures(ts, &snesfails);
869 CHKERR TSGetStepRejections(ts, &rejects);
870 CHKERR TSGetSNESIterations(ts, &nonlinits);
871 CHKERR TSGetKSPIterations(ts, &linits);
873 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
875 steps, rejects, snesfails, ftime, nonlinits, linits);
886 auto dm =
simple->getDM();
888 auto T = createDMVector(
simple->getDM());
889 CHKERR DMoFEMMeshToLocalVector(
simple->getDM(), T, INSERT_VALUES,
892 CHKERR VecNorm(T, NORM_2, &nrm2);
893 MOFEM_LOG(
"EXAMPLE", Sev::inform) <<
"Solution norm " << nrm2;
895 auto post_proc_norm_fe = boost::make_shared<DomainEle>(
mField);
897 auto post_proc_norm_rule_hook = [](int, int,
int p) ->
int {
return 2 * p; };
898 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
901 post_proc_norm_fe->getOpPtrVector(), {H1},
"GEOMETRY");
903 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
907 CHKERR VecZeroEntries(norms_vec);
909 auto u_ptr = boost::make_shared<MatrixDouble>();
910 post_proc_norm_fe->getOpPtrVector().push_back(
911 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
913 post_proc_norm_fe->getOpPtrVector().push_back(
914 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
923 post_proc_norm_fe->getOpPtrVector().push_back(
924 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(m_P, norms_vec,
929 "ADOL-C support is not enabled. Please reconfigure with "
930 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
933 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
934 mField, post_proc_norm_fe->getOpPtrVector(),
"U",
"MAT_ELASTIC",
936 post_proc_norm_fe->getOpPtrVector().push_back(
937 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(
938 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
941 CHKERR DMoFEMLoopFiniteElements(dm,
simple->getDomainFEName(),
944 CHKERR VecAssemblyBegin(norms_vec);
945 CHKERR VecAssemblyEnd(norms_vec);
950 CHKERR VecGetArrayRead(norms_vec, &norms);
952 <<
"norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
954 <<
"norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
955 CHKERR VecRestoreArrayRead(norms_vec, &norms);