v0.16.3
Loading...
Searching...
No Matches
Classes | Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
NonlinearElasticExample Struct Reference

#include "tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp"

Inheritance diagram for NonlinearElasticExample:
[legend]
Collaboration diagram for NonlinearElasticExample:
[legend]

Classes

struct  TSElasticPostStep
 

Public Member Functions

 NonlinearElasticExample (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 [Run problem]
 

Protected Member Functions

MoFEMErrorCode readMesh ()
 [Run problem]
 
MoFEMErrorCode setupProblem ()
 [Read mesh]
 
MoFEMErrorCode boundaryCondition ()
 [Set up problem]
 
MoFEMErrorCode assembleSystemHencky ()
 [Boundary condition]
 
MoFEMErrorCode assembleSystemAdolc ()
 
MoFEMErrorCode opTest ()
 [Push operators to pipeline]
 
MoFEMErrorCode TsSolve ()
 [TS Solve]
 
MoFEMErrorCode gettingNorms ()
 [TS Solve]
 
MoFEMErrorCode outputResults ()
 [Getting norms]
 
MoFEMErrorCode checkPiolaStress (PetscInt test_nb)
 [Postprocessing results]
 
MoFEMErrorCode checkResults ()
 [Check]
 

Static Protected Member Functions

static auto get_skin (MoFEM::Interface &m_field, Range body_ents)
 
static auto filter_true_skin (MoFEM::Interface &m_field, Range &&skin)
 

Protected Attributes

MoFEM::InterfacemField
 
boost::shared_ptr< DomainEleupdateFe
 
boost::shared_ptr< PostProcEleDomainpostProcDomainFe
 
boost::shared_ptr< PostProcEleBdypostProcBdyFe
 
PetscBool useAdolcMaterial = PETSC_FALSE
 
FieldApproximationBase approximationBase = AINSWORTH_LEGENDRE_BASE
 
std::vector< TaglistTagsToTransfer
 list of tags to transfer to postprocessor
 
boost::shared_ptr< MatOps::PhysicalEquationsphysicalEquationsPtr
 
boost::shared_ptr< MatOps::PhysicalEquationsphysicalHuHuPtr
 

Static Protected Attributes

static constexpr int MAT_DIM = SPACE_DIM
 
static constexpr int modelType
 

Detailed Description

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/nonlinear_elastic.cpp, mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 22 of file NonlinearElasticExample.hpp.

Constructor & Destructor Documentation

◆ NonlinearElasticExample()

NonlinearElasticExample::NonlinearElasticExample ( MoFEM::Interface m_field)
inline

Definition at line 24 of file NonlinearElasticExample.hpp.

24: mField(m_field) {}

Member Function Documentation

◆ assembleSystemAdolc()

MoFEMErrorCode NonlinearElasticExample::assembleSystemAdolc ( )
protected
Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 527 of file NonlinearElasticExample.hpp.

527 {
529
530 auto *simple = mField.getInterface<Simple>();
531 auto *pipeline_mng = mField.getInterface<PipelineManager>();
532
533 auto integration_rule = [](int, int, int approx_order) {
534 return 2 * (approx_order - 1) + 1;
535 };
536
537 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
538 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
539 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
540 CHKERR pipeline_mng->setEvaluationIntegrationRule(integration_rule);
541
542#ifdef WITH_ADOL_C
543 auto mat_ops_data_ptr = MatOps::createMatOpsDataPtr();
544
545#ifdef WITH_ADOL_C_UMAT
546 {
547 constexpr int umat_model_type =
549 auto umat_physical_equations_ptr =
551 umat_model_type>(
552 mat_ops_data_ptr, MatOps::MatOpsTagsRegistry::setTagName("Umat"));
553
554 CHKERR umat_physical_equations_ptr->getOptions(&mField);
555 CHKERR umat_physical_equations_ptr->recordTape();
556
557 physicalEquationsPtr = umat_physical_equations_ptr;
558 }
559#else
563 modelType>(
564 mat_ops_data_ptr,
566 }
567
568 #ifdef WITH_ADOL_C_GENERIC_ELASTIC
569 {
570 auto generic_physical_equations_ptr =
572 modelType>(
573 mat_ops_data_ptr,
575
577 // In example, lets do a simple linear elastic material, so we can verify the tangent matrix
578 generic_physical_equations_ptr->hookEvaluateVariable =
580 generic_physical_equations_ptr->hookEvaluateDerivatives =
582 generic_physical_equations_ptr->hookUpdateState =
584
585 CHKERR generic_physical_equations_ptr->getOptions(&mField);
586 CHKERR generic_physical_equations_ptr->recordTape();
587
588 auto &material_map = getMetaElasticMap(physicalEquationsPtr);
589 material_map[generic_physical_equations_ptr->tAg] =
590 generic_physical_equations_ptr;
591 physicalEquationsPtr->tAg = generic_physical_equations_ptr->tAg;
592 }
593 #endif // WITH_ADOL_C_GENERIC_ELASTIC
594
595 #ifdef WITH_ADOL_C_SIMPLE_DAMAGE
596 {
597 auto generic_physical_equations_ptr =
599 modelType>(
601 "GenericElasticSimpleDamage"));
602
604 mField, boost::dynamic_pointer_cast<MatOps::GenericElastic>(
605 generic_physical_equations_ptr));
606
607 CHKERR generic_physical_equations_ptr->getOptions(&mField);
608 CHKERR generic_physical_equations_ptr->recordTape();
609
610 auto &material_map = getMetaElasticMap(physicalEquationsPtr);
611 material_map[generic_physical_equations_ptr->tAg] =
612 generic_physical_equations_ptr;
613 physicalEquationsPtr->tAg = generic_physical_equations_ptr->tAg;
614 }
615 #endif // WITH_ADOL_C_SIMPLE_DAMAGE
616
618 CHKERR physicalEquationsPtr->getOptions(&mField);
619 CHKERR physicalEquationsPtr->recordTape();
620 }
621
622 if (!physicalHuHuPtr &&
623 !mField.getInterface<MeshsetsManager>()
624 ->getCubitMeshsetPtr(std::regex("MAT_HUHU(.*)"))
625 .empty()) {
626 const int tag_hu_hu = MatOps::MatOpsTagsRegistry::setTagName("HuHU");
628 MatOps::createMatOpsPhysicalEquationsPtr<MatOps::HUHU, modelType>(
629 MatOps::createMatOpsDataPtr(), tag_hu_hu);
630 CHKERR physicalHuHuPtr->getOptions(&mField);
631 CHKERR physicalHuHuPtr->recordTape();
632 }
633#endif // WITH_ADOL_C_UMAT
634
635 auto add_domain_ops_lhs = [&](auto &pip) {
638 "GEOMETRY");
641 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
642 mField, pip, "U", physicalEquationsPtr);
643 }
644 if (physicalHuHuPtr) {
646 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
647 mField, pip, simple->getDomainFEName(), "U", physicalHuHuPtr);
648 }
650 };
651
652 auto add_domain_ops_rhs = [&](auto &pip) {
655 "GEOMETRY");
658 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
659 mField, pip, "U", physicalEquationsPtr);
660 }
661 if (physicalHuHuPtr) {
663 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
664 mField, pip, simple->getDomainFEName(), "U", physicalHuHuPtr);
665 }
667 };
668
669 auto add_domain_ops_update = [&](auto &pip) {
672 "GEOMETRY");
676 }
678 };
679
680 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
681 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
682
683 updateFe = boost::make_shared<DomainEle>(mField);
684 updateFe->getRuleHook = integration_rule;
685 CHKERR add_domain_ops_update(updateFe->getOpPtrVector());
686
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,
691 domain_reaction_fe);
692
693 PetscBool post_proc_vol;
694 PetscBool post_proc_skin;
695
696 if constexpr (SPACE_DIM == 2) {
697 post_proc_vol = PETSC_TRUE;
698 post_proc_skin = PETSC_FALSE;
699 } else {
700 post_proc_vol = PETSC_FALSE;
701 post_proc_skin = PETSC_TRUE;
702 }
703
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);
708
709 // Setup postprocessing
710 auto create_post_proc_fe = [&]() {
711 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
712
713 auto post_proc_ele_domain = [&](auto &pip_domain) {
716 "GEOMETRY");
720 }
722 };
723
724 auto post_proc_map = [&](auto &pip, auto u_ptr) {
727 auto grad_ptr =
728 physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("grad");
729 auto first_piola_ptr =
730 physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("P");
731 pip->getOpPtrVector().push_back(new OpPPMap(
732 pip->getPostProcMesh(), pip->getMapGaussPts(), {}, {{"U", u_ptr}},
733 {}, {}));
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}}, {}));
738 }
740 };
741
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));
750 auto op_loop_side =
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);
755 return pip_bdy;
756 };
757
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());
765
767 auto state_tags = physicalEquationsPtr->matOpsDataPtr->getStateTags();
768 if (!state_tags.empty()) {
769 MatOps::StateTags selected_state_tags;
770 MatOps::StateTags statev_tags;
771 selected_state_tags.reserve(state_tags.size());
772 statev_tags.reserve(state_tags.size());
773
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));
778 };
779
780 for (const auto &state_tag : state_tags) {
781 const auto &name = state_tag.name;
782
783 if (name == "UMAT_DFGRD0" || name == "UMAT_STRESS") {
784 selected_state_tags.push_back(state_tag);
785 continue;
786 }
787
788 if (name.rfind(statev_prefix, 0) == 0) {
789 statev_tags.push_back(state_tag);
790 }
791 }
792
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);
797 });
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());
802
803 if (selected_state_tags.empty())
804 return pip_domain;
805
806 auto simple = mField.getInterface<Simple>();
807 int state_order = 2;
808 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &state_order,
809 PETSC_NULLPTR);
810 auto op_loop_this = new OpLoopThis<DomainEle>(
811 mField, simple->getDomainFEName(), Sev::noisy);
812 op_loop_this->getThisFEPtr()->getRuleHook = integration_rule;
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);
819 }
820 }
821
822 CHKERR post_proc_map(pip_domain, u_ptr);
823
824 return pip_domain;
825 };
826
827 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(mField);
828 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
829
830 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
831 push_post_proc_bdy(post_proc_fe_bdy));
832 };
833
834 auto post_proc_pair = create_post_proc_fe();
835 postProcDomainFe = post_proc_pair.first;
836 postProcBdyFe = post_proc_pair.second;
837
838#else
839 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
840 "ADOL-C support is not enabled. Please reconfigure with "
841 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
842
843#endif // WITH_ADOL
845}
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
constexpr int SPACE_DIM
@ H1
continuous field
Definition definitions.h:85
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
auto integration_rule
MoFEMErrorCode configureSimpleDamage(MoFEM::Interface &m_field, boost::shared_ptr< MatOps::GenericElastic > physical_ptr)
std::map< int, boost::shared_ptr< PhysicalEquations > > & getMetaElasticMap(boost::shared_ptr< PhysicalEquations > meta_ptr)
@ MODEL_3D
Definition MatOps.hpp:193
@ MODEL_2D_PLANE_STRAIN
Definition MatOps.hpp:194
std::vector< StateTag > StateTags
Definition MatOps.hpp:21
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
boost::shared_ptr< MatOpsData > createMatOpsDataPtr()
Definition MatOps.cpp:709
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static constexpr int approx_order
static MoFEMErrorCode hookEvaluateVariable(boost::shared_ptr< MatOps::MatOpsData > mat_ops_data_ptr, int, EntityHandle, int)
static MoFEMErrorCode hookEvaluateDerivatives(boost::shared_ptr< MatOps::MatOpsData > mat_ops_data_ptr, int, EntityHandle, int)
static MoFEMErrorCode hookUpdateState(boost::shared_ptr< MatOps::MatOpsData >, int, EntityHandle, int)
static int setTagName(std::string name, int tag=-1)
Definition MatOps.cpp:29
virtual moab::Interface & get_moab()=0
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
FieldApproximationBase approximationBase
boost::shared_ptr< PostProcEleBdy > postProcBdyFe
boost::shared_ptr< MatOps::PhysicalEquations > physicalEquationsPtr
boost::shared_ptr< PostProcEleDomain > postProcDomainFe
boost::shared_ptr< MatOps::PhysicalEquations > physicalHuHuPtr
boost::shared_ptr< DomainEle > updateFe

◆ assembleSystemHencky()

MoFEMErrorCode NonlinearElasticExample::assembleSystemHencky ( )
protected

[Boundary condition]

[Push operators to pipeline]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 335 of file NonlinearElasticExample.hpp.

335 {
337
338 auto *pipeline_mng = mField.getInterface<PipelineManager>();
339
340 auto integration_rule = [](int, int, int approx_order) {
341 return 2 * (approx_order - 1) + 1;
342 };
343
344 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
345 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
346 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
347 CHKERR pipeline_mng->setEvaluationIntegrationRule(integration_rule);
348
349 auto add_domain_ops_lhs = [&](auto &pip) {
352 "GEOMETRY");
353 CHKERR
354 HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
355 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
357 };
358
359 auto add_domain_ops_rhs = [&](auto &pip) {
362 "GEOMETRY");
363 CHKERR
364 HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
365 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
367 };
368
369 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
370 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
371
372 // push operators to evaluation pipeline
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,
377 domain_reaction_fe);
378
379 PetscBool post_proc_vol;
380 PetscBool post_proc_skin;
381
382 if constexpr (SPACE_DIM == 2) {
383 post_proc_vol = PETSC_TRUE;
384 post_proc_skin = PETSC_FALSE;
385 } else {
386 post_proc_vol = PETSC_FALSE;
387 post_proc_skin = PETSC_TRUE;
388 }
389
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);
394
395 // Setup postprocessing
396 auto create_post_proc_fe = [&]() {
397 auto post_proc_ele_domain = [this](auto &pip_domain) {
399 "GEOMETRY");
400 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
401 mField, pip_domain, "U", "MAT_ELASTIC", Sev::inform);
402 return common_ptr;
403 };
404
405 auto post_proc_map = [&](auto &pip, auto u_ptr, auto common_ptr) {
407
408 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
409
410 pip->getOpPtrVector().push_back(
411
412 new OpPPMap(pip->getPostProcMesh(), pip->getMapGaussPts(), {},
413 {{"U", u_ptr}},
414 {{"GRAD", common_ptr->matGradPtr},
415 {"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
416 {}));
418 };
419
420 auto push_post_proc_bdy = [&](auto &pip_bdy) {
421 if (post_proc_skin == PETSC_FALSE)
422 return boost::shared_ptr<PostProcEleBdy>();
423 auto simple = mField.getInterface<Simple>();
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));
428 auto op_loop_side =
429 new OpLoopSide<SideEle>(mField, domain_fe_name, SPACE_DIM);
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);
433 return pip_bdy;
434 };
435
436 auto push_post_proc_domain = [&](auto &pip_domain) {
437 if (post_proc_vol == PETSC_FALSE)
438 return boost::shared_ptr<PostProcEleDomain>();
439
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());
444
445 CHKERR post_proc_map(pip_domain, u_ptr, common_ptr);
446
447 return pip_domain;
448 };
449
450 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(mField);
451 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
452
453 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
454 push_post_proc_bdy(post_proc_fe_bdy));
455 };
456
457 auto post_proc_pair = create_post_proc_fe();
458 postProcDomainFe = post_proc_pair.first;
459 postProcBdyFe = post_proc_pair.second;
460
462}

◆ boundaryCondition()

MoFEMErrorCode NonlinearElasticExample::boundaryCondition ( )
protected

[Set up problem]

[Boundary condition]

[Define gravity vector]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 304 of file NonlinearElasticExample.hpp.

304 {
306 auto *pipeline_mng = mField.getInterface<PipelineManager>();
307 auto simple = mField.getInterface<Simple>();
308 auto bc_mng = mField.getInterface<BcManager>();
309 auto time_scale = boost::make_shared<ExampleTimeScale>();
310
311 CHKERR BoundaryNaturalBC::AddFluxToPipeline<OpForce>::add(
312 pipeline_mng->getOpBoundaryRhsPipeline(), mField, "U", {time_scale},
313 "FORCE", "PRESSURE", Sev::inform);
314
315 //! [Define gravity vector]
316 CHKERR DomainNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
317 pipeline_mng->getOpDomainRhsPipeline(), mField, "U", {time_scale},
318 "BODY_FORCE", Sev::inform);
319
320 // Essential BC
321 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
322 "U", 0, 0);
323 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
324 "U", 1, 1);
325 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
326 "U", 2, 2);
327 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
328 simple->getProblemName(), "U");
329
331}

◆ checkPiolaStress()

MoFEMErrorCode NonlinearElasticExample::checkPiolaStress ( PetscInt  test_nb)
protected

[Postprocessing results]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp.

Definition at line 1043 of file NonlinearElasticExample.hpp.

1043 {
1045 auto simple = mField.getInterface<Simple>();
1046
1051
1052 auto displacement_ptr = boost::make_shared<MatrixDouble>();
1053
1054 constexpr double applied_F_zz = 0.99;
1055
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;
1065 t_P_expected(SPACE_DIM - 1, SPACE_DIM - 1) =
1066 (lambda + 2. * mu) * strain_zz * d_strain_d_F_zz;
1067 };
1068
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;
1076 t_P_expected(SPACE_DIM - 1, SPACE_DIM - 1) =
1077 2. * c10 * (F_zz - inv_F_zz) + K * log_J * inv_F_zz;
1078 };
1079
1080 auto eval_piola_at_point = [&](boost::shared_ptr<MatrixDouble> &mat_p,
1081 std::array<double, 3> field_eval_coords) {
1083 auto field_eval_ptr = mField.getInterface<FieldEvaluatorInterface>();
1084 auto field_eval_data = field_eval_ptr->getData<DomainEle>();
1085 CHKERR field_eval_ptr->buildTree<SPACE_DIM>(field_eval_data,
1086 simple->getDomainFEName());
1087 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1088
1089 auto fe = field_eval_data->feMethodPtr;
1090 fe->getRuleHook = [](int, int, int) { return -1; };
1091
1092 auto &pipeline = fe->getOpPtrVector();
1094 "GEOMETRY");
1095
1096 pipeline.push_back(
1097 new OpCalculateVectorFieldValues<SPACE_DIM>("U", displacement_ptr));
1098
1099 if (useAdolcMaterial == PETSC_FALSE) {
1100 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1101 mField, pipeline, "U", "MAT_ELASTIC", Sev::inform);
1102 mat_p = common_ptr->getMatFirstPiolaStress();
1103 } else {
1104#ifdef WITH_ADOL_C
1107 mat_p = physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("P");
1108#else
1109 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1110 "ADOL-C support is not enabled. Please reconfigure with "
1111 "-DWITH_ADOL_C=ON and recompile to use MatOps material model.");
1112#endif
1113 }
1114 CHKERR field_eval_ptr->evalFEAtThePoint<SPACE_DIM>(
1115 field_eval_coords.data(), 1e-12, simple->getProblemName(),
1116 simple->getDomainFEName(), field_eval_data, mField.get_comm_rank(),
1117 mField.get_comm_rank(), nullptr, MF_EXIST, QUIET);
1119 };
1120
1121 boost::shared_ptr<MatrixDouble> mat_p;
1122 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
1123 switch (test_nb) {
1124 case 100: {
1125 // Hencky, homogeneous strain_z on cube: E = 1, nu = 0.3.
1126 const double hencky_strain_zz = std::log(applied_F_zz);
1127 set_linear_elastic_piola(hencky_strain_zz, 1. / applied_F_zz);
1128 break;
1129 }
1130 case 101: {
1131 // Neo-Hookean, homogeneous strain_z on cube: c10 = K = 1.
1132 const double J = applied_F_zz;
1133 set_neohookean_piola(applied_F_zz, J);
1134 break;
1135 }
1136 case 102: {
1137 // UMAT small strain, homogeneous strain_z on cube: E = 1, nu = 0.3.
1138 const double small_strain_zz = applied_F_zz - 1.;
1139 set_linear_elastic_piola(small_strain_zz, 1.);
1140 break;
1141 }
1142#ifdef AXISYMMETRIC
1143 case 103: {
1144 // Uniform expansion: F = 1.01 I, c10 = K = 1, including hoop stretch.
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);
1154 MOFEM_LOG("EXAMPLE", Sev::inform)
1155 << "Axisymmetric displacement error " << u_err;
1156 if (!std::isfinite(u_err) || u_err > 1e-8)
1157 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1158 "Wrong axisymmetric displacement. Error %6.4e", u_err);
1159 break;
1160 }
1161#endif
1162 default:
1163 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1164 "Wrong Piola stress test number.");
1165 break;
1166 }
1167
1168 if (!mat_p)
1169 CHKERR eval_piola_at_point(mat_p, {0.123, -0.087, 0.193});
1170 auto t_P =
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)
1176 for (int c = 0; c != MAT_DIM; ++c)
1177 MOFEM_LOG("EXAMPLE", Sev::inform)
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);
1181 MOFEM_LOG("EXAMPLE", Sev::inform)
1182 << "Piola stress test " << test_nb << " error " << std::scientific
1183 << p_err;
1184 if (!std::isfinite(p_err) || p_err > 1e-8)
1185 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1186 "Wrong Piola stress. Error %6.4e", p_err);
1187
1189}
#define FTENSOR_INDEX(DIM, I)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
Kronecker Delta class.
@ QUIET
@ MF_EXIST
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
static double lambda
const double c
speed of light (cm/ns)
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
Definition MatHuHu.hpp:33
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
int r
Definition sdf.py:205
static constexpr double delta
virtual int get_comm_rank() const =0

◆ checkResults()

MoFEMErrorCode NonlinearElasticExample::checkResults ( )
protected

[Check]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp.

Definition at line 1192 of file NonlinearElasticExample.hpp.

1192 {
1194 PetscInt test_nb = 0;
1195 PetscBool test_flg = PETSC_FALSE;
1196 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-test", &test_nb, &test_flg);
1197
1198 if (test_flg) {
1199 if (test_nb >= 100) {
1200 CHKERR checkPiolaStress(test_nb);
1202 }
1203
1204 auto simple = mField.getInterface<Simple>();
1205 auto T = createDMVector(simple->getDM());
1206 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
1207 SCATTER_FORWARD);
1208 double nrm2;
1209 CHKERR VecNorm(T, NORM_2, &nrm2);
1210 MOFEM_LOG("EXAMPLE", Sev::verbose) << "Regression norm " << nrm2;
1211
1212 double regression_value = 0;
1213 switch (test_nb) {
1214 case 1:
1215 regression_value = 3.5112e-01;
1216 break;
1217 case 2:
1218 regression_value = 1.8841e+00;
1219 break;
1220 case 3:
1221 regression_value = 1.8841e+00;
1222 break;
1223 default:
1224 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "Wrong test number.");
1225 break;
1226 }
1227 if (fabs(nrm2 - regression_value) > 1e-2)
1228 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1229 "Regression test field; wrong norm value. %6.4e != %6.4e", nrm2,
1230 regression_value);
1231 }
1233}
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
MoFEMErrorCode checkPiolaStress(PetscInt test_nb)
[Postprocessing results]

◆ filter_true_skin()

static auto NonlinearElasticExample::filter_true_skin ( MoFEM::Interface m_field,
Range &&  skin 
)
inlinestaticprotected
Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp.

Definition at line 103 of file NonlinearElasticExample.hpp.

103 {
104 Range boundary_ents;
105 ParallelComm *pcomm =
106 ParallelComm::get_pcomm(&m_field.get_moab(), MYPCOMM_INDEX);
107 CHK_MOAB_THROW(pcomm->filter_pstatus(skin,
108 PSTATUS_SHARED | PSTATUS_MULTISHARED,
109 PSTATUS_NOT, -1, &boundary_ents),
110 "filter_pstatus");
111 return boundary_ents;
112 };
#define MYPCOMM_INDEX
default communicator number PCOMM
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.

◆ get_skin()

static auto NonlinearElasticExample::get_skin ( MoFEM::Interface m_field,
Range  body_ents 
)
inlinestaticprotected

Definition at line 96 of file NonlinearElasticExample.hpp.

96 {
97 Skinner skin(&m_field.get_moab());
98 Range skin_ents;
99 CHK_MOAB_THROW(skin.find_skin(0, body_ents, false, skin_ents), "find_skin");
100 return skin_ents;
101 };

◆ gettingNorms()

MoFEMErrorCode NonlinearElasticExample::gettingNorms ( )
protected

[TS Solve]

[Getting norms]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 956 of file NonlinearElasticExample.hpp.

956 {
958
959 auto simple = mField.getInterface<Simple>();
960 auto dm = simple->getDM();
961
962 auto T = createDMVector(simple->getDM());
963 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
964 SCATTER_FORWARD);
965 double nrm2;
966 CHKERR VecNorm(T, NORM_2, &nrm2);
967 MOFEM_LOG("EXAMPLE", Sev::inform) << "Solution norm " << nrm2;
968
969 auto post_proc_norm_fe = boost::make_shared<DomainEle>(mField);
970
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;
973
975 post_proc_norm_fe->getOpPtrVector(), {H1}, "GEOMETRY");
976
977 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
978 auto norms_vec =
980 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
981 CHKERR VecZeroEntries(norms_vec);
982
983 auto u_ptr = boost::make_shared<MatrixDouble>();
984 post_proc_norm_fe->getOpPtrVector().push_back(
985 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
986
987 post_proc_norm_fe->getOpPtrVector().push_back(
988 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
989
990 if (useAdolcMaterial == PETSC_TRUE) {
991#ifdef WITH_ADOL_C
994 opPostProcFactory(mField, post_proc_norm_fe->getOpPtrVector(), "U",
996 auto m_P = physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("P");
997 post_proc_norm_fe->getOpPtrVector().push_back(
998 new OpCalcNormL2Tensor2<MAT_DIM, MAT_DIM>(m_P, norms_vec,
999 PIOLA_NORM));
1000 }
1001#else
1002 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1003 "ADOL-C support is not enabled. Please reconfigure with "
1004 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
1005#endif
1006 } else {
1007 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1008 mField, post_proc_norm_fe->getOpPtrVector(), "U", "MAT_ELASTIC",
1009 Sev::inform);
1010 post_proc_norm_fe->getOpPtrVector().push_back(
1011 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(
1012 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
1013 }
1014
1015 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
1016 post_proc_norm_fe);
1017
1018 CHKERR VecAssemblyBegin(norms_vec);
1019 CHKERR VecAssemblyEnd(norms_vec);
1020
1021 MOFEM_LOG_CHANNEL("SELF"); // Clear channel from old tags
1022 if (mField.get_comm_rank() == 0) {
1023 const double *norms;
1024 CHKERR VecGetArrayRead(norms_vec, &norms);
1025 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
1026 << "norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
1027 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
1028 << "norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
1029 CHKERR VecRestoreArrayRead(norms_vec, &norms);
1030 }
1031
1033}
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
virtual MPI_Comm & get_comm() const =0

◆ opTest()

MoFEMErrorCode NonlinearElasticExample::opTest ( )
protected

[Push operators to pipeline]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 465 of file NonlinearElasticExample.hpp.

465 {
467
468 // get operators tester
469 auto simple = mField.getInterface<Simple>();
470 auto opt = mField.getInterface<OperatorsTester>(); // get interface to
471 // OperatorsTester
472 auto pip = mField.getInterface<PipelineManager>(); // get interface to
473 // pipeline manager
474
475 constexpr double eps = 1e-9;
476
477 auto x = opt->setRandomFields(simple->getDM(), {
478
479 {"U", {-1e-6, 1e-6}}
480
481 });
482
483 auto dot_x = opt->setRandomFields(simple->getDM(), {
484
485 {"U", {-1, 1}}
486
487 });
488
489 auto diff_x = opt->setRandomFields(simple->getDM(), {
490
491 {"U", {-1, 1}}
492
493 });
494
495 auto test_domain_ops = [&](auto fe_name, auto lhs_pipeline,
496 auto rhs_pipeline) {
498
499 auto diff_res = opt->checkCentralFiniteDifference(
500 simple->getDM(), fe_name, rhs_pipeline, lhs_pipeline, x, dot_x,
501 SmartPetscObj<Vec>(), diff_x, 0, 0.5, eps);
502
503 // Calculate norm of difference between directional derivative calculated
504 // from finite difference, and tangent matrix.
505 double fnorm;
506 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
507 MOFEM_LOG_C("EXAMPLE", Sev::inform,
508 "Test consistency of tangent matrix %3.4e", fnorm);
509
510 constexpr double err = 1e-5;
511 if (fnorm > err)
512 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
513 "Norm of directional derivative too large err = %3.4e", fnorm);
514
516 };
517
518 MOFEM_LOG("EXAMPLE", Sev::inform)
519 << "Test operators with finite difference of directional "
520 "derivative";
521 CHKERR test_domain_ops(simple->getDomainFEName(), pip->getDomainLhsFE(),
522 pip->getDomainRhsFE());
523
525}
#define MOFEM_LOG_C(channel, severity, format,...)
static const double eps

◆ outputResults()

MoFEMErrorCode NonlinearElasticExample::outputResults ( )
protected

◆ readMesh()

MoFEMErrorCode NonlinearElasticExample::readMesh ( )
protected

[Run problem]

[Read mesh]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 144 of file NonlinearElasticExample.hpp.

144 {
146 auto simple = mField.getInterface<Simple>();
147 CHKERR simple->getOptions();
148 CHKERR simple->loadFile();
149 CHKERR mField.getInterface<MeshsetsManager>()->setMeshsetFromFile();
151}

◆ runProblem()

MoFEMErrorCode NonlinearElasticExample::runProblem ( )

[Run problem]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp.

Definition at line 116 of file NonlinearElasticExample.hpp.

116 {
121
122 PetscBool test_op = PETSC_FALSE;
123 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_op", &test_op,
124 PETSC_NULLPTR);
125
126 if (useAdolcMaterial == PETSC_TRUE) {
128 } else {
130 }
131
132 if (test_op == PETSC_TRUE) {
133 CHKERR opTest();
134 }
135 CHKERR TsSolve();
140}
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode readMesh()
[Run problem]
MoFEMErrorCode assembleSystemHencky()
[Boundary condition]
MoFEMErrorCode boundaryCondition()
[Set up problem]
MoFEMErrorCode opTest()
[Push operators to pipeline]
MoFEMErrorCode TsSolve()
[TS Solve]
MoFEMErrorCode outputResults()
[Getting norms]
MoFEMErrorCode checkResults()
[Check]
MoFEMErrorCode gettingNorms()
[TS Solve]

◆ setupProblem()

MoFEMErrorCode NonlinearElasticExample::setupProblem ( )
protected

[Read mesh]

[Set up problem]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp, and mofem/tutorials/vec-9_arc_length/src/ArcLengthExample.hpp.

Definition at line 155 of file NonlinearElasticExample.hpp.

155 {
157 Simple *simple = mField.getInterface<Simple>();
158
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);
164
165 switch (choice_base_value) {
166 case AINSWORTH:
168 MOFEM_LOG("WORLD", Sev::inform)
169 << "Set AINSWORTH_LEGENDRE_BASE for displacements";
170 break;
171 case DEMKOWICZ:
173 MOFEM_LOG("WORLD", Sev::inform)
174 << "Set DEMKOWICZ_JACOBI_BASE for displacements";
175 break;
176 default:
178 break;
179 }
180
181 // Add field
182 CHKERR simple->addDomainField("U", H1, approximationBase, SPACE_DIM);
183 CHKERR simple->addBoundaryField("U", H1, approximationBase, SPACE_DIM);
184 CHKERR simple->addDataField("GEOMETRY", H1, approximationBase, SPACE_DIM);
185 int order = 2;
186 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
187 CHKERR simple->setFieldOrder("U", order);
188 CHKERR simple->setFieldOrder("GEOMETRY", 2);
189 CHKERR simple->setUp();
190
191 auto project_ho_geometry = [&]() {
192 Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
193 return mField.loop_dofs("GEOMETRY", ent_method);
194 };
195 CHKERR project_ho_geometry();
196
197 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-use_adolc_material",
198 &useAdolcMaterial, PETSC_NULLPTR);
199#ifndef WITH_ADOL_C
200 if (useAdolcMaterial == PETSC_TRUE) {
201 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
202 "ADOL-C support is not enabled. Please reconfigure with "
203 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
204 }
205#endif
206 if (useAdolcMaterial == PETSC_TRUE) {
207 MOFEM_LOG("WORLD", Sev::inform) << "Use ADOL-C material model";
208 } else {
209 MOFEM_LOG("WORLD", Sev::inform) << "Use Hencky material model";
210 }
211
212 auto tag_meshest = [&]() {
214
215 auto set_block = [&](auto name, int dim) {
216 std::map<int, Range> map;
217 auto set_tag_impl = [&](auto name) {
219 auto mesh_mng = mField.getInterface<MeshsetsManager>();
220 auto bcs = mesh_mng->getCubitMeshsetPtr(
221
222 std::regex((boost::format("%s(.*)") % name).str())
223
224 );
225 std::map<int, int> ids_map;
226 int bit_id = 1;
227 for (auto bc : bcs) {
228 int id = bc->getMeshsetId();
229 ids_map[id] = bit_id;
230 bit_id <<= 1;
231 }
232 for (auto bc : bcs) {
233 Range r;
234 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
235 true);
236 map[ids_map[bc->getMeshsetId()]] = r;
237 MOFEM_LOG("EXAMPLE", Sev::inform)
238 << "Block " << name << " id " << bc->getMeshsetId() << " : "
239 << ids_map[bc->getMeshsetId()] << " has " << r.size()
240 << " entities";
241 }
243 };
244
245 CHKERR set_tag_impl(name);
246
247 return std::make_pair(name, map);
248 };
249
250 auto set_skin = [&](auto &&map) {
251 for (auto &m : map.second) {
252 auto s = filter_true_skin(mField, get_skin(mField, m.second));
253 m.second.swap(s);
254 MOFEM_LOG("EXAMPLE", Sev::inform)
255 << "Skin for block " << map.first << " id " << m.first << " has "
256 << m.second.size() << " entities";
257 }
258 return map;
259 };
260
261 auto set_tag = [&](auto &&map) {
262 Tag th;
263 auto name = map.first;
264 int def_val[] = {-1};
265 CHK_MOAB_THROW(mField.get_moab().tag_get_handle(
266 name, 1, MB_TYPE_INTEGER, th,
267 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
268 "create tag");
269 for (auto &m : map.second) {
270 int id = m.first;
271 for (auto ent : m.second) {
272 int current_id;
274 mField.get_moab().tag_get_data(th, &ent, 1, &current_id),
275 "get tag data");
276 if (current_id != -1) {
277 id |= current_id;
278 }
279 CHK_MOAB_THROW(mField.get_moab().tag_set_data(th, &ent, 1, &id),
280 "set tag data");
281 }
282 }
283 return th;
284 };
285
286 if (SPACE_DIM == 3) {
287 listTagsToTransfer.push_back(set_tag(set_block("MAT_", 3)));
288 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_", 3))));
289 } else {
290 listTagsToTransfer.push_back(set_tag(set_block("MAT_", 2)));
291 }
292
294 };
295
296 CHKERR tag_meshest();
297
299}
@ LASTBASE
Definition definitions.h:69
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
constexpr int order
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.
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
FTensor::Index< 'm', 3 > m
std::vector< Tag > listTagsToTransfer
list of tags to transfer to postprocessor
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)

◆ TsSolve()

MoFEMErrorCode NonlinearElasticExample::TsSolve ( )
protected

[TS Solve]

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp.

Definition at line 848 of file NonlinearElasticExample.hpp.

848 {
850 auto *simple = mField.getInterface<Simple>();
851 auto *pipeline_mng = mField.getInterface<PipelineManager>();
852
853 auto dm = simple->getDM();
854 auto ts = pipeline_mng->createTSIM();
855
856 auto add_extra_finite_elements_to_solver_pipelines = [&]() {
858
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>();
862
863 auto time_scale = boost::make_shared<ExampleTimeScale>();
864
865 auto get_bc_hook_rhs = [this, pre_proc_ptr, time_scale]() {
867 CHKERR EssentialPreProc<DisplacementCubitBcData>(mField, pre_proc_ptr,
868 {time_scale}, false)();
870 };
871
872 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
873
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.)();
881 };
882 auto get_post_proc_hook_lhs = [this, post_proc_lhs_ptr]() {
884 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
885 mField, post_proc_lhs_ptr, 1.)();
887 };
888 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
889 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
890
891 // This is low level pushing finite elements (pipelines) to solver
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);
898 };
899
900 // Add extra finite elements to SNES solver pipelines to resolve essential
901 // boundary conditions
902 CHKERR add_extra_finite_elements_to_solver_pipelines();
903
904 auto create_monitor_fe = [dm](auto &&post_proc_fe) {
905 return boost::make_shared<Monitor>(dm.get(), post_proc_fe);
906 };
907
908 // Set monitor which postprocessing results and saves them to the hard drive
909 boost::shared_ptr<FEMethod> null_fe;
911 CHKERR postProcDomainFe->setTagsToTransfer(
912 std::vector<Tag>(listTagsToTransfer));
913 if (postProcBdyFe)
914 CHKERR postProcBdyFe->setTagsToTransfer(
915 std::vector<Tag>(listTagsToTransfer));
916 auto monitor_ptr =
917 create_monitor_fe(std::make_pair(postProcDomainFe, postProcBdyFe));
918 CHKERR DMMoFEMTSSetMonitor(dm, ts, simple->getDomainFEName(), null_fe,
919 null_fe, monitor_ptr);
920
921 // Set time solver
922 double ftime = 1;
923 CHKERR TSSetMaxTime(ts, ftime);
924 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
925
926 auto B = createDMMatrix(dm);
927 CHKERR TSSetI2Jacobian(ts, B, B, PETSC_NULLPTR, PETSC_NULLPTR);
928 auto D = createDMVector(simple->getDM());
929 CHKERR TSSetSolution(ts, D);
930 CHKERR TSSetFromOptions(ts);
931
933 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
934 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
935 CHKERR TSSolve(ts, NULL);
937
938 CHKERR TSGetTime(ts, &ftime);
939
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);
946 MOFEM_LOG_C("EXAMPLE", Sev::inform,
947 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
948 "%d, linits %d",
949 steps, rejects, snesfails, ftime, nonlinits, linits);
950
952}
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1194
double D
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
Definition DMMoFEM.cpp:1046
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1279
static MoFEMErrorCode postStepInitialise(NonlinearElasticExample *example_ptr)

Member Data Documentation

◆ approximationBase

FieldApproximationBase NonlinearElasticExample::approximationBase = AINSWORTH_LEGENDRE_BASE
protected

◆ listTagsToTransfer

std::vector<Tag> NonlinearElasticExample::listTagsToTransfer
protected

list of tags to transfer to postprocessor

Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp.

Definition at line 83 of file NonlinearElasticExample.hpp.

◆ MAT_DIM

constexpr int NonlinearElasticExample::MAT_DIM = SPACE_DIM
staticconstexprprotected

◆ mField

MoFEM::Interface& NonlinearElasticExample::mField
protected

◆ modelType

constexpr int NonlinearElasticExample::modelType
inlinestaticconstexprprotected
Initial value:
=
(SPACE_DIM == 3) ? MatOps::MODEL_3D : MatOps::MODEL_2D_PLANE_STRAIN
Examples
mofem/tutorials/vec-2_nonlinear_elasticity/src/NonlinearElasticExample.hpp.

Definition at line 89 of file NonlinearElasticExample.hpp.

◆ physicalEquationsPtr

boost::shared_ptr<MatOps::PhysicalEquations> NonlinearElasticExample::physicalEquationsPtr
protected

◆ physicalHuHuPtr

boost::shared_ptr<MatOps::PhysicalEquations> NonlinearElasticExample::physicalHuHuPtr
protected

◆ postProcBdyFe

boost::shared_ptr<PostProcEleBdy> NonlinearElasticExample::postProcBdyFe
protected

◆ postProcDomainFe

boost::shared_ptr<PostProcEleDomain> NonlinearElasticExample::postProcDomainFe
protected

◆ updateFe

boost::shared_ptr<DomainEle> NonlinearElasticExample::updateFe
protected

◆ useAdolcMaterial

PetscBool NonlinearElasticExample::useAdolcMaterial = PETSC_FALSE
protected

The documentation for this struct was generated from the following file: