53 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
62 PSTATUS_SHARED | PSTATUS_MULTISHARED,
63 PSTATUS_NOT, -1, &boundary_ents),
76 PetscBool test_op = PETSC_FALSE;
77 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-test_op", &test_op,
82 if (test_op == PETSC_TRUE) {
91 if (test_op == PETSC_TRUE) {
127 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
128 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
129 PetscInt choice_base_value = AINSWORTH;
130 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL,
"-base", list_bases,
131 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
134 switch (choice_base_value) {
138 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
143 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
155 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-order", &
order, PETSC_NULLPTR);
160 auto project_ho_geometry = [&]() {
161 Projection10NodeCoordsOnField ent_method(
mField,
"GEOMETRY");
164 CHKERR project_ho_geometry();
166 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-use_adolc_material",
171 "ADOL-C support is not enabled. Please reconfigure with "
172 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
176 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use ADOL-C material model";
178 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Use Hencky material model";
181 auto tag_meshest = [&]() {
184 auto set_block = [&](
auto name,
int dim) {
185 std::map<int, Range> map;
186 auto set_tag_impl = [&](
auto name) {
189 auto bcs = mesh_mng->getCubitMeshsetPtr(
191 std::regex((boost::format(
"%s(.*)") % name).str())
194 std::map<int, int> ids_map;
196 for (
auto bc : bcs) {
197 int id = bc->getMeshsetId();
198 ids_map[id] = bit_id;
201 for (
auto bc : bcs) {
205 map[ids_map[bc->getMeshsetId()]] = r;
207 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" : "
208 << ids_map[bc->getMeshsetId()] <<
" has " << r.size()
214 CHKERR set_tag_impl(name);
216 return std::make_pair(name, map);
219 auto set_skin = [&](
auto &&map) {
220 for (
auto &
m : map.second) {
224 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
225 <<
m.second.size() <<
" entities";
230 auto set_tag = [&](
auto &&map) {
232 auto name = map.first;
233 int def_val[] = {-1};
235 name, 1, MB_TYPE_INTEGER, th,
236 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
238 for (
auto &
m : map.second) {
240 for (
auto ent :
m.second) {
245 if (current_id != -1) {
278 auto time_scale = boost::make_shared<ExampleTimeScale>();
292 pipeline_mng->getOpBoundaryRhsPipeline(),
mField,
"U", {time_scale},
293 "FORCE",
"PRESSURE", Sev::inform);
297 pipeline_mng->getOpDomainRhsPipeline(),
mField,
"U", {time_scale},
298 "BODY_FORCE", Sev::inform);
301 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
303 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
305 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
307 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
308 simple->getProblemName(),
"U");
319 auto add_domain_ops_lhs = [&](
auto &pip) {
324 HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
325 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
329 auto add_domain_ops_rhs = [&](
auto &pip) {
334 HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
335 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
339 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
340 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
347 PetscBool post_proc_vol;
348 PetscBool post_proc_skin;
351 post_proc_vol = PETSC_TRUE;
352 post_proc_skin = PETSC_FALSE;
354 post_proc_vol = PETSC_FALSE;
355 post_proc_skin = PETSC_TRUE;
358 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
359 &post_proc_vol, PETSC_NULLPTR);
360 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
361 &post_proc_skin, PETSC_NULLPTR);
364 auto create_post_proc_fe = [&]() {
365 auto post_proc_ele_domain = [
this](
auto &pip_domain) {
368 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
369 mField, pip_domain,
"U",
"MAT_ELASTIC", Sev::inform);
373 auto post_proc_map = [&](
auto &pip,
auto u_ptr,
auto common_ptr) {
376 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
378 pip->getOpPtrVector().push_back(
380 new OpPPMap(pip->getPostProcMesh(), pip->getMapGaussPts(), {},
382 {{
"GRAD", common_ptr->matGradPtr},
383 {
"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
388 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
389 if (post_proc_skin == PETSC_FALSE)
390 return boost::shared_ptr<PostProcEleBdy>();
392 auto domain_fe_name =
simple->getDomainFEName();
393 auto u_ptr = boost::make_shared<MatrixDouble>();
394 pip_bdy->getOpPtrVector().push_back(
395 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
398 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
399 pip_bdy->getOpPtrVector().push_back(op_loop_side);
400 CHKERR post_proc_map(pip_bdy, u_ptr, common_ptr);
404 auto push_post_proc_domain = [&](
auto &pip_domain) {
405 if (post_proc_vol == PETSC_FALSE)
406 return boost::shared_ptr<PostProcEleDomain>();
408 auto u_ptr = boost::make_shared<MatrixDouble>();
409 pip_domain->getOpPtrVector().push_back(
410 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
411 auto common_ptr = post_proc_ele_domain(pip_domain->getOpPtrVector());
413 CHKERR post_proc_map(pip_domain, u_ptr, common_ptr);
418 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(
mField);
419 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(
mField);
421 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
422 push_post_proc_bdy(post_proc_fe_bdy));
425 auto post_proc_pair = create_post_proc_fe();
426 postProcDomainFe = post_proc_pair.first;
427 postProcBdyFe = post_proc_pair.second;
443 constexpr double eps = 1e-9;
445 auto x = opt->setRandomFields(
simple->getDM(), {
451 auto dot_x = opt->setRandomFields(
simple->getDM(), {
457 auto diff_x = opt->setRandomFields(
simple->getDM(), {
463 auto test_domain_ops = [&](
auto fe_name,
auto lhs_pipeline,
467 auto diff_res = opt->checkCentralFiniteDifference(
468 simple->getDM(), fe_name, rhs_pipeline, lhs_pipeline, x, dot_x,
469 SmartPetscObj<Vec>(), diff_x, 0, 0.5,
eps);
474 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
476 "Test consistency of tangent matrix %3.4e", fnorm);
478 constexpr double err = 1e-5;
481 "Norm of directional derivative too large err = %3.4e", fnorm);
487 <<
"Test operators with finite difference of directional "
489 CHKERR test_domain_ops(
simple->getDomainFEName(), pip->getDomainLhsFE(),
490 pip->getDomainRhsFE());
508 AdolCOps::createAdolCPhysicalEquationsPtr<AdolCOps::HUHU, modelType>(
520 auto add_domain_ops_lhs = [&](
auto &pip) {
525 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
mField, pip,
"U",
528 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
533 auto add_domain_ops_rhs = [&](
auto &pip) {
538 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
mField, pip,
"U",
541 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
546 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
547 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
553 PetscBool post_proc_vol;
554 PetscBool post_proc_skin;
557 post_proc_vol = PETSC_TRUE;
558 post_proc_skin = PETSC_FALSE;
560 post_proc_vol = PETSC_FALSE;
561 post_proc_skin = PETSC_TRUE;
564 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
565 &post_proc_vol, PETSC_NULLPTR);
566 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
567 &post_proc_skin, PETSC_NULLPTR);
570 auto create_post_proc_fe = [&]() {
571 auto post_proc_ele_domain = [&](
auto &pip_domain) {
580 auto post_proc_map = [&](
auto &pip,
auto u_ptr) {
582 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
585 auto first_piola_ptr =
587 pip->getOpPtrVector().push_back(
new OpPPMap(
588 pip->getPostProcMesh(), pip->getMapGaussPts(), {}, {{
"U", u_ptr}},
589 {{
"GRAD", grad_ptr}, {
"FIRST_PIOLA", first_piola_ptr}}, {}));
593 auto push_post_proc_bdy = [&](
auto &pip_bdy) {
594 if (post_proc_skin == PETSC_FALSE)
595 return boost::shared_ptr<PostProcEleBdy>();
597 auto domain_fe_name =
simple->getDomainFEName();
598 auto u_ptr = boost::make_shared<MatrixDouble>();
599 pip_bdy->getOpPtrVector().push_back(
600 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
603 CHKERR post_proc_ele_domain(op_loop_side->getOpPtrVector());
604 pip_bdy->getOpPtrVector().push_back(op_loop_side);
605 CHKERR post_proc_map(pip_bdy, u_ptr);
609 auto push_post_proc_domain = [&](
auto &pip_domain) {
610 if (post_proc_vol == PETSC_FALSE)
611 return boost::shared_ptr<PostProcEleDomain>();
612 auto u_ptr = boost::make_shared<MatrixDouble>();
613 pip_domain->getOpPtrVector().push_back(
614 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
615 CHKERR post_proc_ele_domain(pip_domain->getOpPtrVector());
616 CHKERR post_proc_map(pip_domain, u_ptr);
621 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(
mField);
622 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(
mField);
624 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
625 push_post_proc_bdy(post_proc_fe_bdy));
628 auto post_proc_pair = create_post_proc_fe();
629 postProcDomainFe = post_proc_pair.first;
630 postProcBdyFe = post_proc_pair.second;
634 "ADOL-C support is not enabled. Please reconfigure with "
635 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
647 auto dm =
simple->getDM();
648 auto ts = pipeline_mng->createTSIM();
650 auto add_extra_finite_elements_to_solver_pipelines = [&]() {
653 auto pre_proc_ptr = boost::make_shared<FEMethod>();
654 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
655 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
657 auto time_scale = boost::make_shared<ExampleTimeScale>();
659 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
661 CHKERR EssentialPreProc<DisplacementCubitBcData>(
mField, pre_proc_ptr,
662 {time_scale},
false)();
666 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
668 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
670 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
671 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
672 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
673 mField, post_proc_rhs_ptr, 1.)();
676 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
678 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
679 mField, post_proc_lhs_ptr, 1.)();
682 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
683 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
686 auto ts_ctx_ptr = getDMTsCtx(
simple->getDM());
687 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
688 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
689 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
690 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
696 CHKERR add_extra_finite_elements_to_solver_pipelines();
698 auto create_monitor_fe = [dm](
auto &&post_proc_fe,
auto &&
reactionFe) {
699 return boost::make_shared<Monitor>(dm.get(), post_proc_fe,
reactionFe);
703 boost::shared_ptr<FEMethod> null_fe;
710 auto monitor_ptr = create_monitor_fe(
712 CHKERR DMMoFEMTSSetMonitor(dm, ts,
simple->getDomainFEName(), null_fe,
713 null_fe, monitor_ptr);
717 CHKERR TSSetMaxTime(ts, ftime);
718 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
720 auto B = createDMMatrix(dm);
721 CHKERR TSSetI2Jacobian(ts,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
722 auto D = createDMVector(
simple->getDM());
724 CHKERR TSSetFromOptions(ts);
727 CHKERR TSGetTime(ts, &ftime);
729 PetscInt steps, snesfails, rejects, nonlinits, linits;
730 CHKERR TSGetStepNumber(ts, &steps);
731 CHKERR TSGetSNESFailures(ts, &snesfails);
732 CHKERR TSGetStepRejections(ts, &rejects);
733 CHKERR TSGetSNESIterations(ts, &nonlinits);
734 CHKERR TSGetKSPIterations(ts, &linits);
736 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
738 steps, rejects, snesfails, ftime, nonlinits, linits);
749 auto dm =
simple->getDM();
751 auto T = createDMVector(
simple->getDM());
752 CHKERR DMoFEMMeshToLocalVector(
simple->getDM(), T, INSERT_VALUES,
755 CHKERR VecNorm(T, NORM_2, &nrm2);
756 MOFEM_LOG(
"EXAMPLE", Sev::inform) <<
"Solution norm " << nrm2;
758 auto post_proc_norm_fe = boost::make_shared<DomainEle>(
mField);
760 auto post_proc_norm_rule_hook = [](int, int,
int p) ->
int {
return 2 * p; };
761 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
764 post_proc_norm_fe->getOpPtrVector(), {H1},
"GEOMETRY");
766 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
770 CHKERR VecZeroEntries(norms_vec);
772 auto u_ptr = boost::make_shared<MatrixDouble>();
773 post_proc_norm_fe->getOpPtrVector().push_back(
774 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
776 post_proc_norm_fe->getOpPtrVector().push_back(
777 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
785 post_proc_norm_fe->getOpPtrVector().push_back(
786 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(m_P, norms_vec,
790 "ADOL-C support is not enabled. Please reconfigure with "
791 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
794 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
795 mField, post_proc_norm_fe->getOpPtrVector(),
"U",
"MAT_ELASTIC",
797 post_proc_norm_fe->getOpPtrVector().push_back(
798 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(
799 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
802 CHKERR DMoFEMLoopFiniteElements(dm,
simple->getDomainFEName(),
805 CHKERR VecAssemblyBegin(norms_vec);
806 CHKERR VecAssemblyEnd(norms_vec);
811 CHKERR VecGetArrayRead(norms_vec, &norms);
813 <<
"norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
815 <<
"norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
816 CHKERR VecRestoreArrayRead(norms_vec, &norms);
833 PetscInt test_nb = 0;
834 PetscBool test_flg = PETSC_FALSE;
835 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-test", &test_nb, &test_flg);
839 auto T = createDMVector(
simple->getDM());
840 CHKERR DMoFEMMeshToLocalVector(
simple->getDM(), T, INSERT_VALUES,
843 CHKERR VecNorm(T, NORM_2, &nrm2);
844 MOFEM_LOG(
"EXAMPLE", Sev::verbose) <<
"Regression norm " << nrm2;
845 double regression_value = 0;
848 regression_value = 1.02789;
851 regression_value = 1.8841e+00;
854 regression_value = 1.8841e+00;
860 if (fabs(nrm2 - regression_value) > 1e-2)
862 "Regression test field; wrong norm value. %6.4e != %6.4e", nrm2,
#define MOFEM_LOG_C(channel, severity, format,...)
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
void simple(double P1[], double P2[], double P3[], double c[], const int N)
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_ATOM_TEST_INVALID
@ 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 MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
boost::shared_ptr< ADolCData > createADolCDataPtr()
boost::shared_ptr< PhysicalEquations > createAdolCPhysicalEquationsPtr(boost::shared_ptr< ADolCData > adolc_data_ptr, int tag)
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static constexpr int approx_order
FTensor::Index< 'm', 3 > m
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
Post post-proc data at points from hash maps.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
NonlinearElasticExample(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
[Run problem]
boost::shared_ptr< PostProcEleBdy > postProcBdyFe
MoFEMErrorCode assembleSystemAdolc()
boost::shared_ptr< AdolCOps::PhysicalEquations > physicalEquationsPtr
PetscBool useAdolcMaterial
boost::shared_ptr< DomainEle > reactionFe
std::vector< Tag > listTagsToTransfer
list of tags to transfer to postprocessor
MoFEMErrorCode setupProblem()
[Read mesh]
static constexpr int modelType
MoFEMErrorCode readMesh()
[Run problem]
MoFEMErrorCode assembleSystemHencky()
[Boundary condition]
MoFEMErrorCode boundaryCondition()
[Set up problem]
MoFEMErrorCode opTest()
[Push operators to pipeline]
boost::shared_ptr< PostProcEleDomain > postProcDomainFe
boost::shared_ptr< AdolCOps::PhysicalEquations > physicalHuHuPtr
MoFEMErrorCode TsSolve()
[TS Solve]
MoFEMErrorCode outputResults()
[Getting norms]
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
MoFEM::Interface & mField
MoFEMErrorCode checkResults()
[Postprocessing results]
MoFEMErrorCode gettingNorms()
[TS Solve]