v0.15.0
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Attributes | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
Example Struct Reference

[Example] More...

Collaboration diagram for Example:
[legend]

Classes

struct  BoundaryOp
 
struct  CommonData
 [Example] More...
 
struct  DynamicFirstOrderConsConstantTimeScale
 
struct  DynamicFirstOrderConsSinusTimeScale
 
struct  OpCalcSurfaceAverageTemperature
 
struct  OpError
 
struct  OpError< 1 >
 
struct  OpFirst
 
struct  OpFluxRhs
 
struct  OpRadiationLhs
 
struct  OpRadiationRhs
 
struct  OpRhs
 
struct  OpSecond
 [Operator] More...
 
struct  OpZero
 [Common data] More...
 
struct  ScaledTimeScale
 

Public Types

enum  { VOL , COUNT }
 
enum  { VOL , COUNT }
 

Public Member Functions

 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 [Run problem]
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 Main driver function for the optimization process.
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 
 Example (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 

Static Public Attributes

static std::array< double, 2 > meshVolumeAndCount = {0, 0}
 

Private Types

enum  BoundingBox {
  CENTER_X = 0 , CENTER_Y , MAX_X , MAX_Y ,
  MIN_X , MIN_Y , LAST_BB
}
 

Private Member Functions

MoFEMErrorCode setupProblem ()
 [Run problem]
 
MoFEMErrorCode createCommonData ()
 [Set up problem]
 
MoFEMErrorCode bC ()
 [Create common data]
 
MoFEMErrorCode OPs ()
 [Boundary condition]
 
MoFEMErrorCode tsSolve ()
 
MoFEMErrorCode testOperators ()
 [Solve]
 
MoFEMErrorCode readMesh ()
 [Run problem]
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode boundaryCondition ()
 [Set up problem]
 
MoFEMErrorCode assembleSystem ()
 [Push operators to pipeline]
 
MoFEMErrorCode solveSystem ()
 [Solve]
 
MoFEMErrorCode outputResults ()
 [Solve]
 
MoFEMErrorCode checkResults ()
 [Postprocess results]
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode projectResults (BitRefLevel parent_bit, BitRefLevel child_bit, BitRefLevel refine_bit)
 [Solve]
 
MoFEMErrorCode outputResults (std::string FIELD_NAME_U)
 [Project results]
 
MoFEMErrorCode edgeFlips (BitRefLevel parent_bit, BitRefLevel child_bit)
 [Output results]
 
MoFEMErrorCode refineSkin (BitRefLevel parent_bit, BitRefLevel refine_bit)
 [Edge flips]
 
MoFEMErrorCode reSetupProblem (BitRefLevel child_bit)
 [Refine skin]
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode setUp ()
 [Run all]
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode setFieldValues ()
 [Create common data]
 
MoFEMErrorCode pushOperators ()
 [Set density distribution]
 
MoFEMErrorCode integrateElements ()
 [Push operators to pipeline]
 
MoFEMErrorCode postProcess ()
 [Integrate]
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode setIntegrationRules ()
 [Set up problem]
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode assembleSystemIntensity ()
 [Calculate flux on boundary]
 
MoFEMErrorCode assembleSystemFlux ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode calculateFlux (double &calc_flux)
 [Set up problem]
 
MoFEMErrorCode outputResults (const int i)
 [Solve]
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode setIntegrationRules ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode bC ()
 
MoFEMErrorCode OPs ()
 
MoFEMErrorCode kspSolve ()
 [Push operators to pipeline]
 
MoFEMErrorCode postProcess ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode setIntegrationRules ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 Read mesh from file and setup meshsets.
 
MoFEMErrorCode setupProblem ()
 Setup fields, approximation spaces and DOFs.
 
MoFEMErrorCode setupAdJoint ()
 Setup adjoint fields and finite elements

 
MoFEMErrorCode boundaryCondition ()
 Apply essential boundary conditions.
 
MoFEMErrorCode topologyModes ()
 Compute topology optimization modes.
 
MoFEMErrorCode assembleSystem ()
 Setup operators in finite element pipeline.
 
MoFEMErrorCode solveElastic ()
 Solve forward elastic problem.
 
MoFEMErrorCode postprocessElastic (int iter, SmartPetscObj< Vec > adjoint_vector=nullptr)
 Post-process and output results.
 
MoFEMErrorCode calculateGradient (PetscReal *objective_function_value, Vec objective_function_gradient, Vec adjoint_vector)
 Calculate objective function gradient using adjoint method.
 
friend PetscErrorCode::MyTSResizeTransfer (TS, PetscInt, Vec[], Vec[], void *)
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode initialConditions ()
 [Create common data]
 
MoFEMErrorCode mechanicalBC ()
 [Initial conditions]
 
MoFEMErrorCode thermalBC ()
 [Mechanical boundary conditions]
 
MoFEMErrorCode getElementQuality (std::multimap< double, EntityHandle > &el_q_map, Range &flipped_els, std::vector< EntityHandle > &new_connectivity, bool &do_refine, Tag &th_spatial_coords)
 [Get element quality]
 
MoFEMErrorCode edgeFlips (BitRefLevel parent_bit, BitRefLevel child_bit)
 
MoFEMErrorCode doEdgeFlips (std::multimap< double, EntityHandle > &el_q_map, Range &flipped_els, Tag &th_spatial_coords, std::vector< EntityHandle > &new_connectivity)
 [Edge flips]
 
MoFEMErrorCode doEdgeSplits (bool &refine, bool add_ents)
 [Do Edge Flips]
 
MoFEMErrorCode OPs ()
 
MoFEMErrorCode tsSolve ()
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoPlasticFactoryDomainRhs (MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoPlasticFactoryDomainLhs (MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
 
template<int DIM, IntegrationType I, typename DomainEleOp >
auto createCommonThermoPlasticOps (MoFEM::Interface &m_field, std::string plastic_block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string u, std::string ep, std::string tau, std::string temperature, double scale, ScalerFunTwoArgs thermal_conductivity_scaling, ScalerFunTwoArgs heat_capacity_scaling, ScalerFunThreeArgs inelastic_heat_fraction_scaling, Sev sev, bool with_rates=true)
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode bC ()
 
MoFEMErrorCode OPs ()
 
MoFEMErrorCode tsSolve ()
 
MoFEMErrorCode testOperators ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveSystem ()
 
MoFEMErrorCode gettingNorms ()
 [Solve]
 
MoFEMErrorCode outputResults ()
 
MoFEMErrorCode checkResults ()
 

Static Private Member Functions

static std::pair< int, int > getCoordsInImage (double x, double y)
 
static double rhsSource (const double x, const double y, const double)
 
static double lhsFlux (const double x, const double y, const double)
 
static int integrationRule (int, int, int p_data)
 

Private Attributes

MoFEM::InterfacemField
 Reference to MoFEM interface.
 
boost::shared_ptr< DomainElereactionFe
 
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
 
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
 
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
 
SimplesimpleInterface
 
boost::shared_ptr< std::vector< unsigned char > > boundaryMarker
 
boost::shared_ptr< CommonDatacommonDataPtr
 
FieldApproximationBase base
 Choice of finite element basis functions

 
FieldSpace space
 
boost::shared_ptr< VectorDoubleapproxVals
 
boost::shared_ptr< MatrixDoubleapproxGradVals
 
Range pinchNodes
 
boost::shared_ptr< MatrixDoublematDPtr
 
SmartPetscObj< Mat > M
 
SmartPetscObj< Mat > K
 
SmartPetscObj< EPS > ePS
 
std::array< SmartPetscObj< Vec >, 6 > rigidBodyMotion
 
boost::shared_ptr< FEMethoddomianLhsFEPtr
 
boost::shared_ptr< FEMethoddomianRhsFEPtr
 
boost::shared_ptr< MatrixDoublevectorFieldPtr = nullptr
 Field values at evaluation points.
 
int fieldOrder = 2
 Polynomial order for approximation.
 
SmartPetscObj< KSP > kspElastic
 Linear solver for elastic problem.
 
SmartPetscObj< DM > adjointDM
 Data manager for adjoint problem.
 
boost::shared_ptr< ObjectiveFunctionDatapythonPtr
 Interface to Python objective function.
 
std::vector< SmartPetscObj< Vec > > modeVecs
 Topology mode vectors (design variables)
 
std::vector< std::array< double, 3 > > modeCentroids
 Centroids of optimization blocks

 
std::vector< std::array< double, 6 > > modeBBoxes
 Bounding boxes of optimization blocks.
 
SmartPetscObj< Vec > initialGeometry
 Initial geometry field.
 
boost::shared_ptr< VectorDoubletempFieldPtr
 
boost::shared_ptr< MatrixDoublefluxFieldPtr
 
boost::shared_ptr< MatrixDoubledispFieldPtr
 
boost::shared_ptr< MatrixDoubledispGradPtr
 
boost::shared_ptr< MatrixDoublestrainFieldPtr
 
boost::shared_ptr< MatrixDoublestressFieldPtr
 
boost::shared_ptr< VectorDoubleplasticMultiplierFieldPtr
 
boost::shared_ptr< MatrixDoubleplasticStrainFieldPtr
 

Static Private Attributes

static std::vector< doublerZ
 
static std::vector< MatrixIntiI
 
static std::array< double, LAST_BBaveMaxMin
 
static int focalIndex
 
static int savitzkyGolayNormalisation
 
static const int * savitzkyGolayWeights
 
static ApproxFieldFunction< FIELD_DIMapproxFunction
 

Friends

struct TSPrePostProc
 

Detailed Description

[Example]

Main class for topology optimization using adjoint method.

This class implements a complete topology optimization workflow:

  1. Setup finite element problems for elasticity and adjoint analysis
  2. Define topology modes for design parametrization
  3. Use TAO optimization library to minimize Python-defined objective function
  4. Compute sensitivities using adjoint method for efficient gradient calculation

The optimization process alternates between:

Examples
mofem/tutorials/adv-0/plastic.cpp, mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-1/integration.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/mix-1/phase.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-8/radiation.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, mofem/tutorials/vec-7/adjoint.cpp, nonlinear_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 216 of file plastic.cpp.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
VOL 
COUNT 

Definition at line 222 of file plastic.cpp.

222{ VOL, COUNT };

◆ anonymous enum

anonymous enum
Enumerator
VOL 
COUNT 

Definition at line 222 of file plastic.cpp.

222{ VOL, COUNT };

◆ BoundingBox

enum Example::BoundingBox
private
Enumerator
CENTER_X 
CENTER_Y 
MAX_X 
MAX_Y 
MIN_X 
MIN_Y 
LAST_BB 
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 98 of file phase.cpp.

98 {
99 CENTER_X = 0,
100 CENTER_Y,
101 MAX_X,
102 MAX_Y,
103 MIN_X,
104 MIN_Y,
105 LAST_BB
106 };
@ MAX_X
Definition phase.cpp:101
@ MIN_X
Definition phase.cpp:103
@ MIN_Y
Definition phase.cpp:104
@ CENTER_X
Definition phase.cpp:99
@ MAX_Y
Definition phase.cpp:102
@ CENTER_Y
Definition phase.cpp:100
@ LAST_BB
Definition phase.cpp:105

Constructor & Destructor Documentation

◆ Example() [1/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 218 of file plastic.cpp.

218: mField(m_field) {}
MoFEM::Interface & mField
Reference to MoFEM interface.
Definition plastic.cpp:226

◆ Example() [2/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 420 of file dynamic_first_order_con_law.cpp.

420: mField(m_field) {}

◆ Example() [3/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 42 of file between_meshes_dg_projection.cpp.

42: mField(m_field) {}

◆ Example() [4/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 35 of file helmholtz.cpp.

35: mField(m_field) {}

◆ Example() [5/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 25 of file integration.cpp.

25: mField(m_field) {}

◆ Example() [6/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 50 of file plot_base.cpp.

50: mField(m_field) {}

◆ Example() [7/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 81 of file phase.cpp.

81: mField(m_field) {}

◆ Example() [8/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 53 of file approximaton.cpp.

53: mField(m_field) {}

◆ Example() [9/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 45 of file radiation.cpp.

45: mField(m_field) {}

◆ Example() [10/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 47 of file heat_method.cpp.

47: mField(m_field) {}

◆ Example() [11/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 49 of file eigen_elastic.cpp.

49: mField(m_field) {}

◆ Example() [12/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 52 of file nonlinear_dynamic_elastic.cpp.

52: mField(m_field) {}

◆ Example() [13/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 339 of file shallow_wave.cpp.

339: mField(m_field) {}

◆ Example() [14/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 179 of file adjoint.cpp.

179: mField(m_field) {}

◆ Example() [15/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 835 of file thermoplastic.cpp.

835: mField(m_field) {}

◆ Example() [16/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 218 of file plastic.cpp.

218: mField(m_field) {}

◆ Example() [17/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 80 of file elastic.cpp.

80: mField(m_field) {}

◆ Example() [18/18]

Example::Example ( MoFEM::Interface m_field)
inline

Definition at line 57 of file nonlinear_elastic.cpp.

57: mField(m_field) {}

Member Function Documentation

◆ assembleSystem() [1/12]

MoFEMErrorCode Example::assembleSystem ( )
private

[Push operators to pipeline]

[Adjoint modes]

[Boundary condition]

[Applying essential BC]

[Set up problem]

[Push operators to pipeline]

[Integration rule]

[Integration rule]

[Push domain stiffness matrix to pipeline]

[Push domain stiffness matrix to pipeline]

[Push Body forces]

[Push Body forces]

[Push natural boundary conditions]

[Push natural boundary conditions]

Examples
mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, mofem/tutorials/vec-7/adjoint.cpp, and nonlinear_elastic.cpp.

Definition at line 640 of file dynamic_first_order_con_law.cpp.

640 {
642 auto get_body_force = [this](const double, const double, const double) {
645 t_source(i) = 0.;
646 t_source(0) = 0.1;
647 t_source(1) = 1.;
648 return t_source;
649 };
650
651 // specific time scaling
652 auto get_time_scale = [this](const double time) {
653 return sin(time * omega * M_PI);
654 };
655
656 auto apply_rhs = [&](auto &pip) {
658
660 "GEOMETRY");
661
662 // Calculate Gradient of velocity
663 auto mat_v_grad_ptr = boost::make_shared<MatrixDouble>();
665 "V", mat_v_grad_ptr));
666
667 auto gravity_vector_ptr = boost::make_shared<MatrixDouble>();
668 gravity_vector_ptr->resize(SPACE_DIM, 1);
669 auto set_body_force = [&]() {
672 auto t_force = getFTensor1FromMat<SPACE_DIM, 0>(*gravity_vector_ptr);
673 double unit_weight = 0.;
674 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-unit_weight", &unit_weight,
675 PETSC_NULLPTR);
676 t_force(i) = 0;
677 if (SPACE_DIM == 2) {
678 t_force(1) = -unit_weight;
679 } else if (SPACE_DIM == 3) {
680 t_force(2) = unit_weight;
681 }
683 };
684
685 CHKERR set_body_force();
686 pip.push_back(new OpBodyForce("V", gravity_vector_ptr,
687 [](double, double, double) { return 1.; }));
688
689 // Calculate unknown F
690 auto mat_H_tensor_ptr = boost::make_shared<MatrixDouble>();
692 "F", mat_H_tensor_ptr));
693
694 // // Calculate F
695 double tau = 0.2;
696 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-tau", &tau, PETSC_NULLPTR);
697
698 double xi = 0.;
699 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-xi", &xi, PETSC_NULLPTR);
700
701 // Calculate P stab
702 auto one = [&](const double, const double, const double) {
703 return 3. * bulk_modulus_K;
704 };
705 auto minus_one = [](const double, const double, const double) {
706 return -1.;
707 };
708
709 auto mat_dot_F_tensor_ptr = boost::make_shared<MatrixDouble>();
711 "F_dot", mat_dot_F_tensor_ptr));
712
713 // Calculate Gradient of Spatial Positions
714 auto mat_x_grad_ptr = boost::make_shared<MatrixDouble>();
716 "x_2", mat_x_grad_ptr));
717
718 auto mat_F_tensor_ptr = boost::make_shared<MatrixDouble>();
720 mat_F_tensor_ptr, mat_H_tensor_ptr));
721
722 auto mat_F_stab_ptr = boost::make_shared<MatrixDouble>();
724 mat_F_tensor_ptr, mat_F_stab_ptr, mat_dot_F_tensor_ptr, tau, xi,
725 mat_x_grad_ptr, mat_v_grad_ptr));
726
727 PetscBool is_linear_elasticity = PETSC_TRUE;
728 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-is_linear_elasticity",
729 &is_linear_elasticity, PETSC_NULLPTR);
730
731 auto mat_P_stab_ptr = boost::make_shared<MatrixDouble>();
732 if (is_linear_elasticity) {
735 mat_F_stab_ptr));
736 } else {
737 auto inv_F = boost::make_shared<MatrixDouble>();
738 auto det_ptr = boost::make_shared<VectorDouble>();
739
740 pip.push_back(
741 new OpInvertMatrix<SPACE_DIM>(mat_F_stab_ptr, det_ptr, inv_F));
742
743 // OpCalculatePiolaIncompressibleNH
746 mat_F_stab_ptr, inv_F, det_ptr));
747 }
748
749 pip.push_back(new OpGradTimesTensor2("V", mat_P_stab_ptr, minus_one));
750 pip.push_back(new OpRhsTestPiola("F", mat_v_grad_ptr, one));
751
753 };
754
755 auto *pipeline_mng = mField.getInterface<PipelineManager>();
756 CHKERR apply_rhs(pipeline_mng->getOpDomainExplicitRhsPipeline());
757
758 auto integration_rule = [](int, int, int approx_order) {
759 return 2 * approx_order;
760 };
761 CHKERR pipeline_mng->setDomainExplicitRhsIntegrationRule(integration_rule);
762
764}
@ 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 ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
FormsIntegrators< DomainEleOp >::Assembly< AssemblyType::PETSC >::LinearForm< IntegrationType::GAUSS >::OpBaseTimesVector< 1, SPACE_DIM *SPACE_DIM, 1 > OpRhsTestPiola
constexpr double omega
Save field DOFS on vertices/tags.
double bulk_modulus_K
FormsIntegrators< DomainEleOp >::Assembly< AssemblyType::PETSC >::LinearForm< IntegrationType::GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpGradTimesTensor2
double shear_modulus_G
auto integration_rule
FTensor::Index< 'i', SPACE_DIM > i
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
static constexpr int approx_order
Add operators pushing bases from local to physical configuration.
Get values at integration pts for tensor field rank 2, i.e. matrix field.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Operator for inverting matrices at integration points.
PipelineManager interface.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
constexpr int SPACE_DIM
DomainNaturalBC::OpFlux< NaturalMeshsetType< BLOCKSET >, 1, SPACE_DIM > OpBodyForce

◆ assembleSystem() [2/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [3/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [4/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [5/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [6/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [7/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [8/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [9/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [10/12]

MoFEMErrorCode Example::assembleSystem ( )
private

Setup operators in finite element pipeline.

◆ assembleSystem() [11/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [12/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystemFlux()

MoFEMErrorCode Example::assembleSystemFlux ( )
private

◆ assembleSystemIntensity()

MoFEMErrorCode Example::assembleSystemIntensity ( )
private

[Calculate flux on boundary]

[Push operators to pipeline]

Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 433 of file phase.cpp.

433 {
435
436 auto *pipeline_mng = mField.getInterface<PipelineManager>();
437
438 pipeline_mng->getDomainLhsFE().reset();
439 pipeline_mng->getDomainRhsFE().reset();
440 pipeline_mng->getBoundaryRhsFE().reset();
441
442 auto rule_vol = [](int, int, int order) { return 2 * (order + 1); };
443 pipeline_mng->setDomainLhsIntegrationRule(rule_vol);
444 pipeline_mng->setDomainRhsIntegrationRule(rule_vol);
445
446 auto det_ptr = boost::make_shared<VectorDouble>();
447 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
448 auto jac_ptr = boost::make_shared<MatrixDouble>();
449 pipeline_mng->getOpDomainLhsPipeline().push_back(new OpSetHOWeightsOnFace());
450 pipeline_mng->getOpDomainLhsPipeline().push_back(
451 new OpCalculateHOJacForFace(jac_ptr));
452 pipeline_mng->getOpDomainLhsPipeline().push_back(
453 new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
454 pipeline_mng->getOpDomainLhsPipeline().push_back(new OpMakeHdivFromHcurl());
455 pipeline_mng->getOpDomainLhsPipeline().push_back(
457 pipeline_mng->getOpDomainLhsPipeline().push_back(
458 new OpSetInvJacHcurlFace(inv_jac_ptr));
459 pipeline_mng->getOpDomainLhsPipeline().push_back(new OpSetHOWeightsOnFace());
460
461 pipeline_mng->getOpDomainLhsPipeline().push_back(
462 new OpHdivHdiv("S", "S", lhsFlux));
463 auto unity = []() { return 1; };
464 pipeline_mng->getOpDomainLhsPipeline().push_back(
465 new OpHdivU("S", "PHI", unity, true));
466
467 pipeline_mng->getOpDomainRhsPipeline().push_back(new OpSetHOWeightsOnFace());
468 pipeline_mng->getOpDomainRhsPipeline().push_back(
469 new OpDomainSource("PHI", rhsSource));
470
472}
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, FIELD_DIM > OpDomainSource
constexpr int order
Order displacement.
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< 2 > OpHdivU
OpSetInvJacHcurlFaceImpl< 2 > OpSetInvJacHcurlFace
OpCalculateHOJacForFaceImpl< 2 > OpCalculateHOJacForFace
OpSetContravariantPiolaTransformOnFace2DImpl< 2 > OpSetContravariantPiolaTransformOnFace2D
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 3, 3 > OpHdivHdiv
Integrate Lhs base of flux (1/k) base of flux (FLUX x FLUX)
Definition seepage.cpp:86
static double rhsSource(const double x, const double y, const double)
Definition phase.cpp:150
static double lhsFlux(const double x, const double y, const double)
Definition phase.cpp:165
Make Hdiv space from Hcurl space in 2d.
Modify integration weights on face to take into account higher-order geometry.
boost::shared_ptr< FEMethod > & getDomainLhsFE()
Get domain left-hand side finite element.

◆ bC() [1/3]

MoFEMErrorCode Example::bC ( )
private

[Create common data]

[Boundary condition]

Examples
mofem/tutorials/adv-0/plastic.cpp, mofem/tutorials/scl-8/radiation.cpp, and plastic.cpp.

Definition at line 606 of file plastic.cpp.

606 {
608
610 auto bc_mng = mField.getInterface<BcManager>();
611
612 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
613 "U", 0, 0);
614 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
615 "U", 1, 1);
616 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
617 "U", 2, 2);
618 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
619 "REMOVE_ALL", "U", 0, 3);
620
621#ifdef ADD_CONTACT
622 for (auto b : {"FIX_X", "REMOVE_X"})
623 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
624 "SIGMA", 0, 0, false, true);
625 for (auto b : {"FIX_Y", "REMOVE_Y"})
626 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
627 "SIGMA", 1, 1, false, true);
628 for (auto b : {"FIX_Z", "REMOVE_Z"})
629 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
630 "SIGMA", 2, 2, false, true);
631 for (auto b : {"FIX_ALL", "REMOVE_ALL"})
632 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
633 "SIGMA", 0, 3, false, true);
634 CHKERR bc_mng->removeBlockDOFsOnEntities(
635 simple->getProblemName(), "NO_CONTACT", "SIGMA", 0, 3, false, true);
636#endif
637
638 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
639 simple->getProblemName(), "U");
640
641 auto &bc_map = bc_mng->getBcMapByBlockName();
642 for (auto bc : bc_map)
643 MOFEM_LOG("PLASTICITY", Sev::verbose) << "Marker " << bc.first;
644
646}
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
Boundary condition manager for finite element problem setup.
Definition of the displacement bc data structure.
Definition BCData.hpp:72
Simple interface for fast problem set-up.
Definition Simple.hpp:27

◆ bC() [2/3]

MoFEMErrorCode Example::bC ( )
private

◆ bC() [3/3]

MoFEMErrorCode Example::bC ( )
private

◆ boundaryCondition() [1/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

[Set up problem]

[Create common data]

[Boundary condition]

[Applying essential BC]

[Define gravity vector]

Examples
mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, mofem/tutorials/vec-7/adjoint.cpp, and nonlinear_elastic.cpp.

Definition at line 535 of file dynamic_first_order_con_law.cpp.

535 {
537
539 auto bc_mng = mField.getInterface<BcManager>();
540 auto *pipeline_mng = mField.getInterface<PipelineManager>();
541 auto time_scale = boost::make_shared<TimeScale>();
542
543 PetscBool sin_time_function = PETSC_FALSE;
544 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-sin_time_function",
545 &sin_time_function, PETSC_NULLPTR);
546
547 if (sin_time_function)
548 time_scale = boost::make_shared<DynamicFirstOrderConsSinusTimeScale>();
549 else
550 time_scale = boost::make_shared<DynamicFirstOrderConsConstantTimeScale>();
551
552 pipeline_mng->getBoundaryExplicitRhsFE().reset();
554 pipeline_mng->getOpBoundaryExplicitRhsPipeline(), {NOSPACE}, "GEOMETRY");
555
557 pipeline_mng->getOpBoundaryExplicitRhsPipeline(), mField, "V",
558 {time_scale}, "FORCE", Sev::inform);
559
560 auto integration_rule = [](int, int, int approx_order) {
561 return 2 * approx_order;
562 };
563
564 CHKERR pipeline_mng->setBoundaryExplicitRhsIntegrationRule(integration_rule);
565 CHKERR pipeline_mng->setDomainExplicitRhsIntegrationRule(integration_rule);
566
567 CHKERR bc_mng->removeBlockDOFsOnEntities<DisplacementCubitBcData>(
568 simple->getProblemName(), "V");
569
570 auto get_pre_proc_hook = [&]() {
572 mField, pipeline_mng->getDomainExplicitRhsFE(), {time_scale});
573 };
574 pipeline_mng->getDomainExplicitRhsFE()->preProcessHook = get_pre_proc_hook();
575
577}
Class (Function) to enforce essential constrains.
Definition Essential.hpp:25

◆ boundaryCondition() [2/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [3/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [4/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [5/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [6/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [7/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [8/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [9/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

Apply essential boundary conditions.

◆ boundaryCondition() [10/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [11/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ calculateFlux()

MoFEMErrorCode Example::calculateFlux ( double calc_flux)
private

[Set up problem]

[Calculate flux on boundary]

Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 402 of file phase.cpp.

402 {
404 auto pipeline_mng = mField.getInterface<PipelineManager>();
405
406 pipeline_mng->getDomainLhsFE().reset();
407 pipeline_mng->getDomainRhsFE().reset();
408 pipeline_mng->getBoundaryRhsFE().reset();
409
410 auto rule_vol = [](int, int, int order) { return 2 * (order + 1); };
411 pipeline_mng->setBoundaryRhsIntegrationRule(rule_vol);
412
413 auto flux_ptr = boost::make_shared<MatrixDouble>();
414 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
416 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
417 new OpCalculateHVecVectorField<3>("S", flux_ptr));
418 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
419 new BoundaryOp(flux_ptr, calc_flux));
420
421 calc_flux = 0;
422 CHKERR pipeline_mng->loopFiniteElements();
423 double global_flux_assembeld = 0;
424 MPI_Allreduce(&calc_flux, &global_flux_assembeld, 1, MPI_DOUBLE, MPI_SUM,
425 mField.get_comm());
426 calc_flux = global_flux_assembeld;
427
429}
virtual MPI_Comm & get_comm() const =0
Get vector field for H-div approximation.

◆ calculateGradient()

MoFEMErrorCode Example::calculateGradient ( PetscReal *  objective_function_value,
Vec  objective_function_gradient,
Vec  adjoint_vector 
)
private

Calculate objective function gradient using adjoint method.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 1947 of file adjoint.cpp.

1949 {
1950 MOFEM_LOG_CHANNEL("WORLD");
1952 auto simple = mField.getInterface<Simple>();
1953
1954 auto ents = get_range_from_block(mField, "OPTIMISE", SPACE_DIM - 1);
1955
1956 auto get_essential_fe = [this]() {
1957 auto post_proc_rhs = boost::make_shared<FEMethod>();
1958 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
1960
1962 post_proc_rhs, 0)();
1964 };
1965 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1966 return post_proc_rhs;
1967 };
1968
1969 auto get_fd_direvative_fe = [&]() {
1970 auto fe = boost::make_shared<DomainEle>(mField);
1971 fe->getRuleHook = [](int, int, int p_data) {
1972 return 2 * p_data + p_data - 1;
1973 };
1974 auto &pip = fe->getOpPtrVector();
1976 // Add RHS operators for internal forces
1977 constexpr bool debug = false;
1978 if constexpr (debug) {
1979 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1980 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1981 pip.push_back(
1982 new OpAdJointTestOp<SPACE_DIM, I, DomainBaseOp>("U", common_ptr));
1983 } else {
1984 HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
1985 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1986 }
1987 return fe;
1988 };
1989
1990 auto calulate_fd_residual = [&](auto eps, auto diff_vec, auto fd_vec) {
1992
1993 constexpr bool debug = false;
1994
1995 auto geom_norm = [](MoFEM::Interface &mField) {
1997 auto field_blas = mField.getInterface<FieldBlas>();
1998 double nrm2 = 0.0;
1999 auto norm2_field = [&](const double val) {
2000 nrm2 += val * val;
2001 return val;
2002 };
2003 CHKERR field_blas->fieldLambdaOnValues(norm2_field, "GEOMETRY");
2004 MPI_Allreduce(MPI_IN_PLACE, &nrm2, 1, MPI_DOUBLE, MPI_SUM,
2005 mField.get_comm());
2006 MOFEM_LOG("WORLD", Sev::inform) << "Geometry norm: " << sqrt(nrm2);
2008 };
2009
2010 if constexpr (debug)
2011 CHKERR geom_norm(mField);
2012
2013 auto initial_current_geometry = createDMVector(adjointDM);
2014 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
2015 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
2016 initial_current_geometry, INSERT_VALUES, SCATTER_FORWARD);
2017 CHKERR VecAssemblyBegin(initial_current_geometry);
2018 CHKERR VecAssemblyEnd(initial_current_geometry);
2019
2020 if constexpr (debug)
2021 CHKERR geom_norm(mField);
2022
2023 auto perturb_geometry = [&](auto eps, auto diff_vec) {
2025 auto current_geometry = vectorDuplicate(initial_current_geometry);
2026 CHKERR VecCopy(initial_current_geometry, current_geometry);
2027 CHKERR VecAXPY(current_geometry, eps, diff_vec);
2028 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
2029 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
2030 current_geometry, INSERT_VALUES, SCATTER_REVERSE);
2032 };
2033
2034 auto fe = get_fd_direvative_fe();
2035 auto fp = vectorDuplicate(diff_vec);
2036 auto fm = vectorDuplicate(diff_vec);
2037 auto calc_impl = [&](auto f, auto eps) {
2039 CHKERR VecZeroEntries(f);
2040 fe->f = f;
2041 CHKERR perturb_geometry(eps, diff_vec);
2043 simple->getDomainFEName(), fe);
2044 CHKERR VecAssemblyBegin(f);
2045 CHKERR VecAssemblyEnd(f);
2046 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
2047 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
2048 auto post_proc_rhs = get_essential_fe();
2049 post_proc_rhs->f = f;
2051 post_proc_rhs.get());
2053 };
2054 CHKERR calc_impl(fp, eps);
2055 CHKERR calc_impl(fm, -eps);
2056 CHKERR VecWAXPY(fd_vec, -1.0, fm, fp);
2057 CHKERR VecScale(fd_vec, 1.0 / (2.0 * eps));
2058
2059 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
2060 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
2061 initial_current_geometry, INSERT_VALUES, SCATTER_REVERSE);
2062
2063 if constexpr (debug)
2064 CHKERR geom_norm(mField);
2065
2067 };
2068
2069 auto get_direvative_fe = [&](auto diff_vec) {
2070 auto fe_adjoint = boost::make_shared<DomainEle>(mField);
2071 fe_adjoint->getRuleHook = [](int, int, int p_data) {
2072 return 2 * p_data + p_data - 1;
2073 };
2074 auto &pip = fe_adjoint->getOpPtrVector();
2075
2076 auto jac_ptr = boost::make_shared<MatrixDouble>();
2077 auto det_ptr = boost::make_shared<VectorDouble>();
2078 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
2079 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
2080 auto cof_ptr = boost::make_shared<VectorDouble>();
2081
2082 using OpCoFactor =
2083 AdJoint<DomainEleOp>::Integration<GAUSS>::OpGetCoFactor<SPACE_DIM>;
2084
2086
2088 "GEOMETRY", jac_ptr));
2090 "U", diff_jac_ptr,
2091 diff_vec)); // Note: that vector is stored on displacemnt vector, that
2092 // why is used here
2093
2094 pip.push_back(new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
2095
2096 // Add RHS operators for internal forces
2097 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
2098 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
2100 "U", common_ptr, jac_ptr, diff_jac_ptr, cof_ptr));
2101
2102 return fe_adjoint;
2103 };
2104
2105 auto get_objective_fe = [&](auto diff_vec, auto grad_vec,
2106 auto glob_objective_ptr,
2107 auto glob_objective_grad_ptr) {
2108 auto fe_adjoint = boost::make_shared<DomainEle>(mField);
2109 fe_adjoint->getRuleHook = [](int, int, int p_data) {
2110 return 2 * p_data + p_data - 1;
2111 };
2112 auto &pip = fe_adjoint->getOpPtrVector();
2114
2115 auto jac_ptr = boost::make_shared<MatrixDouble>();
2116 auto det_ptr = boost::make_shared<VectorDouble>();
2117 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
2118 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
2119 auto cof_ptr = boost::make_shared<VectorDouble>();
2120 auto d_grad_ptr = boost::make_shared<MatrixDouble>();
2121 auto u_ptr = boost::make_shared<MatrixDouble>();
2122
2123 using OpCoFactor =
2124 AdJoint<DomainEleOp>::Integration<GAUSS>::OpGetCoFactor<SPACE_DIM>;
2126 "GEOMETRY", jac_ptr));
2128 "U", diff_jac_ptr,
2129 diff_vec)); // Note: that vector is stored on displacemnt vector, that
2130 // why is used here
2131 pip.push_back(new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
2133 "U", d_grad_ptr, grad_vec));
2134 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
2135
2136 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
2137 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
2138 pip.push_back(new OpAdJointObjective(
2139 pythonPtr, common_ptr, jac_ptr, diff_jac_ptr, cof_ptr, d_grad_ptr,
2140 u_ptr, glob_objective_ptr, glob_objective_grad_ptr));
2141
2142 return fe_adjoint;
2143 };
2144
2145 auto dm = simple->getDM();
2146 auto f = createDMVector(dm);
2147 auto d = vectorDuplicate(f);
2148 auto dm_diff_vec = vectorDuplicate(d);
2149
2150 auto adjoint_fe = get_direvative_fe(dm_diff_vec);
2151 auto glob_objective_ptr = boost::make_shared<double>(0.0);
2152 auto glob_objective_grad_ptr = boost::make_shared<double>(0.0);
2153 auto objective_fe = get_objective_fe(dm_diff_vec, d, glob_objective_ptr,
2154 glob_objective_grad_ptr);
2155
2156 auto set_variance_of_geometry = [&](auto mode, auto mod_vec) {
2158 CHKERR DMoFEMMeshToLocalVector(adjointDM, mod_vec, INSERT_VALUES,
2159 SCATTER_REVERSE);
2160 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
2161 simple->getProblemName(), "U", "ADJOINT_FIELD", RowColData::ROW,
2162 dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
2163 CHKERR VecGhostUpdateBegin(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
2164 CHKERR VecGhostUpdateEnd(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
2166 };
2167
2168 auto calculate_variance_internal_forces = [&](auto mode, auto mod_vec) {
2170 CHKERR VecZeroEntries(f);
2171 CHKERR VecGhostUpdateBegin(f, INSERT_VALUES, SCATTER_FORWARD);
2172 CHKERR VecGhostUpdateEnd(f, INSERT_VALUES, SCATTER_FORWARD);
2173 adjoint_fe->f = f;
2174 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(), adjoint_fe);
2175 CHKERR VecAssemblyBegin(f);
2176 CHKERR VecAssemblyEnd(f);
2177 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
2178 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
2179 auto post_proc_rhs = get_essential_fe();
2180 post_proc_rhs->f = f;
2182 post_proc_rhs.get());
2183 CHKERR VecScale(f, -1.0);
2184
2185#ifndef NDEBUG
2186 constexpr bool debug = false;
2187 if constexpr (debug) {
2188 double norm0;
2189 CHKERR VecNorm(f, NORM_2, &norm0);
2190 auto fd_check = vectorDuplicate(f);
2191 double eps = 1e-5;
2192 CHKERR calulate_fd_residual(eps, dm_diff_vec, fd_check);
2193 double nrm;
2194 CHKERR VecAXPY(fd_check, -1.0, f);
2195 CHKERR VecNorm(fd_check, NORM_2, &nrm);
2196 MOFEM_LOG("WORLD", Sev::inform)
2197 << " FD check for internal forces [ " << mode << " ]: " << nrm
2198 << " / " << norm0 << " ( " << (nrm / norm0) << " )";
2199 }
2200#endif
2201
2203 };
2204
2205 auto calulate_variance_of_displacement = [&](auto mode, auto mod_vec) {
2207 CHKERR KSPSolve(kspElastic, f, d);
2208 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
2209 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
2211 };
2212
2213 auto calculate_variance_of_objective_function = [&](auto mode, auto mod_vec) {
2215 *glob_objective_ptr = 0.0;
2216 *glob_objective_grad_ptr = 0.0;
2217 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
2218 objective_fe);
2219 CHKERR VecSetValue(objective_function_gradient, mode,
2220 *glob_objective_grad_ptr, ADD_VALUES);
2221 std::array<double, 2> array = {*glob_objective_ptr,
2222 *glob_objective_grad_ptr};
2223 MPI_Allreduce(MPI_IN_PLACE, array.data(), 2, MPI_DOUBLE, MPI_SUM,
2224 mField.get_comm());
2225 *glob_objective_ptr = array[0];
2226 *glob_objective_grad_ptr = array[1];
2227 (*objective_function_value) += *glob_objective_ptr;
2228 MOFEM_LOG_CHANNEL("WORLD");
2229 MOFEM_LOG("WORLD", Sev::verbose) << " Objective gradient [ " << mode
2230 << " ]: " << *glob_objective_grad_ptr;
2232 };
2233
2234 CHKERR VecZeroEntries(objective_function_gradient);
2235 CHKERR VecZeroEntries(adjoint_vector);
2236 *objective_function_value = 0.0;
2237 int mode = 0;
2238 for (auto mod_vec : modeVecs) {
2239
2240 CHKERR set_variance_of_geometry(mode, mod_vec);
2241 CHKERR calculate_variance_internal_forces(mode, mod_vec);
2242 CHKERR calulate_variance_of_displacement(mode, mod_vec);
2243 CHKERR calculate_variance_of_objective_function(mode, mod_vec);
2244
2245 CHKERR VecAXPY(adjoint_vector, *glob_objective_grad_ptr, dm_diff_vec);
2246 ++mode;
2247 }
2248
2249 (*objective_function_value) /= modeVecs.size();
2250 MOFEM_LOG("WORLD", Sev::verbose)
2251 << "Objective function: " << *glob_objective_ptr;
2252
2253 CHKERR VecAssemblyBegin(objective_function_gradient);
2254 CHKERR VecAssemblyEnd(objective_function_gradient);
2255
2256 CHKERR VecAssemblyBegin(adjoint_vector);
2257 CHKERR VecAssemblyEnd(adjoint_vector);
2258 CHKERR VecGhostUpdateBegin(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2259 CHKERR VecGhostUpdateEnd(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2260
2262}
Range get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
Definition adjoint.cpp:3283
@ ROW
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:546
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
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
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1234
@ GAUSS
Gaussian quadrature integration.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
constexpr double eps
Definition HenckyOps.hpp:13
static const bool debug
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
SmartPetscObj< KSP > kspElastic
Linear solver for elastic problem.
Definition adjoint.cpp:211
std::vector< SmartPetscObj< Vec > > modeVecs
Topology mode vectors (design variables)
Definition adjoint.cpp:216
boost::shared_ptr< ObjectiveFunctionData > pythonPtr
Interface to Python objective function.
Definition adjoint.cpp:213
SmartPetscObj< DM > adjointDM
Data manager for adjoint problem.
Definition adjoint.cpp:212
Deprecated interface functions.
Class (Function) to enforce essential constrains on the right hand side diagonal.
Definition Essential.hpp:41
Basic algebra on fields.
Definition FieldBlas.hpp:21
MoFEMErrorCode fieldLambdaOnValues(OneFieldFunctionOnValues lambda, const std::string field_name, Range *ents_ptr=nullptr)
field lambda
Definition FieldBlas.cpp:21
Specialization for double precision vector field values calculation.
Vector manager is used to create vectors \mofem_vectors.
Forward declaration of operator for gradient times symmetric tensor operations.
Definition adjoint.cpp:90
Operator for computing objective function and gradients in topology optimization.
Definition adjoint.cpp:1794

◆ checkResults() [1/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [2/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [3/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [4/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [5/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [6/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [7/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [8/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [9/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [10/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [11/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ checkResults() [12/12]

MoFEMErrorCode Example::checkResults ( )
private

◆ createCommonData() [1/10]

MoFEMErrorCode Example::createCommonData ( )
private

[Set up problem]

[Set integration rule]

[Create common data]

< true if tau order is set

< true if tau order is set

Examples
mofem/tutorials/adv-0/plastic.cpp, mofem/tutorials/fun-1/integration.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-8/radiation.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 480 of file plastic.cpp.

480 {
482
483 auto get_command_line_parameters = [&]() {
485
486 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-scale", &scale, PETSC_NULL);
487 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-young_modulus",
488 &young_modulus, PETSC_NULL);
489 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-poisson_ratio",
490 &poisson_ratio, PETSC_NULL);
491 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-hardening", &H, PETSC_NULL);
492 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-hardening_viscous", &visH,
493 PETSC_NULL);
494 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-yield_stress", &sigmaY,
495 PETSC_NULL);
496 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-cn0", &cn0, PETSC_NULL);
497 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-cn1", &cn1, PETSC_NULL);
498 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-zeta", &zeta, PETSC_NULL);
499 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-Qinf", &Qinf, PETSC_NULL);
500 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-b_iso", &b_iso, PETSC_NULL);
501 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-C1_k", &C1_k, PETSC_NULL);
502 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-large_strains",
503 &is_large_strains, PETSC_NULL);
504 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-set_timer", &set_timer,
505 PETSC_NULL);
506 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-atom_test", &atom_test,
507 PETSC_NULL);
508
509 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
510 PetscBool tau_order_is_set; ///< true if tau order is set
511 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-tau_order", &tau_order,
512 &tau_order_is_set);
513 PetscBool ep_order_is_set; ///< true if tau order is set
514 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-ep_order", &ep_order,
515 &ep_order_is_set);
516 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-geom_order", &geom_order,
517 PETSC_NULL);
518
519 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-rho", &rho, PETSC_NULL);
520 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-alpha_damping",
521 &alpha_damping, PETSC_NULL);
522
523 MOFEM_LOG("PLASTICITY", Sev::inform) << "Young modulus " << young_modulus;
524 MOFEM_LOG("PLASTICITY", Sev::inform) << "Poisson ratio " << poisson_ratio;
525 MOFEM_LOG("PLASTICITY", Sev::inform) << "Yield stress " << sigmaY;
526 MOFEM_LOG("PLASTICITY", Sev::inform) << "Hardening " << H;
527 MOFEM_LOG("PLASTICITY", Sev::inform) << "Viscous hardening " << visH;
528 MOFEM_LOG("PLASTICITY", Sev::inform) << "Saturation yield stress " << Qinf;
529 MOFEM_LOG("PLASTICITY", Sev::inform) << "Saturation exponent " << b_iso;
530 MOFEM_LOG("PLASTICITY", Sev::inform) << "Kinematic hardening " << C1_k;
531 MOFEM_LOG("PLASTICITY", Sev::inform) << "cn0 " << cn0;
532 MOFEM_LOG("PLASTICITY", Sev::inform) << "cn1 " << cn1;
533 MOFEM_LOG("PLASTICITY", Sev::inform) << "zeta " << zeta;
534
535 if (tau_order_is_set == PETSC_FALSE)
536 tau_order = order - 2;
537 if (ep_order_is_set == PETSC_FALSE)
538 ep_order = order - 1;
539
540 MOFEM_LOG("PLASTICITY", Sev::inform) << "Approximation order " << order;
541 MOFEM_LOG("PLASTICITY", Sev::inform)
542 << "Ep approximation order " << ep_order;
543 MOFEM_LOG("PLASTICITY", Sev::inform)
544 << "Tau approximation order " << tau_order;
545 MOFEM_LOG("PLASTICITY", Sev::inform)
546 << "Geometry approximation order " << geom_order;
547
548 MOFEM_LOG("PLASTICITY", Sev::inform) << "Density " << rho;
549 MOFEM_LOG("PLASTICITY", Sev::inform) << "alpha_damping " << alpha_damping;
550
551 PetscBool is_scale = PETSC_TRUE;
552 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_scale", &is_scale,
553 PETSC_NULL);
554 if (is_scale) {
556 }
557
558 MOFEM_LOG("PLASTICITY", Sev::inform) << "Scale " << scale;
559
560#ifdef ADD_CONTACT
561 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-cn_contact",
562 &ContactOps::cn_contact, PETSC_NULL);
563 MOFEM_LOG("CONTACT", Sev::inform)
564 << "cn_contact " << ContactOps::cn_contact;
565#endif // ADD_CONTACT
566
567 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-quasi_static",
568 &is_quasi_static, PETSC_NULL);
569 MOFEM_LOG("PLASTICITY", Sev::inform)
570 << "Is quasi static: " << (is_quasi_static ? "true" : "false");
571
573 };
574
575 CHKERR get_command_line_parameters();
576
577#ifdef ADD_CONTACT
578 #ifdef ENABLE_PYTHON_BINDING
579 auto file_exists = [](std::string myfile) {
580 std::ifstream file(myfile.c_str());
581 if (file) {
582 return true;
583 }
584 return false;
585 };
586 char sdf_file_name[255] = "sdf.py";
587 CHKERR PetscOptionsGetString(PETSC_NULL, PETSC_NULL, "-sdf_file",
588 sdf_file_name, 255, PETSC_NULL);
589
590 if (file_exists(sdf_file_name)) {
591 MOFEM_LOG("CONTACT", Sev::inform) << sdf_file_name << " file found";
592 sdfPythonPtr = boost::make_shared<ContactOps::SDFPython>();
593 CHKERR sdfPythonPtr->sdfInit(sdf_file_name);
594 ContactOps::sdfPythonWeakPtr = sdfPythonPtr;
595 } else {
596 MOFEM_LOG("CONTACT", Sev::warning) << sdf_file_name << " file NOT found";
597 }
598 #endif
599#endif // ADD_CONTACT
600
602}
double cn_contact
Definition contact.cpp:97
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
double young_modulus
Young modulus.
Definition plastic.cpp:125
double C1_k
Kinematic hardening.
Definition plastic.cpp:133
double Qinf
Saturation yield stress.
Definition plastic.cpp:131
double rho
Definition plastic.cpp:144
int atom_test
Atom test.
Definition plastic.cpp:121
PetscBool is_quasi_static
[Operators used for contact]
Definition plastic.cpp:143
double alpha_damping
Definition plastic.cpp:145
double visH
Viscous hardening.
Definition plastic.cpp:129
double poisson_ratio
Poisson ratio.
Definition plastic.cpp:126
PetscBool set_timer
Set timer.
Definition plastic.cpp:118
double scale
Definition plastic.cpp:123
double zeta
Viscous hardening.
Definition plastic.cpp:130
double H
Hardening.
Definition plastic.cpp:128
int tau_order
Order of tau files.
Definition plastic.cpp:139
double cn0
Definition plastic.cpp:135
double b_iso
Saturation exponent.
Definition plastic.cpp:132
PetscBool is_large_strains
Large strains.
Definition plastic.cpp:117
int geom_order
Order if fixed.
Definition plastic.cpp:141
double sigmaY
Yield stress.
Definition plastic.cpp:127
int ep_order
Order of ep files.
Definition plastic.cpp:140
double cn1
Definition plastic.cpp:136

◆ createCommonData() [2/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [3/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [4/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [5/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [6/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [7/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [8/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [9/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [10/10]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonThermoPlasticOps()

template<int DIM, IntegrationType I, typename DomainEleOp >
auto Example::createCommonThermoPlasticOps ( MoFEM::Interface m_field,
std::string  plastic_block_name,
std::string  thermal_block_name,
std::string  thermoelastic_block_name,
std::string  thermoplastic_block_name,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  u,
std::string  ep,
std::string  tau,
std::string  temperature,
double  scale,
ScalerFunTwoArgs  thermal_conductivity_scaling,
ScalerFunTwoArgs  heat_capacity_scaling,
ScalerFunThreeArgs  inelastic_heat_fraction_scaling,
Sev  sev,
bool  with_rates = true 
)
inlineprivate
Examples
thermoplastic.cpp.

Definition at line 1103 of file thermoplastic.cpp.

1112 {
1113
1115
1116 auto common_plastic_ptr = boost::make_shared<PlasticOps::CommonData>();
1117 auto common_thermal_ptr =
1118 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
1119 auto common_thermoelastic_ptr =
1120 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
1121 auto common_thermoplastic_ptr =
1122 boost::make_shared<ThermoPlasticOps::ThermoPlasticBlockedParameters>();
1123
1124 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
1125 auto make_d_mat = []() {
1126 return boost::make_shared<MatrixDouble>(size_symm * size_symm, 1);
1127 };
1128
1129 common_plastic_ptr->mDPtr = boost::make_shared<MatrixDouble>();
1130 common_plastic_ptr->mGradPtr = boost::make_shared<MatrixDouble>();
1131 common_plastic_ptr->mStrainPtr = boost::make_shared<MatrixDouble>();
1132 common_plastic_ptr->mStressPtr = boost::make_shared<MatrixDouble>();
1133
1134 auto m_D_ptr = common_plastic_ptr->mDPtr;
1135
1136 CHK_THROW_MESSAGE(PlasticOps::addMatBlockOps<DIM>(
1137 m_field, plastic_block_name, pip, m_D_ptr,
1138 common_plastic_ptr->getParamsPtr(), scale, sev),
1139 "add mat block plastic ops");
1141 m_field, pip, thermal_block_name, common_thermal_ptr,
1146 "add mat block thermal ops");
1148 m_field, pip, thermoelastic_block_name,
1149 common_thermoelastic_ptr, default_coeff_expansion,
1150 default_ref_temp, sev),
1151 "add mat block thermal ops");
1153 m_field, pip, thermoplastic_block_name,
1154 common_thermoplastic_ptr, common_thermal_ptr, sev,
1156 "add mat block thermoplastic ops");
1157 auto common_hencky_ptr =
1158 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
1159 mField, pip, "U", "MAT_ELASTIC", Sev::inform, scale);
1160
1161 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1162
1163 pip.push_back(new OpCalculateScalarFieldValues(
1164 tau, common_plastic_ptr->getPlasticTauPtr()));
1166 ep, common_plastic_ptr->getPlasticStrainPtr()));
1168 u, common_plastic_ptr->mGradPtr));
1169
1170 pip.push_back(new OpCalculateScalarFieldValues(
1171 temperature, common_thermoplastic_ptr->getTempPtr()));
1173 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
1174
1175 common_plastic_ptr->mGradPtr = common_hencky_ptr->matGradPtr;
1176 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1177 common_hencky_ptr->matLogCPlastic =
1178 common_plastic_ptr->getPlasticStrainPtr();
1179 common_plastic_ptr->mStrainPtr = common_hencky_ptr->getMatLogC();
1180 common_plastic_ptr->mStressPtr = common_hencky_ptr->getMatHenckyStress();
1181
1183
1184 pip.push_back(new typename H::template OpCalculateEigenVals<DIM, I>(
1185 u, common_hencky_ptr));
1186 pip.push_back(
1187 new typename H::template OpCalculateLogC<DIM, I>(u, common_hencky_ptr));
1188 pip.push_back(new typename H::template OpCalculateLogC_dC<DIM, I>(
1189 u, common_hencky_ptr));
1190
1191 pip.push_back(
1192 new
1193 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
1194 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
1195 common_thermoelastic_ptr->getCoeffExpansionPtr(),
1196 common_thermoelastic_ptr->getRefTempPtr()));
1197 pip.push_back(new typename H::template OpCalculatePiolaStress<DIM, I, 0>(
1198 u, common_hencky_ptr));
1199
1200 pip.push_back(new typename P::template OpCalculatePlasticSurface<DIM, I>(
1201 u, common_plastic_ptr));
1202
1203 pip.push_back(new typename P::template OpCalculatePlasticHardening<DIM, I>(
1204 u, common_plastic_ptr, common_thermoplastic_ptr));
1205
1206 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
1207 common_thermal_ptr, common_thermoelastic_ptr,
1208 common_thermoplastic_ptr);
1209 }
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
MoFEMErrorCode addMatThermalBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, double default_heat_conductivity, double default_heat_capacity, double default_thermal_conductivity_scale, double default_thermal_capacity_scale, Sev sev, ScalerFunTwoArgs thermal_conductivity_scaling_func, ScalerFunTwoArgs heat_capacity_scaling_func)
MoFEMErrorCode addMatThermoElasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, double default_coeff_expansion, double default_ref_temp, Sev sev)
MoFEMErrorCode addMatThermoPlasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string thermoplastic_block_name, boost::shared_ptr< ThermoPlasticBlockedParameters > blockedParamsPtr, boost::shared_ptr< ThermoElasticOps::BlockedThermalParameters > &blockedThermalParamsPtr, Sev sev, ScalerFunThreeArgs inelastic_heat_fraction_scaling)
Specialization for double precision scalar field values calculation.
Calculate symmetric tensor field values at integration pts.
double default_heat_capacity_scale
double default_thermal_conductivity_scale
ScalerFunTwoArgs heat_capacity_scaling
ScalerFunThreeArgs inelastic_heat_fraction_scaling
ScalerFunTwoArgs thermal_conductivity_scaling
constexpr auto size_symm
Definition plastic.cpp:42
double default_ref_temp
double default_heat_capacity
double default_coeff_expansion
double default_heat_conductivity

◆ doEdgeFlips()

MoFEMErrorCode Example::doEdgeFlips ( std::multimap< double, EntityHandle > &  el_q_map,
Range flipped_els,
Tag th_spatial_coords,
std::vector< EntityHandle > &  new_connectivity 
)
private

[Edge flips]

[Do Edge Flips]

Examples
thermoplastic.cpp.

Definition at line 2441 of file thermoplastic.cpp.

2443 {
2445
2446 ReadUtilIface *read_util;
2447 CHKERR mField.get_moab().query_interface(read_util);
2448
2449 const int num_ele = el_q_map.size() * 2; // each flip creates 2 elements
2450 int num_nod_per_ele;
2451 EntityType ent_type;
2452
2453 if (SPACE_DIM == 2) {
2454 num_nod_per_ele = 3;
2455 ent_type = MBTRI;
2456 } else {
2457 num_nod_per_ele = 4;
2458 ent_type = MBTET;
2459 }
2460
2461 Range new_elements;
2462 auto new_conn = new_connectivity.begin();
2463 for (auto e = 0; e != num_ele; ++e) {
2464 EntityHandle conn[num_nod_per_ele];
2465 for (int n = 0; n < num_nod_per_ele; ++n) {
2466 conn[n] = *new_conn;
2467 ++new_conn;
2468 }
2469 EntityHandle new_ele;
2470 Range adj_ele;
2471 CHKERR mField.get_moab().get_adjacencies(conn, num_nod_per_ele, SPACE_DIM,
2472 false, adj_ele);
2473 if (adj_ele.size()) {
2474 if (adj_ele.size() != 1) {
2475 SETERRQ(PETSC_COMM_SELF, MOFEM_STD_EXCEPTION_THROW,
2476 "Element duplication");
2477 } else {
2478 new_ele = adj_ele.front();
2479 }
2480 } else {
2481 CHKERR mField.get_moab().create_element(ent_type, conn, num_nod_per_ele,
2482 new_ele);
2483 }
2484 new_elements.insert(new_ele);
2485 }
2486
2487 MOFEM_LOG("REMESHING", Sev::verbose)
2488 << "New elements from edge flipping: " << new_elements;
2489
2490 auto reset_flip_bit = [](EntityHandle ent, BitRefLevel &bit) {
2491 bit.set(STORAGE_BIT, true);
2492 bit.set(FLIPPED_BIT, false);
2493 };
2494 CHKERR mField.getInterface<BitRefManager>()->lambdaBitRefLevel(
2495 reset_flip_bit);
2496
2497 auto get_adj = [&](auto ents) {
2498 Range adj;
2499 for (auto d = 0; d != SPACE_DIM; ++d) {
2501 mField.get_moab().get_adjacencies(ents, d, true, adj,
2502 moab::Interface::UNION),
2503 "Getting adjacencies of dimension " + std::to_string(d) + " failed");
2504 }
2505 return adj;
2506 };
2507
2508 Range non_flipped_range;
2509 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByDimAndRefLevel(
2510 virgin_mesh_bit, BitRefLevel().set(), SPACE_DIM, non_flipped_range);
2511
2512 non_flipped_range = subtract(non_flipped_range, flipped_els);
2513 auto flip_bit_ents = new_elements;
2514 flip_bit_ents.merge(non_flipped_range);
2515 auto adj = get_adj(new_elements);
2516 // flip_bit_ents.merge(get_adj(new_elements));
2517
2518 CHKERR mField.getInterface<BitRefManager>()->setBitRefLevel(
2519 flip_bit_ents, flipped_bit, false);
2520
2521 CHKERR mField.getInterface<BitRefManager>()->writeBitLevelByDim(
2522 BitRefLevel().set(FLIPPED_BIT), BitRefLevel().set(), 2,
2523 "new_elements_after_edge_flips.vtk", "VTK", "");
2524
2526};
@ MOFEM_STD_EXCEPTION_THROW
Definition definitions.h:39
auto bit
set bit
const double n
refractive index of diffusive medium
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
BitRefLevel flipped_bit
@ FLIPPED_BIT
@ STORAGE_BIT
BitRefLevel virgin_mesh_bit

◆ doEdgeSplits()

MoFEMErrorCode Example::doEdgeSplits ( bool refined,
bool  add_ents 
)
private

[Do Edge Flips]

[Refine edges]

Examples
thermoplastic.cpp.

Definition at line 2530 of file thermoplastic.cpp.

2530 {
2532
2533 Tag th_spatial_coords;
2534 double def_coord[3] = {0.0, 0.0, 0.0};
2535
2536 auto refined_mesh = [&](auto level) {
2538 auto bit = BitRefLevel().set(FLIPPED_BIT + level);
2539 Range edges;
2540 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByDimAndRefLevel(
2541 bit, BitRefLevel().set(), SPACE_DIM - 1, edges);
2542 CHKERR mField.get_moab().tag_get_handle(
2543 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2544 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2545
2546 Range refine_edges;
2547 if (add_ents)
2548 for (auto e : edges) {
2549 const EntityHandle *conn;
2550 int num_nodes;
2551 CHKERR mField.get_moab().get_connectivity(e, conn, num_nodes, true);
2552 std::array<double, 6> ref_coords, spatial_coords;
2553 CHKERR mField.get_moab().get_coords(conn, num_nodes, ref_coords.data());
2554 CHKERR mField.get_moab().tag_get_data(th_spatial_coords, conn,
2555 num_nodes, spatial_coords.data());
2556 auto get_length = [](auto &a) {
2558 FTensor::Tensor1<double, 3> p0{a[0], a[1], a[2]};
2559 FTensor::Tensor1<double, 3> p1{a[3], a[4], a[5]};
2560 p1(i) = p1(i) - p0(i);
2561 return p1.l2();
2562 };
2563 auto ref_edge_length = get_length(ref_coords);
2564 auto spatial_edge_length = get_length(spatial_coords);
2565 auto change = spatial_edge_length / ref_edge_length;
2566 if (change >= 1. + edge_growth_thresh) {
2567 refine_edges.insert(e);
2568 }
2569 }
2570
2571 if (refine_edges.size())
2572 refined = true;
2573
2574 Range prev_level_ents;
2575 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
2576 bit, BitRefLevel().set(), MBEDGE, prev_level_ents);
2577
2578 Range prev_ref_ents;
2579 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
2580 BitRefLevel().set(REFINED_EDGES_BIT), BitRefLevel().set(), MBEDGE,
2581 prev_ref_ents);
2582
2583 refine_edges.merge(intersect(prev_ref_ents, prev_level_ents));
2584 CHKERR mField.getInterface<BitRefManager>()->setNthBitRefLevel(
2585 refine_edges, REFINED_EDGES_BIT, true);
2586
2587 auto refine = mField.getInterface<MeshRefinement>();
2588 auto refined_bit = BitRefLevel().set(FIRST_REF_BIT + level);
2589 CHKERR refine->addVerticesInTheMiddleOfEdges(refine_edges, refined_bit);
2590 Range tris_to_refine;
2591 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByDimAndRefLevel(
2592 bit, BitRefLevel().set(), SPACE_DIM, tris_to_refine);
2593 CHKERR refine->refineTris(tris_to_refine, refined_bit, QUIET, false);
2594
2595 auto set_spatial_coords = [&]() {
2597 Range new_vertices;
2598 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
2599 refined_bit, refined_bit, MBVERTEX, new_vertices);
2600 auto th_parent_handle =
2601 mField.getInterface<BitRefManager>()->get_th_RefParentHandle();
2602 for (auto v : new_vertices) {
2603 EntityHandle parent;
2604 CHKERR mField.get_moab().tag_get_data(th_parent_handle, &v, 1, &parent);
2605 const EntityHandle *conn;
2606 int num_nodes;
2607 CHKERR mField.get_moab().get_connectivity(parent, conn, num_nodes,
2608 true);
2609 std::array<double, 6> spatial_coords;
2610 CHKERR mField.get_moab().tag_get_data(th_spatial_coords, conn,
2611 num_nodes, spatial_coords.data());
2612 for (auto d = 0; d < 3; ++d) {
2613 spatial_coords[d] += spatial_coords[3 + d];
2614 }
2615 for (auto d = 0; d < 3; ++d) {
2616 spatial_coords[d] /= 2.0;
2617 }
2618 CHKERR mField.get_moab().tag_set_data(th_spatial_coords, &v, 1,
2619 spatial_coords.data());
2620 }
2622 };
2623
2624 CHKERR set_spatial_coords();
2625
2626 CHKERR mField.getInterface<BitRefManager>()->writeBitLevelByDim(
2627 BitRefLevel().set(FIRST_REF_BIT + level), BitRefLevel().set(), 2,
2628 ("A_refined_" + boost::lexical_cast<std::string>(level) + ".vtk")
2629 .c_str(),
2630 "VTK", "");
2631
2633 };
2634
2635 auto reset_ref_bits = [](EntityHandle ent, BitRefLevel &bit) {
2636 bit.set(STORAGE_BIT, true);
2637 for (int l = 0; l < num_refinement_levels; ++l) {
2638 bit.set(FIRST_REF_BIT + l, false);
2639 }
2640 };
2641 CHKERR mField.getInterface<BitRefManager>()->lambdaBitRefLevel(
2642 reset_ref_bits);
2643
2644 for (auto l = 0; l < num_refinement_levels; ++l) {
2645 CHKERR refined_mesh(l);
2646 };
2647
2648 CHKERR mField.getInterface<BitRefManager>()->writeBitLevelByDim(
2650 BitRefLevel().set(), 2, "new_elements_after_edge_splits.vtk", "VTK", "");
2651
2653};
#define FTENSOR_INDEX(DIM, I)
constexpr double a
@ QUIET
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'l', 3 > l
Mesh refinement interface.
MoFEMErrorCode addVerticesInTheMiddleOfEdges(const EntityHandle meshset, const BitRefLevel &bit, const bool recursive=false, int verb=QUIET, EntityHandle start_v=0)
make vertices in the middle of edges in meshset and add them to refinement levels defined by bit
@ FIRST_REF_BIT
@ REFINED_EDGES_BIT
double edge_growth_thresh
BitRefLevel refined_bit
int num_refinement_levels

◆ edgeFlips() [1/2]

MoFEMErrorCode Example::edgeFlips ( BitRefLevel  parent_bit,
BitRefLevel  child_bit 
)
private

[Output results]

[Get element quality]

[Edge flips]

Examples
mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, and thermoplastic.cpp.

Definition at line 576 of file between_meshes_dg_projection.cpp.

577 {
579
580 moab::Interface &moab = mField.get_moab();
581
582 auto make_edge_flip = [&](auto edge, auto adj_faces, Range &new_tris) {
584
585 auto get_conn = [&](EntityHandle e, EntityHandle *conn_cpy) {
587 const EntityHandle *conn;
588 int num_nodes;
589 CHKERR moab.get_connectivity(e, conn, num_nodes, true);
590 std::copy(conn, conn + num_nodes, conn_cpy);
592 };
593
594 auto get_tri_normals = [&](auto &conn) {
595 std::array<double, 18> coords;
596 CHKERR moab.get_coords(conn.data(), 6, coords.data());
597 std::array<FTensor::Tensor1<double, 3>, 2> tri_normals;
598 for (int t = 0; t != 2; ++t) {
599 CHKERR Tools::getTriNormal(&coords[9 * t], &tri_normals[t](0));
600 }
601 return tri_normals;
602 };
603
604 auto test_flip = [&](auto &&t_normals) {
605 FTENSOR_INDEX(3, i);
606 if (t_normals[0](i) * t_normals[1](i) <
607 std::numeric_limits<float>::epsilon())
608 return false;
609 return true;
610 };
611
612 std::array<EntityHandle, 6> adj_conn;
613 CHKERR get_conn(adj_faces[0], &adj_conn[0]);
614 CHKERR get_conn(adj_faces[1], &adj_conn[3]);
615 std::array<EntityHandle, 2> edge_conn;
616 CHKERR get_conn(edge, edge_conn.data());
617 std::array<EntityHandle, 2> new_edge_conn;
618
619 int j = 1;
620 for (int i = 0; i != 6; ++i) {
621 if (adj_conn[i] != edge_conn[0] && adj_conn[i] != edge_conn[1]) {
622 new_edge_conn[j] = adj_conn[i];
623 --j;
624 }
625 }
626
627 auto &new_conn = adj_conn; //< just alias this
628 for (int t = 0; t != 2; ++t) {
629 for (int i = 0; i != 3; ++i) {
630 if (
631
632 (adj_conn[3 * t + i % 3] == edge_conn[0] &&
633 adj_conn[3 * t + (i + 1) % 3] == edge_conn[1])
634
635 ||
636
637 (adj_conn[3 * t + i % 3] == edge_conn[1] &&
638 adj_conn[3 * t + (i + 1) % 3] == edge_conn[0])
639
640 ) {
641 new_conn[3 * t + (i + 1) % 3] = new_edge_conn[t];
642 break;
643 }
644 }
645 }
646
647 if (test_flip(get_tri_normals(new_conn))) {
648 for (int t = 0; t != 2; ++t) {
649 Range rtri;
650 CHKERR moab.get_adjacencies(&new_conn[3 * t], SPACE_DIM + 1, SPACE_DIM,
651 false, rtri);
652 if (!rtri.size()) {
653 EntityHandle tri;
654 CHKERR moab.create_element(MBTRI, &new_conn[3 * t], SPACE_DIM + 1,
655 tri);
656 new_tris.insert(tri);
657 } else {
658#ifndef NDEBUG
659 if (rtri.size() != 1) {
660 MOFEM_LOG("SELF", Sev::error)
661 << "Multiple tries created during edge flip for edge " << edge
662 << " adjacent faces " << std::endl
663 << rtri;
664 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
665 "Multiple tries created during edge flip");
666 }
667#endif // NDEBUG
668 new_tris.merge(rtri);
669 }
670 }
671
672 Range new_edges;
673 CHKERR moab.get_adjacencies(new_tris, SPACE_DIM - 1, true, new_edges,
674 moab::Interface::UNION);
675 } else {
676
677 MOFEM_LOG_CHANNEL("SELF");
678 MOFEM_LOG("SELF", Sev::warning)
679 << "Edge flip rejected for edge " << edge << " adjacent faces "
680 << adj_faces;
681 }
682
684 };
685
686 Range tris;
687 CHKERR moab.get_entities_by_dimension(0, SPACE_DIM, tris);
688 CHKERR mField.getInterface<BitRefManager>()->filterEntitiesByRefLevel(
689 parent_bit, BitRefLevel().set(), tris);
690 Skinner skin(&moab);
691 Range skin_edges;
692 CHKERR skin.find_skin(0, tris, false, skin_edges);
693
694 Range edges;
695 CHKERR moab.get_entities_by_dimension(0, SPACE_DIM - 1, edges);
696 edges = subtract(edges, skin_edges);
697 CHKERR mField.getInterface<BitRefManager>()->filterEntitiesByRefLevel(
698 parent_bit, BitRefLevel().set(), edges);
699
700 Range new_tris, flipped_tris, forbidden_tris;
701 int flip_count = 0;
702 for (auto edge : edges) {
703 Range adjacent_tris;
704 CHKERR moab.get_adjacencies(&edge, 1, SPACE_DIM, true, adjacent_tris);
705
706 adjacent_tris = intersect(adjacent_tris, tris);
707 adjacent_tris = subtract(adjacent_tris, forbidden_tris);
708 if (adjacent_tris.size() == 2) {
709
710#ifndef NDEBUG
711 int side_number0, sense0, offset0;
712 CHKERR mField.get_moab().side_number(adjacent_tris[0], edge, side_number0,
713 sense0, offset0);
714 int side_number1, sense1, offset1;
715 CHKERR mField.get_moab().side_number(adjacent_tris[1], edge, side_number1,
716 sense1, offset1);
717 if (sense0 * sense1 > 0)
718 SETERRQ(
719 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
720 "Cannot flip edge with same orientation in both adjacent faces");
721#endif // NDEBUG
722
723 Range new_flipped_tris;
724 CHKERR make_edge_flip(edge, adjacent_tris, new_flipped_tris);
725 if (new_flipped_tris.size()) {
726 flipped_tris.merge(adjacent_tris);
727 forbidden_tris.merge(adjacent_tris);
728 new_tris.merge(new_flipped_tris);
729
730#ifndef NDEBUG
731 CHKERR save_range(moab,
732 "flipped_tris_" + std::to_string(flip_count) + ".vtk",
733 adjacent_tris);
735 moab, "new_flipped_tris_" + std::to_string(flip_count) + ".vtk",
736 new_flipped_tris);
737
738#endif // NDEBUG
739
740 ++flip_count;
741 }
742 }
743 }
744
745 Range all_tris;
746 CHKERR moab.get_entities_by_dimension(0, SPACE_DIM, all_tris);
747 Range not_flipped_tris = subtract(all_tris, flipped_tris);
748
749 MOFEM_LOG("SELF", Sev::noisy)
750 << "Flipped " << flip_count << " edges with two adjacent faces.";
751 CHKERR mField.getInterface<BitRefManager>()->setBitRefLevel(not_flipped_tris,
752 child_bit);
753 CHKERR mField.getInterface<BitRefManager>()->setBitRefLevel(new_tris,
754 child_bit);
755 CHKERR mField.getInterface<BitRefManager>()->writeBitLevel(
756 child_bit, BitRefLevel().set(), "edge_flips_before_refinement.vtk", "VTK",
757 "");
758
760}
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
FTensor::Index< 'j', 3 > j
constexpr double t
plate stiffness
Definition plate.cpp:58
static MoFEMErrorCode getTriNormal(const double *coords, double *normal, double *d_normal=nullptr)
Get the Tri Normal objectGet triangle normal.
Definition Tools.cpp:353
auto save_range

◆ edgeFlips() [2/2]

MoFEMErrorCode Example::edgeFlips ( BitRefLevel  parent_bit,
BitRefLevel  child_bit 
)
private

◆ getCoordsInImage()

std::pair< int, int > Example::getCoordsInImage ( double  x,
double  y 
)
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 131 of file phase.cpp.

131 {
132
133 auto &m = iI[focalIndex];
134 x -= aveMaxMin[MIN_X];
135 y -= aveMaxMin[MIN_Y];
136 x *= (m.size1() - 1) / (aveMaxMin[MAX_X] - aveMaxMin[MIN_X]);
137 y *= (m.size2() - 1) / (aveMaxMin[MAX_Y] - aveMaxMin[MIN_Y]);
138 const auto p = std::make_pair<int, int>(std::round(x), std::round(y));
139
140#ifndef NDEBUG
141 if (p.first < 0 && p.first >= m.size1())
142 THROW_MESSAGE("Wrong index");
143 if (p.second < 0 && p.second >= m.size2())
144 THROW_MESSAGE("Wrong index");
145#endif
146
147 return p;
148}
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
FTensor::Index< 'm', 3 > m
static std::array< double, LAST_BB > aveMaxMin
Definition phase.cpp:110
static int focalIndex
Definition phase.cpp:112
static std::vector< MatrixInt > iI
Definition phase.cpp:109

◆ getElementQuality()

MoFEMErrorCode Example::getElementQuality ( std::multimap< double, EntityHandle > &  el_q_map,
Range flipped_els,
std::vector< EntityHandle > &  new_connectivity,
bool do_refine,
Tag th_spatial_coords 
)
private

[Get element quality]

Examples
thermoplastic.cpp.

Definition at line 1813 of file thermoplastic.cpp.

1816 {
1818
1819 Range verts;
1820 CHKERR mField.get_moab().get_entities_by_type(0, MBVERTEX, verts);
1821 std::vector<double> coords(verts.size() * 3);
1822 CHKERR mField.get_moab().get_coords(verts, coords.data());
1823 auto t_x = getFTensor1FromPtr<3>(coords.data());
1824
1825 auto save_tag = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
1827 FTENSOR_INDEX(3, i)
1828 auto field_data = ent_ptr->getEntFieldData();
1830 if (SPACE_DIM == 2) {
1831 t_u = {field_data[0], field_data[1], 0.0};
1832 } else {
1833 t_u = {field_data[0], field_data[1], field_data[2]};
1834 }
1835
1836 t_x(i) += t_u(i);
1837 ++t_x;
1839 };
1840
1841 mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(save_tag, "U",
1842 &verts);
1843 double def_coord[3] = {0.0, 0.0, 0.0};
1844 CHKERR mField.get_moab().tag_get_handle(
1845 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
1846 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
1847 CHKERR mField.get_moab().tag_set_data(th_spatial_coords, verts,
1848 coords.data());
1849
1850 // get a map which has the element quality for each tag
1851
1852 Range all_els;
1853 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, all_els,
1854 true);
1855 CHKERR mField.getInterface<BitRefManager>()->filterEntitiesByRefLevel(
1856 virgin_mesh_bit, BitRefLevel().set(), all_els);
1857
1858 std::multimap<double, EntityHandle> candidate_el_q_map;
1859 double spatial_coords[9], material_coords[9];
1860 const EntityHandle *conn;
1861 int num_nodes;
1862 Range::iterator nit = all_els.begin();
1863 for (int gg = 0; nit != all_els.end(); nit++, gg++) {
1864 CHKERR mField.get_moab().get_connectivity(*nit, conn, num_nodes, true);
1865
1866 CHKERR mField.get_moab().get_coords(conn, num_nodes, material_coords);
1867 CHKERR mField.get_moab().tag_get_data(th_spatial_coords, conn, num_nodes,
1868 spatial_coords);
1869
1870 double q = Tools::areaLengthQuality(spatial_coords);
1871 if (!std::isnormal(q))
1872 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1873 "Calculated quality of element is not "
1874 "as expected: %f",
1875 q);
1876
1877 if (q < qual_tol && q > 0.)
1878 candidate_el_q_map.insert(std::pair<double, EntityHandle>(q, *nit));
1879 }
1880
1881 double min_q = 1;
1882 CHKERR mField.getInterface<Tools>()->minElQuality<SPACE_DIM>(
1883 all_els, min_q, th_spatial_coords);
1884 MOFEM_LOG("REMESHING", Sev::inform)
1885 << "Old minimum element quality: " << min_q;
1886 // Get the first element using begin()
1887 auto pair = candidate_el_q_map.begin();
1888 MOFEM_LOG("REMESHING", Sev::inform)
1889 << "New minimum element quality: " << pair->first;
1890
1891 for (auto pair = candidate_el_q_map.begin(); pair != candidate_el_q_map.end();
1892 ++pair) {
1893 double quality = pair->first;
1894 Range element;
1895 element.insert(pair->second);
1896 if (!flipped_els.contains(element)) {
1897 // Get edges of element
1898 Range edges;
1899 CHKERR mField.get_moab().get_adjacencies(element, 1, false, edges);
1900
1901 // Get the longest edge
1902 EntityHandle longest_edge;
1903 double longest_edge_length = 0;
1904 std::vector<std::pair<double, EntityHandle>> edge_lengths;
1905 edge_lengths.reserve(edges.size());
1906 for (auto edge : edges) {
1907 edge_lengths.emplace_back(
1908 mField.getInterface<Tools>()->getEdgeLength(edge), edge);
1909 }
1910 if (!edge_lengths.empty()) {
1911 const auto it = std::max_element(
1912 edge_lengths.begin(), edge_lengths.end(),
1913 [](const auto &a, const auto &b) { return a.first < b.first; });
1914 longest_edge_length = it->first;
1915 longest_edge = it->second;
1916 } else {
1917 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1918 "Unable to calculate edge lengths to find longest edge.");
1919 }
1920
1921 MOFEM_LOG("REMESHING", Sev::verbose)
1922 << "Edge flip longest edge length: " << longest_edge_length
1923 << " for edge: " << longest_edge;
1924
1925 auto get_skin = [&]() {
1926 Range body_ents;
1927 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
1928 body_ents);
1929 Skinner skin(&mField.get_moab());
1930 Range skin_ents;
1931 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
1932 return skin_ents;
1933 };
1934
1935 auto filter_true_skin = [&](auto skin) {
1936 Range boundary_ents;
1937 ParallelComm *pcomm =
1938 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1939 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1940 PSTATUS_NOT, -1, &boundary_ents);
1941 return boundary_ents;
1942 };
1943
1944 Range boundary_ents = get_skin();
1945
1946 MOFEM_LOG("REMESHING", Sev::verbose)
1947 << "Boundary entities: " << boundary_ents;
1948
1949 // Get neighbouring element with the longest edge
1950 Range flip_candidate_els;
1951 CHKERR mField.get_moab().get_adjacencies(&longest_edge, 1, SPACE_DIM,
1952 false, flip_candidate_els);
1953 CHKERR mField.getInterface<BitRefManager>()->filterEntitiesByRefLevel(
1954 virgin_mesh_bit, BitRefLevel().set(), flip_candidate_els);
1955
1956 Range neighbouring_el = subtract(flip_candidate_els, element);
1957 CHKERR mField.getInterface<BitRefManager>()->filterEntitiesByRefLevel(
1958 virgin_mesh_bit, BitRefLevel().set(), neighbouring_el);
1959
1960 if (boundary_ents.contains(Range(longest_edge, longest_edge))) {
1961 continue;
1962 }
1963
1964 if (flipped_els.contains(neighbouring_el))
1965 continue; // Already flipped
1966
1967#ifndef NDEBUG
1968 if (neighbouring_el.size() != 1) {
1969 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1970 "Should be 1 neighbouring element to bad element for edge "
1971 "flip. Instead, there are %d",
1972 neighbouring_el.size());
1973 }
1974#endif
1975
1976 MOFEM_LOG("REMESHING", Sev::verbose)
1977 << "flip_candidate_els: " << flip_candidate_els;
1978 MOFEM_LOG("REMESHING", Sev::verbose)
1979 << "Neighbouring element: " << neighbouring_el;
1980
1981 // Check the quality of the neighbouring element
1982 std::vector<EntityHandle> neighbouring_nodes;
1983 CHKERR mField.get_moab().get_connectivity(&neighbouring_el.front(), 1,
1984 neighbouring_nodes, true);
1985
1986 std::vector<EntityHandle> element_nodes;
1987 CHKERR mField.get_moab().get_connectivity(&element.front(), 1,
1988 element_nodes, true);
1989
1990 CHKERR mField.get_moab().tag_get_data(
1991 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
1992
1993 double neighbour_qual = Tools::areaLengthQuality(spatial_coords);
1994 if (!std::isnormal(neighbour_qual))
1995 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1996 "Calculated quality of neighbouring element is not as "
1997 "expected: %f",
1998 neighbour_qual);
1999
2000 // Get the nodes of flip_candidate_els as well as the nodes of
2001 // longest_edge
2002
2003 MOFEM_LOG("REMESHING", Sev::verbose)
2004 << "Element nodes before swap: "
2005 << get_string_from_vector(element_nodes);
2006 MOFEM_LOG("REMESHING", Sev::verbose)
2007 << "Neighbouring nodes before swap: "
2008 << get_string_from_vector(neighbouring_nodes);
2009
2010 CHKERR save_range(mField.get_moab(), "bad_element.vtk", element);
2011 CHKERR save_range(mField.get_moab(), "bad_element_neighbour.vtk",
2012 neighbouring_el);
2013
2014 // Get new canonical ordering of new nodes and new neighbouring
2015 // nodes
2016 std::vector<EntityHandle> reversed_neighbouring_nodes =
2017 neighbouring_nodes;
2018 std::reverse(reversed_neighbouring_nodes.begin(),
2019 reversed_neighbouring_nodes.end());
2020
2021 int num_matches = 0;
2022 std::vector<bool> mismatch_mask(element_nodes.size());
2023 int loop_counter = 0; // To prevent infinite loop
2024 while (num_matches != 2) {
2025 // Permute first element to the end
2026 std::rotate(reversed_neighbouring_nodes.begin(),
2027 reversed_neighbouring_nodes.begin() + 1,
2028 reversed_neighbouring_nodes.end());
2029 // Create a boolean mask
2030 std::transform(element_nodes.begin(), element_nodes.end(),
2031 reversed_neighbouring_nodes.begin(),
2032 mismatch_mask.begin(), std::equal_to<EntityHandle>());
2033 // Check if common edge is found
2034 num_matches =
2035 std::count(mismatch_mask.begin(), mismatch_mask.end(), true);
2036
2037 ++loop_counter;
2038 if (loop_counter > 3) {
2039 SETERRQ(PETSC_COMM_SELF, MOFEM_STD_EXCEPTION_THROW,
2040 "Not found matching nodes for edge flipping");
2041 }
2042 }
2043
2044 // Get matching nodes
2045 std::vector<EntityHandle> matched_elements(element_nodes.size());
2046 std::transform(element_nodes.begin(), element_nodes.end(),
2047 mismatch_mask.begin(), matched_elements.begin(),
2048 [](EntityHandle el, bool match) {
2049 return match ? el : -1; // Or some other "null" value
2050 });
2051
2052 // Remove zero (or "null") elements
2053 matched_elements.erase(
2054 std::remove(matched_elements.begin(), matched_elements.end(), -1),
2055 matched_elements.end());
2056
2057 // Get mismatching nodes
2058 std::vector<EntityHandle> mismatched_elements(element_nodes.size()),
2059 neighbouring_mismatched_elements(neighbouring_nodes.size());
2060 std::transform(element_nodes.begin(), element_nodes.end(),
2061 mismatch_mask.begin(), mismatched_elements.begin(),
2062 [](EntityHandle el, bool match) {
2063 return match ? -1 : el; // Or some other "null" value
2064 });
2065 std::transform(reversed_neighbouring_nodes.begin(),
2066 reversed_neighbouring_nodes.end(), mismatch_mask.begin(),
2067 neighbouring_mismatched_elements.begin(),
2068 [](EntityHandle el, bool match) {
2069 return match ? -1 : el; // Or some other "null" value
2070 });
2071
2072 // Remove zero (or "null") elements
2073 mismatched_elements.erase(std::remove(mismatched_elements.begin(),
2074 mismatched_elements.end(), -1),
2075 mismatched_elements.end());
2076 neighbouring_mismatched_elements.erase(
2077 std::remove(neighbouring_mismatched_elements.begin(),
2078 neighbouring_mismatched_elements.end(), -1),
2079 neighbouring_mismatched_elements.end());
2080
2081 mismatched_elements.insert(mismatched_elements.end(),
2082 neighbouring_mismatched_elements.begin(),
2083 neighbouring_mismatched_elements.end());
2084
2085 MOFEM_LOG("REMESHING", Sev::verbose)
2086 << "Reversed neighbouring nodes: "
2087 << get_string_from_vector(reversed_neighbouring_nodes);
2088
2089 MOFEM_LOG("REMESHING", Sev::verbose)
2090 << "mismatch mask: " << get_string_from_vector(mismatch_mask);
2091
2092 MOFEM_LOG("REMESHING", Sev::verbose)
2093 << "Old nodes are: " << get_string_from_vector(matched_elements);
2094
2095 MOFEM_LOG("REMESHING", Sev::verbose)
2096 << "New nodes are: " << get_string_from_vector(mismatched_elements);
2097
2098 auto replace_correct_nodes = [](std::vector<EntityHandle> &ABC,
2099 std::vector<EntityHandle> &DBA,
2100 const std::vector<EntityHandle> &AB,
2101 const std::vector<EntityHandle> &CD) {
2103 std::vector<std::vector<EntityHandle>> results;
2104 // Assume AB.size() == 2, CD.size() == 2 for tris
2105 for (int i = 0; i < 2; ++i) { // i: 0 for A, 1 for B
2106 for (int j = 0; j < 2; ++j) { // j: 0 for C, 1 for D
2107 // Only try to replace if CD[j] is not already in ABC
2108 if (std::find(ABC.begin(), ABC.end(), CD[j]) == ABC.end()) {
2109 std::vector<EntityHandle> tmp = ABC;
2110 // Find AB[i] in ABC and replace with CD[j]
2111 auto it = std::find(tmp.begin(), tmp.end(), AB[i]);
2112 if (it != tmp.end()) {
2113 *it = CD[j];
2114 results.push_back(tmp);
2115 }
2116 }
2117 }
2118 }
2119
2120 if (results.size() != 2) {
2121 SETERRQ(PETSC_COMM_SELF, MOFEM_STD_EXCEPTION_THROW,
2122 "Failed to find two valid vertex replacements for edge "
2123 "flip");
2124 }
2125
2126 ABC = results[0];
2127 DBA = results[1];
2128
2130 };
2131
2132 CHKERR replace_correct_nodes(element_nodes, neighbouring_nodes,
2133 matched_elements, mismatched_elements);
2134
2135 MOFEM_LOG("REMESHING", Sev::verbose)
2136 << "Element nodes after swap: "
2137 << get_string_from_vector(element_nodes);
2138 MOFEM_LOG("REMESHING", Sev::verbose)
2139 << "Neighbouring nodes after swap: "
2140 << get_string_from_vector(neighbouring_nodes);
2141
2142 // Calculate the quality of the new elements
2143 CHKERR mField.get_moab().tag_get_data(
2144 th_spatial_coords, &element_nodes.front(), 3, spatial_coords);
2145
2146 double new_qual = Tools::areaLengthQuality(spatial_coords);
2147 if (new_qual < 0.0 || !std::isfinite(new_qual))
2148 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
2149 "Calculated quality of new element is not as expected: %f",
2150 new_qual);
2151
2152#ifndef NDEBUG
2153 auto check_normal_direction = [&](double qual_val) {
2155 FTensor::Index<'i', 3> i;
2156 auto t_correct_normal = FTensor::Tensor1<double, 3>(0.0, 0.0, 1.0);
2157 auto [new_area, t_new_normal] = Tools::triAreaAndNormal(spatial_coords);
2158 auto t_diff = FTensor::Tensor1<double, 3>();
2159 t_diff(i) = t_new_normal(i) - t_correct_normal(i);
2160 if (qual_val > 1e-6 && t_diff(i) * t_diff(i) > 1e-6) {
2161 SETERRQ(PETSC_COMM_SELF, MOFEM_STD_EXCEPTION_THROW,
2162 "Direction of element to be created is wrong orientation");
2163 }
2165 };
2166
2167 CHKERR check_normal_direction(new_qual);
2168#endif
2169
2170 CHKERR mField.get_moab().tag_get_data(
2171 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
2172
2173 double new_neighbour_qual = Tools::areaLengthQuality(spatial_coords);
2174 if (new_neighbour_qual < 0.0 || !std::isfinite(new_neighbour_qual))
2175 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
2176 "Calculated quality of new neighbouring element is not "
2177 "as expected: %f",
2178 new_neighbour_qual);
2179
2180#ifndef NDEBUG
2181 CHKERR check_normal_direction(new_neighbour_qual);
2182#endif
2183
2184 // If the minimum element quality has improved, do the flip
2185 if (std::min(new_qual, new_neighbour_qual) >
2186 (1. + qual_thresh) * std::min(quality, neighbour_qual)) {
2187 MOFEM_LOG("REMESHING", Sev::inform)
2188 << "Element quality improved from " << quality << " and "
2189 << neighbour_qual << " to " << new_qual << " and "
2190 << new_neighbour_qual << " for elements" << element << " and "
2191 << neighbouring_el;
2192
2193 // then push to creation "pipeline".
2194 flipped_els.merge(flip_candidate_els);
2195 el_q_map.insert(
2196 std::pair<double, EntityHandle>(pair->first, pair->second));
2197 new_connectivity.insert(new_connectivity.end(), element_nodes.begin(),
2198 element_nodes.end());
2199 new_connectivity.insert(new_connectivity.end(),
2200 neighbouring_nodes.begin(),
2201 neighbouring_nodes.end());
2202 }
2203 }
2204 }
2205
2206 if (el_q_map.size() > 0) {
2207 MOFEM_LOG("REMESHING", Sev::verbose) << "Flipped elements: " << flipped_els;
2208 MOFEM_LOG("REMESHING", Sev::verbose)
2209 << "New connectivity: " << get_string_from_vector(new_connectivity);
2210 }
2211
2212 Range edges;
2213 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByDimAndRefLevel(
2214 virgin_mesh_bit, BitRefLevel().set(), SPACE_DIM - 1, edges);
2215 CHKERR mField.get_moab().tag_get_handle(
2216 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2217 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2218
2219 Range prev_ref_ents;
2220 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
2221 BitRefLevel().set(REFINED_EDGES_BIT), BitRefLevel().set(), MBEDGE,
2222 prev_ref_ents);
2223
2224 for (auto e : edges) {
2225 const EntityHandle *conn;
2226 int num_nodes;
2227 CHKERR mField.get_moab().get_connectivity(e, conn, num_nodes, true);
2228 std::array<double, 6> ref_coords, spatial_coords;
2229 CHKERR mField.get_moab().get_coords(conn, num_nodes, ref_coords.data());
2230 CHKERR mField.get_moab().tag_get_data(th_spatial_coords, conn, num_nodes,
2231 spatial_coords.data());
2232 auto get_length = [](auto &a) {
2234 FTensor::Tensor1<double, 3> p0{a[0], a[1], a[2]};
2235 FTensor::Tensor1<double, 3> p1{a[3], a[4], a[5]};
2236 p1(i) = p1(i) - p0(i);
2237 return p1.l2();
2238 };
2239 auto ref_edge_length = get_length(ref_coords);
2240 auto spatial_edge_length = get_length(spatial_coords);
2241 auto change = spatial_edge_length / ref_edge_length;
2242 if ((change >= 1. + edge_growth_thresh) && (num_refinement_levels > 0) &&
2243 !prev_ref_ents.contains(Range(e, e))) {
2244 do_refine = true;
2245 }
2246 }
2247
2249};
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
#define MYPCOMM_INDEX
default communicator number PCOMM
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
Auxiliary tools.
Definition Tools.hpp:19
static double getEdgeLength(const double *edge_coords)
Get edge length.
Definition Tools.cpp:418
double qual_thresh
auto get_string_from_vector

◆ gettingNorms()

MoFEMErrorCode Example::gettingNorms ( )
private

[Solve]

[Getting norms]

Examples
nonlinear_elastic.cpp.

Definition at line 381 of file nonlinear_elastic.cpp.

381 {
383
385 auto dm = simple->getDM();
386
387 auto T = createDMVector(simple->getDM());
388 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
389 SCATTER_FORWARD);
390 double nrm2;
391 CHKERR VecNorm(T, NORM_2, &nrm2);
392 MOFEM_LOG("EXAMPLE", Sev::inform) << "Solution norm " << nrm2;
393
394 auto post_proc_norm_fe = boost::make_shared<DomainEle>(mField);
395
396 auto post_proc_norm_rule_hook = [](int, int, int p) -> int { return 2 * p; };
397 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
398
400 post_proc_norm_fe->getOpPtrVector(), {H1});
401
402 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
403 auto norms_vec =
405 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
406 CHKERR VecZeroEntries(norms_vec);
407
408 auto u_ptr = boost::make_shared<MatrixDouble>();
409 post_proc_norm_fe->getOpPtrVector().push_back(
411
412 post_proc_norm_fe->getOpPtrVector().push_back(
413 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
414
415 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
416 mField, post_proc_norm_fe->getOpPtrVector(), "U", "MAT_ELASTIC",
417 Sev::inform);
418
419 post_proc_norm_fe->getOpPtrVector().push_back(
421 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
422
423 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
424 post_proc_norm_fe);
425
426 CHKERR VecAssemblyBegin(norms_vec);
427 CHKERR VecAssemblyEnd(norms_vec);
428
429 MOFEM_LOG_CHANNEL("SELF"); // Clear channel from old tags
430 if (mField.get_comm_rank() == 0) {
431 const double *norms;
432 CHKERR VecGetArrayRead(norms_vec, &norms);
433 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
434 << "norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
435 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
436 << "norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
437 CHKERR VecRestoreArrayRead(norms_vec, &norms);
438 }
439
441}
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
virtual int get_comm_rank() const =0
Get norm of input MatrixDouble for Tensor1.
Get norm of input MatrixDouble for Tensor2.
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:800

◆ initialConditions()

MoFEMErrorCode Example::initialConditions ( )
private

[Create common data]

[Initial conditions]

Examples
thermoplastic.cpp.

Definition at line 3088 of file thermoplastic.cpp.

3088 {
3090
3091 auto vol_rule = [](int, int, int ao) { return 2 * ao + geom_order; };
3092
3093 // #ifdef PYTHON_INIT_SURFACE
3094 // auto get_py_surface_init = []() {
3095 // auto py_surf_init = boost::make_shared<SurfacePython>();
3096 // CHKERR py_surf_init->surfaceInit("surface.py");
3097 // surfacePythonWeakPtr = py_surf_init;
3098 // return py_surf_init;
3099 // };
3100 // auto py_surf_init = get_py_surface_init();
3101 // #endif
3102
3103 auto simple = mField.getInterface<Simple>();
3104
3105 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3106 // "REMOVE_X",
3107 // "U", 0, 0);
3108 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3109 // "REMOVE_Y",
3110 // "U", 1, 1);
3111 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3112 // "REMOVE_Z",
3113 // "U", 2, 2);
3114 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3115 // "REMOVE_ALL", "U", 0, 3);
3116
3117 // #ifdef ADD_CONTACT
3118 // for (auto b : {"FIX_X", "REMOVE_X"})
3119 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3120 // "SIGMA", 0, 0, false, true);
3121 // for (auto b : {"FIX_Y", "REMOVE_Y"})
3122 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3123 // "SIGMA", 1, 1, false, true);
3124 // for (auto b : {"FIX_Z", "REMOVE_Z"})
3125 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3126 // "SIGMA", 2, 2, false, true);
3127 // for (auto b : {"FIX_ALL", "REMOVE_ALL"})
3128 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3129 // "SIGMA", 0, 3, false, true);
3130 // CHKERR bc_mng->removeBlockDOFsOnEntities(
3131 // simple->getProblemName(), "NO_CONTACT", "SIGMA", 0, 3, false, true);
3132 // #endif
3133
3134 // CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
3135 // simple->getProblemName(), "U");
3136
3137 using UDO = ForcesAndSourcesCore::UserDataOperator;
3138
3139 auto T_ptr = boost::make_shared<VectorDouble>();
3140
3141 auto post_proc = [&](auto dm) {
3143
3144 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
3145
3147
3148 post_proc_fe->getOpPtrVector().push_back(
3149 new OpCalculateScalarFieldValues("T", T_ptr));
3150 // post_proc_fe->getOpPtrVector().push_back(
3151 // new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
3152 if (atom_test == 8) {
3153
3154 auto TAU_ptr = boost::make_shared<VectorDouble>();
3155 auto EP_ptr = boost::make_shared<MatrixDouble>();
3156
3157 post_proc_fe->getOpPtrVector().push_back(
3158 new OpCalculateScalarFieldValues("TAU", TAU_ptr));
3159 post_proc_fe->getOpPtrVector().push_back(
3161
3162 post_proc_fe->getOpPtrVector().push_back(
3163
3164 new OpPPMap(post_proc_fe->getPostProcMesh(),
3165 post_proc_fe->getMapGaussPts(),
3166
3167 {{"T", T_ptr}, {"TAU", TAU_ptr}},
3168
3169 {},
3170
3171 {},
3172
3173 {{"EP", EP_ptr}}
3174
3175 )
3176
3177 );
3178 } else {
3179 post_proc_fe->getOpPtrVector().push_back(
3180
3181 new OpPPMap(post_proc_fe->getPostProcMesh(),
3182 post_proc_fe->getMapGaussPts(),
3183
3184 {{"T", T_ptr}},
3185
3186 {},
3187
3188 {},
3189
3190 {}
3191
3192 )
3193
3194 );
3195 }
3196
3197 CHKERR DMoFEMLoopFiniteElements(dm, "dFE", post_proc_fe);
3198 CHKERR post_proc_fe->writeFile("out_init.h5m");
3199
3201 };
3202
3203 auto solve_init = [&]() {
3205
3206 auto set_domain_rhs = [&](auto &pip) {
3208
3210
3211 pip.push_back(new OpCalculateScalarFieldValues("T", T_ptr));
3212 pip.push_back(new OpRhsSetInitT<AT, IT>(
3213 "T", nullptr, T_ptr, nullptr, boost::make_shared<double>(init_temp),
3214 boost::make_shared<double>(peak_temp)));
3215
3216 if (atom_test == 8) {
3217 auto TAU_ptr = boost::make_shared<VectorDouble>();
3218 auto EP_ptr = boost::make_shared<MatrixDouble>();
3219
3220 pip.push_back(new OpCalculateScalarFieldValues("TAU", TAU_ptr));
3221 auto min_tau = boost::make_shared<double>(1.0);
3222 auto max_tau = boost::make_shared<double>(2.0);
3223 pip.push_back(new OpRhsSetInitT<AT, IT>("TAU", nullptr, TAU_ptr,
3224 nullptr, min_tau, max_tau));
3225
3227 "EP", EP_ptr));
3228 auto min_EP = boost::make_shared<double>(0.0);
3229 auto max_EP = boost::make_shared<double>(0.01);
3231 "EP", nullptr, EP_ptr, nullptr, min_EP, max_EP));
3232 }
3233
3234 // using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
3235 // AT>::template LinearForm<IT>;
3236 // using OpInternalForceCauchy =
3237 // typename B::template OpGradTimesSymTensor<1, SPACE_DIM, SPACE_DIM>;
3238 // using OpInternalForcePiola =
3239 // typename B::template OpGradTimesTensor<1, SPACE_DIM, SPACE_DIM>;
3240
3241 // using P = PlasticityIntegrators<DomainEleOp>;
3242
3243 // auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
3244 // common_thermoelastic_ptr, common_thermoplastic_ptr] =
3245 // createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
3246 // mField, "MAT_ELASTIC", "MAT_THERMAL", "MAT_THERMOPLASTIC", pip,
3247 // "U", "EP", "TAU", "T", scale, thermal_conductivity_scale,
3248 // heat_capacity_scale, inelastic_heat_fraction_scale,
3249 // Sev::inform);
3250 // auto m_D_ptr = common_hencky_ptr->matDPtr;
3251
3252 // using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
3253 // AT>::template LinearForm<IT>;
3254 // using H = HenckyOps::HenckyIntegrators<DomainEleOp>;
3255 // auto coeff_expansion_ptr = common_thermal_ptr->getCoeffExpansionPtr();
3256 // auto ref_temp_ptr = common_thermal_ptr->getRefTempPtr();
3257 // pip.push_back(new
3258 // typename H::template
3259 // OpCalculateHenckyThermalStress<SPACE_DIM, IT>(
3260 // "U", T_ptr, common_hencky_ptr,
3261 // coeff_expansion_ptr, ref_temp_ptr));
3262 // pip.push_back(new typename H::template
3263 // OpCalculatePiolaStress<SPACE_DIM, IT>(
3264 // "U", common_hencky_ptr));
3265 // using OpInternalForcePiola =
3266 // typename B::template OpGradTimesTensor<1, SPACE_DIM, SPACE_DIM>;
3267 // pip.push_back(new OpInternalForcePiola(
3268 // "U", common_hencky_ptr->getMatFirstPiolaStress()));
3269
3271 };
3272
3273 auto set_domain_lhs = [&](auto &pip) {
3275
3277
3278 using OpLhsScalarLeastSquaresProj = FormsIntegrators<
3279 DomainEleOp>::Assembly<AT>::BiLinearForm<IT>::OpMass<1, 1>;
3280 pip.push_back(new OpLhsScalarLeastSquaresProj("T", "T"));
3281 if (atom_test == 8) {
3282 pip.push_back(new OpLhsScalarLeastSquaresProj("TAU", "TAU"));
3283 pip.push_back(
3285 "EP", "EP"));
3286 }
3287
3288 // auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
3289 // common_thermoelastic_ptr, common_thermoplastic_ptr] =
3290 // createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
3291 // mField, "MAT_ELASTIC", "MAT_THERMAL", "MAT_THERMOPLASTIC", pip,
3292 // "U", "EP", "TAU", "T", scale, thermal_conductivity_scale,
3293 // heat_capacity_scale, inelastic_heat_fraction_scale,
3294 // Sev::inform);
3295
3296 // auto m_D_ptr = common_hencky_ptr->matDPtr;
3297
3298 // using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
3299 // AT>::template BiLinearForm<IT>;
3300 // using OpKPiola = typename B::template OpGradTensorGrad<1, SPACE_DIM,
3301 // SPACE_DIM, 1>;
3302
3303 // using H = HenckyIntegrators<DomainEleOp>;
3304 // pip.push_back(new OpCalculateScalarFieldValues("T", T_ptr));
3305 // auto coeff_expansion_ptr = common_thermal_ptr->getCoeffExpansionPtr();
3306 // auto ref_temp_ptr = common_thermal_ptr->getRefTempPtr();
3307 // pip.push_back(new
3308 // typename H::template
3309 // OpCalculateHenckyThermalStress<SPACE_DIM, IT>(
3310 // "U", T_ptr, common_hencky_ptr,
3311 // coeff_expansion_ptr, ref_temp_ptr));
3312 // pip.push_back(new typename H::template
3313 // OpCalculatePiolaStress<SPACE_DIM, IT>(
3314 // "U", common_hencky_ptr));
3315 // pip.push_back(new typename H::template OpHenckyTangent<SPACE_DIM, IT>(
3316 // "U", common_hencky_ptr));
3317 // pip.push_back(new OpKPiola("U", "U",
3318 // common_hencky_ptr->getMatTangent()));
3319 // pip.push_back(new typename HenckyOps::OpCalculateHenckyThermalStressdT<
3320 // SPACE_DIM, IT, AssemblyDomainEleOp>("U", "T",
3321 // common_hencky_ptr,
3322 // coeff_expansion_ptr));
3323
3325 };
3326
3327 auto create_sub_dm = [&](SmartPetscObj<DM> base_dm) {
3328 auto dm_sub = createDM(mField.get_comm(), "DMMOFEM");
3329 CHKERR DMMoFEMCreateSubDM(dm_sub, base_dm, "INIT_DM");
3330 CHKERR DMMoFEMSetSquareProblem(dm_sub, PETSC_TRUE);
3331 CHKERR DMMoFEMAddElement(dm_sub, simple->getDomainFEName());
3332 for (auto f : {"T"}) {
3335 }
3336 if (atom_test == 8) {
3337 for (auto f : {"TAU", "EP"}) {
3340 }
3341 }
3342 CHKERR DMSetUp(dm_sub);
3343 return dm_sub;
3344 };
3345
3346 auto fe_rhs = boost::make_shared<DomainEle>(mField);
3347 auto fe_lhs = boost::make_shared<DomainEle>(mField);
3348 fe_rhs->getRuleHook = vol_rule;
3349 fe_lhs->getRuleHook = vol_rule;
3350 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
3351 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
3352
3353 auto sub_dm = create_sub_dm(simple->getDM());
3354
3355 auto null_fe = boost::shared_ptr<FEMethod>();
3356 CHKERR DMMoFEMKSPSetComputeOperators(sub_dm, simple->getDomainFEName(),
3357 fe_lhs, null_fe, null_fe);
3358 CHKERR DMMoFEMKSPSetComputeRHS(sub_dm, simple->getDomainFEName(), fe_rhs,
3359 null_fe, null_fe);
3360
3361 auto ksp = MoFEM::createKSP(mField.get_comm());
3362 CHKERR KSPSetDM(ksp, sub_dm);
3363 CHKERR KSPSetFromOptions(ksp);
3364
3365 auto D = createDMVector(sub_dm);
3366
3367 CHKERR KSPSolve(ksp, PETSC_NULLPTR, D);
3368
3369 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
3370 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
3371 CHKERR DMoFEMMeshToGlobalVector(sub_dm, D, INSERT_VALUES, SCATTER_REVERSE);
3372
3374 };
3375
3376 CHKERR solve_init();
3377 CHKERR post_proc(simple->getDM());
3378
3379 MOFEM_LOG("THERMAL", Sev::inform) << "Set thermoelastic initial conditions";
3380
3382}
@ HDIV
field with continuous normal traction
Definition definitions.h:87
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
Definition DMMoFEM.cpp:215
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
Definition DMMoFEM.cpp:450
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
Definition DMMoFEM.cpp:238
PetscErrorCode DMMoFEMKSPSetComputeRHS(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set KSP right hand side evaluation function
Definition DMMoFEM.cpp:627
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
Definition DMMoFEM.cpp:280
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode)
set ghosted vector values on all existing mesh entities
Definition DMMoFEM.cpp:525
PetscErrorCode DMMoFEMKSPSetComputeOperators(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
Set KSP operators and push mofem finite element methods.
Definition DMMoFEM.cpp:668
double D
auto createKSP(MPI_Comm comm)
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
Definition seepage.cpp:56
Rhs for testing EP mapping with initial conditions.
Post post-proc data at points from hash maps.
intrusive_ptr for managing petsc objects
[Target temperature]
constexpr IntegrationType IT
double peak_temp
double init_temp

◆ integrateElements()

MoFEMErrorCode Example::integrateElements ( )
private

[Push operators to pipeline]

[Integrate]

Examples
mofem/tutorials/fun-1/integration.cpp.

Definition at line 218 of file integration.cpp.

218 {
220 // Zero global vector
221 CHKERR VecZeroEntries(commonDataPtr->petscVec);
222
223 // Integrate elements by executing operators in the pipeline
225 CHKERR pipeline_mng->loopFiniteElements();
226
227 // Assemble MPI vector
228 CHKERR VecAssemblyBegin(commonDataPtr->petscVec);
229 CHKERR VecAssemblyEnd(commonDataPtr->petscVec);
231}
MoFEMErrorCode loopFiniteElements(SmartPetscObj< DM > dm=nullptr)
Iterate finite elements.
boost::shared_ptr< CommonData > commonDataPtr

◆ integrationRule()

static int Example::integrationRule ( int  ,
int  ,
int  p_data 
)
inlinestaticprivate
Examples
mofem/tutorials/scl-8/radiation.cpp.

Definition at line 52 of file radiation.cpp.

52{ return 2 * p_data; };

◆ kspSolve()

MoFEMErrorCode Example::kspSolve ( )
private

[Push operators to pipeline]

[Solve]

Examples
mofem/tutorials/scl-8/radiation.cpp.

Definition at line 230 of file radiation.cpp.

230 {
234 auto ts = pipeline_mng->createTSIM();
235
236 double ftime = 1;
237 CHKERR TSSetDuration(ts, PETSC_DEFAULT, ftime);
238 CHKERR TSSetFromOptions(ts);
239 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
240
241 auto T = createDMVector(simple->getDM());
242 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
243 SCATTER_FORWARD);
244
245 CHKERR TSSolve(ts, T);
246 CHKERR TSGetTime(ts, &ftime);
247
248 PetscInt steps, snesfails, rejects, nonlinits, linits;
249 CHKERR TSGetTimeStepNumber(ts, &steps);
250 CHKERR TSGetSNESFailures(ts, &snesfails);
251 CHKERR TSGetStepRejections(ts, &rejects);
252 CHKERR TSGetSNESIterations(ts, &nonlinits);
253 CHKERR TSGetKSPIterations(ts, &linits);
254 MOFEM_LOG_C("EXAMPLE", Sev::inform,
255 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
256 "%d, linits %d",
257 steps, rejects, snesfails, ftime, nonlinits, linits);
258
260}
#define MOFEM_LOG_C(channel, severity, format,...)
SmartPetscObj< TS > createTSIM(SmartPetscObj< DM > dm=nullptr)
Create TS (time) implicit solver.

◆ lhsFlux()

double Example::lhsFlux ( const double  x,
const double  y,
const double   
)
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 165 of file phase.cpp.

165 {
166 const auto idx = getCoordsInImage(x, y);
167 const auto &m = iI[focalIndex];
168 return 1. / m(idx.first, idx.second);
169}
static std::pair< int, int > getCoordsInImage(double x, double y)
Definition phase.cpp:131

◆ mechanicalBC()

MoFEMErrorCode Example::mechanicalBC ( )
private

[Initial conditions]

[Mechanical boundary conditions]

Examples
thermoplastic.cpp.

Definition at line 3386 of file thermoplastic.cpp.

3386 {
3388
3389 auto simple = mField.getInterface<Simple>();
3390 auto bc_mng = mField.getInterface<BcManager>();
3391
3392 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
3393 "U", 0, 0, true,
3395 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
3396 "U", 1, 1, true,
3398 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
3399 "U", 2, 2, true,
3401 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3402 "REMOVE_ALL", "U", 0, 3, true,
3404
3405#ifdef ADD_CONTACT
3406 for (auto b : {"FIX_X", "REMOVE_X"})
3407 CHKERR bc_mng->removeBlockDOFsOnEntities(
3408 simple->getProblemName(), b, "SIGMA", 0, 0, false, is_distributed_mesh);
3409 for (auto b : {"FIX_Y", "REMOVE_Y"})
3410 CHKERR bc_mng->removeBlockDOFsOnEntities(
3411 simple->getProblemName(), b, "SIGMA", 1, 1, false, is_distributed_mesh);
3412 for (auto b : {"FIX_Z", "REMOVE_Z"})
3413 CHKERR bc_mng->removeBlockDOFsOnEntities(
3414 simple->getProblemName(), b, "SIGMA", 2, 2, false, is_distributed_mesh);
3415 for (auto b : {"FIX_ALL", "REMOVE_ALL"})
3416 CHKERR bc_mng->removeBlockDOFsOnEntities(
3417 simple->getProblemName(), b, "SIGMA", 0, 3, false, is_distributed_mesh);
3418 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3419 "NO_CONTACT", "SIGMA", 0, 3, false,
3421#endif
3422
3423 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
3424 simple->getProblemName(), "U");
3425
3426 auto &bc_map = bc_mng->getBcMapByBlockName();
3427 for (auto bc : bc_map)
3428 MOFEM_LOG("PLASTICITY", Sev::verbose) << "Marker " << bc.first;
3429
3431}
PetscBool is_distributed_mesh

◆ OPs() [1/4]

MoFEMErrorCode Example::OPs ( )
private

[Boundary condition]

[Thermal Boundary conditions]

[Push operators to pipeline]

[Only used for dynamics]

[Only used for dynamics]

[Only used for dynamics]

[Only used for dynamics]

Examples
mofem/tutorials/adv-0/plastic.cpp, mofem/tutorials/scl-8/radiation.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 650 of file plastic.cpp.

650 {
652 auto pip_mng = mField.getInterface<PipelineManager>();
653
654 auto integration_rule_bc = [](int, int, int ao) { return 2 * ao; };
655
656 auto vol_rule = [](int, int, int ao) { return 2 * ao + geom_order - 1; };
657
658 auto add_boundary_ops_lhs_mechanical = [&](auto &pip) {
660
662 pip, {HDIV}, "GEOMETRY");
663 pip.push_back(new OpSetHOWeightsOnSubDim<SPACE_DIM>());
664
665 // Add Natural BCs to LHS
667 pip, mField, "U", Sev::inform);
668
669#ifdef ADD_CONTACT
671 CHKERR
672 ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
673 pip, "SIGMA", "U");
674 CHKERR
675 ContactOps::opFactoryBoundaryToDomainLhs<SPACE_DIM, AT, IT, DomainEle>(
676 mField, pip, simple->getDomainFEName(), "SIGMA", "U", "GEOMETRY",
677 vol_rule);
678#endif // ADD_CONTACT
679
681 };
682
683 auto add_boundary_ops_rhs_mechanical = [&](auto &pip) {
685
687 pip, {HDIV}, "GEOMETRY");
688 pip.push_back(new OpSetHOWeightsOnSubDim<SPACE_DIM>());
689
690 // Add Natural BCs to RHS
692 pip, mField, "U", {boost::make_shared<ScaledTimeScale>()}, Sev::inform);
693
694#ifdef ADD_CONTACT
695 CHKERR ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
696 pip, "SIGMA", "U");
697#endif // ADD_CONTACT
698
700 };
701
702 auto add_domain_ops_lhs = [this](auto &pip) {
705 pip, {H1, HDIV}, "GEOMETRY");
706
707 if (is_quasi_static == PETSC_FALSE) {
708
709 //! [Only used for dynamics]
712 //! [Only used for dynamics]
713
714 auto get_inertia_and_mass_damping = [this](const double, const double,
715 const double) {
716 auto *pip = mField.getInterface<PipelineManager>();
717 auto &fe_domain_lhs = pip->getDomainLhsFE();
718 return (rho / scale) * fe_domain_lhs->ts_aa +
719 (alpha_damping / scale) * fe_domain_lhs->ts_a;
720 };
721 pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
722 }
723
724 CHKERR PlasticOps::opFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
725 mField, "MAT_PLASTIC", pip, "U", "EP", "TAU");
726
728 };
729
730 auto add_domain_ops_rhs = [this](auto &pip) {
732
734 pip, {H1, HDIV}, "GEOMETRY");
735
737 pip, mField, "U",
738 {boost::make_shared<ScaledTimeScale>("body_force_hist.txt")},
739 Sev::inform);
740
741 // only in case of dynamics
742 if (is_quasi_static == PETSC_FALSE) {
743
744 //! [Only used for dynamics]
747 //! [Only used for dynamics]
748
749 auto mat_acceleration = boost::make_shared<MatrixDouble>();
751 "U", mat_acceleration));
752 pip.push_back(
753 new OpInertiaForce("U", mat_acceleration, [](double, double, double) {
754 return rho / scale;
755 }));
756 if (alpha_damping > 0) {
757 auto mat_velocity = boost::make_shared<MatrixDouble>();
758 pip.push_back(
759 new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", mat_velocity));
760 pip.push_back(
761 new OpInertiaForce("U", mat_velocity, [](double, double, double) {
762 return alpha_damping / scale;
763 }));
764 }
765 }
766
767 CHKERR PlasticOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
768 mField, "MAT_PLASTIC", pip, "U", "EP", "TAU");
769
770#ifdef ADD_CONTACT
771 CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
772 pip, "SIGMA", "U");
773#endif // ADD_CONTACT
774
776 };
777
778 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
779 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
780
781 // Boundary
782 CHKERR add_boundary_ops_lhs_mechanical(pip_mng->getOpBoundaryLhsPipeline());
783 CHKERR add_boundary_ops_rhs_mechanical(pip_mng->getOpBoundaryRhsPipeline());
784
785 CHKERR pip_mng->setDomainRhsIntegrationRule(vol_rule);
786 CHKERR pip_mng->setDomainLhsIntegrationRule(vol_rule);
787
788 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_bc);
789 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_bc);
790
791 auto create_reaction_pipeline = [&](auto &pip) {
794 pip, {H1}, "GEOMETRY");
795 CHKERR PlasticOps::opFactoryDomainReactions<SPACE_DIM, AT, IT, DomainEleOp>(
796 mField, "MAT_PLASTIC", pip, "U", "EP", "TAU");
798 };
799
800 reactionFe = boost::make_shared<DomainEle>(mField);
801 reactionFe->getRuleHook = vol_rule;
802 CHKERR create_reaction_pipeline(reactionFe->getOpPtrVector());
803 reactionFe->postProcessHook =
805
807}
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpInertiaForce
boost::shared_ptr< DomainEle > reactionFe
Definition plastic.cpp:235
Class (Function) to calculate residual side diagonal.
Definition Essential.hpp:49
Approximate field values for given petsc vector.
constexpr AssemblyType AT

◆ OPs() [2/4]

MoFEMErrorCode Example::OPs ( )
private

◆ OPs() [3/4]

MoFEMErrorCode Example::OPs ( )
private

◆ OPs() [4/4]

MoFEMErrorCode Example::OPs ( )
private

◆ opThermoPlasticFactoryDomainLhs()

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode Example::opThermoPlasticFactoryDomainLhs ( MoFEM::Interface m_field,
std::string  block_name,
std::string  thermal_block_name,
std::string  thermoelastic_block_name,
std::string  thermoplastic_block_name,
Pip pip,
std::string  u,
std::string  ep,
std::string  tau,
std::string  temperature 
)
inlineprivate
Examples
thermoplastic.cpp.

Definition at line 980 of file thermoplastic.cpp.

984 {
986
987 using namespace HenckyOps;
989
990 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
991 A>::template BiLinearForm<I>;
992 using OpKPiola = typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
993 using OpKCauchy = typename B::template OpGradSymTensorGrad<1, DIM, DIM, 0>;
994
996
997 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
998 common_thermoelastic_ptr, common_thermoplastic_ptr] =
999 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
1000 m_field, block_name, thermal_block_name, thermoelastic_block_name,
1001 thermoplastic_block_name, pip, u, ep, tau, temperature, scale,
1003 inelastic_heat_fraction_scaling, Sev::inform);
1004
1005 auto m_D_ptr = common_hencky_ptr->matDPtr;
1006
1008 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
1009 pip.push_back(new OpCalculateScalarFieldValuesDot(
1010 tau, common_plastic_ptr->getPlasticTauDotPtr()));
1011 pip.push_back(new typename P::template OpCalculatePlasticity<DIM, I>(
1012 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1013
1014 if (common_hencky_ptr) {
1015 pip.push_back(new typename H::template OpHenckyTangent<DIM, I, 0>(
1016 u, common_hencky_ptr, m_D_ptr));
1017 pip.push_back(new OpKPiola(u, u, common_hencky_ptr->getMatTangent()));
1018 pip.push_back(
1019 new typename P::template Assembly<A>::
1020 template OpCalculatePlasticInternalForceLhs_LogStrain_dEP<DIM, I>(
1021 u, ep, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1022 } else {
1023 pip.push_back(new OpKCauchy(u, u, m_D_ptr));
1024 pip.push_back(new typename P::template Assembly<A>::
1025 template OpCalculatePlasticInternalForceLhs_dEP<DIM, I>(
1026 u, ep, common_plastic_ptr, m_D_ptr));
1027 }
1028
1029 if (common_hencky_ptr) {
1030 pip.push_back(
1031 new typename P::template Assembly<A>::
1032 template OpCalculateConstraintsLhs_LogStrain_dU<DIM, I>(
1033 tau, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1034 pip.push_back(
1035 new typename P::template Assembly<A>::
1036 template OpCalculatePlasticFlowLhs_LogStrain_dU<DIM, I>(
1037 ep, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1038 } else {
1039 pip.push_back(new typename P::template Assembly<A>::
1040 template OpCalculateConstraintsLhs_dU<DIM, I>(
1041 tau, u, common_plastic_ptr, m_D_ptr));
1042 pip.push_back(new typename P::template Assembly<A>::
1043 template OpCalculatePlasticFlowLhs_dU<DIM, I>(
1044 ep, u, common_plastic_ptr, m_D_ptr));
1045 }
1046
1047 pip.push_back(new typename P::template Assembly<A>::
1048 template OpCalculatePlasticFlowLhs_dEP<DIM, I>(
1049 ep, ep, common_plastic_ptr, m_D_ptr));
1050 pip.push_back(new typename P::template Assembly<A>::
1051 template OpCalculatePlasticFlowLhs_dTAU<DIM, I>(
1052 ep, tau, common_plastic_ptr, m_D_ptr));
1053 pip.push_back(
1055 ep, temperature, common_thermoplastic_ptr));
1056 pip.push_back(new typename P::template Assembly<A>::
1057 template OpCalculateConstraintsLhs_dEP<DIM, I>(
1058 tau, ep, common_plastic_ptr, m_D_ptr));
1059 pip.push_back(
1060 new typename P::template Assembly<
1061 A>::template OpCalculateConstraintsLhs_dTAU<I>(tau, tau,
1062 common_plastic_ptr));
1063
1064 // TODO: add scenario for when not using Hencky material
1065 pip.push_back(new typename H::template OpCalculateHenckyThermalStressdT<
1066 DIM, I, AssemblyDomainEleOp, 0>(
1067 u, temperature, common_hencky_ptr,
1068 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1069
1070 auto inelastic_heat_frac_ptr =
1071 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
1073 [inelastic_heat_frac_ptr](const double, const double, const double) {
1074 return (*inelastic_heat_frac_ptr);
1075 };
1076
1077 // TODO: add scenario for when not using Hencky material
1080 temperature, temperature, common_hencky_ptr, common_plastic_ptr,
1082 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1083
1084 // TODO: add scenario for when not using Hencky material
1087 temperature, ep, common_hencky_ptr, common_plastic_ptr,
1089
1090 // TODO: add scenario for when not using Hencky material
1093 temperature, u, common_hencky_ptr, common_plastic_ptr,
1095
1097 tau, temperature, common_thermoplastic_ptr));
1098
1100 }
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
constexpr IntegrationType I
constexpr AssemblyType A
[Define dimension]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, 1 > OpKPiola
[Only used for dynamics]
Definition seepage.cpp:63
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradSymTensorGrad< 1, SPACE_DIM, SPACE_DIM, 0 > OpKCauchy
[Only used with Hooke equation (linear material model)]
Definition seepage.cpp:49
Calculate symmetric tensor field rates ant integratio pts.
double inelastic_heat_fraction
fraction of plastic dissipation converted to heat
constexpr bool IS_LARGE_STRAINS

◆ opThermoPlasticFactoryDomainRhs()

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode Example::opThermoPlasticFactoryDomainRhs ( MoFEM::Interface m_field,
std::string  block_name,
std::string  thermal_block_name,
std::string  thermoelastic_block_name,
std::string  thermoplastic_block_name,
Pip pip,
std::string  u,
std::string  ep,
std::string  tau,
std::string  temperature 
)
inlineprivate
Examples
thermoplastic.cpp.

Definition at line 899 of file thermoplastic.cpp.

903 {
905
906 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
907 A>::template LinearForm<I>;
909 typename B::template OpGradTimesSymTensor<1, DIM, DIM>;
911 typename B::template OpGradTimesTensor<1, DIM, DIM>;
912
914
916
917 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
918 common_thermoelastic_ptr, common_thermoplastic_ptr] =
919 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
920 m_field, block_name, thermal_block_name, thermoelastic_block_name,
921 thermoplastic_block_name, pip, u, ep, tau, temperature, scale,
924
925 auto m_D_ptr = common_hencky_ptr->matDPtr;
926
928 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
929 pip.push_back(new OpCalculateScalarFieldValuesDot(
930 tau, common_plastic_ptr->getPlasticTauDotPtr()));
931 pip.push_back(new OpCalculateScalarFieldValues(
932 temperature, common_thermoplastic_ptr->getTempPtr()));
934 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
935 pip.push_back(new typename P::template OpCalculatePlasticity<DIM, I>(
936 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
937
938 pip.push_back(
939 new
940 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
941 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
942 common_thermoelastic_ptr->getCoeffExpansionPtr(),
943 common_thermoelastic_ptr->getRefTempPtr()));
944
945 // Calculate internal forces
946 if (common_hencky_ptr) {
947 pip.push_back(new OpInternalForcePiola(
948 u, common_hencky_ptr->getMatFirstPiolaStress()));
949 } else {
950 pip.push_back(
951 new OpInternalForceCauchy(u, common_plastic_ptr->mStressPtr));
952 }
953
954 auto inelastic_heat_frac_ptr =
955 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
957 [inelastic_heat_frac_ptr](const double, const double, const double) {
958 return (*inelastic_heat_frac_ptr);
959 };
960
961 // TODO: add scenario for when not using Hencky material
964 temperature, common_hencky_ptr->getMatHenckyStress(),
965 common_plastic_ptr->getPlasticStrainDotPtr(), inelastic_heat_fraction));
966
967 pip.push_back(
968 new
969 typename P::template Assembly<A>::template OpCalculateConstraintsRhs<I>(
970 tau, common_plastic_ptr, m_D_ptr));
971 pip.push_back(
972 new
973 typename P::template Assembly<A>::template OpCalculatePlasticFlowRhs<
974 DIM, I>(ep, common_plastic_ptr, m_D_ptr));
975
977 }
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForcePiola
Definition seepage.cpp:65
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesSymTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForceCauchy
Definition seepage.cpp:51

◆ outputResults() [1/12]

MoFEMErrorCode Example::outputResults ( )
private

[Solve]

[Getting norms]

[Postprocess results]

[Postprocessing results]

[Postprocess clean]

[Postprocess clean]

[Postprocess initialise]

[Postprocess initialise]

Examples
mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/mix-1/phase.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, and nonlinear_elastic.cpp.

Definition at line 1160 of file dynamic_first_order_con_law.cpp.

1160 {
1162 PetscBool test_flg = PETSC_FALSE;
1163 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test", &test_flg, PETSC_NULLPTR);
1164 if (test_flg) {
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::inform) << "Regression norm " << nrm2;
1172 constexpr double regression_value = 0.0194561;
1173 if (fabs(nrm2 - regression_value) > 1e-2)
1174 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1175 "Regression test failed; wrong norm value.");
1176 }
1178}

◆ outputResults() [2/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [3/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [4/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [5/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [6/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [7/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [8/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [9/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [10/12]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [11/12]

MoFEMErrorCode Example::outputResults ( const int  i)
private

[Solve]

[Postprocess results]

Definition at line 504 of file phase.cpp.

504 {
507 pipeline_mng->getDomainLhsFE().reset();
508 pipeline_mng->getDomainRhsFE().reset();
509 pipeline_mng->getBoundaryRhsFE().reset();
510
512
513 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
514 auto jac_ptr = boost::make_shared<MatrixDouble>();
515 post_proc_fe->getOpPtrVector().push_back(
516 new OpCalculateHOJacForFace(jac_ptr));
517 post_proc_fe->getOpPtrVector().push_back(new OpMakeHdivFromHcurl());
518 post_proc_fe->getOpPtrVector().push_back(
520
521 auto s_ptr = boost::make_shared<VectorDouble>();
522 auto phi_ptr = boost::make_shared<MatrixDouble>();
523 post_proc_fe->getOpPtrVector().push_back(
524 new OpCalculateScalarFieldValues("S", s_ptr));
525 post_proc_fe->getOpPtrVector().push_back(
526 new OpCalculateHVecVectorField<3>("PHI", phi_ptr));
527
529
530 post_proc_fe->getOpPtrVector().push_back(
531
532 new OpPPMap(post_proc_fe->getPostProcMesh(),
533 post_proc_fe->getMapGaussPts(),
534
535 OpPPMap::DataMapVec{{"S", s_ptr}},
536
537 OpPPMap::DataMapMat{{"PHI", phi_ptr}},
538
540
542
543 )
544
545 );
546
547 // post_proc_fe->addFieldValuesPostProc("S");
548 // post_proc_fe->addFieldValuesPostProc("PHI");
549
550
551 pipeline_mng->getDomainRhsFE() = post_proc_fe;
552 CHKERR pipeline_mng->loopFiniteElements();
553 CHKERR post_proc_fe->writeFile("out_" + boost::lexical_cast<std::string>(i) +
554 ".h5m");
556}
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
std::map< std::string, boost::shared_ptr< VectorDouble > > DataMapVec
boost::shared_ptr< FEMethod > & getDomainRhsFE()
Get domain right-hand side finite element.
boost::shared_ptr< FEMethod > & getBoundaryRhsFE()
Get boundary right-hand side finite element.

◆ outputResults() [12/12]

MoFEMErrorCode Example::outputResults ( std::string  file_name)
private

[Project results]

[Output results]

Definition at line 518 of file between_meshes_dg_projection.cpp.

518 {
520
521 auto pipeline_mng = mField.getInterface<PipelineManager>();
522 pipeline_mng->getDomainLhsFE().reset();
523
524 auto post_proc_fe = boost::make_shared<PostProcFaceEle>(mField);
526 post_proc_fe->getOpPtrVector(), {H1});
527
528 auto u_ptr = boost::make_shared<VectorDouble>();
529 post_proc_fe->getOpPtrVector().push_back(
531 auto s_ptr = boost::make_shared<VectorDouble>();
532 post_proc_fe->getOpPtrVector().push_back(
534
535 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
536 post_proc_fe->getOpPtrVector().push_back(
538 auto grad_s_ptr = boost::make_shared<MatrixDouble>();
539 post_proc_fe->getOpPtrVector().push_back(
541
542
544
545 post_proc_fe->getOpPtrVector().push_back(
546
547 new OpPPMap(
548 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
549
550 OpPPMap::DataMapVec{{FIELD_NAME_U, u_ptr}, {FIELD_NAME_S, s_ptr}},
551
553
554 {"GRAD_" + std::string(FIELD_NAME_U), grad_u_ptr},
555 {"GRAD_" + std::string(FIELD_NAME_S), grad_s_ptr}
556
557 },
558
560
562
563 )
564
565 );
566
567 pipeline_mng->getDomainRhsFE() = post_proc_fe;
568 CHKERR pipeline_mng->loopFiniteElements();
569 CHKERR post_proc_fe->writeFile(file_name);
570
572}
constexpr char FIELD_NAME_U[]
constexpr char FIELD_NAME_S[]
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.

◆ PetscErrorCode::MyTSResizeTransfer()

Example::PetscErrorCode::MyTSResizeTransfer ( TS  ,
PetscInt  ,
Vec  [],
Vec  [],
void *   
)
private

◆ postProcess() [1/2]

MoFEMErrorCode Example::postProcess ( )
private

[Integrate]

[Solve]

[Print results]

[Postprocess results]

Examples
mofem/tutorials/fun-1/integration.cpp, and mofem/tutorials/scl-8/radiation.cpp.

Definition at line 235 of file integration.cpp.

235 {
237 const double *array;
238 CHKERR VecGetArrayRead(commonDataPtr->petscVec, &array);
239 if (mField.get_comm_rank() == 0) {
240 MOFEM_LOG_C("SELF", Sev::inform, "Mass %6.4e", array[CommonData::ZERO]);
241 MOFEM_LOG_C("SELF", Sev::inform,
242 "First moment of inertia [ %6.4e, %6.4e, %6.4e ]",
244 array[CommonData::FIRST_Z]);
245 MOFEM_LOG_C("SELF", Sev::inform,
246 "Second moment of inertia [ %6.4e, %6.4e, %6.4e; %6.4e %6.4e; "
247 "%6.4e ]",
251 }
252 CHKERR VecRestoreArrayRead(commonDataPtr->petscVec, &array);
254}

◆ postProcess() [2/2]

MoFEMErrorCode Example::postProcess ( )
private

◆ postprocessElastic()

MoFEMErrorCode Example::postprocessElastic ( int  iter,
SmartPetscObj< Vec >  adjoint_vector = nullptr 
)
private

Post-process and output results.

[Solve]

[Postprocess results]

[Postprocess clean]

[Postprocess clean]

[Postprocess initialise]

[Postprocess initialise]

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 1347 of file adjoint.cpp.

1348 {
1350 auto simple = mField.getInterface<Simple>();
1351 auto pip = mField.getInterface<PipelineManager>();
1352 auto det_ptr = boost::make_shared<VectorDouble>();
1353 auto jac_ptr = boost::make_shared<MatrixDouble>();
1354 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1355 //! [Postprocess clean]
1356 pip->getDomainRhsFE().reset();
1357 pip->getDomainLhsFE().reset();
1358 pip->getBoundaryRhsFE().reset();
1359 pip->getBoundaryLhsFE().reset();
1360 //! [Postprocess clean]
1361
1362 //! [Postprocess initialise]
1363 auto post_proc_mesh = boost::make_shared<moab::Core>();
1364 auto post_proc_begin = boost::make_shared<PostProcBrokenMeshInMoabBaseBegin>(
1365 mField, post_proc_mesh);
1366 auto post_proc_end = boost::make_shared<PostProcBrokenMeshInMoabBaseEnd>(
1367 mField, post_proc_mesh);
1368 //! [Postprocess initialise]
1369
1370 // lambada function to calculate displacement, strain and stress
1371 auto calculate_stress_ops = [&](auto &pip) {
1372 // Add H1 geometry ops
1374
1375 // Use HookeOps commonDataFactory to get matStrainPtr and matCauchyStressPtr
1376 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEle>(
1377 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1378
1379 // Store U and GEOMETRY values if needed
1380 auto u_ptr = boost::make_shared<MatrixDouble>();
1381 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1382 auto x_ptr = boost::make_shared<MatrixDouble>();
1383 pip.push_back(
1384 new OpCalculateVectorFieldValues<SPACE_DIM>("GEOMETRY", x_ptr));
1385
1386 using DataMapMat = std::map<std::string, boost::shared_ptr<MatrixDouble>>;
1387
1388 DataMapMat vec_map = {{"U", u_ptr}, {"GEOMETRY", x_ptr}};
1389 DataMapMat sym_map = {{"STRAIN", common_ptr->getMatStrain()},
1390 {"STRESS", common_ptr->getMatCauchyStress()}};
1391
1392 if (adjoint_vector) {
1393 auto adjoint_ptr = boost::make_shared<MatrixDouble>();
1395 "U", adjoint_ptr, adjoint_vector));
1396 vec_map["ADJOINT"] = adjoint_ptr;
1397 }
1398
1399 // Return what you need: displacements, coordinates, strain, stress
1400 return boost::make_tuple(u_ptr, x_ptr, common_ptr->getMatStrain(),
1401 common_ptr->getMatCauchyStress(), vec_map,
1402 sym_map);
1403 };
1404
1405 auto get_tag_id_on_pmesh = [&](bool post_proc_skin) {
1406 int def_val_int = 0;
1407 Tag tag_mat;
1408 CHKERR mField.get_moab().tag_get_handle(
1409 "MAT_ELASTIC", 1, MB_TYPE_INTEGER, tag_mat,
1410 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val_int);
1411 auto meshset_vec_ptr =
1412 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
1413 std::regex((boost::format("%s(.*)") % "MAT_ELASTIC").str()));
1414
1415 Range skin_ents;
1416 std::unique_ptr<Skinner> skin_ptr;
1417 if (post_proc_skin) {
1418 skin_ptr = std::make_unique<Skinner>(&mField.get_moab());
1419 auto boundary_meshset = simple->getBoundaryMeshSet();
1420 CHKERR mField.get_moab().get_entities_by_handle(boundary_meshset,
1421 skin_ents, true);
1422 }
1423
1424 for (auto m : meshset_vec_ptr) {
1425 Range ents_3d;
1426 CHKERR mField.get_moab().get_entities_by_handle(m->getMeshset(), ents_3d,
1427 true);
1428 int const id = m->getMeshsetId();
1429 ents_3d = ents_3d.subset_by_dimension(SPACE_DIM);
1430 if (post_proc_skin) {
1431 Range skin_faces;
1432 CHKERR skin_ptr->find_skin(0, ents_3d, false, skin_faces);
1433 ents_3d = intersect(skin_ents, skin_faces);
1434 }
1435 CHKERR mField.get_moab().tag_clear_data(tag_mat, ents_3d, &id);
1436 }
1437
1438 return tag_mat;
1439 };
1440
1441 auto post_proc_domain = [&](auto post_proc_mesh) {
1442 auto post_proc_fe =
1443 boost::make_shared<PostProcEleDomain>(mField, post_proc_mesh);
1445
1446 auto [u_ptr, x_ptr, mat_strain_ptr, mat_stress_ptr, vec_map, sym_map] =
1447 calculate_stress_ops(post_proc_fe->getOpPtrVector());
1448
1449 post_proc_fe->getOpPtrVector().push_back(
1450
1451 new OpPPMap(
1452
1453 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
1454
1455 {},
1456
1457 vec_map,
1458
1459 {},
1460
1461 sym_map
1462
1463 )
1464
1465 );
1466
1467 post_proc_fe->setTagsToTransfer({get_tag_id_on_pmesh(false)});
1468 return post_proc_fe;
1469 };
1470
1471 auto post_proc_boundary = [&](auto post_proc_mesh) {
1472 auto post_proc_fe =
1473 boost::make_shared<PostProcEleBdy>(mField, post_proc_mesh);
1475 post_proc_fe->getOpPtrVector(), {}, "GEOMETRY");
1476 auto op_loop_side =
1477 new OpLoopSide<SideEle>(mField, simple->getDomainFEName(), SPACE_DIM);
1478 // push ops to side element, through op_loop_side operator
1479 auto [u_ptr, x_ptr, mat_strain_ptr, mat_stress_ptr, vec_map, sym_map] =
1480 calculate_stress_ops(op_loop_side->getOpPtrVector());
1481 post_proc_fe->getOpPtrVector().push_back(op_loop_side);
1482 auto mat_traction_ptr = boost::make_shared<MatrixDouble>();
1483 post_proc_fe->getOpPtrVector().push_back(
1484 new ElasticOps::OpCalculateTraction(mat_stress_ptr, mat_traction_ptr));
1485 vec_map["T"] = mat_traction_ptr;
1486
1488
1489 post_proc_fe->getOpPtrVector().push_back(
1490
1491 new OpPPMap(
1492
1493 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
1494
1495 {},
1496
1497 vec_map,
1498
1499 {},
1500
1501 sym_map
1502
1503 )
1504
1505 );
1506
1507 post_proc_fe->setTagsToTransfer({get_tag_id_on_pmesh(true)});
1508 return post_proc_fe;
1509 };
1510
1511 PetscBool post_proc_skin_only = PETSC_FALSE;
1512 if (SPACE_DIM == 3) {
1513 post_proc_skin_only = PETSC_TRUE;
1514 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-post_proc_skin_only",
1515 &post_proc_skin_only, PETSC_NULLPTR);
1516 }
1517 if (post_proc_skin_only == PETSC_FALSE) {
1518 pip->getDomainRhsFE() = post_proc_domain(post_proc_mesh);
1519 } else {
1520 pip->getBoundaryRhsFE() = post_proc_boundary(post_proc_mesh);
1521 }
1522
1524 post_proc_begin->getFEMethod());
1525 CHKERR pip->loopFiniteElements();
1527 post_proc_end->getFEMethod());
1528
1529 CHKERR post_proc_end->writeFile("out_elastic_" + std::to_string(iter) +
1530 ".h5m");
1532}
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:536
Interface for managing meshsets containing materials and boundary conditions.
Element used to execute operators on side of the element.

◆ projectResults()

MoFEMErrorCode Example::projectResults ( BitRefLevel  parent_bit,
BitRefLevel  child_bit,
BitRefLevel  refine_bit 
)
private

[Solve]

[Project results]

Examples
mofem/tutorials/adv-6/between_meshes_dg_projection.cpp.

Definition at line 255 of file between_meshes_dg_projection.cpp.

257 {
260 auto pipeline_mng = mField.getInterface<PipelineManager>();
261
262 pipeline_mng->getDomainLhsFE().reset();
263 pipeline_mng->getDomainRhsFE().reset();
264 pipeline_mng->getOpDomainRhsPipeline().clear();
265
266 auto rule = [](int, int, int p) -> int { return 2 * p; };
267 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule);
268
269 // OpLoopThis, is child operator, and is use to execute
270 // fe_child_ptr, only on bit ref level and mask
271 // for child elements
272 auto get_child_op = [&](auto &pip) {
273 auto op_this_child =
274 new OpLoopThis<DomainEle>(mField, simple->getDomainFEName(), refine_bit,
275 child_bit | refine_bit, Sev::noisy);
276 auto fe_child_ptr = op_this_child->getThisFEPtr();
277 fe_child_ptr->getRuleHook = [] (int, int, int p) { return -1; };
278 Range child_edges;
279 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
280 refine_bit, child_bit | refine_bit, MBEDGE, child_edges);
281 // set integration rule, such that integration points are not on flipped edge
282 CHKERR setDGSetIntegrationPoints<SPACE_DIM>(
283 fe_child_ptr->setRuleHook, [](int, int, int p) { return 2 * p; },
284 boost::make_shared<Range>(child_edges));
285 pip.push_back(op_this_child);
286 return fe_child_ptr;
287 };
288
289 // Use field evaluator to calculate field values on parent bitref level,
290 // i.e. elements which were flipped.
291 auto get_field_eval_op = [&](auto fe_child_ptr) {
292 auto field_eval_ptr = mField.getInterface<FieldEvaluatorInterface>();
293
294 // Get pointer of FieldEvaluator data. Note finite element and method
295 // set integration points is destroyed when this pointer is releases
296 auto field_eval_data = field_eval_ptr->getData<DomainEle>();
297 // Build tree for particular element
298 CHKERR field_eval_ptr->buildTree<SPACE_DIM>(
299 field_eval_data, simpleInterface->getDomainFEName(), parent_bit,
300 parent_bit | child_bit);
301
302 // You can add more fields here
303 auto data_U_ptr = boost::make_shared<MatrixDouble>();
304 auto eval_data_U_ptr = boost::make_shared<MatrixDouble>();
305 auto data_S_ptr = boost::make_shared<MatrixDouble>();
306 auto eval_data_S_ptr = boost::make_shared<MatrixDouble>();
307
308
309 if (auto fe_eval_ptr = field_eval_data->feMethodPtr.lock()) {
310 fe_eval_ptr->getRuleHook = [] (int, int, int p) { return -1; };
311 fe_eval_ptr->getOpPtrVector().push_back(
313 eval_data_U_ptr));
314 fe_eval_ptr->getOpPtrVector().push_back(
316 eval_data_S_ptr));
317
318 auto op_test = new DomainEleOp(NOSPACE, DomainEleOp::OPSPACE);
319 op_test->doWorkRhsHook =
320 [](DataOperator *base_op_ptr, int side, EntityType type,
323
324 auto op_ptr = static_cast<DomainEleOp *>(base_op_ptr);
325 MOFEM_LOG_CHANNEL("SELF");
326 MOFEM_LOG("SELF", Sev::noisy)
327 << "Field evaluator method pointer is valid";
328 MOFEM_LOG("SELF", Sev::noisy)
329 << op_ptr->getGaussPts();
330 MOFEM_LOG("SELF", Sev::noisy)
331 << "Loop size " << op_ptr->getPtrFE()->getLoopSize();
332 MOFEM_LOG("SELF", Sev::noisy)
333 << "Coords at gauss pts: " << op_ptr->getCoordsAtGaussPts();
334
336 };
337
338 fe_eval_ptr->getOpPtrVector().push_back(op_test);
339
340 } else {
342 "Field evaluator method pointer is expired");
343 }
344
345 auto op_ptr = field_eval_ptr->getDataOperator<SPACE_DIM>(
346 {{eval_data_U_ptr, data_U_ptr}, {eval_data_S_ptr, data_S_ptr}},
347 simpleInterface->getDomainFEName(), field_eval_data, 0,
348 mField.get_comm_size(), parent_bit, parent_bit | child_bit, MF_EXIST,
349 QUIET);
350
351 fe_child_ptr->getOpPtrVector().push_back(op_ptr);
352 return std::make_pair(
353
354 std::vector<std::pair<std::string, boost::shared_ptr<MatrixDouble>>>{
355 {FIELD_NAME_U, data_U_ptr}},
356
357 std::vector<std::pair<std::string, boost::shared_ptr<MatrixDouble>>>{
358 {FIELD_NAME_S, data_S_ptr}}
359
360 );
361
362 };
363
364 // calculate coefficients on child (flipped) elements
365 auto dg_projection_base = [&](auto fe_child_ptr, auto vec_data_ptr, auto mat,
366 auto vec) {
368 constexpr int projection_order = order;
369 auto entity_data_l2 = boost::make_shared<EntitiesFieldData>(MBENTITYSET);
370 auto mass_ptr = boost::make_shared<MatrixDouble>();
371 auto coeffs_ptr = boost::make_shared<MatrixDouble>();
372
373 // project L2 (directly from coefficients)
374 for (auto &p : vec_data_ptr.first) {
375 auto field_name = p.first;
376 auto data_ptr = p.second;
377
378 fe_child_ptr->getOpPtrVector().push_back(new OpDGProjectionMassMatrix(
379 projection_order, mass_ptr, entity_data_l2, AINSWORTH_LEGENDRE_BASE,
380 L2));
381 fe_child_ptr->getOpPtrVector().push_back(new OpDGProjectionCoefficients(
382 data_ptr, coeffs_ptr, mass_ptr, entity_data_l2,
384
385 // next two lines are only for testing if projection is correct, they are not
386 // essential
387 fe_child_ptr->getOpPtrVector().push_back(new OpDGProjectionEvaluation(
388 data_ptr, coeffs_ptr, entity_data_l2, AINSWORTH_LEGENDRE_BASE, L2));
389 fe_child_ptr->getOpPtrVector().push_back(new OpError(data_ptr));
390
391 // set coefficients to flipped element
392 auto op_set_coeffs = new DomainEleOp(field_name, DomainEleOp::OPROW);
393 op_set_coeffs->doWorkRhsHook =
394 [coeffs_ptr](DataOperator *base_op_ptr, int side, EntityType type,
397 auto field_ents = data.getFieldEntities();
398 auto nb_dofs = data.getIndices().size();
399 if (!field_ents.size())
401 if (auto e_ptr = field_ents[0]) {
402 auto field_ent_data = e_ptr->getEntFieldData();
403 std::copy(coeffs_ptr->data().data(),
404 coeffs_ptr->data().data() + nb_dofs,
405 field_ent_data.begin());
406 }
408 };
409 fe_child_ptr->getOpPtrVector().push_back(op_set_coeffs);
410 }
411
412 // project H1 (via coefficients)
413 for (auto &p : vec_data_ptr.second) {
414 auto field_name = p.first;
415 auto data_ptr = p.second;
416
417 fe_child_ptr->getOpPtrVector().push_back(new OpDGProjectionMassMatrix(
418 projection_order, mass_ptr, entity_data_l2, AINSWORTH_LEGENDRE_BASE,
419 L2));
420 fe_child_ptr->getOpPtrVector().push_back(new OpDGProjectionCoefficients(
421 data_ptr, coeffs_ptr, mass_ptr, entity_data_l2,
423
424 // next two lines are only for testing if projection is correct, they are not
425 // essential
426 fe_child_ptr->getOpPtrVector().push_back(new OpDGProjectionEvaluation(
427 data_ptr, coeffs_ptr, entity_data_l2, AINSWORTH_LEGENDRE_BASE, L2));
428 fe_child_ptr->getOpPtrVector().push_back(new OpError(data_ptr));
429
430 // assemble to global matrix, since this is H1 (you will do the shame for Hcurl of Hdiv)
431 auto beta = [](const double, const double, const double) { return 1; };
432 fe_child_ptr->getOpPtrVector().push_back(
435 GAUSS>::OpBaseTimesVector<1, FIELD_DIM, 1>;
436 fe_child_ptr->getOpPtrVector().push_back(
437 new OpVec(FIELD_NAME_S, data_ptr, beta));
438 }
439
441 };
442
443 auto dm = simple->getDM();
444 auto sub_dm = createDM(mField.get_comm(), "DMMOFEM");
445 CHKERR DMMoFEMCreateSubDM(sub_dm, dm, "SUB");
446 CHKERR DMMoFEMSetSquareProblem(sub_dm, PETSC_TRUE);
447 CHKERR DMMoFEMAddElement(sub_dm, simple->getDomainFEName());
448
449 // get only refinement bit DOFs
450 auto ref_entities_ptr = boost::make_shared<Range>();
451 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByRefLevel(
452 refine_bit, child_bit | refine_bit, *ref_entities_ptr);
453 Range verts;
454 CHKERR mField.get_moab().get_connectivity(*ref_entities_ptr, verts, true);
455 ref_entities_ptr->merge(verts);
456
457 CHKERR DMMoFEMAddSubFieldRow(sub_dm, FIELD_NAME_S, ref_entities_ptr);
458 CHKERR DMMoFEMAddSubFieldCol(sub_dm, FIELD_NAME_S, ref_entities_ptr);
459 CHKERR DMSetUp(sub_dm);
460
461 auto mat = createDMMatrix(sub_dm);
462 auto vec = createDMVector(sub_dm);
463
464 // create child operator, and fe_child_ptr element in it
465 auto fe_child_ptr = get_child_op(pipeline_mng->getOpDomainRhsPipeline());
466 // run dg projection, note that get_field_eval_op,
467 // pass data_ptr values used to project and calculate coefficients
468 CHKERR dg_projection_base(fe_child_ptr, get_field_eval_op(fe_child_ptr), mat,
469 vec);
470
471 // That is to test, if projection works, and coefficients are set in correctly
472 // Note: FIELD_S is not tested, it is in H1, so we have to solve KSP problem first
473 auto test_U_data_ptr = boost::make_shared<MatrixDouble>();
474 pipeline_mng->getOpDomainRhsPipeline().push_back(
476 test_U_data_ptr));
477 pipeline_mng->getOpDomainRhsPipeline().push_back(
478 new OpError(test_U_data_ptr, refine_bit, BitRefLevel().set()));
479
480 auto fe_rhs = pipeline_mng->getCastDomainRhsFE<DomainEle>();
481 fe_rhs->ksp_A = mat;
482 fe_rhs->ksp_B = mat;
483 fe_rhs->ksp_f = vec;
484 fe_rhs->data_ctx =
486 CHKERR pipeline_mng->loopFiniteElements(sub_dm);
487
488 CHKERR VecAssemblyBegin(vec);
489 CHKERR VecAssemblyEnd(vec);
490 CHKERR VecGhostUpdateBegin(vec, ADD_VALUES, SCATTER_REVERSE);
491 CHKERR VecGhostUpdateEnd(vec, ADD_VALUES, SCATTER_REVERSE);
492 CHKERR MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);
493 CHKERR MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);
494
495 auto ksp = createKSP(mField.get_comm());
496 CHKERR KSPSetOperators(ksp, mat, mat);
497 CHKERR KSPSetFromOptions(ksp);
498
499 auto sol = createDMVector(sub_dm);
500 CHKERR KSPSolve(ksp, vec, sol);
501 CHKERR VecGhostUpdateBegin(sol, INSERT_VALUES, SCATTER_FORWARD);
502 CHKERR VecGhostUpdateEnd(sol, INSERT_VALUES, SCATTER_FORWARD);
503 CHKERR DMoFEMMeshToLocalVector(sub_dm, sol, INSERT_VALUES, SCATTER_REVERSE);
504
505 pipeline_mng->getOpDomainRhsPipeline().clear();
506 auto test_S_data_ptr = boost::make_shared<MatrixDouble>();
507 pipeline_mng->getOpDomainRhsPipeline().push_back(
509 test_S_data_ptr));
510 pipeline_mng->getOpDomainRhsPipeline().push_back(
511 new OpError(test_S_data_ptr, refine_bit, BitRefLevel().set()));
512
514}
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, FIELD_DIM > OpDomainMass
@ MF_EXIST
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ L2
field with C-1 continuity
Definition definitions.h:88
@ NOSPACE
Definition definitions.h:83
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1191
@ PETSC
Standard PETSc assembly.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
constexpr auto field_name
virtual int get_comm_size() const =0
base operator to do operations at Gauss Pt. level
Data on single entity (This is passed as argument to DataOperator::doWork)
Field evaluator interface.
boost::shared_ptr< SPD > getData(const double *ptr=nullptr, const int nb_eval_points=0, const double eps=1e-12, VERBOSITY_LEVELS verb=QUIET)
Get the Data object.
Execute "this" element in the operator.
static constexpr Switches CtxSetA
Jacobian matrix switch.
static constexpr Switches CtxSetF
Residual vector switch.
static constexpr Switches CtxSetB
Preconditioner matrix switch.
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:429
DomainEle::UserDataOperator DomainEleOp

◆ pushOperators()

MoFEMErrorCode Example::pushOperators ( )
private

[Set density distribution]

[Push operators to pipeline]

Examples
mofem/tutorials/fun-1/integration.cpp.

Definition at line 188 of file integration.cpp.

188 {
191
192 // Push an operator which calculates values of density at integration points
193 pipeline_mng->getOpDomainRhsPipeline().push_back(
195 "rho", commonDataPtr->getRhoAtIntegrationPtsPtr()));
196
197 // Push an operator to pipeline to calculate zero moment of inertia (mass)
198 pipeline_mng->getOpDomainRhsPipeline().push_back(new OpZero(commonDataPtr));
199
200 // Push an operator to the pipeline to calculate first moment of inertaia
201 pipeline_mng->getOpDomainRhsPipeline().push_back(new OpFirst(commonDataPtr));
202
203 // Push an operator to the pipeline to calculate second moment of inertaia
204 pipeline_mng->getOpDomainRhsPipeline().push_back(new OpSecond(commonDataPtr));
205
206 // Set integration rule. Integration rule is equal to the polynomial order of
207 // the density field plus 2, since under the integral of the second moment of
208 // inertia term x*x is present
209 auto integration_rule = [](int, int, int p_data) { return p_data + 2; };
210
211 // Add integration rule to the element
214}
boost::ptr_deque< UserDataOperator > & getOpDomainRhsPipeline()
Get the Op Domain Rhs Pipeline object.
MoFEMErrorCode setDomainRhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain right-hand side finite element.

◆ readMesh() [1/13]

MoFEMErrorCode Example::readMesh ( )
private

[Run problem]

[run problem]

[Run programme]

[Read mesh]

[Read mesh]

Read mesh from file and setup material/boundary condition meshsets

This function loads the finite element mesh from file and processes associated meshsets that define material properties and boundary conditions. The mesh is typically generated using CUBIT and exported in .h5m format.

Meshsets are used to group elements/faces by:

  • Material properties (for different material blocks)
  • Boundary conditions (for applying loads and constraints)
  • Optimization regions (for topology optimization)
Returns
MoFEMErrorCode Success or error code
Examples
mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/mix-1/phase.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, mofem/tutorials/vec-7/adjoint.cpp, and nonlinear_elastic.cpp.

Definition at line 462 of file dynamic_first_order_con_law.cpp.

462 {
465
467 CHKERR simple->loadFile();
469}
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180

◆ readMesh() [2/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [3/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [4/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [5/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [6/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [7/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [8/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [9/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [10/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [11/13]

MoFEMErrorCode Example::readMesh ( )
private

Read mesh from file and setup meshsets.

◆ readMesh() [12/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [13/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ refineSkin()

MoFEMErrorCode Example::refineSkin ( BitRefLevel  parent_bit,
BitRefLevel  child_bit 
)
private

[Edge flips]

[Refine skin]

Examples
mofem/tutorials/adv-6/between_meshes_dg_projection.cpp.

Definition at line 764 of file between_meshes_dg_projection.cpp.

765 {
767
768 moab::Interface &moab = mField.get_moab();
769 Range tris;
770 CHKERR moab.get_entities_by_dimension(0, SPACE_DIM, tris);
771 CHKERR mField.getInterface<BitRefManager>()->filterEntitiesByRefLevel(
772 parent_bit, BitRefLevel().set(), tris);
773
774 Skinner skin(&moab);
775 Range skin_edges;
776 CHKERR skin.find_skin(0, tris, false, skin_edges);
777
778 auto refine = mField.getInterface<MeshRefinement>();
779 CHKERR refine->addVerticesInTheMiddleOfEdges(skin_edges, child_bit);
780#ifndef NDEBUG
781 auto debug = true;
782#else
783 auto debug = false;
784#endif
785 CHKERR refine->refineTris(tris, child_bit, QUIET, debug);
786
787 CHKERR mField.getInterface<BitRefManager>()->writeBitLevel(
788 child_bit, BitRefLevel().set(), "edge_flips_after_refinement.vtk", "VTK",
789 "");
790
792}

◆ reSetupProblem()

MoFEMErrorCode Example::reSetupProblem ( BitRefLevel  child_bit)
private

[Refine skin]

[Re-setup problem after mesh modification

Examples
mofem/tutorials/adv-6/between_meshes_dg_projection.cpp.

Definition at line 796 of file between_meshes_dg_projection.cpp.

796 {
798 simpleInterface->getBitRefLevel() = child_bit;
801}
MoFEMErrorCode reSetUp(bool only_dm=false)
Rebuild internal MoFEM data structures.
Definition Simple.cpp:762
BitRefLevel & getBitRefLevel()
Get the BitRefLevel.
Definition Simple.hpp:415

◆ rhsSource()

double Example::rhsSource ( const double  x,
const double  y,
const double   
)
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 150 of file phase.cpp.

150 {
151 const auto idx = getCoordsInImage(x, y);
152
153 double v = 0;
154 for (auto w = 0; w != window_savitzky_golay; ++w) {
155 const auto i = focalIndex - (window_savitzky_golay - 1) / 2 + w;
156 const auto &intensity = iI[i];
157 v += intensity(idx.first, idx.second) * savitzkyGolayWeights[w];
158 }
159 v = static_cast<double>(v) / savitzkyGolayNormalisation;
160
161 const auto dz = rZ[focalIndex + 1] - rZ[focalIndex - 1];
162 return -k * v / dz;
163}
FTensor::Index< 'k', 3 > k
static int window_savitzky_golay
Definition phase.cpp:77
static int savitzkyGolayNormalisation
Definition phase.cpp:113
static std::vector< double > rZ
Definition phase.cpp:108
static const int * savitzkyGolayWeights
Definition phase.cpp:114

◆ runProblem() [1/18]

MoFEMErrorCode Example::runProblem ( )

[Run problem]

[Refine edges]

[Run topology optimization problem]

[Create common data]

[Operator]

[run problem]

[Run programme]

[Run all]

[Run problem]

Main driver for topology optimization using adjoint sensitivity analysis

This function orchestrates the complete topology optimization workflow:

  1. Initialize Python objective function interface
  2. Setup finite element problems (forward and adjoint)
  3. Compute initial elastic solution
  4. Generate topology optimization modes
  5. Run TAO optimization loop with adjoint-based gradients

The optimization uses TAO (Toolkit for Advanced Optimization) with L-BFGS algorithm. At each iteration:

  • Update geometry based on current design variables
  • Solve forward elastic problem
  • Compute objective function and gradients using adjoint method
  • Post-process results
Returns
MoFEMErrorCode Success or error code

Setup TAO (Toolkit for Advanced Optimization) solver for topology optimization

TAO provides various optimization algorithms. Here we use TAOLMVM (Limited Memory Variable Metric) which is a quasi-Newton method suitable for unconstrained optimization with gradient information.

The optimization variables are coefficients for the topology modes, and gradients are computed using the adjoint method for efficiency.

Generate modes for topology optimization design parameterization

These modes represent perturbations to the geometry that can be used as design variables in topology optimization. The modes are defined through the Python interface and provide spatial basis functions for shape modifications.

Start optimization with zero initial guess for design variables

The TAO solver will iteratively:

  1. Evaluate objective function at current design point
  2. Compute gradients using adjoint sensitivity analysis
  3. Update design variables using L-BFGS algorithm
  4. Check convergence criteria

Each function evaluation involves solving the forward elastic problem and the adjoint problem to compute sensitivities efficiently.

Examples
mofem/tutorials/adv-0/plastic.cpp, mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-1/integration.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/mix-1/phase.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-8/radiation.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, mofem/tutorials/vec-7/adjoint.cpp, nonlinear_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 256 of file plastic.cpp.

256 {
260 CHKERR bC();
261 CHKERR OPs();
262 PetscBool test_ops = PETSC_FALSE;
263 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-test_operators", &test_ops,
264 PETSC_NULL);
265 if (test_ops == PETSC_FALSE) {
266 CHKERR tsSolve();
267 } else {
269 }
271}
MoFEMErrorCode testOperators()
[Solve]
Definition plastic.cpp:1477
MoFEMErrorCode tsSolve()
Definition plastic.cpp:834
MoFEMErrorCode createCommonData()
[Set up problem]
Definition plastic.cpp:480
MoFEMErrorCode OPs()
[Boundary condition]
Definition plastic.cpp:650
MoFEMErrorCode setupProblem()
[Run problem]
Definition plastic.cpp:275
MoFEMErrorCode bC()
[Create common data]
Definition plastic.cpp:606

◆ runProblem() [2/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [3/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [4/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [5/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [6/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [7/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [8/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [9/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [10/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [11/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [12/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [13/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [14/18]

MoFEMErrorCode Example::runProblem ( )

Main driver function for the optimization process.

◆ runProblem() [15/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [16/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [17/18]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [18/18]

MoFEMErrorCode Example::runProblem ( )

◆ setFieldValues()

MoFEMErrorCode Example::setFieldValues ( )
private

[Create common data]

[Set density distribution]

Examples
mofem/tutorials/fun-1/integration.cpp.

Definition at line 172 of file integration.cpp.

172 {
174 auto set_density = [&](VectorAdaptor &&field_data, double *xcoord,
175 double *ycoord, double *zcoord) {
177 field_data[0] = 1;
179 };
180 FieldBlas *field_blas;
181 CHKERR mField.getInterface(field_blas);
182 CHKERR field_blas->setVertexDofs(set_density, "rho");
184}
VectorShallowArrayAdaptor< double > VectorAdaptor
Definition Types.hpp:115
MoFEMErrorCode setVertexDofs(VertexCoordsFunction lambda, const std::string field_name, Range *verts=nullptr)
Set DOFs on vertices using user function.

◆ setIntegrationRules() [1/3]

MoFEMErrorCode Example::setIntegrationRules ( )
private

[Set up problem]

[Set integration rule]

Examples
mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/scl-0/approximaton.cpp, and mofem/tutorials/scl-9/heat_method.cpp.

Definition at line 229 of file plot_base.cpp.

229 {
232}

◆ setIntegrationRules() [2/3]

MoFEMErrorCode Example::setIntegrationRules ( )
private

◆ setIntegrationRules() [3/3]

MoFEMErrorCode Example::setIntegrationRules ( )
private

◆ setUp()

MoFEMErrorCode Example::setUp ( )
private

[Run all]

[Set up problem]

Examples
mofem/tutorials/fun-1/integration.cpp.

Definition at line 137 of file integration.cpp.

137 {
141 CHKERR simple->loadFile();
142 // Add field
143 CHKERR simple->addDomainField("rho", H1, AINSWORTH_LEGENDRE_BASE, 1);
144 constexpr int order = 1;
145 CHKERR simple->setFieldOrder("rho", order);
146 CHKERR simple->setUp();
148}

◆ setupAdJoint()

MoFEMErrorCode Example::setupAdJoint ( )
private

Setup adjoint fields and finite elements

[Set up problem]

[Setup adjoint]

Setup adjoint fields and finite elements for sensitivity analysis

The adjoint method is used to efficiently compute gradients of the objective function with respect to design variables. This function sets up:

  1. ADJOINT_FIELD - stores adjoint variables (Lagrange multipliers)
  2. ADJOINT_DM - data manager for adjoint problem
  3. Adjoint finite elements for domain and boundary

The adjoint equation is: K^T * λ = ∂f/∂u where λ are adjoint variables, K is stiffness matrix, f is objective

Returns
MoFEMErrorCode Success or error code
Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 623 of file adjoint.cpp.

623 {
626
627 // Create adjoint data manager and field
628 auto create_adjoint_dm = [&]() {
629 auto adjoint_dm = createDM(mField.get_comm(), "DMMOFEM");
630
631 auto add_field = [&]() {
633 CHKERR mField.add_field("ADJOINT_FIELD", H1, base, SPACE_DIM);
635 "ADJOINT_FIELD");
636 for (auto tt = MBEDGE; tt <= moab::CN::TypeDimensionMap[SPACE_DIM].second;
637 ++tt)
638 CHKERR mField.set_field_order(simple->getMeshset(), tt, "ADJOINT_FIELD",
639 fieldOrder);
640 CHKERR mField.set_field_order(simple->getMeshset(), MBVERTEX,
641 "ADJOINT_FIELD", 1);
644 };
645
646 auto add_adjoint_fe_impl = [&]() {
648 CHKERR mField.add_finite_element("ADJOINT_DOMAIN_FE");
650 "ADJOINT_FIELD");
652 "ADJOINT_FIELD");
654 "ADJOINT_FIELD");
656 "GEOMETRY");
658 simple->getMeshset(), SPACE_DIM, "ADJOINT_DOMAIN_FE");
659 CHKERR mField.build_finite_elements("ADJOINT_DOMAIN_FE");
660
661 CHKERR mField.add_finite_element("ADJOINT_BOUNDARY_FE");
663 "ADJOINT_FIELD");
665 "ADJOINT_FIELD");
667 "ADJOINT_FIELD");
669 "GEOMETRY");
670
671 auto block_name = "OPTIMISE";
672 auto mesh_mng = mField.getInterface<MeshsetsManager>();
673 auto bcs = mesh_mng->getCubitMeshsetPtr(
674
675 std::regex((boost::format("%s(.*)") % block_name).str())
676
677 );
678
679 for (auto bc : bcs) {
681 bc->getMeshset(), SPACE_DIM - 1, "ADJOINT_BOUNDARY_FE");
682 }
683
684 CHKERR mField.build_finite_elements("ADJOINT_BOUNDARY_FE");
685
686 CHKERR mField.build_adjacencies(simple->getBitRefLevel(),
687 simple->getBitRefLevelMask());
688
690 };
691
692 auto set_adjoint_dm_imp = [&]() {
694 CHKERR DMMoFEMCreateMoFEM(adjoint_dm, &mField, "ADJOINT",
695 simple->getBitRefLevel(),
696 simple->getBitRefLevelMask());
697 CHKERR DMMoFEMSetDestroyProblem(adjoint_dm, PETSC_TRUE);
698 CHKERR DMSetFromOptions(adjoint_dm);
699 CHKERR DMMoFEMAddElement(adjoint_dm, "ADJOINT_DOMAIN_FE");
700 CHKERR DMMoFEMAddElement(adjoint_dm, "ADJOINT_BOUNDARY_FE");
701 CHKERR DMMoFEMSetSquareProblem(adjoint_dm, PETSC_TRUE);
702 CHKERR DMMoFEMSetIsPartitioned(adjoint_dm, PETSC_TRUE);
703 mField.getInterface<ProblemsManager>()->buildProblemFromFields =
704 PETSC_TRUE;
705 CHKERR DMSetUp(adjoint_dm);
706 mField.getInterface<ProblemsManager>()->buildProblemFromFields =
707 PETSC_FALSE;
709 };
710
711 CHK_THROW_MESSAGE(add_field(), "add adjoint field");
712 CHK_THROW_MESSAGE(add_adjoint_fe_impl(), "add adjoint fe");
713 CHK_THROW_MESSAGE(set_adjoint_dm_imp(), "set adjoint dm");
714
715 return adjoint_dm;
716 };
717
718 adjointDM = create_adjoint_dm();
719
721}
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
Definition DMMoFEM.cpp:1113
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
Definition DMMoFEM.cpp:114
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode add_ents_to_field_by_dim(const Range &ents, const int dim, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
Definition DMMoFEM.cpp:434
FieldApproximationBase base
Choice of finite element basis functions
Definition plot_base.cpp:68
int fieldOrder
Polynomial order for approximation.
Definition adjoint.cpp:208
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
Problem manager is used to build and partition problems.

◆ setupProblem() [1/17]

MoFEMErrorCode Example::setupProblem ( )
private

[Run problem]

[Read mesh]

[Set up problem]

[Set up problem]

Setup finite element fields, approximation spaces and degrees of freedom

This function configures the finite element problem by:

  1. Setting up the displacement field "U" with vector approximation
  2. Setting up the geometry field "GEOMETRY" for mesh deformation
  3. Defining polynomial approximation order and basis functions
  4. Creating degrees of freedom on mesh entities

The displacement field uses H1 vector space for standard elasticity. The geometry field allows mesh modification during topology optimization. Different basis functions (Ainsworth-Legendre vs Demkowicz) can be selected.

Returns
MoFEMErrorCode Success or error code

Setup displacement field "U" - the primary unknown in elasticity This field represents displacement vector at each node/DOF

Setup geometry field "GEOMETRY" - used for mesh deformation in optimization This field stores current nodal coordinates and can be modified during topology optimization to represent design changes

For higher-order elements, this projects the exact geometry onto the geometry field to maintain curved boundaries accurately

Examples
mofem/tutorials/adv-0/plastic.cpp, mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/mix-1/phase.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-8/radiation.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, mofem/tutorials/vec-7/adjoint.cpp, nonlinear_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 275 of file plastic.cpp.

275 {
278
279 Range domain_ents;
280 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, domain_ents,
281 true);
282 auto get_ents_by_dim = [&](const auto dim) {
283 if (dim == SPACE_DIM) {
284 return domain_ents;
285 } else {
286 Range ents;
287 if (dim == 0)
288 CHKERR mField.get_moab().get_connectivity(domain_ents, ents, true);
289 else
290 CHKERR mField.get_moab().get_entities_by_dimension(0, dim, ents, true);
291 return ents;
292 }
293 };
294
295 auto get_base = [&]() {
296 auto domain_ents = get_ents_by_dim(SPACE_DIM);
297 if (domain_ents.empty())
298 CHK_THROW_MESSAGE(MOFEM_NOT_FOUND, "Empty mesh");
299 const auto type = type_from_handle(domain_ents[0]);
300 switch (type) {
301 case MBQUAD:
303 case MBHEX:
305 case MBTRI:
307 case MBTET:
309 default:
310 CHK_THROW_MESSAGE(MOFEM_NOT_FOUND, "Element type not handled");
311 }
312 return NOBASE;
313 };
314
315 const auto base = get_base();
316 MOFEM_LOG("PLASTICITY", Sev::inform)
317 << "Base " << ApproximationBaseNames[base];
318
319 CHKERR simple->addDomainField("U", H1, base, SPACE_DIM);
320 CHKERR simple->addDomainField("EP", L2, base, size_symm);
321 CHKERR simple->addDomainField("TAU", L2, base, 1);
322 CHKERR simple->addBoundaryField("U", H1, base, SPACE_DIM);
323
324 CHKERR simple->addDataField("GEOMETRY", H1, base, SPACE_DIM);
325
326 PetscBool order_edge = PETSC_FALSE;
327 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-order_edge", &order_edge,
328 PETSC_NULL);
329 PetscBool order_face = PETSC_FALSE;
330 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-order_face", &order_face,
331 PETSC_NULL);
332 PetscBool order_volume = PETSC_FALSE;
333 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-order_volume", &order_volume,
334 PETSC_NULL);
335
337
338 MOFEM_LOG("PLASTICITY", Sev::inform) << "Order edge " << order_edge
339 ? "true"
340 : "false";
341 MOFEM_LOG("PLASTICITY", Sev::inform) << "Order face " << order_face
342 ? "true"
343 : "false";
344 MOFEM_LOG("PLASTICITY", Sev::inform) << "Order volume " << order_volume
345 ? "true"
346 : "false";
347
348 auto ents = get_ents_by_dim(0);
349 if (order_edge)
350 ents.merge(get_ents_by_dim(1));
351 if (order_face)
352 ents.merge(get_ents_by_dim(2));
353 if (order_volume)
354 ents.merge(get_ents_by_dim(3));
355 CHKERR simple->setFieldOrder("U", order, &ents);
356 } else {
357 CHKERR simple->setFieldOrder("U", order);
358 }
359 CHKERR simple->setFieldOrder("EP", ep_order);
360 CHKERR simple->setFieldOrder("TAU", tau_order);
361
362 CHKERR simple->setFieldOrder("GEOMETRY", geom_order);
363
364#ifdef ADD_CONTACT
365 CHKERR simple->addDomainField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
366 SPACE_DIM);
367 CHKERR simple->addBoundaryField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
368 SPACE_DIM);
369
370 auto get_skin = [&]() {
371 Range body_ents;
372 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
373 Skinner skin(&mField.get_moab());
374 Range skin_ents;
375 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
376 return skin_ents;
377 };
378
379 auto filter_blocks = [&](auto skin) {
380 bool is_contact_block = true;
381 Range contact_range;
382 for (auto m :
383 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
384
385 (boost::format("%s(.*)") % "CONTACT").str()
386
387 ))
388
389 ) {
390 is_contact_block =
391 true; ///< blocs interation is collective, so that is set irrespective
392 ///< if there are entities in given rank or not in the block
393 MOFEM_LOG("CONTACT", Sev::inform)
394 << "Find contact block set: " << m->getName();
395 auto meshset = m->getMeshset();
396 Range contact_meshset_range;
397 CHKERR mField.get_moab().get_entities_by_dimension(
398 meshset, SPACE_DIM - 1, contact_meshset_range, true);
399
400 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
401 contact_meshset_range);
402 contact_range.merge(contact_meshset_range);
403 }
404 if (is_contact_block) {
405 MOFEM_LOG("SYNC", Sev::inform)
406 << "Nb entities in contact surface: " << contact_range.size();
408 skin = intersect(skin, contact_range);
409 }
410 return skin;
411 };
412
413 auto filter_true_skin = [&](auto skin) {
414 Range boundary_ents;
415 ParallelComm *pcomm =
416 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
417 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
418 PSTATUS_NOT, -1, &boundary_ents);
419 return boundary_ents;
420 };
421
422 auto boundary_ents = filter_true_skin(filter_blocks(get_skin()));
423 CHKERR simple->setFieldOrder("SIGMA", 0);
424 CHKERR simple->setFieldOrder("SIGMA", order - 1, &boundary_ents);
425#endif
426
427 CHKERR simple->setUp();
428 CHKERR simple->addFieldToEmptyFieldBlocks("U", "TAU");
429
430 auto project_ho_geometry = [&]() {
431 Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
432 return mField.loop_dofs("GEOMETRY", ent_method);
433 };
434 PetscBool project_geometry = PETSC_TRUE;
435 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-project_geometry",
436 &project_geometry, PETSC_NULL);
437 if (project_geometry) {
438 CHKERR project_ho_geometry();
439 }
440
441 auto get_volume = [&]() {
442 using VolOp = DomainEle::UserDataOperator;
443 auto *op_ptr = new VolOp(NOSPACE, VolOp::OPSPACE);
444 std::array<double, 2> volume_and_count;
445 op_ptr->doWorkRhsHook = [&](DataOperator *base_op_ptr, int side,
446 EntityType type,
449 auto op_ptr = static_cast<VolOp *>(base_op_ptr);
450 volume_and_count[VOL] += op_ptr->getMeasure();
451 volume_and_count[COUNT] += 1;
452 // in necessary at integration over Gauss points.
454 };
455 volume_and_count = {0, 0};
456 auto fe = boost::make_shared<DomainEle>(mField);
457 fe->getOpPtrVector().push_back(op_ptr);
458
459 auto dm = simple->getDM();
461 DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(), fe),
462 "cac volume");
463 std::array<double, 2> tot_volume_and_count;
464 MPI_Allreduce(volume_and_count.data(), tot_volume_and_count.data(),
465 volume_and_count.size(), MPI_DOUBLE, MPI_SUM,
466 mField.get_comm());
467 return tot_volume_and_count;
468 };
469
470 meshVolumeAndCount = get_volume();
471 MOFEM_LOG("PLASTICITY", Sev::inform)
472 << "Mesh volume " << meshVolumeAndCount[VOL] << " nb. of elements "
474
476}
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
@ NOBASE
Definition definitions.h:59
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
@ MOFEM_NOT_FOUND
Definition definitions.h:33
static const char *const ApproximationBaseNames[]
Definition definitions.h:72
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.
auto type_from_handle(const EntityHandle h)
get type from entity handle
static std::array< double, 2 > meshVolumeAndCount
Definition plastic.cpp:223
Managing BitRefLevels.
double getMeasure() const
get measure of element
@ OPSPACE
operator do Work is execute on space data
Projection of edge entities with one mid-node on hierarchical basis.
VolEle::UserDataOperator VolOp
PetscBool order_face
PetscBool order_edge
PetscBool order_volume
constexpr FieldSpace CONTACT_SPACE
[Specialisation for assembly]
Definition plastic.cpp:52

◆ setupProblem() [2/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [3/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [4/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [5/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [6/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [7/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [8/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [9/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [10/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [11/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [12/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [13/17]

MoFEMErrorCode Example::setupProblem ( )
private

Setup fields, approximation spaces and DOFs.

◆ setupProblem() [14/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [15/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [16/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [17/17]

MoFEMErrorCode Example::setupProblem ( )
private

◆ solveElastic()

MoFEMErrorCode Example::solveElastic ( )
private

Solve forward elastic problem.

[Push operators to pipeline]

[Solve]

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 1219 of file adjoint.cpp.

1219 {
1221 auto simple = mField.getInterface<Simple>();
1222 auto dm = simple->getDM();
1223 auto f = createDMVector(dm);
1224 auto d = vectorDuplicate(f);
1225 CHKERR VecZeroEntries(d);
1226 CHKERR DMoFEMMeshToLocalVector(dm, d, INSERT_VALUES, SCATTER_REVERSE);
1227
1228 auto set_essential_bc = [&]() {
1230 // This is low level pushing finite elements (pipelines) to solver
1231
1232 auto ksp_ctx_ptr = getDMKspCtx(dm);
1233 auto pre_proc_rhs = boost::make_shared<FEMethod>();
1234 auto post_proc_rhs = boost::make_shared<FEMethod>();
1235 auto post_proc_lhs = boost::make_shared<FEMethod>();
1236
1237 auto get_pre_proc_hook = [&]() {
1239 {});
1240 };
1241 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
1242
1243 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
1245
1247 post_proc_rhs, 1.)();
1249 };
1250
1251 auto get_post_proc_hook_lhs = [this, post_proc_lhs]() {
1253
1255 post_proc_lhs, 1.)();
1257 };
1258
1259 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1260 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
1261
1262 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
1263 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
1264 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
1266 };
1267
1268 auto setup_and_solve = [&](auto solver) {
1270 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
1271 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSetUp";
1272 CHKERR KSPSetUp(solver);
1273 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSetUp <= Done";
1274 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSolve";
1275 CHKERR KSPSolve(solver, f, d);
1276 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSolve <= Done";
1278 };
1279
1280 MOFEM_LOG_CHANNEL("TIMER");
1281 MOFEM_LOG_TAG("TIMER", "timer");
1282
1283 CHKERR set_essential_bc();
1284 CHKERR setup_and_solve(kspElastic);
1285
1286 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
1287 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
1288 CHKERR DMoFEMMeshToLocalVector(dm, d, INSERT_VALUES, SCATTER_REVERSE);
1289
1290 auto evaluate_field_at_the_point = [&]() {
1292
1293 int coords_dim = 3;
1294 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
1295 PetscBool do_eval_field = PETSC_FALSE;
1296 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
1297 field_eval_coords.data(), &coords_dim,
1298 &do_eval_field);
1299
1300 if (do_eval_field) {
1301
1302 vectorFieldPtr = boost::make_shared<MatrixDouble>();
1303 auto field_eval_data =
1304 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
1305
1307 ->buildTree<SPACE_DIM>(field_eval_data, simple->getDomainFEName());
1308
1309 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1310 auto no_rule = [](int, int, int) { return -1; };
1311 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
1312 field_eval_fe_ptr->getRuleHook = no_rule;
1313
1314 field_eval_fe_ptr->getOpPtrVector().push_back(
1316
1318 ->evalFEAtThePoint<SPACE_DIM>(
1319 field_eval_coords.data(), 1e-12, simple->getProblemName(),
1320 simple->getDomainFEName(), field_eval_data,
1322 QUIET);
1323
1324 if (vectorFieldPtr->size1()) {
1325 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*vectorFieldPtr);
1326 if constexpr (SPACE_DIM == 2)
1327 MOFEM_LOG("FieldEvaluator", Sev::inform)
1328 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1);
1329 else
1330 MOFEM_LOG("FieldEvaluator", Sev::inform)
1331 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1)
1332 << " U_Z: " << t_disp(2);
1333 }
1334
1336 }
1338 };
1339
1340 CHKERR evaluate_field_at_the_point();
1341
1343}
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
auto getDMKspCtx(DM dm)
Get KSP context data structure used by DM.
Definition DMMoFEM.hpp:1248
boost::shared_ptr< MatrixDouble > vectorFieldPtr
Field values at evaluation points.
Definition adjoint.cpp:187
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition Essential.hpp:33
PetscBool do_eval_field
Evaluate field.
Definition plastic.cpp:119

◆ solveSystem() [1/12]

MoFEMErrorCode Example::solveSystem ( )
private

[Solve]

[Push operators to pipeline]

[Solve]

< Mass matrix

< Linear solver

Examples
mofem/tutorials/adv-4/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0/helmholtz.cpp, mofem/tutorials/fun-2/plot_base.cpp, mofem/tutorials/mix-1/phase.cpp, mofem/tutorials/scl-0/approximaton.cpp, mofem/tutorials/scl-9/heat_method.cpp, mofem/tutorials/vec-1/eigen_elastic.cpp, mofem/tutorials/vec-3/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4/shallow_wave.cpp, and nonlinear_elastic.cpp.

Definition at line 877 of file dynamic_first_order_con_law.cpp.

877 {
879 auto *simple = mField.getInterface<Simple>();
880 auto *pipeline_mng = mField.getInterface<PipelineManager>();
881
882 auto dm = simple->getDM();
883
884 auto calculate_stress_ops = [&](auto &pip) {
886
887 auto v_ptr = boost::make_shared<MatrixDouble>();
888 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("V", v_ptr));
889 auto X_ptr = boost::make_shared<MatrixDouble>();
890 pip.push_back(
891 new OpCalculateVectorFieldValues<SPACE_DIM>("GEOMETRY", X_ptr));
892
893 auto x_ptr = boost::make_shared<MatrixDouble>();
894 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("x_1", x_ptr));
895
896 // Calculate unknown F
897 auto mat_H_tensor_ptr = boost::make_shared<MatrixDouble>();
899 "F", mat_H_tensor_ptr));
900
901 auto u_ptr = boost::make_shared<MatrixDouble>();
902 pip.push_back(new OpCalculateDisplacement<SPACE_DIM>(x_ptr, X_ptr, u_ptr));
903 // Calculate P
904
905 auto mat_F_ptr = boost::make_shared<MatrixDouble>();
907 mat_F_ptr, mat_H_tensor_ptr));
908
909 PetscBool is_linear_elasticity = PETSC_TRUE;
910 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-is_linear_elasticity",
911 &is_linear_elasticity, PETSC_NULLPTR);
912
913 auto mat_P_ptr = boost::make_shared<MatrixDouble>();
914 if (is_linear_elasticity) {
917 mat_F_ptr));
918 } else {
919 auto inv_F = boost::make_shared<MatrixDouble>();
920 auto det_ptr = boost::make_shared<VectorDouble>();
921
922 pip.push_back(new OpInvertMatrix<SPACE_DIM>(mat_F_ptr, det_ptr, inv_F));
923
926 mat_F_ptr, inv_F, det_ptr));
927 }
928
929 auto mat_v_grad_ptr = boost::make_shared<MatrixDouble>();
931 "V", mat_v_grad_ptr));
932
933 return boost::make_tuple(v_ptr, X_ptr, x_ptr, mat_P_ptr, mat_F_ptr, u_ptr);
934 };
935
936 auto post_proc_boundary = [&]() {
937 auto boundary_post_proc_fe = boost::make_shared<PostProcFaceEle>(mField);
938
940 boundary_post_proc_fe->getOpPtrVector(), {}, "GEOMETRY");
941 auto op_loop_side =
942 new OpLoopSide<SideEle>(mField, simple->getDomainFEName(), SPACE_DIM);
943 // push ops to side element, through op_loop_side operator
944 auto [boundary_v_ptr, boundary_X_ptr, boundary_x_ptr, boundary_mat_P_ptr,
945 boundary_mat_F_ptr, boundary_u_ptr] =
946 calculate_stress_ops(op_loop_side->getOpPtrVector());
947 boundary_post_proc_fe->getOpPtrVector().push_back(op_loop_side);
948
950
951 boundary_post_proc_fe->getOpPtrVector().push_back(
952
953 new OpPPMap(
954
955 boundary_post_proc_fe->getPostProcMesh(),
956 boundary_post_proc_fe->getMapGaussPts(),
957
959
960 OpPPMap::DataMapMat{{"V", boundary_v_ptr},
961 {"GEOMETRY", boundary_X_ptr},
962 {"x", boundary_x_ptr},
963 {"U", boundary_u_ptr}},
964
965 OpPPMap::DataMapMat{{"FIRST_PIOLA", boundary_mat_P_ptr},
966 {"F", boundary_mat_F_ptr}},
967
969
970 )
971
972 );
973 return boundary_post_proc_fe;
974 };
975
976 // Add monitor to time solver
977
978 double rho = 1.;
979 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-density", &rho, PETSC_NULLPTR);
980 auto get_rho = [rho](const double, const double, const double) {
981 return rho;
982 };
983
984 SmartPetscObj<Mat> M; ///< Mass matrix
985 SmartPetscObj<KSP> ksp; ///< Linear solver
986
987 auto ts_pre_post_proc = boost::make_shared<TSPrePostProc>();
988 tsPrePostProc = ts_pre_post_proc;
989
991 CHKERR MatZeroEntries(M);
992
993 boost::shared_ptr<DomainEle> vol_mass_ele(new DomainEle(mField));
994
995 vol_mass_ele->B = M;
996
997 auto integration_rule = [](int, int, int approx_order) {
998 return 2 * approx_order;
999 };
1000
1001 vol_mass_ele->getRuleHook = integration_rule;
1002
1003 vol_mass_ele->getOpPtrVector().push_back(new OpMassV("V", "V", get_rho));
1004 vol_mass_ele->getOpPtrVector().push_back(new OpMassF("F", "F"));
1005
1006 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(), vol_mass_ele);
1007 CHKERR MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY);
1008 CHKERR MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY);
1009
1010 auto lumpVec = createDMVector(simple->getDM());
1011 CHKERR MatGetRowSum(M, lumpVec);
1012
1013 CHKERR MatZeroEntries(M);
1014 CHKERR MatDiagonalSet(M, lumpVec, INSERT_VALUES);
1015
1016 // Create and septup KSP (linear solver), we need this to calculate g(t,u) =
1017 // M^-1G(t,u)
1018 ksp = createKSP(mField.get_comm());
1019 CHKERR KSPSetOperators(ksp, M, M);
1020 CHKERR KSPSetFromOptions(ksp);
1021 CHKERR KSPSetUp(ksp);
1022
1023 auto solve_boundary_for_g = [&]() {
1025 if (*(pipeline_mng->getBoundaryExplicitRhsFE()->vecAssembleSwitch)) {
1026
1027 CHKERR VecGhostUpdateBegin(pipeline_mng->getBoundaryExplicitRhsFE()->ts_F,
1028 ADD_VALUES, SCATTER_REVERSE);
1029 CHKERR VecGhostUpdateEnd(pipeline_mng->getBoundaryExplicitRhsFE()->ts_F,
1030 ADD_VALUES, SCATTER_REVERSE);
1031 CHKERR VecAssemblyBegin(pipeline_mng->getBoundaryExplicitRhsFE()->ts_F);
1032 CHKERR VecAssemblyEnd(pipeline_mng->getBoundaryExplicitRhsFE()->ts_F);
1033 *(pipeline_mng->getBoundaryExplicitRhsFE()->vecAssembleSwitch) = false;
1034
1035 auto D =
1036 smartVectorDuplicate(pipeline_mng->getBoundaryExplicitRhsFE()->ts_F);
1037 CHKERR KSPSolve(ksp, pipeline_mng->getBoundaryExplicitRhsFE()->ts_F, D);
1038 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
1039 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
1040 CHKERR VecCopy(D, pipeline_mng->getBoundaryExplicitRhsFE()->ts_F);
1041 }
1042
1044 };
1045
1046 pipeline_mng->getBoundaryExplicitRhsFE()->postProcessHook =
1047 solve_boundary_for_g;
1048
1050 ts = pipeline_mng->createTSEX(dm);
1051
1052 // Field eval
1053 PetscBool field_eval_flag = PETSC_TRUE;
1054 boost::shared_ptr<MatrixDouble> velocity_field_ptr;
1055 boost::shared_ptr<MatrixDouble> geometry_field_ptr;
1056 boost::shared_ptr<MatrixDouble> spatial_position_field_ptr;
1057 boost::shared_ptr<SetPtsData> field_eval_data;
1058
1059 std::array<double, 3> field_eval_coords = {0.5, 0.5, 5.};
1060 int dim = 3;
1061 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
1062 field_eval_coords.data(), &dim,
1063 &field_eval_flag);
1064
1065 if (field_eval_flag) {
1066 field_eval_data =
1067 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
1068 CHKERR mField.getInterface<FieldEvaluatorInterface>()->buildTree<SPACE_DIM>(
1069 field_eval_data, simple->getDomainFEName());
1070
1071 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1072
1073 auto no_rule = [](int, int, int) { return -1; };
1074
1075 auto fe_ptr = field_eval_data->feMethodPtr.lock();
1076 fe_ptr->getRuleHook = no_rule;
1077 velocity_field_ptr = boost::make_shared<MatrixDouble>();
1078 geometry_field_ptr = boost::make_shared<MatrixDouble>();
1079 spatial_position_field_ptr = boost::make_shared<MatrixDouble>();
1080 fe_ptr->getOpPtrVector().push_back(
1081 new OpCalculateVectorFieldValues<SPACE_DIM>("V", velocity_field_ptr));
1082 fe_ptr->getOpPtrVector().push_back(
1084 geometry_field_ptr));
1085 fe_ptr->getOpPtrVector().push_back(
1087 "x_2", spatial_position_field_ptr));
1088 }
1089
1090 auto post_proc_domain = [&]() {
1091 auto post_proc_fe_vol = boost::make_shared<PostProcEle>(mField);
1092
1094
1095 auto [boundary_v_ptr, boundary_X_ptr, boundary_x_ptr, boundary_mat_P_ptr,
1096 boundary_mat_F_ptr, boundary_u_ptr] =
1097 calculate_stress_ops(post_proc_fe_vol->getOpPtrVector());
1098
1099 post_proc_fe_vol->getOpPtrVector().push_back(
1100
1101 new OpPPMap(
1102
1103 post_proc_fe_vol->getPostProcMesh(),
1104 post_proc_fe_vol->getMapGaussPts(),
1105
1106 {},
1107
1108 {{"V", boundary_v_ptr},
1109 {"GEOMETRY", boundary_X_ptr},
1110 {"x", boundary_x_ptr},
1111 {"U", boundary_u_ptr}},
1112
1113 {{"FIRST_PIOLA", boundary_mat_P_ptr}, {"F", boundary_mat_F_ptr}},
1114
1115 {}
1116
1117 )
1118
1119 );
1120 return post_proc_fe_vol;
1121 };
1122
1123 boost::shared_ptr<FEMethod> null_fe;
1124 auto monitor_ptr = boost::make_shared<Monitor>(
1125 SmartPetscObj<DM>(dm, true), mField, post_proc_domain(),
1126 post_proc_boundary(), velocity_field_ptr, spatial_position_field_ptr,
1127 geometry_field_ptr, field_eval_coords, field_eval_data);
1128
1129 CHKERR DMMoFEMTSSetMonitor(dm, ts, simple->getDomainFEName(), null_fe,
1130 null_fe, monitor_ptr);
1131
1132 double ftime = 1;
1133 // CHKERR TSSetMaxTime(ts, ftime);
1134 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
1135
1136 auto T = createDMVector(simple->getDM());
1137 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
1138 SCATTER_FORWARD);
1139 CHKERR TSSetSolution(ts, T);
1140 CHKERR TSSetFromOptions(ts);
1141
1142 CHKERR TSSetPostStage(ts, TSPrePostProc::tsPostStage);
1143 CHKERR TSSetPostStep(ts, TSPrePostProc::tsPostStep);
1144 CHKERR TSSetPreStep(ts, TSPrePostProc::tsPreStep);
1145
1146 boost::shared_ptr<ForcesAndSourcesCore> null;
1147
1148 if (auto ptr = tsPrePostProc.lock()) {
1149 ptr->fsRawPtr = this;
1150 CHKERR TSSetUp(ts);
1151 CHKERR TSSolve(ts, NULL);
1152 CHKERR TSGetTime(ts, &ftime);
1153 }
1154
1156}
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMassV
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM *SPACE_DIM > OpMassF
static boost::weak_ptr< TSPrePostProc > tsPrePostProc
PetscErrorCode DMCreateMatrix_MoFEM(DM dm, Mat *M)
Definition DMMoFEM.cpp:1187
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
DEPRECATED SmartPetscObj< Vec > smartVectorDuplicate(Vec vec)
SmartPetscObj< Mat > M
static MoFEMErrorCode tsPostStep(TS ts)
static MoFEMErrorCode tsPreStep(TS ts)
static MoFEMErrorCode tsPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
[Boundary condition]
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::DomainEle DomainEle

◆ solveSystem() [2/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [3/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [4/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [5/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [6/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [7/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [8/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [9/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [10/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [11/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [12/12]

MoFEMErrorCode Example::solveSystem ( )
private

◆ testOperators() [1/2]

MoFEMErrorCode Example::testOperators ( )
private

[Solve]

[TestOperators]

Examples
mofem/tutorials/adv-0/plastic.cpp, and plastic.cpp.

Definition at line 1477 of file plastic.cpp.

1485 {
1486
1487 {"U", {-1e-6, 1e-6}},
1488
1489 {"EP", {-1e-6, 1e-6}},
1490
1491 {"TAU", {0, 1e-4}}
1492
1493 });
1494
1495 auto dot_x_plastic_active =
1496 opt->setRandomFields(simple->getDM(), {
1497
1498 {"U", {-1, 1}},
1499
1500 {"EP", {-1, 1}},
1501
1502 {"TAU", {0.1, 1}}
1503
1504 });
1505 auto diff_x_plastic_active =
1506 opt->setRandomFields(simple->getDM(), {
1507
1508 {"U", {-1, 1}},
1509
1510 {"EP", {-1, 1}},
1511
1512 {"TAU", {-1, 1}}
1513
1514 });
1515
1516 auto dot_x_elastic =
1517 opt->setRandomFields(simple->getDM(), {
1518
1519 {"U", {-1, 1}},
1520
1521 {"EP", {-1, 1}},
1522
1523 {"TAU", {-1, -0.1}}
1524
1525 });
1526 auto diff_x_elastic =
1527 opt->setRandomFields(simple->getDM(), {
1528
1529 {"U", {-1, 1}},
1530
1531 {"EP", {-1, 1}},
1532
1533 {"TAU", {-1, 1}}
1534
1535 });
1536
1537 auto test_domain_ops = [&](auto fe_name, auto lhs_pipeline, auto rhs_pipeline,
1538 auto dot_x, auto diff_x) {
1540
1541 auto diff_res = opt->checkCentralFiniteDifference(
1542 simple->getDM(), fe_name, rhs_pipeline, lhs_pipeline, x, dot_x,
1543 SmartPetscObj<Vec>(), diff_x, 0, 0.5, eps);
1544
1545 // Calculate norm of difference between directional derivative calculated
1546 // from finite difference, and tangent matrix.
1547 double fnorm;
1548 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
1549 MOFEM_LOG_C("PLASTICITY", Sev::inform,
1550 "Test consistency of tangent matrix %3.4e", fnorm);
1551
1552 constexpr double err = 1e-5;
1553 if (fnorm > err)
1554 SETERRQ1(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1555 "Norm of directional derivative too large err = %3.4e", fnorm);
1556
1558 };
1559
1560 MOFEM_LOG("PLASTICITY", Sev::inform) << "Elastic active";
1561 CHKERR test_domain_ops(simple->getDomainFEName(), pip->getDomainLhsFE(),
1562 pip->getDomainRhsFE(), dot_x_elastic, diff_x_elastic);
1563
1564 MOFEM_LOG("PLASTICITY", Sev::inform) << "Plastic active";
1565 CHKERR test_domain_ops(simple->getDomainFEName(), pip->getDomainLhsFE(),
1566 pip->getDomainRhsFE(), dot_x_plastic_active,
1567 diff_x_plastic_active);
1568
1570};
1571
1572//! [TestOperators]
1573
1574static char help[] = "...\n\n";
static char help[]

◆ testOperators() [2/2]

MoFEMErrorCode Example::testOperators ( )
private

◆ thermalBC()

MoFEMErrorCode Example::thermalBC ( )
private

[Mechanical boundary conditions]

[Thermal boundary conditions]

Examples
thermoplastic.cpp.

Definition at line 3435 of file thermoplastic.cpp.

3435 {
3437
3438 MOFEM_LOG("SYNC", Sev::noisy) << "bC";
3440
3441 auto simple = mField.getInterface<Simple>();
3442 auto bc_mng = mField.getInterface<BcManager>();
3443
3444 auto get_skin = [&]() {
3445 Range body_ents;
3446 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
3447 Skinner skin(&mField.get_moab());
3448 Range skin_ents;
3449 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
3450 return skin_ents;
3451 };
3452
3453 auto filter_flux_blocks = [&](auto skin, bool temp_bc = false) {
3454 auto remove_cubit_blocks = [&](auto c) {
3456 for (auto m :
3457
3458 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(c)
3459
3460 ) {
3461 Range ents;
3462 CHKERR mField.get_moab().get_entities_by_dimension(
3463 m->getMeshset(), SPACE_DIM - 1, ents, true);
3464 skin = subtract(skin, ents);
3465 }
3467 };
3468
3469 auto remove_named_blocks = [&](auto n) {
3471 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
3472 std::regex(
3473
3474 (boost::format("%s(.*)") % n).str()
3475
3476 ))
3477
3478 ) {
3479 Range ents;
3480 CHKERR mField.get_moab().get_entities_by_dimension(
3481 m->getMeshset(), SPACE_DIM - 1, ents, true);
3482 skin = subtract(skin, ents);
3483 }
3485 };
3486 if (!temp_bc) {
3487 CHK_THROW_MESSAGE(remove_cubit_blocks(NODESET | TEMPERATURESET),
3488 "remove_cubit_blocks");
3489 CHK_THROW_MESSAGE(remove_named_blocks("TEMPERATURE"),
3490 "remove_named_blocks");
3491 }
3492 CHK_THROW_MESSAGE(remove_cubit_blocks(SIDESET | HEATFLUXSET),
3493 "remove_cubit_blocks");
3494 CHK_THROW_MESSAGE(remove_named_blocks("HEATFLUX"), "remove_named_blocks");
3495 CHK_THROW_MESSAGE(remove_named_blocks("CONVECTION"), "remove_named_blocks");
3496 CHK_THROW_MESSAGE(remove_named_blocks("RADIATION"), "remove_named_blocks");
3497 return skin;
3498 };
3499
3500 auto filter_true_skin = [&](auto skin) {
3501 Range boundary_ents;
3502 ParallelComm *pcomm =
3503 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
3504 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
3505 PSTATUS_NOT, -1, &boundary_ents);
3506 return boundary_ents;
3507 };
3508
3509 auto remove_flux_ents = filter_true_skin(filter_flux_blocks(get_skin()));
3510 auto remove_temp_bc_ents =
3511 filter_true_skin(filter_flux_blocks(get_skin(), true));
3512
3513 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
3514 remove_flux_ents);
3515 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
3516 remove_temp_bc_ents);
3517
3518 MOFEM_LOG("SYNC", Sev::noisy) << remove_flux_ents << endl;
3520
3521 MOFEM_LOG("SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
3523
3524#ifndef NDEBUG
3525
3527 mField.get_moab(),
3528 (boost::format("flux_remove_%d.vtk") % mField.get_comm_rank()).str(),
3529 remove_flux_ents);
3530
3531#endif
3532
3533 if (is_distributed_mesh == PETSC_TRUE) {
3534 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
3535 simple->getProblemName(), "FLUX", remove_flux_ents);
3536 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
3537 simple->getProblemName(), "TBC", remove_temp_bc_ents);
3538 } else {
3540 ->removeDofsOnEntitiesNotDistributed(simple->getProblemName(), "FLUX",
3541 remove_flux_ents);
3543 ->removeDofsOnEntitiesNotDistributed(simple->getProblemName(), "TBC",
3544 remove_temp_bc_ents);
3545 }
3546
3547 // auto set_init_temp = [](boost::shared_ptr<FieldEntity> field_entity_ptr) {
3548 // field_entity_ptr->getEntFieldData()[0] = init_temp;
3549 // return 0;
3550 // };
3551 // CHKERR
3552 // mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(set_init_temp,
3553 // "T");
3554
3555 CHKERR bc_mng->pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
3556 simple->getProblemName(), "FLUX", false);
3557
3559}
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
@ TEMPERATURESET
@ HEATFLUXSET
@ NODESET
@ SIDESET
const double c
speed of light (cm/ns)
Definition of the heat flux bc data structure.
Definition BCData.hpp:423

◆ topologyModes()

MoFEMErrorCode Example::topologyModes ( )
private

Compute topology optimization modes.

[Boundary condition]

[Adjoint modes]

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 746 of file adjoint.cpp.

746 {
748
749 auto opt_ents = get_range_from_block(mField, "OPTIMISE", SPACE_DIM - 1);
750 auto subset_dm_bdy = createDM(mField.get_comm(), "DMMOFEM");
751 CHKERR DMMoFEMSetSquareProblem(subset_dm_bdy, PETSC_TRUE);
752 CHKERR DMMoFEMCreateSubDM(subset_dm_bdy, adjointDM, "SUBSET_BDY");
753 CHKERR DMMoFEMAddElement(subset_dm_bdy, "ADJOINT_BOUNDARY_FE");
754 CHKERR DMMoFEMAddSubFieldRow(subset_dm_bdy, "ADJOINT_FIELD",
755 boost::make_shared<Range>(opt_ents));
756 CHKERR DMMoFEMAddSubFieldCol(subset_dm_bdy, "ADJOINT_FIELD",
757 boost::make_shared<Range>(opt_ents));
758 CHKERR DMSetUp(subset_dm_bdy);
759
760 auto subset_dm_domain = createDM(mField.get_comm(), "DMMOFEM");
761 CHKERR DMMoFEMSetSquareProblem(subset_dm_domain, PETSC_TRUE);
762 CHKERR DMMoFEMCreateSubDM(subset_dm_domain, adjointDM, "SUBSET_DOMAIN");
763 CHKERR DMMoFEMAddElement(subset_dm_domain, "ADJOINT_DOMAIN_FE");
764 CHKERR DMMoFEMAddSubFieldRow(subset_dm_domain, "ADJOINT_FIELD");
765 CHKERR DMMoFEMAddSubFieldCol(subset_dm_domain, "ADJOINT_FIELD");
766 CHKERR DMSetUp(subset_dm_domain);
767
768 // remove dofs on boundary of the domain
769 auto remove_dofs = [&]() {
771
772 std::array<Range, 3> remove_dim_ents;
773 remove_dim_ents[0] =
774 get_range_from_block(mField, "OPT_REMOVE_X", SPACE_DIM - 1);
775 remove_dim_ents[1] =
776 get_range_from_block(mField, "OPT_REMOVE_Y", SPACE_DIM - 1);
777 remove_dim_ents[2] =
778 get_range_from_block(mField, "OPT_REMOVE_Z", SPACE_DIM - 1);
779
780 for (int d = 0; d != 3; ++d) {
781 MOFEM_LOG("WORLD", Sev::inform)
782 << "Removing topology modes on block OPT_REMOVE_" << (char)('X' + d)
783 << " with " << remove_dim_ents[d].size() << " entities";
784 }
785
786 Range body_ents;
787 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents,
788 true);
789 auto skin = moab::Skinner(&mField.get_moab());
790 Range boundary_ents;
791 CHKERR skin.find_skin(0, body_ents, false, boundary_ents);
792 for (int d = 0; d != 3; ++d) {
793 boundary_ents = subtract(boundary_ents, remove_dim_ents[d]);
794 }
795 ParallelComm *pcomm =
796 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
797 CHKERR pcomm->filter_pstatus(boundary_ents,
798 PSTATUS_SHARED | PSTATUS_MULTISHARED,
799 PSTATUS_NOT, -1, nullptr);
800 for (auto d = SPACE_DIM - 2; d >= 0; --d) {
801 if (d >= 0) {
802 Range ents;
803 CHKERR mField.get_moab().get_adjacencies(boundary_ents, d, false, ents,
804 moab::Interface::UNION);
805 boundary_ents.merge(ents);
806 } else {
807 Range verts;
808 CHKERR mField.get_moab().get_connectivity(boundary_ents, verts);
809 boundary_ents.merge(verts);
810 }
811 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
812 boundary_ents);
813 }
814 boundary_ents.merge(opt_ents);
815 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
816 "SUBSET_DOMAIN", "ADJOINT_FIELD", boundary_ents);
817 for (int d = 0; d != 3; ++d) {
818 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
819 "SUBSET_DOMAIN", "ADJOINT_FIELD", remove_dim_ents[d], d, d);
820 }
821
822 // #ifndef NDEBUG
823 if (mField.get_comm_rank() == 0) {
824 CHKERR save_range(mField.get_moab(), "topoMode_boundary_ents.vtk",
825 boundary_ents);
826 }
827 // #endif
828
830 };
831
832 CHKERR remove_dofs();
833
834 auto get_lhs_fe = [&]() {
835 auto fe_lhs = boost::make_shared<BoundaryEle>(mField);
836 fe_lhs->getRuleHook = [](int, int, int p_data) {
837 return 2 * p_data + p_data - 1;
838 };
839 auto &pip = fe_lhs->getOpPtrVector();
841 "GEOMETRY");
844 pip.push_back(new OpMass("ADJOINT_FIELD", "ADJOINT_FIELD",
845 [](double, double, double) { return 1.; }));
846 return fe_lhs;
847 };
848
849 auto get_rhs_fe = [&]() {
850 auto fe_rhs = boost::make_shared<BoundaryEle>(mField);
851 fe_rhs->getRuleHook = [](int, int, int p_data) {
852 return 2 * p_data + p_data - 1;
853 };
854 auto &pip = fe_rhs->getOpPtrVector();
856 "GEOMETRY");
857
858 return fe_rhs;
859 };
860
861 auto block_name = "OPTIMISE";
862 auto mesh_mng = mField.getInterface<MeshsetsManager>();
863 auto bcs = mesh_mng->getCubitMeshsetPtr(
864
865 std::regex((boost::format("%s(.*)") % block_name).str())
866
867 );
868
869 for (auto &v : modeVecs) {
870 v = createDMVector(subset_dm_bdy);
871 }
872
874 struct OpMode : public OP {
875 OpMode(const std::string name,
876 boost::shared_ptr<ObjectiveFunctionData> python_ptr, int id,
877 std::vector<SmartPetscObj<Vec>> mode_vecs,
878 std::vector<std::array<double, 3>> mode_centroids,
879 std::vector<std::array<double, 6>> mode_bboxes, int block_counter,
880 int mode_counter, boost::shared_ptr<Range> range = nullptr)
881 : OP(name, name, OP::OPROW, range), pythonPtr(python_ptr), iD(id),
882 modeVecs(mode_vecs), modeCentroids(mode_centroids),
883 modeBboxes(mode_bboxes), blockCounter(block_counter),
884 modeCounter(mode_counter) {}
885
886 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
888
889 if (OP::entsPtr) {
890 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
892 }
893
894 auto nb_rows = data.getIndices().size();
895 if (!nb_rows) {
897 }
898 auto nb_base_functions = data.getN().size2();
899
901 CHKERR pythonPtr->blockModes(iD, OP::getCoordsAtGaussPts(),
902 modeCentroids[blockCounter],
903 modeBboxes[blockCounter], blockModes);
904
905 auto nb_integration_pts = getGaussPts().size2();
906 if (blockModes.size2() != 3 * nb_integration_pts) {
907 MOFEM_LOG("WORLD", Sev::error)
908 << "Number of modes does not match number of integration points: "
909 << blockModes.size2() << "!=" << 3 * nb_integration_pts;
910 CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "modes/integration points");
911 }
912
913 VectorDouble nf(nb_rows);
914
915 int nb_modes = blockModes.size1();
916 for (auto mode = 0; mode != nb_modes; ++mode) {
917 nf.clear();
918 // get mode
919 auto t_mode = getFTensor1FromPtr<3>(&blockModes(mode, 0));
920 // get element volume
921 const double vol = OP::getMeasure();
922 // get integration weights
923 auto t_w = OP::getFTensor0IntegrationWeight();
924 // get base function gradient on rows
925 auto t_base = data.getFTensor0N();
926 // loop over integration points
927 for (int gg = 0; gg != nb_integration_pts; gg++) {
928
929 // take into account Jacobian
930 const double alpha = t_w * vol;
931 // loop over rows base functions
932 auto t_nf = getFTensor1FromPtr<SPACE_DIM>(nf.data().data());
933 int rr = 0;
934 for (; rr != nb_rows / SPACE_DIM; ++rr) {
935 t_nf(i) += alpha * t_base * t_mode(i);
936 ++t_base;
937 ++t_nf;
938 }
939 for (; rr < nb_base_functions; ++rr)
940 ++t_base;
941 ++t_w; // move to another integration weight
942 ++t_mode; // move to another mode
943 }
944 Vec vec = modeVecs[modeCounter + mode];
945 auto size = data.getIndices().size();
946 auto *indices = data.getIndices().data().data();
947 auto *nf_data = nf.data().data();
948 CHKERR VecSetValues(vec, size, indices, nf_data, ADD_VALUES);
949 }
950
952 }
953
954 private:
955 boost::shared_ptr<ObjectiveFunctionData> pythonPtr;
956 MatrixDouble blockModes;
957 std::vector<std::array<double, 3>> modeCentroids;
958 std::vector<std::array<double, 6>> modeBboxes;
959 int iD;
960 std::vector<SmartPetscObj<Vec>> modeVecs;
961 int blockCounter;
962 int modeCounter;
963 };
964
965 auto solve_bdy = [&]() {
967
968 auto fe_lhs = get_lhs_fe();
969 auto fe_rhs = get_rhs_fe();
970 int block_counter = 0;
971 int mode_counter = 0;
972 for (auto &bc : bcs) {
973 auto id = bc->getMeshsetId();
974 Range ents;
975 CHKERR mField.get_moab().get_entities_by_handle(bc->getMeshset(), ents,
976 true);
977 auto range = boost::make_shared<Range>(ents);
978 auto &pip_rhs = fe_rhs->getOpPtrVector();
979 pip_rhs.push_back(new OpMode("ADJOINT_FIELD", pythonPtr, id, modeVecs,
980 modeCentroids, modeBBoxes, block_counter,
981 mode_counter, range));
982 CHKERR DMoFEMLoopFiniteElements(subset_dm_bdy, "ADJOINT_BOUNDARY_FE",
983 fe_rhs);
984 pip_rhs.pop_back();
985 int nb_modes;
986 CHKERR pythonPtr->numberOfModes(id, nb_modes);
987 ++block_counter;
988 mode_counter += nb_modes;
989 MOFEM_LOG("WORLD", Sev::inform)
990 << "Setting mode block block: " << bc->getName()
991 << " with ID: " << bc->getMeshsetId()
992 << " total modes: " << mode_counter;
993 }
994
995 for (auto &v : modeVecs) {
996 CHKERR VecAssemblyBegin(v);
997 CHKERR VecAssemblyEnd(v);
998 CHKERR VecGhostUpdateBegin(v, ADD_VALUES, SCATTER_REVERSE);
999 CHKERR VecGhostUpdateEnd(v, ADD_VALUES, SCATTER_REVERSE);
1000 }
1001
1002 auto M = createDMMatrix(subset_dm_bdy);
1003 fe_lhs->B = M;
1004 CHKERR DMoFEMLoopFiniteElements(subset_dm_bdy, "ADJOINT_BOUNDARY_FE",
1005 fe_lhs);
1006 CHKERR MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY);
1007 CHKERR MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY);
1008
1009 auto solver = createKSP(mField.get_comm());
1010 CHKERR KSPSetOperators(solver, M, M);
1011 CHKERR KSPSetFromOptions(solver);
1012 CHKERR KSPSetUp(solver);
1013 auto v = createDMVector(subset_dm_bdy);
1014 for (auto &f : modeVecs) {
1015 CHKERR KSPSolve(solver, f, v);
1016 CHKERR VecSwap(f, v);
1017 }
1018
1019 for (auto &v : modeVecs) {
1020 CHKERR VecGhostUpdateBegin(v, INSERT_VALUES, SCATTER_FORWARD);
1021 CHKERR VecGhostUpdateEnd(v, INSERT_VALUES, SCATTER_FORWARD);
1022 }
1023
1025 };
1026
1027 CHKERR solve_bdy();
1028
1029 auto get_elastic_fe_lhs = [&]() {
1030 auto fe = boost::make_shared<DomainEle>(mField);
1031 fe->getRuleHook = [](int, int, int p_data) {
1032 return 2 * p_data + p_data - 1;
1033 };
1034 auto &pip = fe->getOpPtrVector();
1036 "GEOMETRY");
1037 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, A, I, DomainEleOp>(
1038 mField, pip, "ADJOINT_FIELD", "MAT_ADJOINT", Sev::noisy);
1039 return fe;
1040 };
1041
1042 auto get_elastic_fe_rhs = [&]() {
1043 auto fe = boost::make_shared<DomainEle>(mField);
1044 fe->getRuleHook = [](int, int, int p_data) {
1045 return 2 * p_data + p_data - 1;
1046 };
1047 auto &pip = fe->getOpPtrVector();
1049 "GEOMETRY");
1050 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
1051 mField, pip, "ADJOINT_FIELD", "MAT_ADJOINT", Sev::noisy);
1052 return fe;
1053 };
1054
1055 auto adjoint_gradient_postprocess = [&](auto mode) {
1057 auto post_proc_mesh = boost::make_shared<moab::Core>();
1058 auto post_proc_begin =
1059 boost::make_shared<PostProcBrokenMeshInMoabBaseBegin>(mField,
1060 post_proc_mesh);
1061 auto post_proc_end = boost::make_shared<PostProcBrokenMeshInMoabBaseEnd>(
1062 mField, post_proc_mesh);
1063
1064 auto geom_vec = boost::make_shared<MatrixDouble>();
1065
1066 auto post_proc_fe =
1067 boost::make_shared<PostProcEleDomain>(mField, post_proc_mesh);
1069 post_proc_fe->getOpPtrVector(), {H1}, "GEOMETRY");
1070 post_proc_fe->getOpPtrVector().push_back(
1071 new OpCalculateVectorFieldValues<SPACE_DIM>("ADJOINT_FIELD", geom_vec,
1072 modeVecs[mode]));
1073
1075
1076 post_proc_fe->getOpPtrVector().push_back(
1077
1078 new OpPPMap(
1079
1080 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
1081
1082 {},
1083
1084 {{"MODE", geom_vec}},
1085
1086 {},
1087
1088 {}
1089
1090 )
1091
1092 );
1093
1095 post_proc_begin->getFEMethod());
1096 CHKERR DMoFEMLoopFiniteElements(adjointDM, "ADJOINT_DOMAIN_FE",
1097 post_proc_fe);
1099 post_proc_begin->getFEMethod());
1100
1101 CHKERR post_proc_end->writeFile("mode_" + std::to_string(mode) + ".h5m");
1102
1104 };
1105
1106 auto solve_domain = [&]() {
1108 auto fe_lhs = get_elastic_fe_lhs();
1109 auto fe_rhs = get_elastic_fe_rhs();
1110 auto v = createDMVector(subset_dm_domain);
1111 auto F = vectorDuplicate(v);
1112 fe_rhs->f = F;
1113
1114 auto M = createDMMatrix(subset_dm_domain);
1115 fe_lhs->B = M;
1116 CHKERR DMoFEMLoopFiniteElements(subset_dm_domain, "ADJOINT_DOMAIN_FE",
1117 fe_lhs);
1118 CHKERR MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY);
1119 CHKERR MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY);
1120
1121 auto solver = createKSP(mField.get_comm());
1122 CHKERR KSPSetOperators(solver, M, M);
1123 CHKERR KSPSetFromOptions(solver);
1124 CHKERR KSPSetUp(solver);
1125
1126 int mode_counter = 0;
1127 for (auto &f : modeVecs) {
1128 CHKERR mField.getInterface<FieldBlas>()->setField(0, "ADJOINT_FIELD");
1129 CHKERR DMoFEMMeshToLocalVector(subset_dm_bdy, f, INSERT_VALUES,
1130 SCATTER_REVERSE);
1131 CHKERR VecZeroEntries(F);
1132 CHKERR DMoFEMLoopFiniteElements(subset_dm_domain, "ADJOINT_DOMAIN_FE",
1133 fe_rhs);
1134 CHKERR VecAssemblyBegin(F);
1135 CHKERR VecAssemblyEnd(F);
1136 CHKERR VecGhostUpdateBegin(F, ADD_VALUES, SCATTER_REVERSE);
1137 CHKERR VecGhostUpdateEnd(F, ADD_VALUES, SCATTER_REVERSE);
1138 CHKERR KSPSolve(solver, F, v);
1139 CHKERR VecGhostUpdateBegin(v, INSERT_VALUES, SCATTER_FORWARD);
1140 CHKERR VecGhostUpdateEnd(v, INSERT_VALUES, SCATTER_FORWARD);
1141 CHKERR DMoFEMMeshToLocalVector(subset_dm_domain, v, INSERT_VALUES,
1142 SCATTER_REVERSE);
1143 auto m = createDMVector(adjointDM);
1144 CHKERR DMoFEMMeshToLocalVector(adjointDM, m, INSERT_VALUES,
1145 SCATTER_FORWARD);
1146 f = m;
1147 ++mode_counter;
1148 }
1150 };
1151
1152 CHKERR solve_domain();
1153
1154 for (int i = 0; i < modeVecs.size(); ++i) {
1155 CHKERR adjoint_gradient_postprocess(i);
1156 }
1157
1159}
constexpr int SPACE_DIM
[Define dimension]
@ F
const FTensor::Tensor2< T, Dim, Dim > Vec
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
OpBaseImpl< PETSC, EdgeEleOp > OpBase
Definition radiation.cpp:29
std::vector< std::array< double, 3 > > modeCentroids
Centroids of optimization blocks
Definition adjoint.cpp:217
std::vector< std::array< double, 6 > > modeBBoxes
Bounding boxes of optimization blocks.
Definition adjoint.cpp:218
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.

◆ tsSolve() [1/3]

MoFEMErrorCode Example::tsSolve ( )
private
Examples
mofem/tutorials/adv-0/plastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 834 of file plastic.cpp.

834 {
836
839 ISManager *is_manager = mField.getInterface<ISManager>();
840
841 auto snes_ctx_ptr = getDMSnesCtx(simple->getDM());
842
843 auto set_section_monitor = [&](auto solver) {
845 SNES snes;
846 CHKERR TSGetSNES(solver, &snes);
847 CHKERR SNESMonitorSet(snes,
848 (MoFEMErrorCode(*)(SNES, PetscInt, PetscReal,
850 (void *)(snes_ctx_ptr.get()), nullptr);
852 };
853
854 auto create_post_process_elements = [&]() {
855 auto push_vol_ops = [this](auto &pip) {
857 pip, {H1, HDIV}, "GEOMETRY");
858
859 auto [common_plastic_ptr, common_hencky_ptr] =
860 PlasticOps::createCommonPlasticOps<SPACE_DIM, IT, DomainEleOp>(
861 mField, "MAT_PLASTIC", pip, "U", "EP", "TAU", 1., Sev::inform);
862
863 if (common_hencky_ptr) {
864 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
865 CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "Wrong pointer for grad");
866 }
867
868 return std::make_pair(common_plastic_ptr, common_hencky_ptr);
869 };
870
871 auto push_vol_post_proc_ops = [this](auto &pp_fe, auto &&p) {
873
874 auto &pip = pp_fe->getOpPtrVector();
875
876 auto [common_plastic_ptr, common_hencky_ptr] = p;
877
879
880 auto x_ptr = boost::make_shared<MatrixDouble>();
881 pip.push_back(
882 new OpCalculateVectorFieldValues<SPACE_DIM>("GEOMETRY", x_ptr));
883 auto u_ptr = boost::make_shared<MatrixDouble>();
884 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
885
886 if (is_large_strains) {
887
888 pip.push_back(
889
890 new OpPPMap(
891
892 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
893
894 {{"PLASTIC_SURFACE",
895 common_plastic_ptr->getPlasticSurfacePtr()},
896 {"PLASTIC_MULTIPLIER",
897 common_plastic_ptr->getPlasticTauPtr()}},
898
899 {{"U", u_ptr}, {"GEOMETRY", x_ptr}},
900
901 {{"GRAD", common_hencky_ptr->matGradPtr},
902 {"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()}},
903
904 {{"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
905 {"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
906 {"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
907
908 )
909
910 );
911
912 } else {
913
914 pip.push_back(
915
916 new OpPPMap(
917
918 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
919
920 {{"PLASTIC_SURFACE",
921 common_plastic_ptr->getPlasticSurfacePtr()},
922 {"PLASTIC_MULTIPLIER",
923 common_plastic_ptr->getPlasticTauPtr()}},
924
925 {{"U", u_ptr}, {"GEOMETRY", x_ptr}},
926
927 {},
928
929 {{"STRAIN", common_plastic_ptr->mStrainPtr},
930 {"STRESS", common_plastic_ptr->mStressPtr},
931 {"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
932 {"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
933
934 )
935
936 );
937 }
938
940 };
941
942 PetscBool post_proc_vol;
943 PetscBool post_proc_skin;
944
945 if constexpr (SPACE_DIM == 2) {
946 post_proc_vol = PETSC_TRUE;
947 post_proc_skin = PETSC_FALSE;
948 } else {
949 post_proc_vol = PETSC_FALSE;
950 post_proc_skin = PETSC_TRUE;
951 }
952 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-post_proc_vol", &post_proc_vol,
953 PETSC_NULL);
954 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-post_proc_skin",
955 &post_proc_skin, PETSC_NULL);
956
957 auto vol_post_proc = [this, push_vol_post_proc_ops, push_vol_ops,
958 post_proc_vol]() {
959 if (post_proc_vol == PETSC_FALSE)
960 return boost::shared_ptr<PostProcEle>();
961 auto pp_fe = boost::make_shared<PostProcEle>(mField);
963 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
964 "push_vol_post_proc_ops");
965 return pp_fe;
966 };
967
968 auto skin_post_proc = [this, push_vol_post_proc_ops, push_vol_ops,
969 post_proc_skin]() {
970 if (post_proc_skin == PETSC_FALSE)
971 return boost::shared_ptr<SkinPostProcEle>();
972
974 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
975 auto op_side = new OpLoopSide<SideEle>(mField, simple->getDomainFEName(),
976 SPACE_DIM, Sev::verbose);
977 pp_fe->getOpPtrVector().push_back(op_side);
978 CHK_MOAB_THROW(push_vol_post_proc_ops(
979 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
980 "push_vol_post_proc_ops");
981 return pp_fe;
982 };
983
984 return std::make_pair(vol_post_proc(), skin_post_proc());
985 };
986
987 auto scatter_create = [&](auto D, auto coeff) {
989 CHKERR is_manager->isCreateProblemFieldAndRank(simple->getProblemName(),
990 ROW, "U", coeff, coeff, is);
991 int loc_size;
992 CHKERR ISGetLocalSize(is, &loc_size);
993 Vec v;
994 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &v);
995 VecScatter scatter;
996 CHKERR VecScatterCreate(D, is, v, PETSC_NULL, &scatter);
997 return std::make_tuple(SmartPetscObj<Vec>(v),
999 };
1000
1001 boost::shared_ptr<SetPtsData> field_eval_data;
1002 boost::shared_ptr<MatrixDouble> u_field_ptr;
1003
1004 std::array<double, SPACE_DIM> field_eval_coords;
1005 int coords_dim = SPACE_DIM;
1006 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
1007 field_eval_coords.data(), &coords_dim,
1008 &do_eval_field);
1009
1010 boost::shared_ptr<std::map<std::string, boost::shared_ptr<VectorDouble>>>
1011 scalar_field_ptrs = boost::make_shared<
1012 std::map<std::string, boost::shared_ptr<VectorDouble>>>();
1013 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
1014 vector_field_ptrs = boost::make_shared<
1015 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
1016 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
1017 sym_tensor_field_ptrs = boost::make_shared<
1018 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
1019 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
1020 tensor_field_ptrs = boost::make_shared<
1021 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
1022
1023 if (do_eval_field) {
1024 auto u_field_ptr = boost::make_shared<MatrixDouble>();
1025 field_eval_data =
1026 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
1027
1028 CHKERR mField.getInterface<FieldEvaluatorInterface>()->buildTree<SPACE_DIM>(
1029 field_eval_data, simple->getDomainFEName());
1030
1031 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1032 auto no_rule = [](int, int, int) { return -1; };
1033 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
1034 field_eval_fe_ptr->getRuleHook = no_rule;
1035
1037 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV}, "GEOMETRY");
1038
1039 auto [common_plastic_ptr, common_hencky_ptr] =
1040 PlasticOps::createCommonPlasticOps<SPACE_DIM, IT, DomainEleOp>(
1041 mField, "MAT_PLASTIC", field_eval_fe_ptr->getOpPtrVector(), "U",
1042 "EP", "TAU", 1., Sev::inform);
1043
1044 field_eval_fe_ptr->getOpPtrVector().push_back(
1045 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_field_ptr));
1046
1047 if ((common_plastic_ptr) && (common_hencky_ptr) && (scalar_field_ptrs)) {
1048 if (is_large_strains) {
1049 scalar_field_ptrs->insert(
1050 {"PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()});
1051 scalar_field_ptrs->insert(
1052 {"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()});
1053 vector_field_ptrs->insert({"U", u_field_ptr});
1054 sym_tensor_field_ptrs->insert(
1055 {"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()});
1056 sym_tensor_field_ptrs->insert(
1057 {"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()});
1058 sym_tensor_field_ptrs->insert(
1059 {"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()});
1060 tensor_field_ptrs->insert({"GRAD", common_hencky_ptr->matGradPtr});
1061 tensor_field_ptrs->insert(
1062 {"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()});
1063 } else {
1064 scalar_field_ptrs->insert(
1065 {"PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()});
1066 scalar_field_ptrs->insert(
1067 {"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()});
1068 vector_field_ptrs->insert({"U", u_field_ptr});
1069 sym_tensor_field_ptrs->insert(
1070 {"STRAIN", common_plastic_ptr->mStrainPtr});
1071 sym_tensor_field_ptrs->insert(
1072 {"STRESS", common_plastic_ptr->mStressPtr});
1073 sym_tensor_field_ptrs->insert(
1074 {"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()});
1075 sym_tensor_field_ptrs->insert(
1076 {"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()});
1077 }
1078 }
1079 }
1080
1081 auto test_monitor_ptr = boost::make_shared<FEMethod>();
1082
1083 auto set_time_monitor = [&](auto dm, auto solver) {
1085 boost::shared_ptr<Monitor<SPACE_DIM>> monitor_ptr(new Monitor<SPACE_DIM>(
1086 dm, create_post_process_elements(), reactionFe, uXScatter, uYScatter,
1087 uZScatter, field_eval_coords, field_eval_data, scalar_field_ptrs,
1088 vector_field_ptrs, sym_tensor_field_ptrs, tensor_field_ptrs));
1089 boost::shared_ptr<ForcesAndSourcesCore> null;
1090
1091 test_monitor_ptr->postProcessHook = [&]() {
1093
1094 if (atom_test && fabs(test_monitor_ptr->ts_t - 0.5) < 1e-12 &&
1095 test_monitor_ptr->ts_step == 25) {
1096
1097 if (scalar_field_ptrs->at("PLASTIC_MULTIPLIER")->size()) {
1098 auto t_tau =
1099 getFTensor0FromVec(*scalar_field_ptrs->at("PLASTIC_MULTIPLIER"));
1100 MOFEM_LOG("PlasticSync", Sev::inform) << "Eval point tau: " << t_tau;
1101
1102 if (atom_test == 1 && fabs(t_tau - 0.688861) > 1e-5) {
1103 SETERRQ1(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1104 "atom test %d failed: wrong plastic multiplier value",
1105 atom_test);
1106 }
1107 }
1108
1109 if (vector_field_ptrs->at("U")->size1()) {
1111 auto t_disp =
1112 getFTensor1FromMat<SPACE_DIM>(*vector_field_ptrs->at("U"));
1113 MOFEM_LOG("PlasticSync", Sev::inform) << "Eval point U: " << t_disp;
1114
1115 if (atom_test == 1 && fabs(t_disp(0) - 0.25 / 2.) > 1e-5 ||
1116 fabs(t_disp(1) + 0.0526736) > 1e-5) {
1117 SETERRQ1(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1118 "atom test %d failed: wrong displacement value",
1119 atom_test);
1120 }
1121 }
1122
1123 if (sym_tensor_field_ptrs->at("PLASTIC_STRAIN")->size1()) {
1124 auto t_plastic_strain = getFTensor2SymmetricFromMat<SPACE_DIM>(
1125 *sym_tensor_field_ptrs->at("PLASTIC_STRAIN"));
1126 MOFEM_LOG("PlasticSync", Sev::inform)
1127 << "Eval point EP: " << t_plastic_strain;
1128
1129 if (atom_test == 1 &&
1130 fabs(t_plastic_strain(0, 0) - 0.221943) > 1e-5 ||
1131 fabs(t_plastic_strain(0, 1)) > 1e-5 ||
1132 fabs(t_plastic_strain(1, 1) + 0.110971) > 1e-5) {
1133 SETERRQ1(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1134 "atom test %d failed: wrong plastic strain value",
1135 atom_test);
1136 }
1137 }
1138
1139 if (tensor_field_ptrs->at("FIRST_PIOLA")->size1()) {
1140 auto t_piola_stress = getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(
1141 *tensor_field_ptrs->at("FIRST_PIOLA"));
1142 MOFEM_LOG("PlasticSync", Sev::inform)
1143 << "Eval point Piola stress: " << t_piola_stress;
1144
1145 if (atom_test == 1 && fabs((t_piola_stress(0, 0) - 198.775) /
1146 t_piola_stress(0, 0)) > 1e-5 ||
1147 fabs(t_piola_stress(0, 1)) + fabs(t_piola_stress(1, 0)) +
1148 fabs(t_piola_stress(1, 1)) >
1149 1e-5) {
1150 SETERRQ1(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1151 "atom test %d failed: wrong Piola stress value",
1152 atom_test);
1153 }
1154 }
1155 }
1156
1159 };
1160
1161 CHKERR DMMoFEMTSSetMonitor(dm, solver, simple->getDomainFEName(),
1162 monitor_ptr, null, test_monitor_ptr);
1163
1165 };
1166
1167 auto set_schur_pc = [&](auto solver,
1168 boost::shared_ptr<SetUpSchur> &schur_ptr) {
1170
1171 auto name_prb = simple->getProblemName();
1172
1173 // create sub dm for Schur complement
1174 auto create_schur_dm = [&](SmartPetscObj<DM> base_dm,
1175 SmartPetscObj<DM> &dm_sub) {
1177 dm_sub = createDM(mField.get_comm(), "DMMOFEM");
1178 CHKERR DMMoFEMCreateSubDM(dm_sub, base_dm, "SCHUR");
1179 CHKERR DMMoFEMSetSquareProblem(dm_sub, PETSC_TRUE);
1180 CHKERR DMMoFEMAddElement(dm_sub, simple->getDomainFEName());
1181 CHKERR DMMoFEMAddElement(dm_sub, simple->getBoundaryFEName());
1182 for (auto f : {"U"}) {
1185 }
1186 CHKERR DMSetUp(dm_sub);
1187
1189 };
1190
1191 auto create_block_dm = [&](SmartPetscObj<DM> base_dm,
1192 SmartPetscObj<DM> &dm_sub) {
1194 dm_sub = createDM(mField.get_comm(), "DMMOFEM");
1195 CHKERR DMMoFEMCreateSubDM(dm_sub, base_dm, "BLOCK");
1196 CHKERR DMMoFEMSetSquareProblem(dm_sub, PETSC_TRUE);
1197 CHKERR DMMoFEMAddElement(dm_sub, simple->getDomainFEName());
1198 CHKERR DMMoFEMAddElement(dm_sub, simple->getBoundaryFEName());
1199#ifdef ADD_CONTACT
1200 for (auto f : {"SIGMA", "EP", "TAU"}) {
1203 }
1204#else
1205 for (auto f : {"EP", "TAU"}) {
1208 }
1209#endif
1210 CHKERR DMSetUp(dm_sub);
1212 };
1213
1214 // Create nested (sub BC) Schur DM
1215 if constexpr (AT == AssemblyType::BLOCK_SCHUR) {
1216
1217 SmartPetscObj<DM> dm_schur;
1218 CHKERR create_schur_dm(simple->getDM(), dm_schur);
1219 SmartPetscObj<DM> dm_block;
1220 CHKERR create_block_dm(simple->getDM(), dm_block);
1221
1222#ifdef ADD_CONTACT
1223
1224 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
1225 auto block_mat_data = createBlockMatStructure(
1226 simple->getDM(),
1227
1228 {
1229
1230 {simple->getDomainFEName(),
1231
1232 {{"U", "U"},
1233 {"SIGMA", "SIGMA"},
1234 {"U", "SIGMA"},
1235 {"SIGMA", "U"},
1236 {"EP", "EP"},
1237 {"TAU", "TAU"},
1238 {"U", "EP"},
1239 {"EP", "U"},
1240 {"EP", "TAU"},
1241 {"TAU", "EP"},
1242 {"TAU", "U"}
1243
1244 }},
1245
1246 {simple->getBoundaryFEName(),
1247
1248 {{"SIGMA", "SIGMA"}, {"U", "SIGMA"}, {"SIGMA", "U"}
1249
1250 }}
1251
1252 }
1253
1254 );
1255
1257
1258 {dm_schur, dm_block}, block_mat_data,
1259
1260 {"SIGMA", "EP", "TAU"}, {nullptr, nullptr, nullptr}, true
1261
1262 );
1263 };
1264
1265#else
1266
1267 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
1268 auto block_mat_data =
1270
1271 {{simple->getDomainFEName(),
1272
1273 {{"U", "U"},
1274 {"EP", "EP"},
1275 {"TAU", "TAU"},
1276 {"U", "EP"},
1277 {"EP", "U"},
1278 {"EP", "TAU"},
1279 {"TAU", "U"},
1280 {"TAU", "EP"}
1281
1282 }}}
1283
1284 );
1285
1287
1288 {dm_schur, dm_block}, block_mat_data,
1289
1290 {"EP", "TAU"}, {nullptr, nullptr}, false
1291
1292 );
1293 };
1294
1295#endif
1296
1297 auto nested_mat_data = get_nested_mat_data(dm_schur, dm_block);
1298 CHKERR DMMoFEMSetNestSchurData(simple->getDM(), nested_mat_data);
1299
1300 auto block_is = getDMSubData(dm_block)->getSmartRowIs();
1301 auto ao_schur = getDMSubData(dm_schur)->getSmartRowMap();
1302
1303 // Indices has to be map fro very to level, while assembling Schur
1304 // complement.
1305 schur_ptr =
1306 SetUpSchur::createSetUpSchur(mField, dm_schur, block_is, ao_schur);
1307 CHKERR schur_ptr->setUp(solver);
1308 }
1309
1311 };
1312
1313 auto dm = simple->getDM();
1314 auto D = createDMVector(dm);
1315 auto DD = vectorDuplicate(D);
1316 uXScatter = scatter_create(D, 0);
1317 uYScatter = scatter_create(D, 1);
1318 if constexpr (SPACE_DIM == 3)
1319 uZScatter = scatter_create(D, 2);
1320
1321 auto create_solver = [pip_mng]() {
1322 if (is_quasi_static == PETSC_TRUE)
1323 return pip_mng->createTSIM();
1324 else
1325 return pip_mng->createTSIM2();
1326 };
1327
1328 auto solver = create_solver();
1329
1330 auto active_pre_lhs = []() {
1332 std::fill(PlasticOps::CommonData::activityData.begin(),
1335 };
1336
1337 auto active_post_lhs = [&]() {
1339 auto get_iter = [&]() {
1340 SNES snes;
1341 CHK_THROW_MESSAGE(TSGetSNES(solver, &snes), "Can not get SNES");
1342 int iter;
1343 CHK_THROW_MESSAGE(SNESGetIterationNumber(snes, &iter),
1344 "Can not get iter");
1345 return iter;
1346 };
1347
1348 auto iter = get_iter();
1349 if (iter >= 0) {
1350
1351 std::array<int, 5> activity_data;
1352 std::fill(activity_data.begin(), activity_data.end(), 0);
1353 MPI_Allreduce(PlasticOps::CommonData::activityData.data(),
1354 activity_data.data(), activity_data.size(), MPI_INT,
1355 MPI_SUM, mField.get_comm());
1356
1357 int &active_points = activity_data[0];
1358 int &avtive_full_elems = activity_data[1];
1359 int &avtive_elems = activity_data[2];
1360 int &nb_points = activity_data[3];
1361 int &nb_elements = activity_data[4];
1362
1363 if (nb_points) {
1364
1365 double proc_nb_points =
1366 100 * static_cast<double>(active_points) / nb_points;
1367 double proc_nb_active =
1368 100 * static_cast<double>(avtive_elems) / nb_elements;
1369 double proc_nb_full_active = 100;
1370 if (avtive_elems)
1371 proc_nb_full_active =
1372 100 * static_cast<double>(avtive_full_elems) / avtive_elems;
1373
1374 MOFEM_LOG_C("PLASTICITY", Sev::inform,
1375 "Iter %d nb pts %d nb active pts %d (%3.3f\%) nb active "
1376 "elements %d "
1377 "(%3.3f\%) nb full active elems %d (%3.3f\%)",
1378 iter, nb_points, active_points, proc_nb_points,
1379 avtive_elems, proc_nb_active, avtive_full_elems,
1380 proc_nb_full_active, iter);
1381 }
1382 }
1383
1385 };
1386
1387 auto add_active_dofs_elem = [&](auto dm) {
1389 auto fe_pre_proc = boost::make_shared<FEMethod>();
1390 fe_pre_proc->preProcessHook = active_pre_lhs;
1391 auto fe_post_proc = boost::make_shared<FEMethod>();
1392 fe_post_proc->postProcessHook = active_post_lhs;
1393 auto ts_ctx_ptr = getDMTsCtx(dm);
1394 ts_ctx_ptr->getPreProcessIJacobian().push_front(fe_pre_proc);
1395 ts_ctx_ptr->getPostProcessIJacobian().push_back(fe_post_proc);
1397 };
1398
1399 auto set_essential_bc = [&](auto dm, auto solver) {
1401 // This is low level pushing finite elements (pipelines) to solver
1402
1403 auto pre_proc_ptr = boost::make_shared<FEMethod>();
1404 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
1405 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
1406
1407 // Add boundary condition scaling
1408 auto disp_time_scale = boost::make_shared<TimeScale>();
1409
1410 auto get_bc_hook_rhs = [this, pre_proc_ptr, disp_time_scale]() {
1412 {disp_time_scale}, false);
1413 return hook;
1414 };
1415 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
1416
1417 auto get_post_proc_hook_rhs = [this, post_proc_rhs_ptr]() {
1420 mField, post_proc_rhs_ptr, nullptr, Sev::verbose)();
1422 mField, post_proc_rhs_ptr, 1.)();
1424 };
1425 auto get_post_proc_hook_lhs = [this, post_proc_lhs_ptr]() {
1427 mField, post_proc_lhs_ptr, 1.);
1428 };
1429 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
1430
1431 auto ts_ctx_ptr = getDMTsCtx(dm);
1432 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
1433 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
1434 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
1435 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
1436 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
1437
1439 };
1440
1441 if (is_quasi_static == PETSC_TRUE) {
1442 CHKERR TSSetSolution(solver, D);
1443 } else {
1444 CHKERR TS2SetSolution(solver, D, DD);
1445 }
1446
1447 CHKERR set_section_monitor(solver);
1448 CHKERR set_time_monitor(dm, solver);
1449 CHKERR TSSetFromOptions(solver);
1450 CHKERR TSSetUp(solver);
1451
1452 CHKERR add_active_dofs_elem(dm);
1453 boost::shared_ptr<SetUpSchur> schur_ptr;
1454 CHKERR set_schur_pc(solver, schur_ptr);
1455 CHKERR set_essential_bc(dm, solver);
1456
1457 MOFEM_LOG_CHANNEL("TIMER");
1458 MOFEM_LOG_TAG("TIMER", "timer");
1459 if (set_timer)
1460 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
1461 MOFEM_LOG("TIMER", Sev::verbose) << "TSSetUp";
1462 CHKERR TSSetUp(solver);
1463 MOFEM_LOG("TIMER", Sev::verbose) << "TSSetUp <= done";
1464 MOFEM_LOG("TIMER", Sev::verbose) << "TSSolve";
1465 CHKERR TSSolve(solver, NULL);
1466 MOFEM_LOG("TIMER", Sev::verbose) << "TSSolve <= done";
1467
1469}
1470//! [Solve]
1471
1472//! [TestOperators]
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1276
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *ctx)
Sens monitor printing residual field by field.
Definition SnesCtx.cpp:596
auto getDMSubData(DM dm)
Get sub problem data structure.
Definition DMMoFEM.hpp:1292
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create a Mat Diag Blocks object.
Definition Schur.cpp:1082
boost::shared_ptr< NestSchurData > createSchurNestedMatrixStruture(std::pair< SmartPetscObj< DM >, SmartPetscObj< DM > > dms, boost::shared_ptr< BlockStructure > block_mat_data_ptr, std::vector< std::string > fields_names, std::vector< boost::shared_ptr< Range > > field_ents, bool add_preconditioner_block)
Get the Schur Nest Mat Array object.
Definition Schur.cpp:2343
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition DMMoFEM.cpp:1554
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
Definition DMMoFEM.hpp:1262
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
Definition plastic.cpp:238
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
Definition plastic.cpp:239
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
Definition plastic.cpp:237
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
static std::array< int, 5 > activityData
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)

◆ tsSolve() [2/3]

MoFEMErrorCode Example::tsSolve ( )
private

◆ tsSolve() [3/3]

MoFEMErrorCode Example::tsSolve ( )
private

Friends And Related Symbol Documentation

◆ TSPrePostProc

TSPrePostProc
friend

Definition at line 434 of file dynamic_first_order_con_law.cpp.

Member Data Documentation

◆ adjointDM

SmartPetscObj<DM> Example::adjointDM
private

Data manager for adjoint problem.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 212 of file adjoint.cpp.

◆ approxFunction

ApproxFieldFunction< FIELD_DIM > Example::approxFunction
staticprivate

◆ approxGradVals

boost::shared_ptr<MatrixDouble> Example::approxGradVals
private
Examples
mofem/tutorials/scl-8/radiation.cpp.

Definition at line 63 of file radiation.cpp.

◆ approxVals

boost::shared_ptr<VectorDouble> Example::approxVals
private
Examples
mofem/tutorials/scl-8/radiation.cpp.

Definition at line 62 of file radiation.cpp.

◆ aveMaxMin

std::array< double, Example::BoundingBox::LAST_BB > Example::aveMaxMin
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 110 of file phase.cpp.

◆ base

FieldApproximationBase Example::base
private

◆ boundaryMarker

boost::shared_ptr< std::vector< unsigned char > > Example::boundaryMarker
private

◆ commonDataPtr

boost::shared_ptr< CommonData > Example::commonDataPtr
private

◆ dispFieldPtr

boost::shared_ptr<MatrixDouble> Example::dispFieldPtr
private
Initial value:
=
boost::make_shared<MatrixDouble>()
Examples
thermoplastic.cpp.

Definition at line 872 of file thermoplastic.cpp.

◆ dispGradPtr

boost::shared_ptr<MatrixDouble> Example::dispGradPtr
private
Initial value:
=
boost::make_shared<MatrixDouble>()
Examples
thermoplastic.cpp.

Definition at line 874 of file thermoplastic.cpp.

◆ domianLhsFEPtr

boost::shared_ptr<FEMethod> Example::domianLhsFEPtr
private
Examples
mofem/tutorials/vec-4/shallow_wave.cpp.

Definition at line 355 of file shallow_wave.cpp.

◆ domianRhsFEPtr

boost::shared_ptr<FEMethod> Example::domianRhsFEPtr
private
Examples
mofem/tutorials/vec-4/shallow_wave.cpp.

Definition at line 356 of file shallow_wave.cpp.

◆ ePS

SmartPetscObj<EPS> Example::ePS
private
Examples
mofem/tutorials/vec-1/eigen_elastic.cpp.

Definition at line 69 of file eigen_elastic.cpp.

◆ fieldOrder

int Example::fieldOrder = 2
private

Polynomial order for approximation.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 208 of file adjoint.cpp.

◆ fluxFieldPtr

boost::shared_ptr<MatrixDouble> Example::fluxFieldPtr
private
Initial value:
=
boost::make_shared<MatrixDouble>()
Examples
thermoplastic.cpp.

Definition at line 870 of file thermoplastic.cpp.

◆ focalIndex

int Example::focalIndex
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 112 of file phase.cpp.

◆ iI

std::vector< MatrixInt > Example::iI
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 109 of file phase.cpp.

◆ initialGeometry

SmartPetscObj<Vec> Example::initialGeometry
private

Initial geometry field.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 219 of file adjoint.cpp.

◆ K

SmartPetscObj<Mat> Example::K
private
Examples
mofem/tutorials/vec-1/eigen_elastic.cpp.

Definition at line 68 of file eigen_elastic.cpp.

◆ kspElastic

SmartPetscObj<KSP> Example::kspElastic
private

Linear solver for elastic problem.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 211 of file adjoint.cpp.

◆ M

SmartPetscObj<Mat> Example::M
private

◆ matDPtr

boost::shared_ptr<MatrixDouble> Example::matDPtr
private
Examples
mofem/tutorials/vec-1/eigen_elastic.cpp.

Definition at line 65 of file eigen_elastic.cpp.

◆ meshVolumeAndCount

static std::array< double, 2 > Example::meshVolumeAndCount = {0, 0}
inlinestatic
Examples
mofem/tutorials/adv-0/plastic.cpp, and plastic.cpp.

Definition at line 223 of file plastic.cpp.

223{0, 0};

◆ mField

MoFEM::Interface & Example::mField
private

◆ modeBBoxes

std::vector<std::array<double, 6> > Example::modeBBoxes
private

Bounding boxes of optimization blocks.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 218 of file adjoint.cpp.

◆ modeCentroids

std::vector<std::array<double, 3> > Example::modeCentroids
private

Centroids of optimization blocks

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 217 of file adjoint.cpp.

◆ modeVecs

std::vector<SmartPetscObj<Vec> > Example::modeVecs
private

Topology mode vectors (design variables)

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 216 of file adjoint.cpp.

◆ pinchNodes

Range Example::pinchNodes
private
Examples
mofem/tutorials/scl-9/heat_method.cpp.

Definition at line 55 of file heat_method.cpp.

◆ plasticMultiplierFieldPtr

boost::shared_ptr<VectorDouble> Example::plasticMultiplierFieldPtr
private
Initial value:
=
boost::make_shared<VectorDouble>()
Examples
thermoplastic.cpp.

Definition at line 880 of file thermoplastic.cpp.

◆ plasticStrainFieldPtr

boost::shared_ptr<MatrixDouble> Example::plasticStrainFieldPtr
private
Initial value:
=
boost::make_shared<MatrixDouble>()
Examples
thermoplastic.cpp.

Definition at line 882 of file thermoplastic.cpp.

◆ pythonPtr

boost::shared_ptr<ObjectiveFunctionData> Example::pythonPtr
private

Interface to Python objective function.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 213 of file adjoint.cpp.

◆ reactionFe

boost::shared_ptr< DomainEle > Example::reactionFe
private

◆ rigidBodyMotion

std::array<SmartPetscObj<Vec>, 6> Example::rigidBodyMotion
private
Examples
mofem/tutorials/vec-1/eigen_elastic.cpp.

Definition at line 71 of file eigen_elastic.cpp.

◆ rZ

std::vector< double > Example::rZ
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 108 of file phase.cpp.

◆ savitzkyGolayNormalisation

int Example::savitzkyGolayNormalisation
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 113 of file phase.cpp.

◆ savitzkyGolayWeights

const int * Example::savitzkyGolayWeights
staticprivate
Examples
mofem/tutorials/mix-1/phase.cpp.

Definition at line 114 of file phase.cpp.

◆ simpleInterface

Simple * Example::simpleInterface
private

◆ space

FieldSpace Example::space
private
Examples
mofem/tutorials/fun-2/plot_base.cpp.

Definition at line 69 of file plot_base.cpp.

◆ strainFieldPtr

boost::shared_ptr<MatrixDouble> Example::strainFieldPtr
private
Initial value:
=
boost::make_shared<MatrixDouble>()
Examples
thermoplastic.cpp.

Definition at line 876 of file thermoplastic.cpp.

◆ stressFieldPtr

boost::shared_ptr<MatrixDouble> Example::stressFieldPtr
private
Initial value:
=
boost::make_shared<MatrixDouble>()
Examples
thermoplastic.cpp.

Definition at line 878 of file thermoplastic.cpp.

◆ tempFieldPtr

boost::shared_ptr<VectorDouble> Example::tempFieldPtr
private
Initial value:
=
boost::make_shared<VectorDouble>()
Examples
thermoplastic.cpp.

Definition at line 868 of file thermoplastic.cpp.

◆ uXScatter

std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > Example::uXScatter
private

◆ uYScatter

std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > Example::uYScatter
private

◆ uZScatter

std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > Example::uZScatter
private

◆ vectorFieldPtr

boost::shared_ptr< MatrixDouble > Example::vectorFieldPtr = nullptr
private

Field values at evaluation points.

Examples
mofem/tutorials/vec-7/adjoint.cpp.

Definition at line 187 of file adjoint.cpp.


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