v0.16.0
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 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 517 of file NonlinearElasticExample.hpp.

517 {
519
520 auto *simple = mField.getInterface<Simple>();
521 auto *pipeline_mng = mField.getInterface<PipelineManager>();
522
523 auto integration_rule = [](int, int, int approx_order) {
524 return 2 * (approx_order - 1) + 1;
525 };
526
527 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
528 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
529 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
530 CHKERR pipeline_mng->setEvaluationIntegrationRule(integration_rule);
531
532#ifdef WITH_ADOL_C
533 auto mat_ops_data_ptr = MatOps::createMatOpsDataPtr();
534
535#ifdef WITH_ADOL_C_UMAT
536 {
537 constexpr int umat_model_type =
539 auto umat_physical_equations_ptr =
541 umat_model_type>(
542 mat_ops_data_ptr, MatOps::MatOpsTagsRegistry::setTagName("Umat"));
543
544 CHKERR umat_physical_equations_ptr->getOptions(&mField);
545 CHKERR umat_physical_equations_ptr->recordTape();
546
547 physicalEquationsPtr = umat_physical_equations_ptr;
548 }
549#else
553 modelType>(
554 mat_ops_data_ptr,
556 }
557
558 #ifdef WITH_ADOL_C_GENERIC_ELASTIC
559 {
560 auto generic_physical_equations_ptr =
562 modelType>(
563 mat_ops_data_ptr,
565
567 // In example, lets do a simple linear elastic material, so we can verify the tangent matrix
568 generic_physical_equations_ptr->hookEvaluateVariable =
570 generic_physical_equations_ptr->hookEvaluateDerivatives =
572 generic_physical_equations_ptr->hookUpdateState =
574
575 CHKERR generic_physical_equations_ptr->getOptions(&mField);
576 CHKERR generic_physical_equations_ptr->recordTape();
577
578 auto &material_map = getMetaElasticMap(physicalEquationsPtr);
579 material_map[generic_physical_equations_ptr->tAg] =
580 generic_physical_equations_ptr;
581 physicalEquationsPtr->tAg = generic_physical_equations_ptr->tAg;
582 }
583 #endif // WITH_ADOL_C_GENERIC_ELASTIC
584
585 #ifdef WITH_ADOL_C_SIMPLE_DAMAGE
586 {
587 auto generic_physical_equations_ptr =
589 modelType>(
591 "GenericElasticSimpleDamage"));
592
594 mField, boost::dynamic_pointer_cast<MatOps::GenericElastic>(
595 generic_physical_equations_ptr));
596
597 CHKERR generic_physical_equations_ptr->getOptions(&mField);
598 CHKERR generic_physical_equations_ptr->recordTape();
599
600 auto &material_map = getMetaElasticMap(physicalEquationsPtr);
601 material_map[generic_physical_equations_ptr->tAg] =
602 generic_physical_equations_ptr;
603 physicalEquationsPtr->tAg = generic_physical_equations_ptr->tAg;
604 }
605 #endif // WITH_ADOL_C_SIMPLE_DAMAGE
606
608 CHKERR physicalEquationsPtr->getOptions(&mField);
609 CHKERR physicalEquationsPtr->recordTape();
610 }
611
612 if (!physicalHuHuPtr) {
613 const int tag_hu_hu = MatOps::MatOpsTagsRegistry::setTagName("HuHU");
615 MatOps::createMatOpsPhysicalEquationsPtr<MatOps::HUHU, modelType>(
616 MatOps::createMatOpsDataPtr(), tag_hu_hu);
617 CHKERR physicalHuHuPtr->getOptions(&mField);
618 CHKERR physicalHuHuPtr->recordTape();
619 }
620#endif // WITH_ADOL_C_UMAT
621
622 auto add_domain_ops_lhs = [&](auto &pip) {
625 "GEOMETRY");
628 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
629 mField, pip, "U", physicalEquationsPtr);
630 }
631 if (physicalHuHuPtr) {
633 template opLhsFactory<PETSC, GAUSS, DomainEleOp>(
634 mField, pip, simple->getDomainFEName(), "U", physicalHuHuPtr);
635 }
637 };
638
639 auto add_domain_ops_rhs = [&](auto &pip) {
642 "GEOMETRY");
645 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
646 mField, pip, "U", physicalEquationsPtr);
647 }
648 if (physicalHuHuPtr) {
650 template opRhsFactory<PETSC, GAUSS, DomainEleOp>(
651 mField, pip, simple->getDomainFEName(), "U", physicalHuHuPtr);
652 }
654 };
655
656 auto add_domain_ops_update = [&](auto &pip) {
659 "GEOMETRY");
663 }
665 };
666
667 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
668 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
669
670 updateFe = boost::make_shared<DomainEle>(mField);
671 updateFe->getRuleHook = integration_rule;
672 CHKERR add_domain_ops_update(updateFe->getOpPtrVector());
673
674 CHKERR add_domain_ops_rhs(pipeline_mng->getOpEvaluationPipeline());
675 auto &domain_reaction_fe = pipeline_mng->getEvaluationFE();
676 domain_reaction_fe->postProcessHook =
677 EssentialPreProcReaction<DisplacementCubitBcData>(mField,
678 domain_reaction_fe);
679
680 PetscBool post_proc_vol;
681 PetscBool post_proc_skin;
682
683 if constexpr (SPACE_DIM == 2) {
684 post_proc_vol = PETSC_TRUE;
685 post_proc_skin = PETSC_FALSE;
686 } else {
687 post_proc_vol = PETSC_FALSE;
688 post_proc_skin = PETSC_TRUE;
689 }
690
691 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-post_proc_vol",
692 &post_proc_vol, PETSC_NULLPTR);
693 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-post_proc_skin",
694 &post_proc_skin, PETSC_NULLPTR);
695
696 // Setup postprocessing
697 auto create_post_proc_fe = [&]() {
698 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
699
700 auto post_proc_ele_domain = [&](auto &pip_domain) {
703 "GEOMETRY");
707 }
709 };
710
711 auto post_proc_map = [&](auto &pip, auto u_ptr) {
714 auto grad_ptr =
715 physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("grad");
716 auto first_piola_ptr =
717 physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("P");
718 pip->getOpPtrVector().push_back(new OpPPMap(
719 pip->getPostProcMesh(), pip->getMapGaussPts(), {}, {{"U", u_ptr}},
720 {{"GRAD", grad_ptr}, {"FIRST_PIOLA", first_piola_ptr}}, {}));
721 }
723 };
724
725 auto push_post_proc_bdy = [&](auto &pip_bdy) {
726 if (post_proc_skin == PETSC_FALSE)
727 return boost::shared_ptr<PostProcEleBdy>();
728 auto simple = mField.getInterface<Simple>();
729 auto domain_fe_name = simple->getDomainFEName();
730 auto u_ptr = boost::make_shared<MatrixDouble>();
731 pip_bdy->getOpPtrVector().push_back(
732 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
733 auto op_loop_side =
734 new OpLoopSide<SideEle>(mField, domain_fe_name, SPACE_DIM);
735 CHKERR post_proc_ele_domain(op_loop_side->getOpPtrVector());
736 pip_bdy->getOpPtrVector().push_back(op_loop_side);
737 CHKERR post_proc_map(pip_bdy, u_ptr);
738 return pip_bdy;
739 };
740
741 auto push_post_proc_domain = [&](auto &pip_domain) {
742 if (post_proc_vol == PETSC_FALSE)
743 return boost::shared_ptr<PostProcEleDomain>();
744 auto u_ptr = boost::make_shared<MatrixDouble>();
745 pip_domain->getOpPtrVector().push_back(
746 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
747 CHKERR post_proc_ele_domain(pip_domain->getOpPtrVector());
748
750 auto state_tags = physicalEquationsPtr->matOpsDataPtr->getStateTags();
751 if (!state_tags.empty()) {
752 MatOps::StateTags selected_state_tags;
753 MatOps::StateTags statev_tags;
754 selected_state_tags.reserve(state_tags.size());
755 statev_tags.reserve(state_tags.size());
756
757 constexpr auto statev_prefix = "UMAT_STATEV_";
758 constexpr auto statev_prefix_len = sizeof("UMAT_STATEV_") - 1;
759 auto get_statev_index = [&](const std::string &name) {
760 return std::stoi(name.substr(statev_prefix_len));
761 };
762
763 for (const auto &state_tag : state_tags) {
764 const auto &name = state_tag.name;
765
766 if (name == "UMAT_DFGRD0" || name == "UMAT_STRESS") {
767 selected_state_tags.push_back(state_tag);
768 continue;
769 }
770
771 if (name.rfind(statev_prefix, 0) == 0) {
772 statev_tags.push_back(state_tag);
773 }
774 }
775
776 std::sort(statev_tags.begin(), statev_tags.end(),
777 [&](const auto &lhs, const auto &rhs) {
778 return get_statev_index(lhs.name) <
779 get_statev_index(rhs.name);
780 });
781 if (statev_tags.size() > 10)
782 statev_tags.resize(10);
783 selected_state_tags.insert(selected_state_tags.end(),
784 statev_tags.begin(), statev_tags.end());
785
786 if (selected_state_tags.empty())
787 return pip_domain;
788
789 auto simple = mField.getInterface<Simple>();
790 int state_order = 2;
791 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &state_order,
792 PETSC_NULLPTR);
793 auto op_loop_this = new OpLoopThis<DomainEle>(
794 mField, simple->getDomainFEName(), Sev::noisy);
795 op_loop_this->getThisFEPtr()->getRuleHook = integration_rule;
796 pip_domain->getOpPtrVector().push_back(op_loop_this);
797 CHKERR addTagDGProjectionOps<SPACE_DIM, SPACE_DIM>(
798 mField.get_moab(), pip_domain->getOpPtrVector(),
799 op_loop_this->getThisFEPtr()->getOpPtrVector(),
800 pip_domain->getPostProcMesh(), pip_domain->getMapGaussPts(),
801 selected_state_tags, state_order, approximationBase);
802 }
803 }
804
805 CHKERR post_proc_map(pip_domain, u_ptr);
806
807 return pip_domain;
808 };
809
810 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(mField);
811 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
812
813 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
814 push_post_proc_bdy(post_proc_fe_bdy));
815 };
816
817 auto post_proc_pair = create_post_proc_fe();
818 postProcDomainFe = post_proc_pair.first;
819 postProcBdyFe = post_proc_pair.second;
820
821#else
822 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
823 "ADOL-C support is not enabled. Please reconfigure with "
824 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
825
826#endif // WITH_ADOL
828}
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:181
@ MODEL_2D_PLANE_STRAIN
Definition MatOps.hpp:182
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:671
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:30
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 325 of file NonlinearElasticExample.hpp.

325 {
327
328 auto *pipeline_mng = mField.getInterface<PipelineManager>();
329
330 auto integration_rule = [](int, int, int approx_order) {
331 return 2 * (approx_order - 1) + 1;
332 };
333
334 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
335 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
336 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
337 CHKERR pipeline_mng->setEvaluationIntegrationRule(integration_rule);
338
339 auto add_domain_ops_lhs = [&](auto &pip) {
342 "GEOMETRY");
343 CHKERR
344 HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
345 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
347 };
348
349 auto add_domain_ops_rhs = [&](auto &pip) {
352 "GEOMETRY");
353 CHKERR
354 HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
355 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
357 };
358
359 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
360 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
361
362 // push operators to evaluation pipeline
363 CHKERR add_domain_ops_rhs(pipeline_mng->getOpEvaluationPipeline());
364 auto &domain_reaction_fe = pipeline_mng->getEvaluationFE();
365 domain_reaction_fe->postProcessHook =
366 EssentialPreProcReaction<DisplacementCubitBcData>(mField,
367 domain_reaction_fe);
368
369 PetscBool post_proc_vol;
370 PetscBool post_proc_skin;
371
372 if constexpr (SPACE_DIM == 2) {
373 post_proc_vol = PETSC_TRUE;
374 post_proc_skin = PETSC_FALSE;
375 } else {
376 post_proc_vol = PETSC_FALSE;
377 post_proc_skin = PETSC_TRUE;
378 }
379
380 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-post_proc_vol",
381 &post_proc_vol, PETSC_NULLPTR);
382 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-post_proc_skin",
383 &post_proc_skin, PETSC_NULLPTR);
384
385 // Setup postprocessing
386 auto create_post_proc_fe = [&]() {
387 auto post_proc_ele_domain = [this](auto &pip_domain) {
389 "GEOMETRY");
390 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
391 mField, pip_domain, "U", "MAT_ELASTIC", Sev::inform);
392 return common_ptr;
393 };
394
395 auto post_proc_map = [&](auto &pip, auto u_ptr, auto common_ptr) {
397
398 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
399
400 pip->getOpPtrVector().push_back(
401
402 new OpPPMap(pip->getPostProcMesh(), pip->getMapGaussPts(), {},
403 {{"U", u_ptr}},
404 {{"GRAD", common_ptr->matGradPtr},
405 {"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
406 {}));
408 };
409
410 auto push_post_proc_bdy = [&](auto &pip_bdy) {
411 if (post_proc_skin == PETSC_FALSE)
412 return boost::shared_ptr<PostProcEleBdy>();
413 auto simple = mField.getInterface<Simple>();
414 auto domain_fe_name = simple->getDomainFEName();
415 auto u_ptr = boost::make_shared<MatrixDouble>();
416 pip_bdy->getOpPtrVector().push_back(
417 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
418 auto op_loop_side =
419 new OpLoopSide<SideEle>(mField, domain_fe_name, SPACE_DIM);
420 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
421 pip_bdy->getOpPtrVector().push_back(op_loop_side);
422 CHKERR post_proc_map(pip_bdy, u_ptr, common_ptr);
423 return pip_bdy;
424 };
425
426 auto push_post_proc_domain = [&](auto &pip_domain) {
427 if (post_proc_vol == PETSC_FALSE)
428 return boost::shared_ptr<PostProcEleDomain>();
429
430 auto u_ptr = boost::make_shared<MatrixDouble>();
431 pip_domain->getOpPtrVector().push_back(
432 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
433 auto common_ptr = post_proc_ele_domain(pip_domain->getOpPtrVector());
434
435 CHKERR post_proc_map(pip_domain, u_ptr, common_ptr);
436
437 return pip_domain;
438 };
439
440 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(mField);
441 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
442
443 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
444 push_post_proc_bdy(post_proc_fe_bdy));
445 };
446
447 auto post_proc_pair = create_post_proc_fe();
448 postProcDomainFe = post_proc_pair.first;
449 postProcBdyFe = post_proc_pair.second;
450
452}

◆ 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 294 of file NonlinearElasticExample.hpp.

294 {
296 auto *pipeline_mng = mField.getInterface<PipelineManager>();
297 auto simple = mField.getInterface<Simple>();
298 auto bc_mng = mField.getInterface<BcManager>();
299 auto time_scale = boost::make_shared<ExampleTimeScale>();
300
301 CHKERR BoundaryNaturalBC::AddFluxToPipeline<OpForce>::add(
302 pipeline_mng->getOpBoundaryRhsPipeline(), mField, "U", {time_scale},
303 "FORCE", "PRESSURE", Sev::inform);
304
305 //! [Define gravity vector]
306 CHKERR DomainNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
307 pipeline_mng->getOpDomainRhsPipeline(), mField, "U", {time_scale},
308 "BODY_FORCE", Sev::inform);
309
310 // Essential BC
311 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
312 "U", 0, 0);
313 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
314 "U", 1, 1);
315 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
316 "U", 2, 2);
317 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
318 simple->getProblemName(), "U");
319
321}

◆ checkPiolaStress()

MoFEMErrorCode NonlinearElasticExample::checkPiolaStress ( PetscInt  test_nb)
protected

[Postprocessing results]

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

Definition at line 1026 of file NonlinearElasticExample.hpp.

1026 {
1028 auto simple = mField.getInterface<Simple>();
1029
1034
1035 constexpr double applied_F_zz = 0.99;
1036
1037 t_P_expected(i, J) = 0.;
1038 auto set_linear_elastic_piola = [&](const double strain_zz,
1039 const double d_strain_d_F_zz) {
1040 constexpr double E = 1.;
1041 constexpr double nu = 0.3;
1042 const double lambda = E * nu / ((1. + nu) * (1. - 2. * nu));
1043 const double mu = E / (2. * (1. + nu));
1044 for (int d = 0; d != SPACE_DIM - 1; ++d)
1045 t_P_expected(d, d) = lambda * strain_zz;
1046 t_P_expected(SPACE_DIM - 1, SPACE_DIM - 1) =
1047 (lambda + 2. * mu) * strain_zz * d_strain_d_F_zz;
1048 };
1049
1050 auto set_neohookean_piola = [&](const double F_zz, const double J) {
1051 constexpr double c10 = 1.;
1052 constexpr double K = 1.;
1053 double I1 = (SPACE_DIM - 1) + F_zz * F_zz;
1054 if constexpr (SPACE_DIM == 2)
1055 I1 += 1.; // Plane strain has F33 = 1.
1056 const double J_to_minus_two_thirds = std::pow(J, -2. / 3.);
1057 for (int d = 0; d != SPACE_DIM; ++d) {
1058 const double F_dd = d == SPACE_DIM - 1 ? F_zz : 1.;
1059 const double inv_F_dd = 1. / F_dd;
1060 t_P_expected(d, d) =
1061 2. * c10 * J_to_minus_two_thirds *
1062 (F_dd - (I1 / 3.) * inv_F_dd) +
1063 K * J * (J - 1.) * inv_F_dd;
1064 }
1065 };
1066
1067 auto eval_piola_at_point = [&](boost::shared_ptr<MatrixDouble> &mat_p) {
1069 std::array<double, 3> field_eval_coords = {0.123, -0.087, 0.193};
1070 auto field_eval_ptr = mField.getInterface<FieldEvaluatorInterface>();
1071 auto field_eval_data = field_eval_ptr->getData<DomainEle>();
1072 CHKERR field_eval_ptr->buildTree<SPACE_DIM>(field_eval_data,
1073 simple->getDomainFEName());
1074 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1075
1076 auto fe = field_eval_data->feMethodPtr;
1077 fe->getRuleHook = [](int, int, int) { return -1; };
1078
1079 auto &pipeline = fe->getOpPtrVector();
1081 "GEOMETRY");
1082
1083 if (useAdolcMaterial == PETSC_FALSE) {
1084 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1085 mField, pipeline, "U", "MAT_ELASTIC", Sev::inform);
1086 mat_p = common_ptr->getMatFirstPiolaStress();
1087 } else {
1088#ifdef WITH_ADOL_C
1091 mat_p = physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("P");
1092#else
1093 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1094 "ADOL-C support is not enabled. Please reconfigure with "
1095 "-DWITH_ADOL_C=ON and recompile to use MatOps material model.");
1096#endif
1097 }
1098 CHKERR field_eval_ptr->evalFEAtThePoint<SPACE_DIM>(
1099 field_eval_coords.data(), 1e-12, simple->getProblemName(),
1100 simple->getDomainFEName(), field_eval_data, mField.get_comm_rank(),
1101 mField.get_comm_rank(), nullptr, MF_EXIST, QUIET);
1103 };
1104
1105 switch (test_nb) {
1106 case 100: {
1107 // Hencky, homogeneous strain_z on cube: E = 1, nu = 0.3.
1108 const double hencky_strain_zz = std::log(applied_F_zz);
1109 set_linear_elastic_piola(hencky_strain_zz, 1. / applied_F_zz);
1110 break;
1111 }
1112 case 101: {
1113 // Neo-Hookean, homogeneous strain_z on cube: c10 = K = 1.
1114 const double J = applied_F_zz;
1115 set_neohookean_piola(applied_F_zz, J);
1116 break;
1117 }
1118 case 102: {
1119 // UMAT small strain, homogeneous strain_z on cube: E = 1, nu = 0.3.
1120 const double small_strain_zz = applied_F_zz - 1.;
1121 set_linear_elastic_piola(small_strain_zz, 1.);
1122 break;
1123 }
1124 default:
1125 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1126 "Wrong Piola stress test number.");
1127 break;
1128 }
1129
1130 boost::shared_ptr<MatrixDouble> mat_p;
1131 CHKERR eval_piola_at_point(mat_p);
1132
1133 auto t_P = getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*mat_p);
1134 t_P_diff(i, J) = t_P(i, J) - t_P_expected(i, J);
1135 const double p_err = std::sqrt(t_P_diff(i, J) * t_P_diff(i, J));
1136 for (int r = 0; r != SPACE_DIM; ++r)
1137 for (int c = 0; c != SPACE_DIM; ++c)
1138 MOFEM_LOG("EXAMPLE", Sev::inform)
1139 << "Piola stress test " << test_nb << " P(" << r << ", " << c
1140 << ") actual " << std::scientific << t_P(r, c) << " expected "
1141 << t_P_expected(r, c) << " diff " << t_P_diff(r, c);
1142 MOFEM_LOG("EXAMPLE", Sev::inform)
1143 << "Piola stress test " << test_nb << " error " << std::scientific
1144 << p_err;
1145 if (p_err > 1e-8)
1146 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1147 "Wrong Piola stress. Error %6.4e", p_err);
1148
1150}
#define FTENSOR_INDEX(DIM, I)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
@ 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
int r
Definition sdf.py:205
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 1153 of file NonlinearElasticExample.hpp.

1153 {
1155 PetscInt test_nb = 0;
1156 PetscBool test_flg = PETSC_FALSE;
1157 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-test", &test_nb, &test_flg);
1158
1159 if (test_flg) {
1160 if (test_nb >= 100) {
1161 CHKERR checkPiolaStress(test_nb);
1163 }
1164
1165 auto simple = mField.getInterface<Simple>();
1166 auto T = createDMVector(simple->getDM());
1167 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
1168 SCATTER_FORWARD);
1169 double nrm2;
1170 CHKERR VecNorm(T, NORM_2, &nrm2);
1171 MOFEM_LOG("EXAMPLE", Sev::verbose) << "Regression norm " << nrm2;
1172
1173 double regression_value = 0;
1174 switch (test_nb) {
1175 case 1:
1176 regression_value = 3.5112e-01;
1177 break;
1178 case 2:
1179 regression_value = 1.8841e+00;
1180 break;
1181 case 3:
1182 regression_value = 1.8841e+00;
1183 break;
1184 default:
1185 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "Wrong test number.");
1186 break;
1187 }
1188 if (fabs(nrm2 - regression_value) > 1e-2)
1189 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1190 "Regression test field; wrong norm value. %6.4e != %6.4e", nrm2,
1191 regression_value);
1192 }
1194}
#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 93 of file NonlinearElasticExample.hpp.

93 {
94 Range boundary_ents;
95 ParallelComm *pcomm =
96 ParallelComm::get_pcomm(&m_field.get_moab(), MYPCOMM_INDEX);
97 CHK_MOAB_THROW(pcomm->filter_pstatus(skin,
98 PSTATUS_SHARED | PSTATUS_MULTISHARED,
99 PSTATUS_NOT, -1, &boundary_ents),
100 "filter_pstatus");
101 return boundary_ents;
102 };
#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 86 of file NonlinearElasticExample.hpp.

86 {
87 Skinner skin(&m_field.get_moab());
88 Range skin_ents;
89 CHK_MOAB_THROW(skin.find_skin(0, body_ents, false, skin_ents), "find_skin");
90 return skin_ents;
91 };

◆ 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 939 of file NonlinearElasticExample.hpp.

939 {
941
942 auto simple = mField.getInterface<Simple>();
943 auto dm = simple->getDM();
944
945 auto T = createDMVector(simple->getDM());
946 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
947 SCATTER_FORWARD);
948 double nrm2;
949 CHKERR VecNorm(T, NORM_2, &nrm2);
950 MOFEM_LOG("EXAMPLE", Sev::inform) << "Solution norm " << nrm2;
951
952 auto post_proc_norm_fe = boost::make_shared<DomainEle>(mField);
953
954 auto post_proc_norm_rule_hook = [](int, int, int p) -> int { return 2 * p; };
955 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
956
958 post_proc_norm_fe->getOpPtrVector(), {H1}, "GEOMETRY");
959
960 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
961 auto norms_vec =
963 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
964 CHKERR VecZeroEntries(norms_vec);
965
966 auto u_ptr = boost::make_shared<MatrixDouble>();
967 post_proc_norm_fe->getOpPtrVector().push_back(
968 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
969
970 post_proc_norm_fe->getOpPtrVector().push_back(
971 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
972
973 if (useAdolcMaterial == PETSC_TRUE) {
974#ifdef WITH_ADOL_C
977 opPostProcFactory(mField, post_proc_norm_fe->getOpPtrVector(), "U",
979 auto m_P = physicalEquationsPtr->matOpsDataPtr->getCommonDataPtr("P");
980 post_proc_norm_fe->getOpPtrVector().push_back(
981 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(m_P, norms_vec,
982 PIOLA_NORM));
983 }
984#else
985 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
986 "ADOL-C support is not enabled. Please reconfigure with "
987 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
988#endif
989 } else {
990 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
991 mField, post_proc_norm_fe->getOpPtrVector(), "U", "MAT_ELASTIC",
992 Sev::inform);
993 post_proc_norm_fe->getOpPtrVector().push_back(
994 new OpCalcNormL2Tensor2<SPACE_DIM, SPACE_DIM>(
995 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
996 }
997
998 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
999 post_proc_norm_fe);
1000
1001 CHKERR VecAssemblyBegin(norms_vec);
1002 CHKERR VecAssemblyEnd(norms_vec);
1003
1004 MOFEM_LOG_CHANNEL("SELF"); // Clear channel from old tags
1005 if (mField.get_comm_rank() == 0) {
1006 const double *norms;
1007 CHKERR VecGetArrayRead(norms_vec, &norms);
1008 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
1009 << "norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
1010 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
1011 << "norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
1012 CHKERR VecRestoreArrayRead(norms_vec, &norms);
1013 }
1014
1016}
#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 455 of file NonlinearElasticExample.hpp.

455 {
457
458 // get operators tester
459 auto simple = mField.getInterface<Simple>();
460 auto opt = mField.getInterface<OperatorsTester>(); // get interface to
461 // OperatorsTester
462 auto pip = mField.getInterface<PipelineManager>(); // get interface to
463 // pipeline manager
464
465 constexpr double eps = 1e-9;
466
467 auto x = opt->setRandomFields(simple->getDM(), {
468
469 {"U", {-1e-6, 1e-6}}
470
471 });
472
473 auto dot_x = opt->setRandomFields(simple->getDM(), {
474
475 {"U", {-1, 1}}
476
477 });
478
479 auto diff_x = opt->setRandomFields(simple->getDM(), {
480
481 {"U", {-1, 1}}
482
483 });
484
485 auto test_domain_ops = [&](auto fe_name, auto lhs_pipeline,
486 auto rhs_pipeline) {
488
489 auto diff_res = opt->checkCentralFiniteDifference(
490 simple->getDM(), fe_name, rhs_pipeline, lhs_pipeline, x, dot_x,
491 SmartPetscObj<Vec>(), diff_x, 0, 0.5, eps);
492
493 // Calculate norm of difference between directional derivative calculated
494 // from finite difference, and tangent matrix.
495 double fnorm;
496 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
497 MOFEM_LOG_C("EXAMPLE", Sev::inform,
498 "Test consistency of tangent matrix %3.4e", fnorm);
499
500 constexpr double err = 1e-5;
501 if (fnorm > err)
502 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
503 "Norm of directional derivative too large err = %3.4e", fnorm);
504
506 };
507
508 MOFEM_LOG("EXAMPLE", Sev::inform)
509 << "Test operators with finite difference of directional "
510 "derivative";
511 CHKERR test_domain_ops(simple->getDomainFEName(), pip->getDomainLhsFE(),
512 pip->getDomainRhsFE());
513
515}
#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 134 of file NonlinearElasticExample.hpp.

134 {
136 auto simple = mField.getInterface<Simple>();
137 CHKERR simple->getOptions();
138 CHKERR simple->loadFile();
139 CHKERR mField.getInterface<MeshsetsManager>()->setMeshsetFromFile();
141}

◆ runProblem()

MoFEMErrorCode NonlinearElasticExample::runProblem ( )

[Run problem]

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

Definition at line 106 of file NonlinearElasticExample.hpp.

106 {
111
112 PetscBool test_op = PETSC_FALSE;
113 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_op", &test_op,
114 PETSC_NULLPTR);
115
116 if (useAdolcMaterial == PETSC_TRUE) {
118 } else {
120 }
121
122 if (test_op == PETSC_TRUE) {
123 CHKERR opTest();
124 }
125 CHKERR TsSolve();
130}
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 145 of file NonlinearElasticExample.hpp.

145 {
147 Simple *simple = mField.getInterface<Simple>();
148
149 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
150 const char *list_bases[LASBASETOPT] = {"ainsworth", "demkowicz"};
151 PetscInt choice_base_value = AINSWORTH;
152 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL, "-base", list_bases,
153 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
154
155 switch (choice_base_value) {
156 case AINSWORTH:
158 MOFEM_LOG("WORLD", Sev::inform)
159 << "Set AINSWORTH_LEGENDRE_BASE for displacements";
160 break;
161 case DEMKOWICZ:
163 MOFEM_LOG("WORLD", Sev::inform)
164 << "Set DEMKOWICZ_JACOBI_BASE for displacements";
165 break;
166 default:
168 break;
169 }
170
171 // Add field
172 CHKERR simple->addDomainField("U", H1, approximationBase, SPACE_DIM);
173 CHKERR simple->addBoundaryField("U", H1, approximationBase, SPACE_DIM);
174 CHKERR simple->addDataField("GEOMETRY", H1, approximationBase, SPACE_DIM);
175 int order = 2;
176 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
177 CHKERR simple->setFieldOrder("U", order);
178 CHKERR simple->setFieldOrder("GEOMETRY", 2);
179 CHKERR simple->setUp();
180
181 auto project_ho_geometry = [&]() {
182 Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
183 return mField.loop_dofs("GEOMETRY", ent_method);
184 };
185 CHKERR project_ho_geometry();
186
187 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-use_adolc_material",
188 &useAdolcMaterial, PETSC_NULLPTR);
189#ifndef WITH_ADOL_C
190 if (useAdolcMaterial == PETSC_TRUE) {
191 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
192 "ADOL-C support is not enabled. Please reconfigure with "
193 "-DWITH_ADOL_C=ON and recompile to use AdolC material model.");
194 }
195#endif
196 if (useAdolcMaterial == PETSC_TRUE) {
197 MOFEM_LOG("WORLD", Sev::inform) << "Use ADOL-C material model";
198 } else {
199 MOFEM_LOG("WORLD", Sev::inform) << "Use Hencky material model";
200 }
201
202 auto tag_meshest = [&]() {
204
205 auto set_block = [&](auto name, int dim) {
206 std::map<int, Range> map;
207 auto set_tag_impl = [&](auto name) {
209 auto mesh_mng = mField.getInterface<MeshsetsManager>();
210 auto bcs = mesh_mng->getCubitMeshsetPtr(
211
212 std::regex((boost::format("%s(.*)") % name).str())
213
214 );
215 std::map<int, int> ids_map;
216 int bit_id = 1;
217 for (auto bc : bcs) {
218 int id = bc->getMeshsetId();
219 ids_map[id] = bit_id;
220 bit_id <<= 1;
221 }
222 for (auto bc : bcs) {
223 Range r;
224 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
225 true);
226 map[ids_map[bc->getMeshsetId()]] = r;
227 MOFEM_LOG("EXAMPLE", Sev::inform)
228 << "Block " << name << " id " << bc->getMeshsetId() << " : "
229 << ids_map[bc->getMeshsetId()] << " has " << r.size()
230 << " entities";
231 }
233 };
234
235 CHKERR set_tag_impl(name);
236
237 return std::make_pair(name, map);
238 };
239
240 auto set_skin = [&](auto &&map) {
241 for (auto &m : map.second) {
242 auto s = filter_true_skin(mField, get_skin(mField, m.second));
243 m.second.swap(s);
244 MOFEM_LOG("EXAMPLE", Sev::inform)
245 << "Skin for block " << map.first << " id " << m.first << " has "
246 << m.second.size() << " entities";
247 }
248 return map;
249 };
250
251 auto set_tag = [&](auto &&map) {
252 Tag th;
253 auto name = map.first;
254 int def_val[] = {-1};
255 CHK_MOAB_THROW(mField.get_moab().tag_get_handle(
256 name, 1, MB_TYPE_INTEGER, th,
257 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
258 "create tag");
259 for (auto &m : map.second) {
260 int id = m.first;
261 for (auto ent : m.second) {
262 int current_id;
264 mField.get_moab().tag_get_data(th, &ent, 1, &current_id),
265 "get tag data");
266 if (current_id != -1) {
267 id |= current_id;
268 }
269 CHK_MOAB_THROW(mField.get_moab().tag_set_data(th, &ent, 1, &id),
270 "set tag data");
271 }
272 }
273 return th;
274 };
275
276 if (SPACE_DIM == 3) {
277 listTagsToTransfer.push_back(set_tag(set_block("MAT_", 3)));
278 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_", 3))));
279 } else {
280 listTagsToTransfer.push_back(set_tag(set_block("MAT_", 2)));
281 }
282
284 };
285
286 CHKERR tag_meshest();
287
289}
@ 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 831 of file NonlinearElasticExample.hpp.

831 {
833 auto *simple = mField.getInterface<Simple>();
834 auto *pipeline_mng = mField.getInterface<PipelineManager>();
835
836 auto dm = simple->getDM();
837 auto ts = pipeline_mng->createTSIM();
838
839 auto add_extra_finite_elements_to_solver_pipelines = [&]() {
841
842 auto pre_proc_ptr = boost::make_shared<FEMethod>();
843 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
844 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
845
846 auto time_scale = boost::make_shared<ExampleTimeScale>();
847
848 auto get_bc_hook_rhs = [this, pre_proc_ptr, time_scale]() {
850 CHKERR EssentialPreProc<DisplacementCubitBcData>(mField, pre_proc_ptr,
851 {time_scale}, false)();
853 };
854
855 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
856
857 auto get_post_proc_hook_rhs = [this, post_proc_rhs_ptr]() {
859 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
860 mField, post_proc_rhs_ptr, nullptr, Sev::verbose)();
861 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
862 mField, post_proc_rhs_ptr, 1.)();
864 };
865 auto get_post_proc_hook_lhs = [this, post_proc_lhs_ptr]() {
867 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
868 mField, post_proc_lhs_ptr, 1.)();
870 };
871 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
872 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
873
874 // This is low level pushing finite elements (pipelines) to solver
875 auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
876 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
877 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
878 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
879 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
881 };
882
883 // Add extra finite elements to SNES solver pipelines to resolve essential
884 // boundary conditions
885 CHKERR add_extra_finite_elements_to_solver_pipelines();
886
887 auto create_monitor_fe = [dm](auto &&post_proc_fe) {
888 return boost::make_shared<Monitor>(dm.get(), post_proc_fe);
889 };
890
891 // Set monitor which postprocessing results and saves them to the hard drive
892 boost::shared_ptr<FEMethod> null_fe;
894 CHKERR postProcDomainFe->setTagsToTransfer(
895 std::vector<Tag>(listTagsToTransfer));
896 if (postProcBdyFe)
897 CHKERR postProcBdyFe->setTagsToTransfer(
898 std::vector<Tag>(listTagsToTransfer));
899 auto monitor_ptr =
900 create_monitor_fe(std::make_pair(postProcDomainFe, postProcBdyFe));
901 CHKERR DMMoFEMTSSetMonitor(dm, ts, simple->getDomainFEName(), null_fe,
902 null_fe, monitor_ptr);
903
904 // Set time solver
905 double ftime = 1;
906 CHKERR TSSetMaxTime(ts, ftime);
907 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
908
909 auto B = createDMMatrix(dm);
910 CHKERR TSSetI2Jacobian(ts, B, B, PETSC_NULLPTR, PETSC_NULLPTR);
911 auto D = createDMVector(simple->getDM());
912 CHKERR TSSetSolution(ts, D);
913 CHKERR TSSetFromOptions(ts);
914
916 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
917 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
918 CHKERR TSSolve(ts, NULL);
920
921 CHKERR TSGetTime(ts, &ftime);
922
923 PetscInt steps, snesfails, rejects, nonlinits, linits;
924 CHKERR TSGetStepNumber(ts, &steps);
925 CHKERR TSGetSNESFailures(ts, &snesfails);
926 CHKERR TSGetStepRejections(ts, &rejects);
927 CHKERR TSGetSNESIterations(ts, &nonlinits);
928 CHKERR TSGetKSPIterations(ts, &linits);
929 MOFEM_LOG_C("EXAMPLE", Sev::inform,
930 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
931 "%d, linits %d",
932 steps, rejects, snesfails, ftime, nonlinits, linits);
933
935}
#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 77 of file NonlinearElasticExample.hpp.

◆ 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 80 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: