v0.16.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 >
 [OpError def] More...
 
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 ()
 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.
 
MoFEMErrorCode readMesh ()
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode setupAdJoint ()
 
MoFEMErrorCode boundaryCondition ()
 
MoFEMErrorCode assembleSystem ()
 
MoFEMErrorCode solveElastic ()
 Solve forward elastic problem.
 
MoFEMErrorCode postprocessElastic (int iter, SmartPetscObj< Vec > gradient_vector=nullptr, SmartPetscObj< Vec > adjoint_vector=nullptr, SmartPetscObj< Vec > dJ_du=nullptr)
 Post-process and output results.
 
MoFEMErrorCode calculateGradient (PetscReal *objective_function_value, Vec objective_function_gradient, Vec adjoint_vector, Vec dJ_du)
 Calculate objective function gradient using adjoint method.
 
MoFEMErrorCode testGradient (Vec gradient_vector)
 [calculateGradient]
 
friend PetscErrorCode::MyTSResizeTransfer (TS, PetscInt, Vec[], Vec[], void *)
 
MoFEMErrorCode setupProblem ()
 
MoFEMErrorCode createCommonData ()
 
MoFEMErrorCode initialConditions ()
 [Create common data]
 
MoFEMErrorCode mechanicalBC (BitRefLevel bit, BitRefLevel mask)
 [Initial conditions]
 
MoFEMErrorCode thermalBC (BitRefLevel bit, BitRefLevel mask)
 [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.
 
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
 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< DomainElereactionFe
 
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]

[Create Example_struct]

Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp, mofem/tutorials/adv-4_dynamic_first_order_con_law/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6_dg_projection/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-1_integration/integration.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/mix-1_light_intensity_equation/phase.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-8_heat_radiation/radiation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp, nonlinear_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 217 of file plastic.cpp.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
VOL 
COUNT 

Definition at line 223 of file plastic.cpp.

223{ 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_light_intensity_equation/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/19]

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

Definition at line 219 of file plastic.cpp.

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

◆ Example() [2/19]

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

Definition at line 417 of file dynamic_first_order_con_law.cpp.

417: mField(m_field) {}

◆ Example() [3/19]

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

Definition at line 42 of file between_meshes_dg_projection.cpp.

42: mField(m_field) {}

◆ Example() [4/19]

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

Definition at line 35 of file helmholtz.cpp.

35: mField(m_field) {}

◆ Example() [5/19]

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

Definition at line 25 of file integration.cpp.

25: mField(m_field) {}

◆ Example() [6/19]

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

Definition at line 50 of file plot_base.cpp.

50: mField(m_field) {}

◆ Example() [7/19]

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

Definition at line 81 of file phase.cpp.

81: mField(m_field) {}

◆ Example() [8/19]

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

Definition at line 51 of file approximation.cpp.

51: mField(m_field) {}

◆ Example() [9/19]

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

Definition at line 45 of file radiation.cpp.

45: mField(m_field) {}

◆ Example() [10/19]

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

Definition at line 47 of file heat_method.cpp.

47: mField(m_field) {}

◆ Example() [11/19]

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

Definition at line 54 of file eigen_elastic.cpp.

54: mField(m_field) {}

◆ Example() [12/19]

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

Definition at line 52 of file nonlinear_dynamic_elastic.cpp.

52: mField(m_field) {}

◆ Example() [13/19]

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

Definition at line 339 of file shallow_wave.cpp.

339: mField(m_field) {}

◆ Example() [14/19]

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

Definition at line 129 of file adjoint.cpp.

129: mField(m_field) {}

◆ Example() [15/19]

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

Definition at line 116 of file gradient.cpp.

116: mField(m_field) {}

◆ Example() [16/19]

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

Definition at line 896 of file thermoplastic.cpp.

896: mField(m_field) {}

◆ Example() [17/19]

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

Definition at line 218 of file plastic.cpp.

218: mField(m_field) {}

◆ Example() [18/19]

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

Definition at line 80 of file elastic.cpp.

80: mField(m_field) {}

◆ Example() [19/19]

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

Definition at line 58 of file nonlinear_elastic.cpp.

58: mField(m_field) {}

Member Function Documentation

◆ assembleSystem() [1/13]

MoFEMErrorCode Example::assembleSystem ( )
private

[Push operators to pipeline]

[Adjoint modes]

[Boundary condition]

[Applying essential BC]

[Set up problem]

[Push operators to pipeline]

[Assemble system]

[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/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6_dg_projection/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp, and nonlinear_elastic.cpp.

Definition at line 635 of file dynamic_first_order_con_law.cpp.

635 {
637 [[maybe_unused]] auto get_body_force = [this](const double, const double,
638 const double) {
641 t_source(i) = 0.;
642 t_source(0) = 0.1;
643 t_source(1) = 1.;
644 return t_source;
645 };
646
647 // specific time scaling
648 [[maybe_unused]] auto get_time_scale = [this](const double time) {
649 return sin(time * omega * M_PI);
650 };
651
652 auto apply_rhs = [&](auto &pip) {
654
656 "GEOMETRY");
657
658 // Calculate Gradient of velocity
659 auto mat_v_grad_ptr = boost::make_shared<MatrixDouble>();
661 "V", mat_v_grad_ptr));
662
663 auto gravity_vector_ptr = boost::make_shared<MatrixDouble>();
664 gravity_vector_ptr->resize(1, SPACE_DIM);
665 auto set_body_force = [&]() {
668 auto t_force = getFTensor1FromMat<SPACE_DIM, 0>(*gravity_vector_ptr);
669 double unit_weight = 0.;
670 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-unit_weight", &unit_weight,
671 PETSC_NULLPTR);
672 t_force(i) = 0;
673 if (SPACE_DIM == 2) {
674 t_force(1) = -unit_weight;
675 } else if (SPACE_DIM == 3) {
676 t_force(2) = unit_weight;
677 }
679 };
680
681 CHKERR set_body_force();
682 pip.push_back(new OpBodyForce("V", gravity_vector_ptr,
683 [](double, double, double) { return 1.; }));
684
685 // Calculate unknown F
686 auto mat_H_tensor_ptr = boost::make_shared<MatrixDouble>();
688 "F", mat_H_tensor_ptr));
689
690 // // Calculate F
691 double tau = 0.2;
692 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-tau", &tau, PETSC_NULLPTR);
693
694 double xi = 0.;
695 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-xi", &xi, PETSC_NULLPTR);
696
697 // Calculate P stab
698 auto one = [&](const double, const double, const double) {
699 return 3. * bulk_modulus_K;
700 };
701 auto minus_one = [](const double, const double, const double) {
702 return -1.;
703 };
704
705 auto mat_dot_F_tensor_ptr = boost::make_shared<MatrixDouble>();
707 "F_dot", mat_dot_F_tensor_ptr));
708
709 // Calculate Gradient of Spatial Positions
710 auto mat_x_grad_ptr = boost::make_shared<MatrixDouble>();
712 "x_2", mat_x_grad_ptr));
713
714 auto mat_F_tensor_ptr = boost::make_shared<MatrixDouble>();
716 mat_F_tensor_ptr, mat_H_tensor_ptr));
717
718 auto mat_F_stab_ptr = boost::make_shared<MatrixDouble>();
720 mat_F_tensor_ptr, mat_F_stab_ptr, mat_dot_F_tensor_ptr, tau, xi,
721 mat_x_grad_ptr, mat_v_grad_ptr));
722
723 PetscBool is_linear_elasticity = PETSC_TRUE;
724 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-is_linear_elasticity",
725 &is_linear_elasticity, PETSC_NULLPTR);
726
727 auto mat_P_stab_ptr = boost::make_shared<MatrixDouble>();
728 if (is_linear_elasticity) {
731 mat_F_stab_ptr));
732 } else {
733 auto inv_F = boost::make_shared<MatrixDouble>();
734 auto det_ptr = boost::make_shared<VectorDouble>();
735
736 pip.push_back(
737 new OpInvertMatrix<SPACE_DIM>(mat_F_stab_ptr, det_ptr, inv_F));
738
739 // OpCalculatePiolaIncompressibleNH
742 mat_F_stab_ptr, inv_F, det_ptr));
743 }
744
745 pip.push_back(new OpGradTimesTensor2("V", mat_P_stab_ptr, minus_one));
746 pip.push_back(new OpRhsTestPiola("F", mat_v_grad_ptr, one));
747
749 };
750
751 auto *pipeline_mng = mField.getInterface<PipelineManager>();
752 CHKERR apply_rhs(pipeline_mng->getOpDomainExplicitRhsPipeline());
753
754 auto integration_rule = [](int, int, int approx_order) {
755 return 2 * approx_order;
756 };
757 CHKERR pipeline_mng->setDomainExplicitRhsIntegrationRule(integration_rule);
758
760}
@ 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.
constexpr double omega
Save field DOFS on vertices/tags.
double bulk_modulus_K
FormsIntegrators< DomainEleOp >::Assembly< AssemblyType::PETSC >::LinearForm< IntegrationType::GAUSS >::OpBaseTimesVector< 1, SPACE_DIM *SPACE_DIM, SPACE_DIM *SPACE_DIM > OpRhsTestPiola
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/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [3/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [4/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [5/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [6/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [7/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [8/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [9/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [10/13]

MoFEMErrorCode Example::assembleSystem ( )
private

Setup operators in finite element pipeline.

◆ assembleSystem() [11/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [12/13]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [13/13]

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_light_intensity_equation/phase.cpp.

Definition at line 434 of file phase.cpp.

434 {
436
437 auto *pipeline_mng = mField.getInterface<PipelineManager>();
438
439 pipeline_mng->getDomainLhsFE().reset();
440 pipeline_mng->getDomainRhsFE().reset();
441 pipeline_mng->getBoundaryRhsFE().reset();
442
443 auto rule_vol = [](int, int, int order) { return 2 * (order + 1); };
444 pipeline_mng->setDomainLhsIntegrationRule(rule_vol);
445 pipeline_mng->setDomainRhsIntegrationRule(rule_vol);
446
447 CHKERR AddHOOps<2, 2, 2>::add(pipeline_mng->getOpDomainLhsPipeline(), {HDIV, L2});
448 CHKERR AddHOOps<2, 2, 2>::add(pipeline_mng->getOpDomainRhsPipeline(), {HDIV, L2});
449
450 pipeline_mng->getOpDomainLhsPipeline().push_back(
451 new OpHdivHdiv("S", "S", lhsFlux));
452 auto unity = []() { return 1; };
453 pipeline_mng->getOpDomainLhsPipeline().push_back(
454 new OpHdivU("S", "PHI", unity, true));
455 pipeline_mng->getOpDomainRhsPipeline().push_back(
456 new OpDomainSource("PHI", rhsSource));
457
459}
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, FIELD_DIM > OpDomainSource
constexpr int order
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< 2 > OpHdivU
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
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_plasticity/plastic.cpp, mofem/tutorials/scl-8_heat_radiation/radiation.cpp, and plastic.cpp.

Definition at line 605 of file plastic.cpp.

605 {
607
609 auto bc_mng = mField.getInterface<BcManager>();
610
611 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
612 "U", 0, 0);
613 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
614 "U", 1, 1);
615 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
616 "U", 2, 2);
617 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
618 "REMOVE_ALL", "U", 0, 3);
619
620#ifdef ADD_CONTACT
621 for (auto b : {"FIX_X", "REMOVE_X"})
622 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
623 "SIGMA", 0, 0, false, true);
624 for (auto b : {"FIX_Y", "REMOVE_Y"})
625 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
626 "SIGMA", 1, 1, false, true);
627 for (auto b : {"FIX_Z", "REMOVE_Z"})
628 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
629 "SIGMA", 2, 2, false, true);
630 for (auto b : {"FIX_ALL", "REMOVE_ALL"})
631 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
632 "SIGMA", 0, 3, false, true);
633 CHKERR bc_mng->removeBlockDOFsOnEntities(
634 simple->getProblemName(), "NO_CONTACT", "SIGMA", 0, 3, false, true);
635#endif
636
637 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
638 simple->getProblemName(), "U");
639
640 auto &bc_map = bc_mng->getBcMapByBlockName();
641 for (auto bc : bc_map)
642 MOFEM_LOG("PLASTICITY", Sev::verbose) << "Marker " << bc.first;
643
645}
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/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

[Set up problem]

[Setup adjoint]

[Create common data]

[Boundary condition]

[Applying essential BC]

[Define gravity vector]

Examples
mofem/tutorials/adv-4_dynamic_first_order_con_law/dynamic_first_order_con_law.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp, and nonlinear_elastic.cpp.

Definition at line 532 of file dynamic_first_order_con_law.cpp.

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

◆ boundaryCondition() [2/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [3/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [4/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [5/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [6/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [7/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [8/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [9/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

Apply essential boundary conditions.

◆ boundaryCondition() [10/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [11/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [12/12]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ calculateFlux()

MoFEMErrorCode Example::calculateFlux ( double calc_flux)
private

[Set up problem]

[Calculate flux on boundary]

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

Definition at line 402 of file phase.cpp.

402 {
404 auto pipeline_mng = mField.getInterface<PipelineManager>();
405
406 auto rule = [](int, int, int order) { return 2 * (order + 1); };
407 CHKERR pipeline_mng->setEvaluationIntegrationRule(rule);
408
409 auto op_loop_boundary = new OpLoopSide<EdgeEle>(
410 mField, simpleInterface->getBoundaryFEName(), 1, Sev::verbose);
411 op_loop_boundary->getSideFEPtr()->getRuleHook = rule;
412 auto &boundary_evaluation_pipeline = op_loop_boundary->getOpPtrVector();
413
414 CHKERR AddHOOps<1, 2, 2>::add(boundary_evaluation_pipeline, {HDIV});
415
416 auto flux_ptr = boost::make_shared<MatrixDouble>();
417 boundary_evaluation_pipeline.push_back(
418 new OpCalculateHVecVectorField<3>("S", flux_ptr));
419 boundary_evaluation_pipeline.push_back(new BoundaryOp(flux_ptr, calc_flux));
420 pipeline_mng->getOpEvaluationPipeline().push_back(op_loop_boundary);
421
422 calc_flux = 0;
423 CHKERR pipeline_mng->loopFiniteElementsEvaluation();
424 double global_flux_assembeld = 0;
425 MPI_Allreduce(&calc_flux, &global_flux_assembeld, 1, MPI_DOUBLE, MPI_SUM,
426 mField.get_comm());
427 calc_flux = global_flux_assembeld;
428
430}
@ HDIV
field with continuous normal traction
Definition definitions.h:87
virtual MPI_Comm & get_comm() const =0
Get vector field for H-div approximation.
Element used to execute operators on side of the element.
MoFEMErrorCode setEvaluationIntegrationRule(RuleHookFun rule)
Set integration rule for domain evaluation finite element.
const std::string getBoundaryFEName() const
Get the Boundary FE Name.
Definition Simple.hpp:436

◆ calculateGradient() [1/2]

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_shape_optimisation/adjoint.cpp.

Definition at line 1726 of file adjoint.cpp.

1728 {
1729 MOFEM_LOG_CHANNEL("WORLD");
1731 auto simple = mField.getInterface<Simple>();
1732
1733 auto ents = get_range_from_block(mField, "OPTIMISE", SPACE_DIM - 1);
1734
1735 auto get_essential_fe = [this]() {
1736 auto post_proc_rhs = boost::make_shared<FEMethod>();
1737 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
1739
1741 post_proc_rhs, 0)();
1743 };
1744 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1745 return post_proc_rhs;
1746 };
1747
1748 auto get_fd_direvative_fe = [&]() {
1749 auto fe = boost::make_shared<DomainEle>(mField);
1750 fe->getRuleHook = [](int, int, int p_data) {
1751 return 2 * p_data + p_data - 1;
1752 };
1753 auto &pip = fe->getOpPtrVector();
1755 // Add RHS operators for internal forces
1756 HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
1757 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1758
1759 return fe;
1760 };
1761
1762 auto calulate_fd_residual = [&](auto eps, auto diff_vec, auto fd_vec) {
1764
1765 constexpr bool debug = false;
1766
1767 auto geom_norm = [](MoFEM::Interface &mField) {
1769 auto field_blas = mField.getInterface<FieldBlas>();
1770 double nrm2 = 0.0;
1771 auto norm2_field = [&](const double val) {
1772 nrm2 += val * val;
1773 return val;
1774 };
1775 CHKERR field_blas->fieldLambdaOnValues(norm2_field, "GEOMETRY");
1776 MPI_Allreduce(MPI_IN_PLACE, &nrm2, 1, MPI_DOUBLE, MPI_SUM,
1777 mField.get_comm());
1778 MOFEM_LOG("WORLD", Sev::inform) << "Geometry norm: " << sqrt(nrm2);
1780 };
1781
1782 if constexpr (debug)
1783 CHKERR geom_norm(mField);
1784
1785 auto initial_current_geometry = createDMVector(adjointDM);
1786 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1787 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
1788 initial_current_geometry, INSERT_VALUES, SCATTER_FORWARD);
1789 CHKERR VecAssemblyBegin(initial_current_geometry);
1790 CHKERR VecAssemblyEnd(initial_current_geometry);
1791
1792 if constexpr (debug)
1793 CHKERR geom_norm(mField);
1794
1795 auto perturb_geometry = [&](auto eps, auto diff_vec) {
1797 auto current_geometry = vectorDuplicate(initial_current_geometry);
1798 CHKERR VecCopy(initial_current_geometry, current_geometry);
1799 CHKERR VecAXPY(current_geometry, eps, diff_vec);
1800 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1801 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
1802 current_geometry, INSERT_VALUES, SCATTER_REVERSE);
1804 };
1805
1806 auto fe = get_fd_direvative_fe();
1807 auto fp = vectorDuplicate(diff_vec);
1808 auto fm = vectorDuplicate(diff_vec);
1809 auto calc_impl = [&](auto f, auto eps) { // is this finite difference!
1811 CHKERR VecZeroEntries(f);
1812 fe->f = f;
1813 CHKERR perturb_geometry(eps, diff_vec);
1815 simple->getDomainFEName(), fe);
1816 CHKERR VecAssemblyBegin(f);
1817 CHKERR VecAssemblyEnd(f);
1818 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
1819 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
1820 auto post_proc_rhs = get_essential_fe();
1821 post_proc_rhs->f = f;
1823 post_proc_rhs.get());
1825 };
1826 CHKERR calc_impl(fp, eps);
1827 CHKERR calc_impl(fm, -eps);
1828 CHKERR VecWAXPY(fd_vec, -1.0, fm, fp);
1829 CHKERR VecScale(fd_vec, 1.0 / (2.0 * eps));
1830
1831 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1832 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
1833 initial_current_geometry, INSERT_VALUES, SCATTER_REVERSE);
1834
1835 if constexpr (debug)
1836 CHKERR geom_norm(mField);
1837
1839 };
1840 // here starts the preperation for the derivative
1841 auto get_direvative_fe = [&](auto diff_vec) {
1842 auto fe_adjoint = boost::make_shared<DomainEle>(mField);
1843 fe_adjoint->getRuleHook = [](int, int, int p_data) {
1844 return 2 * p_data + p_data - 1;
1845 };
1846 auto &pip = fe_adjoint->getOpPtrVector();
1847
1848 auto jac_ptr = boost::make_shared<MatrixDouble>();
1849 auto det_ptr = boost::make_shared<VectorDouble>();
1850 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1851 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
1852 auto cof_ptr = boost::make_shared<VectorDouble>();
1853
1854 using OpCoFactor =
1855 AdJoint<DomainEleOp>::Integration<GAUSS>::OpGetCoFactor<SPACE_DIM>;
1856
1858
1860 "GEOMETRY", jac_ptr));
1862 "U", diff_jac_ptr, diff_vec));
1863
1864 pip.push_back(new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
1865
1866 // Add RHS operators for internal forces
1867 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1868 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1870 "U", common_ptr, jac_ptr, diff_jac_ptr, cof_ptr));
1871
1872 return fe_adjoint;
1873 };
1874
1875 auto get_objective_fe = [&](auto diff_vec, auto grad_vec,
1876 auto glob_objective_ptr,
1877 auto glob_objective_grad_ptr) {
1878 auto fe_adjoint = boost::make_shared<DomainEle>(mField);
1879 fe_adjoint->getRuleHook = [](int, int, int p_data) {
1880 return 2 * p_data + p_data - 1;
1881 };
1882 auto &pip = fe_adjoint->getOpPtrVector();
1884
1885 auto jac_ptr = boost::make_shared<MatrixDouble>();
1886 auto det_ptr = boost::make_shared<VectorDouble>();
1887 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1888 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
1889 auto cof_ptr = boost::make_shared<VectorDouble>();
1890 auto d_grad_ptr = boost::make_shared<MatrixDouble>();
1891 auto d_u_ptr = boost::make_shared<MatrixDouble>();
1892 auto u_ptr = boost::make_shared<MatrixDouble>();
1893
1894 using OpCoFactor =
1895 AdJoint<DomainEleOp>::Integration<GAUSS>::OpGetCoFactor<SPACE_DIM>;
1897 "GEOMETRY", jac_ptr));
1899 "U", diff_jac_ptr,
1900 diff_vec)); // Note: that vector is stored on displacemnt vector, that
1901 // why is used here
1902 pip.push_back(new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
1904 "U", d_grad_ptr, grad_vec));
1905 pip.push_back(
1906 new OpCalculateVectorFieldValues<SPACE_DIM>("U", d_u_ptr, grad_vec));
1907 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1908
1909 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1910 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1911 pip.push_back(new OpAdJointObjective(
1912 pythonPtr, common_ptr, jac_ptr, diff_jac_ptr, cof_ptr, d_grad_ptr,
1913 d_u_ptr, u_ptr, glob_objective_ptr, glob_objective_grad_ptr));
1914
1915 return fe_adjoint;
1916 };
1917
1918 auto dm = simple->getDM();
1919 auto f = createDMVector(dm);
1920 auto d = vectorDuplicate(f);
1921 auto dm_diff_vec = vectorDuplicate(d);
1922 auto zero_diff_vec = vectorDuplicate(dm_diff_vec);
1923 auto zero_state_sensitivity = vectorDuplicate(d);
1924 CHKERR VecZeroEntries(zero_diff_vec);
1925 CHKERR VecZeroEntries(zero_state_sensitivity);
1926 CHKERR VecGhostUpdateBegin(zero_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1927 CHKERR VecGhostUpdateEnd(zero_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1928 CHKERR VecGhostUpdateBegin(zero_state_sensitivity, INSERT_VALUES,
1929 SCATTER_FORWARD);
1930 CHKERR VecGhostUpdateEnd(zero_state_sensitivity, INSERT_VALUES,
1931 SCATTER_FORWARD);
1932
1933 auto adjoint_fe = get_direvative_fe(dm_diff_vec);
1934 auto objective_ptr_direct = boost::make_shared<double>(0.0);
1935 auto objective_grad_ptr_direct = boost::make_shared<double>(0.0);
1936 auto objective_fe_direct = get_objective_fe(
1937 dm_diff_vec, d, objective_ptr_direct, objective_grad_ptr_direct);
1938 auto objective_ptr_explicit = boost::make_shared<double>(0.0);
1939 auto objective_grad_ptr_explicit = boost::make_shared<double>(0.0);
1940 auto objective_fe_explicit =
1941 get_objective_fe(dm_diff_vec, zero_state_sensitivity,
1942 objective_ptr_explicit, objective_grad_ptr_explicit);
1943 auto objective_ptr_value = boost::make_shared<double>(0.0);
1944 auto objective_grad_ptr_value = boost::make_shared<double>(0.0);
1945 auto objective_fe_value =
1946 get_objective_fe(zero_diff_vec, zero_state_sensitivity,
1947 objective_ptr_value, objective_grad_ptr_value);
1948
1949 auto set_variance_of_geometry =
1950 [&](auto mode, auto mod_vec) { // think of mod_vec as X(tau) = X + tau*v_h
1951 // take the mod_vec and write it into the adjoint DM then copy that
1952 // field to dm_diff_vec using the same layout as U
1954 CHKERR DMoFEMMeshToLocalVector(adjointDM, mod_vec, INSERT_VALUES,
1955 SCATTER_REVERSE);
1956 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1957 simple->getProblemName(), "U", "ADJOINT_FIELD", RowColData::ROW,
1958 dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1959 CHKERR VecGhostUpdateBegin(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1960 CHKERR VecGhostUpdateEnd(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1962 };
1963
1964 auto calculate_variance_internal_forces = [&](auto mode, auto mod_vec) {
1966 CHKERR VecZeroEntries(f);
1967 CHKERR VecGhostUpdateBegin(f, INSERT_VALUES, SCATTER_FORWARD);
1968 CHKERR VecGhostUpdateEnd(f, INSERT_VALUES, SCATTER_FORWARD);
1969 adjoint_fe->f = f;
1970 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(), adjoint_fe);
1971 CHKERR VecAssemblyBegin(f);
1972 CHKERR VecAssemblyEnd(f);
1973 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
1974 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
1975 auto post_proc_rhs = get_essential_fe();
1976 post_proc_rhs->f = f;
1978 post_proc_rhs.get());
1979 CHKERR VecScale(f, -1.0);
1980
1981#ifndef NDEBUG
1982 constexpr bool debug = true;
1983 if constexpr (debug) {
1984 double norm0;
1985 CHKERR VecNorm(f, NORM_2, &norm0);
1986 auto fd_check = vectorDuplicate(f);
1987 double eps = 1e-5;
1988 CHKERR calulate_fd_residual(eps, dm_diff_vec, fd_check);
1989 double nrm;
1990 CHKERR VecAXPY(fd_check, -1.0, f);
1991 CHKERR VecNorm(fd_check, NORM_2, &nrm);
1992 MOFEM_LOG("WORLD", Sev::inform)
1993 << " FD check for internal forces [ " << mode << " ]: " << nrm
1994 << " / " << norm0 << " ( " << (nrm / norm0) << " )";
1995 }
1996#endif
1997
1999 };
2000
2001 auto calculate_variance_of_displacement = [&](auto mode, auto mod_vec) {
2003 CHKERR KSPSolve(kspElastic, f, d);
2004
2005 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
2006 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
2008 };
2009
2010 auto evaluate_objective_terms =
2011 [&](auto objective_fe, auto objective_ptr, auto objective_grad_ptr,
2012 double &objective_value, double &objective_gradient) {
2014 *objective_ptr = 0.0;
2015 *objective_grad_ptr = 0.0;
2016 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
2017 objective_fe);
2018 std::array<double, 2> array = {*objective_ptr, *objective_grad_ptr};
2019 MPI_Allreduce(MPI_IN_PLACE, array.data(), 2, MPI_DOUBLE, MPI_SUM,
2020 mField.get_comm());
2021 objective_value = array[0];
2022 objective_gradient = array[1];
2024 };
2025
2026 auto calculate_objective_value = [&]() {
2028 double objective_value = 0;
2029 double objective_gradient = 0;
2030 CHKERR evaluate_objective_terms(objective_fe_value, objective_ptr_value,
2031 objective_grad_ptr_value, objective_value,
2032 objective_gradient);
2033 *objective_function_value = objective_value;
2035 };
2036
2037 auto calculate_variance_of_objective_function_dJ_du = [&](Vec dJ_du) {
2039
2040 auto fe = boost::make_shared<DomainEle>(mField);
2041 fe->getRuleHook = [](int, int, int p_data) {
2042 return 2 * p_data + p_data - 1;
2043 };
2044 auto &pip = fe->getOpPtrVector();
2046
2047 auto u_ptr = boost::make_shared<MatrixDouble>();
2048 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
2049
2050 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
2051 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
2052 pip.push_back(new OpStateSensitivity("U", pythonPtr, common_ptr, u_ptr));
2053
2054 CHKERR VecZeroEntries(dJ_du);
2055 fe->f = dJ_du;
2056 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(), fe);
2057 CHKERR VecAssemblyBegin(dJ_du);
2058 CHKERR VecAssemblyEnd(dJ_du);
2059
2060 auto post_proc_rhs = get_essential_fe();
2061 post_proc_rhs->f = dJ_du;
2063 post_proc_rhs.get());
2064
2066 };
2067
2068 auto calculate_adjoint_lambda = [&](auto lambda, auto dJ_du) {
2070
2071 MOFEM_LOG("WORLD", Sev::inform) << "Solving for adjoint variable lambda";
2072 CHKERR VecZeroEntries(lambda);
2073 CHKERR KSPSolveTranspose(kspElastic, dJ_du, lambda);
2074 CHKERR VecGhostUpdateBegin(lambda, INSERT_VALUES, SCATTER_FORWARD);
2075 CHKERR VecGhostUpdateEnd(lambda, INSERT_VALUES, SCATTER_FORWARD);
2077 };
2078
2079 CHKERR VecZeroEntries(objective_function_gradient);
2080 CHKERR VecZeroEntries(adjoint_vector);
2081
2082 CHKERR calculate_objective_value();
2083 MOFEM_LOG("WORLD", Sev::verbose)
2084 << "Objective function: " << *objective_function_value;
2085
2086 auto direct = [&]() {
2088 int mode = 0;
2089 for (auto mod_vec : modeVecs) {
2090 CHKERR set_variance_of_geometry(mode, mod_vec);
2091 CHKERR calculate_variance_internal_forces(mode, mod_vec);
2092 CHKERR calculate_variance_of_displacement(mode, mod_vec);
2093 double objective_value = 0;
2094 double objective_gradient = 0;
2095 CHKERR evaluate_objective_terms(objective_fe_direct, objective_ptr_direct,
2096 objective_grad_ptr_direct,
2097 objective_value, objective_gradient);
2098 CHKERR VecSetValue(objective_function_gradient, mode, objective_gradient,
2099 INSERT_VALUES);
2100 CHKERR VecAXPY(adjoint_vector, objective_gradient, dm_diff_vec);
2101 ++mode;
2102 }
2104 };
2105
2106 auto lambda = vectorDuplicate(f);
2107 auto dJ_du = vectorDuplicate(f);
2108
2109 auto adjoint = [&]() {
2111
2112 CHKERR calculate_variance_of_objective_function_dJ_du(dJ_du);
2113 CHKERR calculate_adjoint_lambda(lambda, dJ_du);
2114
2115 int mode = 0;
2116
2117 for (auto mod_vec : modeVecs) {
2118
2119 CHKERR set_variance_of_geometry(mode, mod_vec);
2120 CHKERR calculate_variance_internal_forces(mode, mod_vec);
2121 double objective_value = 0;
2122 double objective_gradient_explicit = 0;
2123 CHKERR evaluate_objective_terms(
2124 objective_fe_explicit, objective_ptr_explicit,
2125 objective_grad_ptr_explicit, objective_value,
2126 objective_gradient_explicit);
2127 double lambda_dot_residual_variation = 0;
2128 CHKERR VecDot(lambda, f, &lambda_dot_residual_variation);
2129 const double dJ_dp =
2130 objective_gradient_explicit + lambda_dot_residual_variation;
2131 CHKERR VecSetValue(objective_function_gradient, mode, dJ_dp,
2132 INSERT_VALUES);
2133 CHKERR VecAXPY(adjoint_vector, dJ_dp, dm_diff_vec);
2134 ++mode;
2135 }
2136 CHKERR VecAssemblyBegin(objective_function_gradient);
2137 CHKERR VecAssemblyEnd(objective_function_gradient);
2139 };
2140
2141 switch (derivative_type) {
2142 case DIRECT:
2143 MOFEM_LOG("WORLD", Sev::inform) << "Running Direct Sensitivity...";
2144 CHKERR direct();
2145 break;
2146
2147 case ADJOINT:
2148 MOFEM_LOG("WORLD", Sev::inform) << "Running Adjoint Sensitivity...";
2149 CHKERR adjoint();
2150 break;
2151
2152 default:
2153 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
2154 "Wrong sensitivity type selected");
2155 }
2156
2157 CHKERR VecAssemblyBegin(objective_function_gradient);
2158 CHKERR VecAssemblyEnd(objective_function_gradient);
2159
2160 CHKERR VecAssemblyBegin(adjoint_vector);
2161 CHKERR VecAssemblyEnd(adjoint_vector);
2162 CHKERR VecGhostUpdateBegin(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2163 CHKERR VecGhostUpdateEnd(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2164
2166}
SensitivityMethod derivative_type
Definition adjoint.cpp:109
@ DIRECT
Definition adjoint.cpp:107
@ ADJOINT
Definition adjoint.cpp:107
Range get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
Definition adjoint.cpp:2254
@ ROW
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#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, RowColData rc=RowColData::COL)
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, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
@ GAUSS
Gaussian quadrature integration.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
static double lambda
const FTensor::Tensor2< T, Dim, Dim > Vec
const double eps
Definition HenckyOps.hpp:13
static const bool debug
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
boost::shared_ptr< ObjectiveFunctionData > pythonPtr
Interface to Python objective function.
Definition adjoint.cpp:170
std::vector< SmartPetscObj< Vec > > modeVecs
Topology mode vectors (design variables)
Definition adjoint.cpp:174
SmartPetscObj< DM > adjointDM
Data manager for adjoint problem.
Definition adjoint.cpp:168
SmartPetscObj< KSP > kspElastic
Linear solver for elastic problem.
Definition adjoint.cpp:167
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 MatrixDouble 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:105

◆ calculateGradient() [2/2]

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

Calculate objective function gradient using adjoint method.

Definition at line 1020 of file gradient.cpp.

1022 {
1023 MOFEM_LOG_CHANNEL("WORLD");
1025 auto simple = mField.getInterface<Simple>();
1026 auto dm = simple->getDM();
1027
1028 auto get_essential_fe = [this]() {
1029 auto post_proc_rhs = boost::make_shared<FEMethod>();
1030 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
1033 post_proc_rhs, 0)();
1035 };
1036 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1037 return post_proc_rhs;
1038 };
1039
1040 auto get_objective_fe = [&](auto lambda_vec, auto glob_objective_ptr,
1041 auto fe_rule) {
1042 auto fe_obj = boost::make_shared<DomainEle>(mField);
1043 fe_obj->getRuleHook = fe_rule;
1044 auto &pip = fe_obj->getOpPtrVector();
1046
1047 auto jac_ptr = boost::make_shared<MatrixDouble>();
1048 auto u_ptr = boost::make_shared<MatrixDouble>();
1049 auto grad_lambda_ptr = boost::make_shared<MatrixDouble>();
1050
1052 "GEOMETRY", jac_ptr));
1053 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1054 auto lambda_smart_vec = SmartPetscObj<Vec>(lambda_vec, true);
1056 "U", grad_lambda_ptr, lambda_smart_vec));
1057
1058 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1059 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1060 pip.push_back(new OpAdJointObjective(pythonPtr, common_ptr, jac_ptr, u_ptr,
1061 grad_lambda_ptr,
1062 glob_objective_ptr));
1063 return fe_obj;
1064 };
1065
1066 auto evaluate_objective_terms =
1067 [&](auto objective_fe, auto objective_ptr) {
1069 *objective_ptr = 0.0;
1070 CHKERR VecZeroEntries(objective_function_gradient);
1071 CHKERR VecGhostUpdateBegin(lambda, INSERT_VALUES, SCATTER_FORWARD);
1072 CHKERR VecGhostUpdateEnd(lambda, INSERT_VALUES, SCATTER_FORWARD);
1073 objective_fe->f = objective_function_gradient;
1074 CHKERR DMoFEMLoopFiniteElements(adjointDM, "ADJOINT_DOMAIN_FE",
1075 objective_fe);
1076 MPI_Allreduce(MPI_IN_PLACE, objective_ptr.get(), 1, MPI_DOUBLE, MPI_SUM,
1077 mField.get_comm());
1078 CHKERR VecAssemblyBegin(objective_function_gradient);
1079 CHKERR VecAssemblyEnd(objective_function_gradient);
1080 CHKERR VecGhostUpdateBegin(objective_function_gradient, ADD_VALUES,
1081 SCATTER_REVERSE);
1082 CHKERR VecGhostUpdateEnd(objective_function_gradient, ADD_VALUES,
1083 SCATTER_REVERSE);
1085 };
1086
1087 auto calculate_variance_of_objective_function_dJ_du = [&]() {
1089 auto fe = boost::make_shared<DomainEle>(mField);
1090 fe->getRuleHook = [](int, int, int p_data) {
1091 return 2 * p_data + p_data - 1;
1092 };
1093 auto &pip = fe->getOpPtrVector();
1095 auto u_ptr = boost::make_shared<MatrixDouble>();
1096 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1097 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1098 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1099 pip.push_back(new OpStateSensitivity("U", pythonPtr, common_ptr, u_ptr));
1100 CHKERR VecZeroEntries(dJ_du);
1101 fe->f = dJ_du;
1102 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(), fe);
1103 CHKERR VecAssemblyBegin(dJ_du);
1104 CHKERR VecAssemblyEnd(dJ_du);
1105 auto post_proc_rhs = get_essential_fe();
1106 post_proc_rhs->f = dJ_du;
1108 post_proc_rhs.get());
1110 };
1111
1112 auto calculate_adjoint_lambda = [&]() {
1114
1115 MOFEM_LOG("WORLD", Sev::inform) << "Solving for adjoint variable lambda";
1116 CHKERR VecZeroEntries(lambda);
1117 CHKERR KSPSolveTranspose(kspElastic, dJ_du, lambda);
1118 CHKERR VecGhostUpdateBegin(lambda, INSERT_VALUES, SCATTER_FORWARD);
1119 CHKERR VecGhostUpdateEnd(lambda, INSERT_VALUES, SCATTER_FORWARD);
1121 };
1122
1123 auto fe_rule = [](int, int, int p_data) { return 2 * p_data + p_data - 1; };
1124 auto objective_ptr_value = boost::make_shared<double>(0.0);
1125 auto objective_fe = get_objective_fe(lambda, objective_ptr_value, fe_rule);
1126
1127 auto adjoint = [&]() {
1129
1130 CHKERR calculate_variance_of_objective_function_dJ_du();
1131 CHKERR calculate_adjoint_lambda();
1132 CHKERR evaluate_objective_terms(objective_fe, objective_ptr_value);
1133 *objective_function_value = *objective_ptr_value;
1134
1135 MOFEM_LOG("WORLD", Sev::verbose)
1136 << "Objective function: " << *objective_function_value;
1137
1138 CHKERR VecAssemblyBegin(objective_function_gradient);
1139 CHKERR VecAssemblyEnd(objective_function_gradient);
1140 CHKERR VecGhostUpdateBegin(lambda, INSERT_VALUES, SCATTER_FORWARD);
1141 CHKERR VecGhostUpdateEnd(lambda, INSERT_VALUES, SCATTER_FORWARD);
1142
1144 };
1145
1146 switch (derivative_type) {
1147
1148 case ADJOINT:
1149 MOFEM_LOG("WORLD", Sev::inform) << "Running Adjoint Sensitivity...";
1150 CHKERR adjoint();
1151 break;
1152
1153 default:
1154 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1155 "Wrong sensitivity type selected");
1156 }
1157
1158 CHKERR VecAssemblyBegin(objective_function_gradient);
1159 CHKERR VecAssemblyEnd(objective_function_gradient);
1160
1162}
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
intrusive_ptr for managing petsc objects

◆ 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]

[Create Example_struct]

[Set integration rule]

[Create common data]

< true if tau order is set

< true if tau order is set

Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp, mofem/tutorials/fun-1_integration/integration.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-8_heat_radiation/radiation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 479 of file plastic.cpp.

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

◆ 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 1164 of file thermoplastic.cpp.

1173 {
1174
1176
1177 auto common_plastic_ptr = boost::make_shared<PlasticOps::CommonData>();
1178 auto common_thermal_ptr =
1179 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
1180 auto common_thermoelastic_ptr =
1181 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
1182 auto common_thermoplastic_ptr =
1183 boost::make_shared<ThermoPlasticOps::ThermoPlasticBlockedParameters>();
1184
1185 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
1186 auto make_d_mat = []() {
1187 return boost::make_shared<MatrixDouble>(size_symm * size_symm, 1);
1188 };
1189
1190 common_plastic_ptr->mDPtr = boost::make_shared<MatrixDouble>();
1191 common_plastic_ptr->mGradPtr = boost::make_shared<MatrixDouble>();
1192 common_plastic_ptr->mStrainPtr = boost::make_shared<MatrixDouble>();
1193 common_plastic_ptr->mStressPtr = boost::make_shared<MatrixDouble>();
1194
1195 auto m_D_ptr = common_plastic_ptr->mDPtr;
1196
1197 CHK_THROW_MESSAGE(PlasticOps::addMatBlockOps<DIM>(
1198 m_field, plastic_block_name, pip, m_D_ptr,
1199 common_plastic_ptr->getParamsPtr(), scale, sev),
1200 "add mat block plastic ops");
1202 m_field, pip, thermal_block_name, common_thermal_ptr,
1207 "add mat block thermal ops");
1209 m_field, pip, thermoelastic_block_name,
1210 common_thermoelastic_ptr, default_coeff_expansion,
1211 default_ref_temp, sev),
1212 "add mat block thermal ops");
1214 m_field, pip, thermoplastic_block_name,
1215 common_thermoplastic_ptr, common_thermal_ptr, sev,
1217 "add mat block thermoplastic ops");
1218 auto common_hencky_ptr =
1219 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
1220 mField, pip, "U", "MAT_ELASTIC", Sev::inform, scale);
1221
1222 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1223
1224 pip.push_back(new OpCalculateScalarFieldValues(
1225 tau, common_plastic_ptr->getPlasticTauPtr()));
1227 ep, common_plastic_ptr->getPlasticStrainPtr()));
1229 u, common_plastic_ptr->mGradPtr));
1230
1231 pip.push_back(new OpCalculateScalarFieldValues(
1232 temperature, common_thermoplastic_ptr->getTempPtr()));
1234 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
1235
1236 common_plastic_ptr->mGradPtr = common_hencky_ptr->matGradPtr;
1237 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1238 common_hencky_ptr->matLogCPlastic =
1239 common_plastic_ptr->getPlasticStrainPtr();
1240 common_plastic_ptr->mStrainPtr = common_hencky_ptr->getMatLogC();
1241 common_plastic_ptr->mStressPtr = common_hencky_ptr->getMatHenckyStress();
1242
1244
1245 pip.push_back(new typename H::template OpCalculateEigenVals<DIM, I>(
1246 u, common_hencky_ptr));
1247 pip.push_back(
1248 new typename H::template OpCalculateLogC<DIM, I>(u, common_hencky_ptr));
1249 pip.push_back(new typename H::template OpCalculateLogC_dC<DIM, I>(
1250 u, common_hencky_ptr));
1251
1252 pip.push_back(
1253 new
1254 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
1255 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
1256 common_thermoelastic_ptr->getCoeffExpansionPtr(),
1257 common_thermoelastic_ptr->getRefTempPtr()));
1258 pip.push_back(new typename H::template OpCalculatePiolaStress<DIM, I, 0>(
1259 u, common_hencky_ptr));
1260
1261 pip.push_back(new typename P::template OpCalculatePlasticSurface<DIM, I>(
1262 u, common_plastic_ptr));
1263
1264 pip.push_back(new typename P::template OpCalculatePlasticHardening<DIM, I>(
1265 u, common_plastic_ptr, common_thermoplastic_ptr));
1266
1267 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
1268 common_thermal_ptr, common_thermoelastic_ptr,
1269 common_thermoplastic_ptr);
1270 }
#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 2513 of file thermoplastic.cpp.

2515 {
2517
2518 ReadUtilIface *read_util;
2519 CHKERR mField.get_moab().query_interface(read_util);
2520
2521 const int num_ele = el_q_map.size() * 2; // each flip creates 2 elements
2522 int num_nod_per_ele;
2523 EntityType ent_type;
2524
2525 if (SPACE_DIM == 2) {
2526 num_nod_per_ele = 3;
2527 ent_type = MBTRI;
2528 } else {
2529 num_nod_per_ele = 4;
2530 ent_type = MBTET;
2531 }
2532
2533 Range new_elements;
2534 auto new_conn = new_connectivity.begin();
2535 for (auto e = 0; e != num_ele; ++e) {
2536 EntityHandle conn[num_nod_per_ele];
2537 for (int n = 0; n < num_nod_per_ele; ++n) {
2538 conn[n] = *new_conn;
2539 ++new_conn;
2540 }
2541 EntityHandle new_ele;
2542 Range adj_ele;
2543 CHKERR mField.get_moab().get_adjacencies(conn, num_nod_per_ele, SPACE_DIM,
2544 false, adj_ele);
2545 if (adj_ele.size()) {
2546 if (adj_ele.size() != 1) {
2547 SETERRQ(PETSC_COMM_SELF, MOFEM_STD_EXCEPTION_THROW,
2548 "Element duplication");
2549 } else {
2550 new_ele = adj_ele.front();
2551 }
2552 } else {
2553 CHKERR mField.get_moab().create_element(ent_type, conn, num_nod_per_ele,
2554 new_ele);
2555 }
2556 new_elements.insert(new_ele);
2557 }
2558
2559 MOFEM_LOG("REMESHING", Sev::verbose)
2560 << "New elements from edge flipping: " << new_elements;
2561
2562 auto reset_flip_bit = [](EntityHandle ent, BitRefLevel &bit) {
2563 bit.set(STORAGE_BIT, true);
2564 bit.set(FLIPPED_BIT, false);
2565 };
2566 CHKERR mField.getInterface<BitRefManager>()->lambdaBitRefLevel(
2567 reset_flip_bit);
2568
2569 auto get_adj = [&](auto ents) {
2570 Range adj;
2571 for (auto d = 0; d != SPACE_DIM; ++d) {
2573 mField.get_moab().get_adjacencies(ents, d, true, adj,
2574 moab::Interface::UNION),
2575 "Getting adjacencies of dimension " + std::to_string(d) + " failed");
2576 }
2577 return adj;
2578 };
2579
2580 Range non_flipped_range;
2581 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByDimAndRefLevel(
2582 virgin_mesh_bit, BitRefLevel().set(), SPACE_DIM, non_flipped_range);
2583
2584 non_flipped_range = subtract(non_flipped_range, flipped_els);
2585 auto flip_bit_ents = new_elements;
2586 flip_bit_ents.merge(non_flipped_range);
2587 auto adj = get_adj(new_elements);
2588 // flip_bit_ents.merge(get_adj(new_elements));
2589
2590 CHKERR mField.getInterface<BitRefManager>()->setBitRefLevel(
2591 flip_bit_ents, flipped_bit, false);
2592
2593 CHKERR mField.getInterface<BitRefManager>()->writeBitLevelByDim(
2594 BitRefLevel().set(FLIPPED_BIT), BitRefLevel().set(), 2,
2595 "new_elements_after_edge_flips.vtk", "VTK", "");
2596
2598};
@ 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 2602 of file thermoplastic.cpp.

2602 {
2604
2605 Tag th_spatial_coords;
2606 double def_coord[3] = {0.0, 0.0, 0.0};
2607
2608 auto refined_mesh = [&](auto level) {
2610 auto bit = BitRefLevel().set(FLIPPED_BIT + level);
2611 Range edges;
2612 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByDimAndRefLevel(
2613 bit, BitRefLevel().set(), SPACE_DIM - 1, edges);
2614 CHKERR mField.get_moab().tag_get_handle(
2615 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2616 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2617
2618 Range refine_edges;
2619 if (add_ents)
2620 for (auto e : edges) {
2621 const EntityHandle *conn;
2622 int num_nodes;
2623 CHKERR mField.get_moab().get_connectivity(e, conn, num_nodes, true);
2624 std::array<double, 6> ref_coords, spatial_coords;
2625 CHKERR mField.get_moab().get_coords(conn, num_nodes, ref_coords.data());
2626 CHKERR mField.get_moab().tag_get_data(th_spatial_coords, conn,
2627 num_nodes, spatial_coords.data());
2628 auto get_length = [](auto &a) {
2630 FTensor::Tensor1<double, 3> p0{a[0], a[1], a[2]};
2631 FTensor::Tensor1<double, 3> p1{a[3], a[4], a[5]};
2632 p1(i) = p1(i) - p0(i);
2633 return p1.l2();
2634 };
2635 auto ref_edge_length = get_length(ref_coords);
2636 auto spatial_edge_length = get_length(spatial_coords);
2637 auto change = spatial_edge_length / ref_edge_length;
2638 if (change >= 1. + edge_growth_thresh) {
2639 refine_edges.insert(e);
2640 }
2641 }
2642
2643 if (refine_edges.size())
2644 refined = true;
2645
2646 Range prev_level_ents;
2647 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
2648 bit, BitRefLevel().set(), MBEDGE, prev_level_ents);
2649
2650 Range prev_ref_ents;
2651 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
2652 BitRefLevel().set(REFINED_EDGES_BIT), BitRefLevel().set(), MBEDGE,
2653 prev_ref_ents);
2654
2655 refine_edges.merge(intersect(prev_ref_ents, prev_level_ents));
2656 CHKERR mField.getInterface<BitRefManager>()->setNthBitRefLevel(
2657 refine_edges, REFINED_EDGES_BIT, true);
2658
2659 auto refine = mField.getInterface<MeshRefinement>();
2660 auto refined_bit = BitRefLevel().set(FIRST_REF_BIT + level);
2661 CHKERR refine->addVerticesInTheMiddleOfEdges(refine_edges, refined_bit);
2662 Range tris_to_refine;
2663 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByDimAndRefLevel(
2664 bit, BitRefLevel().set(), SPACE_DIM, tris_to_refine);
2665 CHKERR refine->refineTris(tris_to_refine, refined_bit, QUIET, false);
2666
2667 auto set_spatial_coords = [&]() {
2669 Range new_vertices;
2670 CHKERR mField.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
2671 refined_bit, refined_bit, MBVERTEX, new_vertices);
2672 auto th_parent_handle =
2673 mField.getInterface<BitRefManager>()->get_th_RefParentHandle();
2674 for (auto v : new_vertices) {
2675 EntityHandle parent;
2676 CHKERR mField.get_moab().tag_get_data(th_parent_handle, &v, 1, &parent);
2677 const EntityHandle *conn;
2678 int num_nodes;
2679 CHKERR mField.get_moab().get_connectivity(parent, conn, num_nodes,
2680 true);
2681 std::array<double, 6> spatial_coords;
2682 CHKERR mField.get_moab().tag_get_data(th_spatial_coords, conn,
2683 num_nodes, spatial_coords.data());
2684 for (auto d = 0; d < 3; ++d) {
2685 spatial_coords[d] += spatial_coords[3 + d];
2686 }
2687 for (auto d = 0; d < 3; ++d) {
2688 spatial_coords[d] /= 2.0;
2689 }
2690 CHKERR mField.get_moab().tag_set_data(th_spatial_coords, &v, 1,
2691 spatial_coords.data());
2692 }
2694 };
2695
2696 CHKERR set_spatial_coords();
2697
2698 CHKERR mField.getInterface<BitRefManager>()->writeBitLevelByDim(
2699 BitRefLevel().set(FIRST_REF_BIT + level), BitRefLevel().set(), 2,
2700 ("A_refined_" + boost::lexical_cast<std::string>(level) + ".vtk")
2701 .c_str(),
2702 "VTK", "");
2703
2705 };
2706
2707 auto reset_ref_bits = [](EntityHandle ent, BitRefLevel &bit) {
2708 bit.set(STORAGE_BIT, true);
2709 for (int l = 0; l < num_refinement_levels; ++l) {
2710 bit.set(FIRST_REF_BIT + l, false);
2711 }
2712 };
2713 CHKERR mField.getInterface<BitRefManager>()->lambdaBitRefLevel(
2714 reset_ref_bits);
2715
2716 for (auto l = 0; l < num_refinement_levels; ++l) {
2717 CHKERR refined_mesh(l);
2718 };
2719
2720 CHKERR mField.getInterface<BitRefManager>()->writeBitLevelByDim(
2722 BitRefLevel().set(), 2, "new_elements_after_edge_splits.vtk", "VTK", "");
2723
2725};
#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_dg_projection/between_meshes_dg_projection.cpp, and thermoplastic.cpp.

Definition at line 578 of file between_meshes_dg_projection.cpp.

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

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

382 {
384
386 auto dm = simple->getDM();
387
388 auto T = createDMVector(simple->getDM());
389 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
390 SCATTER_FORWARD);
391 double nrm2;
392 CHKERR VecNorm(T, NORM_2, &nrm2);
393 MOFEM_LOG("EXAMPLE", Sev::inform) << "Solution norm " << nrm2;
394
395 auto post_proc_norm_fe = boost::make_shared<DomainEle>(mField);
396
397 auto post_proc_norm_rule_hook = [](int, int, int p) -> int { return 2 * p; };
398 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
399
401 post_proc_norm_fe->getOpPtrVector(), {H1});
402
403 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
404 auto norms_vec =
406 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
407 CHKERR VecZeroEntries(norms_vec);
408
409 auto u_ptr = boost::make_shared<MatrixDouble>();
410 post_proc_norm_fe->getOpPtrVector().push_back(
412
413 post_proc_norm_fe->getOpPtrVector().push_back(
414 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
415
416 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
417 mField, post_proc_norm_fe->getOpPtrVector(), "U", "MAT_ELASTIC",
418 Sev::inform);
419
420 post_proc_norm_fe->getOpPtrVector().push_back(
422 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
423
424 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
425 post_proc_norm_fe);
426
427 CHKERR VecAssemblyBegin(norms_vec);
428 CHKERR VecAssemblyEnd(norms_vec);
429
430 MOFEM_LOG_CHANNEL("SELF"); // Clear channel from old tags
431 if (mField.get_comm_rank() == 0) {
432 const double *norms;
433 CHKERR VecGetArrayRead(norms_vec, &norms);
434 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
435 << "norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
436 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
437 << "norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
438 CHKERR VecRestoreArrayRead(norms_vec, &norms);
439 }
440
442}
#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.

◆ initialConditions()

MoFEMErrorCode Example::initialConditions ( )
private

[Create common data]

[Initial conditions]

Examples
thermoplastic.cpp.

Definition at line 3158 of file thermoplastic.cpp.

3158 {
3160
3161 auto vol_rule = [](int, int, int ao) { return 2 * ao + geom_order; };
3162
3163 // #ifdef PYTHON_INIT_SURFACE
3164 // auto get_py_surface_init = []() {
3165 // auto py_surf_init = boost::make_shared<SurfacePython>();
3166 // CHKERR py_surf_init->surfaceInit("surface.py");
3167 // surfacePythonWeakPtr = py_surf_init;
3168 // return py_surf_init;
3169 // };
3170 // auto py_surf_init = get_py_surface_init();
3171 // #endif
3172
3173 auto simple = mField.getInterface<Simple>();
3174
3175 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3176 // "REMOVE_X",
3177 // "U", 0, 0);
3178 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3179 // "REMOVE_Y",
3180 // "U", 1, 1);
3181 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3182 // "REMOVE_Z",
3183 // "U", 2, 2);
3184 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3185 // "REMOVE_ALL", "U", 0, 3);
3186
3187 // #ifdef ADD_CONTACT
3188 // for (auto b : {"FIX_X", "REMOVE_X"})
3189 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3190 // "SIGMA", 0, 0, false, true);
3191 // for (auto b : {"FIX_Y", "REMOVE_Y"})
3192 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3193 // "SIGMA", 1, 1, false, true);
3194 // for (auto b : {"FIX_Z", "REMOVE_Z"})
3195 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3196 // "SIGMA", 2, 2, false, true);
3197 // for (auto b : {"FIX_ALL", "REMOVE_ALL"})
3198 // CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), b,
3199 // "SIGMA", 0, 3, false, true);
3200 // CHKERR bc_mng->removeBlockDOFsOnEntities(
3201 // simple->getProblemName(), "NO_CONTACT", "SIGMA", 0, 3, false, true);
3202 // #endif
3203
3204 // CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
3205 // simple->getProblemName(), "U");
3206
3207 using UDO = ForcesAndSourcesCore::UserDataOperator;
3208
3209 auto T_ptr = boost::make_shared<VectorDouble>();
3210
3211 auto post_proc = [&](auto dm) {
3213
3214 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
3215
3217
3218 post_proc_fe->getOpPtrVector().push_back(
3219 new OpCalculateScalarFieldValues("T", T_ptr));
3220 // post_proc_fe->getOpPtrVector().push_back(
3221 // new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
3222 if (atom_test == 8) {
3223
3224 auto TAU_ptr = boost::make_shared<VectorDouble>();
3225 auto EP_ptr = boost::make_shared<MatrixDouble>();
3226
3227 post_proc_fe->getOpPtrVector().push_back(
3228 new OpCalculateScalarFieldValues("TAU", TAU_ptr));
3229 post_proc_fe->getOpPtrVector().push_back(
3231
3232 post_proc_fe->getOpPtrVector().push_back(
3233
3234 new OpPPMap(post_proc_fe->getPostProcMesh(),
3235 post_proc_fe->getMapGaussPts(),
3236
3237 {{"T", T_ptr}, {"TAU", TAU_ptr}},
3238
3239 {},
3240
3241 {},
3242
3243 {{"EP", EP_ptr}}
3244
3245 )
3246
3247 );
3248 } else {
3249 post_proc_fe->getOpPtrVector().push_back(
3250
3251 new OpPPMap(post_proc_fe->getPostProcMesh(),
3252 post_proc_fe->getMapGaussPts(),
3253
3254 {{"T", T_ptr}},
3255
3256 {},
3257
3258 {},
3259
3260 {}
3261
3262 )
3263
3264 );
3265 }
3266
3267 CHKERR DMoFEMLoopFiniteElements(dm, "dFE", post_proc_fe);
3268 CHKERR post_proc_fe->writeFile("out_init.h5m");
3269
3271 };
3272
3273 auto solve_init = [&]() {
3275
3276 auto set_domain_rhs = [&](auto &pip) {
3278
3280
3281 pip.push_back(new OpCalculateScalarFieldValues("T", T_ptr));
3282 pip.push_back(new OpRhsSetInitT<AT, IT>(
3283 "T", nullptr, T_ptr, nullptr, boost::make_shared<double>(init_temp),
3284 boost::make_shared<double>(peak_temp)));
3285
3286 if (atom_test == 8) {
3287 auto TAU_ptr = boost::make_shared<VectorDouble>();
3288 auto EP_ptr = boost::make_shared<MatrixDouble>();
3289
3290 pip.push_back(new OpCalculateScalarFieldValues("TAU", TAU_ptr));
3291 auto min_tau = boost::make_shared<double>(1.0);
3292 auto max_tau = boost::make_shared<double>(2.0);
3293 pip.push_back(new OpRhsSetInitT<AT, IT>("TAU", nullptr, TAU_ptr,
3294 nullptr, min_tau, max_tau));
3295
3297 "EP", EP_ptr));
3298 auto min_EP = boost::make_shared<double>(0.0);
3299 auto max_EP = boost::make_shared<double>(0.01);
3301 "EP", nullptr, EP_ptr, nullptr, min_EP, max_EP));
3302 }
3303
3304 // using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
3305 // AT>::template LinearForm<IT>;
3306 // using OpInternalForceCauchy =
3307 // typename B::template OpGradTimesSymTensor<1, SPACE_DIM, SPACE_DIM>;
3308 // using OpInternalForcePiola =
3309 // typename B::template OpGradTimesTensor<1, SPACE_DIM, SPACE_DIM>;
3310
3311 // using P = PlasticityIntegrators<DomainEleOp>;
3312
3313 // auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
3314 // common_thermoelastic_ptr, common_thermoplastic_ptr] =
3315 // createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
3316 // mField, "MAT_ELASTIC", "MAT_THERMAL", "MAT_THERMOPLASTIC", pip,
3317 // "U", "EP", "TAU", "T", scale, thermal_conductivity_scale,
3318 // heat_capacity_scale, inelastic_heat_fraction_scale,
3319 // Sev::inform);
3320 // auto m_D_ptr = common_hencky_ptr->matDPtr;
3321
3322 // using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
3323 // AT>::template LinearForm<IT>;
3324 // using H = HenckyOps::HenckyIntegrators<DomainEleOp>;
3325 // auto coeff_expansion_ptr = common_thermal_ptr->getCoeffExpansionPtr();
3326 // auto ref_temp_ptr = common_thermal_ptr->getRefTempPtr();
3327 // pip.push_back(new
3328 // typename H::template
3329 // OpCalculateHenckyThermalStress<SPACE_DIM, IT>(
3330 // "U", T_ptr, common_hencky_ptr,
3331 // coeff_expansion_ptr, ref_temp_ptr));
3332 // pip.push_back(new typename H::template
3333 // OpCalculatePiolaStress<SPACE_DIM, IT>(
3334 // "U", common_hencky_ptr));
3335 // using OpInternalForcePiola =
3336 // typename B::template OpGradTimesTensor<1, SPACE_DIM, SPACE_DIM>;
3337 // pip.push_back(new OpInternalForcePiola(
3338 // "U", common_hencky_ptr->getMatFirstPiolaStress()));
3339
3341 };
3342
3343 auto set_domain_lhs = [&](auto &pip) {
3345
3347
3348 using OpLhsScalarLeastSquaresProj = FormsIntegrators<
3349 DomainEleOp>::Assembly<AT>::BiLinearForm<IT>::OpMass<1, 1>;
3350 pip.push_back(new OpLhsScalarLeastSquaresProj("T", "T"));
3351 if (atom_test == 8) {
3352 pip.push_back(new OpLhsScalarLeastSquaresProj("TAU", "TAU"));
3353 pip.push_back(
3355 "EP", "EP"));
3356 }
3357
3358 // auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
3359 // common_thermoelastic_ptr, common_thermoplastic_ptr] =
3360 // createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
3361 // mField, "MAT_ELASTIC", "MAT_THERMAL", "MAT_THERMOPLASTIC", pip,
3362 // "U", "EP", "TAU", "T", scale, thermal_conductivity_scale,
3363 // heat_capacity_scale, inelastic_heat_fraction_scale,
3364 // Sev::inform);
3365
3366 // auto m_D_ptr = common_hencky_ptr->matDPtr;
3367
3368 // using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
3369 // AT>::template BiLinearForm<IT>;
3370 // using OpKPiola = typename B::template OpGradTensorGrad<1, SPACE_DIM,
3371 // SPACE_DIM, 1>;
3372
3373 // using H = HenckyIntegrators<DomainEleOp>;
3374 // pip.push_back(new OpCalculateScalarFieldValues("T", T_ptr));
3375 // auto coeff_expansion_ptr = common_thermal_ptr->getCoeffExpansionPtr();
3376 // auto ref_temp_ptr = common_thermal_ptr->getRefTempPtr();
3377 // pip.push_back(new
3378 // typename H::template
3379 // OpCalculateHenckyThermalStress<SPACE_DIM, IT>(
3380 // "U", T_ptr, common_hencky_ptr,
3381 // coeff_expansion_ptr, ref_temp_ptr));
3382 // pip.push_back(new typename H::template
3383 // OpCalculatePiolaStress<SPACE_DIM, IT>(
3384 // "U", common_hencky_ptr));
3385 // pip.push_back(new typename H::template OpHenckyTangent<SPACE_DIM, IT>(
3386 // "U", common_hencky_ptr));
3387 // pip.push_back(new OpKPiola("U", "U",
3388 // common_hencky_ptr->getMatTangent()));
3389 // pip.push_back(new typename HenckyOps::OpCalculateHenckyThermalStressdT<
3390 // SPACE_DIM, IT, AssemblyDomainEleOp>("U", "T",
3391 // common_hencky_ptr,
3392 // coeff_expansion_ptr));
3393
3395 };
3396
3397 auto create_sub_dm = [&](SmartPetscObj<DM> base_dm) {
3398 auto dm_sub = createDM(mField.get_comm(), "DMMOFEM");
3399 CHKERR DMMoFEMCreateSubDM(dm_sub, base_dm, "INIT_DM");
3400 CHKERR DMMoFEMSetSquareProblem(dm_sub, PETSC_TRUE);
3401 CHKERR DMMoFEMAddElement(dm_sub, simple->getDomainFEName());
3402 for (auto f : {"T"}) {
3405 }
3406 if (atom_test == 8) {
3407 for (auto f : {"TAU", "EP"}) {
3410 }
3411 }
3412 CHKERR DMSetUp(dm_sub);
3413 return dm_sub;
3414 };
3415
3416 auto fe_rhs = boost::make_shared<DomainEle>(mField);
3417 auto fe_lhs = boost::make_shared<DomainEle>(mField);
3418 fe_rhs->getRuleHook = vol_rule;
3419 fe_lhs->getRuleHook = vol_rule;
3420 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
3421 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
3422
3423 auto sub_dm = create_sub_dm(simple->getDM());
3424
3425 auto null_fe = boost::shared_ptr<FEMethod>();
3426 CHKERR DMMoFEMKSPSetComputeOperators(sub_dm, simple->getDomainFEName(),
3427 fe_lhs, null_fe, null_fe);
3428 CHKERR DMMoFEMKSPSetComputeRHS(sub_dm, simple->getDomainFEName(), fe_rhs,
3429 null_fe, null_fe);
3430
3431 auto ksp = MoFEM::createKSP(mField.get_comm());
3432 CHKERR KSPSetDM(ksp, sub_dm);
3433 CHKERR KSPSetFromOptions(ksp);
3434
3435 auto D = createDMVector(sub_dm);
3436
3437 CHKERR KSPSolve(ksp, PETSC_NULLPTR, D);
3438
3439 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
3440 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
3441 CHKERR DMoFEMMeshToGlobalVector(sub_dm, D, INSERT_VALUES, SCATTER_REVERSE);
3442
3444 };
3445
3446 CHKERR solve_init();
3447 CHKERR post_proc(simple->getDM());
3448
3449 MOFEM_LOG("THERMAL", Sev::inform) << "Set thermoelastic initial conditions";
3450
3452}
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set ghosted vector values on all existing mesh entities
Definition DMMoFEM.cpp:525
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 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.
[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/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_heat_radiation/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_heat_radiation/radiation.cpp.

Definition at line 230 of file radiation.cpp.

230 {
234 auto ts = pipeline_mng->createTSIM();
235
236 double ftime = 1;
237 CHKERR TSSetMaxTime(ts, 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 TSGetStepNumber(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_light_intensity_equation/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 ( BitRefLevel  bit,
BitRefLevel  mask 
)
private

[Initial conditions]

[Mechanical boundary conditions]

Examples
thermoplastic.cpp.

Definition at line 3456 of file thermoplastic.cpp.

3456 {
3458
3459 auto simple = mField.getInterface<Simple>();
3460 auto bc_mng = mField.getInterface<BcManager>();
3461
3462 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
3463 "U", 0, 0, true,
3465 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
3466 "U", 1, 1, true,
3468 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
3469 "U", 2, 2, true,
3471 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3472 "REMOVE_ALL", "U", 0, 3, true,
3474
3475#ifdef ADD_CONTACT
3476 for (auto b : {"FIX_X", "REMOVE_X"})
3477 CHKERR bc_mng->removeBlockDOFsOnEntities(
3478 simple->getProblemName(), b, "SIGMA", 0, 0, false, is_distributed_mesh);
3479 for (auto b : {"FIX_Y", "REMOVE_Y"})
3480 CHKERR bc_mng->removeBlockDOFsOnEntities(
3481 simple->getProblemName(), b, "SIGMA", 1, 1, false, is_distributed_mesh);
3482 for (auto b : {"FIX_Z", "REMOVE_Z"})
3483 CHKERR bc_mng->removeBlockDOFsOnEntities(
3484 simple->getProblemName(), b, "SIGMA", 2, 2, false, is_distributed_mesh);
3485 for (auto b : {"FIX_ALL", "REMOVE_ALL"})
3486 CHKERR bc_mng->removeBlockDOFsOnEntities(
3487 simple->getProblemName(), b, "SIGMA", 0, 3, false, is_distributed_mesh);
3488 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
3489 "NO_CONTACT", "SIGMA", 0, 3, false,
3491#endif
3492
3493 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
3494 simple->getProblemName(), "U");
3495
3496 auto &bc_map = bc_mng->getBcMapByBlockName();
3497 for (auto bc : bc_map)
3498 MOFEM_LOG("PLASTICITY", Sev::verbose) << "Marker " << bc.first;
3499
3501}
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_plasticity/plastic.cpp, mofem/tutorials/scl-8_heat_radiation/radiation.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 649 of file plastic.cpp.

649 {
651 auto pip_mng = mField.getInterface<PipelineManager>();
652
653 auto integration_rule_bc = [](int, int, int ao) { return 2 * ao; };
654
655 auto vol_rule = [](int, int, int ao) { return 2 * ao + geom_order - 1; };
656
657 auto add_boundary_ops_lhs_mechanical = [&](auto &pip) {
659
661 pip, {HDIV}, "GEOMETRY");
662 pip.push_back(new OpSetHOWeightsOnSubDim<SPACE_DIM>());
663
664 // Add Natural BCs to LHS
666 pip, mField, "U", Sev::inform);
667
668#ifdef ADD_CONTACT
670 CHKERR
671 ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
672 pip, "SIGMA", "U");
673 CHKERR
674 ContactOps::opFactoryBoundaryToDomainLhs<SPACE_DIM, AT, IT, DomainEle>(
675 mField, pip, simple->getDomainFEName(), "SIGMA", "U", "GEOMETRY",
676 vol_rule);
677#endif // ADD_CONTACT
678
680 };
681
682 auto add_boundary_ops_rhs_mechanical = [&](auto &pip) {
684
686 pip, {HDIV}, "GEOMETRY");
687 pip.push_back(new OpSetHOWeightsOnSubDim<SPACE_DIM>());
688
689 // Add Natural BCs to RHS
691 pip, mField, "U", {boost::make_shared<ScaledTimeScale>()}, Sev::inform);
692
693#ifdef ADD_CONTACT
694 CHKERR ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
695 pip, "SIGMA", "U");
696#endif // ADD_CONTACT
697
699 };
700
701 auto add_domain_ops_lhs = [this](auto &pip) {
704 pip, {H1, HDIV}, "GEOMETRY");
705
706 if (is_quasi_static == PETSC_FALSE) {
707
708 //! [Only used for dynamics]
711 //! [Only used for dynamics]
712
713 auto get_inertia_and_mass_damping = [this](const double, const double,
714 const double) {
715 auto *pip = mField.getInterface<PipelineManager>();
716 auto &fe_domain_lhs = pip->getDomainLhsFE();
717 return (rho / scale) * fe_domain_lhs->ts_aa +
718 (alpha_damping / scale) * fe_domain_lhs->ts_a;
719 };
720 pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
721 }
722
723 CHKERR PlasticOps::opFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
724 mField, "MAT_PLASTIC", pip, "U", "EP", "TAU");
725
727 };
728
729 auto add_domain_ops_rhs = [this](auto &pip) {
731
733 pip, {H1, HDIV}, "GEOMETRY");
734
736 pip, mField, "U",
737 {boost::make_shared<ScaledTimeScale>("body_force_hist.txt")},
738 Sev::inform);
739
740 // only in case of dynamics
741 if (is_quasi_static == PETSC_FALSE) {
742
743 //! [Only used for dynamics]
746 //! [Only used for dynamics]
747
748 auto mat_acceleration = boost::make_shared<MatrixDouble>();
750 "U", mat_acceleration));
751 pip.push_back(
752 new OpInertiaForce("U", mat_acceleration, [](double, double, double) {
753 return rho / scale;
754 }));
755 if (alpha_damping > 0) {
756 auto mat_velocity = boost::make_shared<MatrixDouble>();
757 pip.push_back(
758 new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", mat_velocity));
759 pip.push_back(
760 new OpInertiaForce("U", mat_velocity, [](double, double, double) {
761 return alpha_damping / scale;
762 }));
763 }
764 }
765
766 CHKERR PlasticOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
767 mField, "MAT_PLASTIC", pip, "U", "EP", "TAU");
768
769#ifdef ADD_CONTACT
770 CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
771 pip, "SIGMA", "U");
772#endif // ADD_CONTACT
773
775 };
776
777 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
778 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
779
780 // Boundary
781 CHKERR add_boundary_ops_lhs_mechanical(pip_mng->getOpBoundaryLhsPipeline());
782 CHKERR add_boundary_ops_rhs_mechanical(pip_mng->getOpBoundaryRhsPipeline());
783
784 CHKERR pip_mng->setDomainRhsIntegrationRule(vol_rule);
785 CHKERR pip_mng->setDomainLhsIntegrationRule(vol_rule);
786
787 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_bc);
788 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_bc);
789
790 auto create_reaction_pipeline = [&](auto &pip) {
793 pip, {H1}, "GEOMETRY");
794 CHKERR PlasticOps::opFactoryDomainReactions<SPACE_DIM, AT, IT, DomainEleOp>(
795 mField, "MAT_PLASTIC", pip, "U", "EP", "TAU");
797 };
798
799 CHKERR pip_mng->setEvaluationIntegrationRule(vol_rule);
800 CHKERR create_reaction_pipeline(pip_mng->getOpEvaluationPipeline());
801 auto &reaction_fe = pip_mng->getEvaluationFE();
802 reaction_fe->postProcessHook =
804
806}
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, SPACE_DIM > OpInertiaForce
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 1041 of file thermoplastic.cpp.

1045 {
1047
1048 using namespace HenckyOps;
1050
1051 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
1052 A>::template BiLinearForm<I>;
1053 using OpKPiola = typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
1054 using OpKCauchy = typename B::template OpGradSymTensorGrad<1, DIM, DIM, 0>;
1055
1057
1058 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1059 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1060 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
1061 m_field, block_name, thermal_block_name, thermoelastic_block_name,
1062 thermoplastic_block_name, pip, u, ep, tau, temperature, scale,
1064 inelastic_heat_fraction_scaling, Sev::inform);
1065
1066 auto m_D_ptr = common_hencky_ptr->matDPtr;
1067
1069 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
1070 pip.push_back(new OpCalculateScalarFieldValuesDot(
1071 tau, common_plastic_ptr->getPlasticTauDotPtr()));
1072 pip.push_back(new typename P::template OpCalculatePlasticity<DIM, I>(
1073 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1074
1075 if (common_hencky_ptr) {
1076 pip.push_back(new typename H::template OpHenckyTangent<DIM, I, 0>(
1077 u, common_hencky_ptr, m_D_ptr));
1078 pip.push_back(new OpKPiola(u, u, common_hencky_ptr->getMatTangent()));
1079 pip.push_back(
1080 new typename P::template Assembly<A>::
1081 template OpCalculatePlasticInternalForceLhs_LogStrain_dEP<DIM, I>(
1082 u, ep, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1083 } else {
1084 pip.push_back(new OpKCauchy(u, u, m_D_ptr));
1085 pip.push_back(new typename P::template Assembly<A>::
1086 template OpCalculatePlasticInternalForceLhs_dEP<DIM, I>(
1087 u, ep, common_plastic_ptr, m_D_ptr));
1088 }
1089
1090 if (common_hencky_ptr) {
1091 pip.push_back(
1092 new typename P::template Assembly<A>::
1093 template OpCalculateConstraintsLhs_LogStrain_dU<DIM, I>(
1094 tau, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1095 pip.push_back(
1096 new typename P::template Assembly<A>::
1097 template OpCalculatePlasticFlowLhs_LogStrain_dU<DIM, I>(
1098 ep, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1099 } else {
1100 pip.push_back(new typename P::template Assembly<A>::
1101 template OpCalculateConstraintsLhs_dU<DIM, I>(
1102 tau, u, common_plastic_ptr, m_D_ptr));
1103 pip.push_back(new typename P::template Assembly<A>::
1104 template OpCalculatePlasticFlowLhs_dU<DIM, I>(
1105 ep, u, common_plastic_ptr, m_D_ptr));
1106 }
1107
1108 pip.push_back(new typename P::template Assembly<A>::
1109 template OpCalculatePlasticFlowLhs_dEP<DIM, I>(
1110 ep, ep, common_plastic_ptr, m_D_ptr));
1111 pip.push_back(new typename P::template Assembly<A>::
1112 template OpCalculatePlasticFlowLhs_dTAU<DIM, I>(
1113 ep, tau, common_plastic_ptr, m_D_ptr));
1114 pip.push_back(
1116 ep, temperature, common_thermoplastic_ptr));
1117 pip.push_back(new typename P::template Assembly<A>::
1118 template OpCalculateConstraintsLhs_dEP<DIM, I>(
1119 tau, ep, common_plastic_ptr, m_D_ptr));
1120 pip.push_back(
1121 new typename P::template Assembly<
1122 A>::template OpCalculateConstraintsLhs_dTAU<I>(tau, tau,
1123 common_plastic_ptr));
1124
1125 // TODO: add scenario for when not using Hencky material
1126 pip.push_back(new typename H::template OpCalculateHenckyThermalStressdT<
1127 DIM, I, AssemblyDomainEleOp, 0>(
1128 u, temperature, common_hencky_ptr,
1129 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1130
1131 auto inelastic_heat_frac_ptr =
1132 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
1134 [inelastic_heat_frac_ptr](const double, const double, const double) {
1135 return (*inelastic_heat_frac_ptr);
1136 };
1137
1138 // TODO: add scenario for when not using Hencky material
1141 temperature, temperature, common_hencky_ptr, common_plastic_ptr,
1143 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1144
1145 // TODO: add scenario for when not using Hencky material
1148 temperature, ep, common_hencky_ptr, common_plastic_ptr,
1150
1151 // TODO: add scenario for when not using Hencky material
1154 temperature, u, common_hencky_ptr, common_plastic_ptr,
1156
1158 tau, temperature, common_thermoplastic_ptr));
1159
1161 }
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
constexpr IntegrationType I
constexpr AssemblyType A
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 960 of file thermoplastic.cpp.

964 {
966
967 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
968 A>::template LinearForm<I>;
970 typename B::template OpGradTimesSymTensor<1, DIM, DIM>;
972 typename B::template OpGradTimesTensor<1, DIM, DIM>;
973
975
977
978 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
979 common_thermoelastic_ptr, common_thermoplastic_ptr] =
980 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
981 m_field, block_name, thermal_block_name, thermoelastic_block_name,
982 thermoplastic_block_name, pip, u, ep, tau, temperature, scale,
985
986 auto m_D_ptr = common_hencky_ptr->matDPtr;
987
989 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
990 pip.push_back(new OpCalculateScalarFieldValuesDot(
991 tau, common_plastic_ptr->getPlasticTauDotPtr()));
992 pip.push_back(new OpCalculateScalarFieldValues(
993 temperature, common_thermoplastic_ptr->getTempPtr()));
995 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
996 pip.push_back(new typename P::template OpCalculatePlasticity<DIM, I>(
997 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
998
999 pip.push_back(
1000 new
1001 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
1002 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
1003 common_thermoelastic_ptr->getCoeffExpansionPtr(),
1004 common_thermoelastic_ptr->getRefTempPtr()));
1005
1006 // Calculate internal forces
1007 if (common_hencky_ptr) {
1008 pip.push_back(new OpInternalForcePiola(
1009 u, common_hencky_ptr->getMatFirstPiolaStress()));
1010 } else {
1011 pip.push_back(
1012 new OpInternalForceCauchy(u, common_plastic_ptr->mStressPtr));
1013 }
1014
1015 auto inelastic_heat_frac_ptr =
1016 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
1018 [inelastic_heat_frac_ptr](const double, const double, const double) {
1019 return (*inelastic_heat_frac_ptr);
1020 };
1021
1022 // TODO: add scenario for when not using Hencky material
1025 temperature, common_hencky_ptr->getMatHenckyStress(),
1026 common_plastic_ptr->getPlasticStrainDotPtr(), inelastic_heat_fraction));
1027
1028 pip.push_back(
1029 new
1030 typename P::template Assembly<A>::template OpCalculateConstraintsRhs<I>(
1031 tau, common_plastic_ptr, m_D_ptr));
1032 pip.push_back(
1033 new
1034 typename P::template Assembly<A>::template OpCalculatePlasticFlowRhs<
1035 DIM, I>(ep, common_plastic_ptr, m_D_ptr));
1036
1038 }
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/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6_dg_projection/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/mix-1_light_intensity_equation/phase.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, and nonlinear_elastic.cpp.

Definition at line 1156 of file dynamic_first_order_con_law.cpp.

1156 {
1158 PetscBool test_flg = PETSC_FALSE;
1159 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test", &test_flg, PETSC_NULLPTR);
1160 if (test_flg) {
1161 auto *simple = mField.getInterface<Simple>();
1162 auto T = createDMVector(simple->getDM());
1163 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
1164 SCATTER_FORWARD);
1165 double nrm2;
1166 CHKERR VecNorm(T, NORM_2, &nrm2);
1167 MOFEM_LOG("EXAMPLE", Sev::inform) << "Regression norm " << nrm2;
1168 constexpr double regression_value = 0.0194561;
1169 if (fabs(nrm2 - regression_value) > 1e-2)
1170 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1171 "Regression test failed; wrong norm value.");
1172 }
1174}

◆ 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 491 of file phase.cpp.

491 {
494
496
497 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
498 CHKERR AddHOOps<2, 2, 2>::add(post_proc_fe->getOpPtrVector(), {HDIV, L2});
499
500 auto phi_ptr = boost::make_shared<VectorDouble>();
501 auto s_ptr = boost::make_shared<MatrixDouble>();
502 post_proc_fe->getOpPtrVector().push_back(
503 new OpCalculateScalarFieldValues("PHI", phi_ptr));
504 post_proc_fe->getOpPtrVector().push_back(
505 new OpCalculateHVecVectorField<3>("S", s_ptr));
506
508
509 post_proc_fe->getOpPtrVector().push_back(
510
511 new OpPPMap(post_proc_fe->getPostProcMesh(),
512 post_proc_fe->getMapGaussPts(),
513
514 OpPPMap::DataMapVec{{"PHI", phi_ptr}},
515
516 OpPPMap::DataMapMat{{"S", s_ptr}},
517
519
521
522 )
523
524 );
525
526 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
527 CHKERR pipeline_mng->loopFiniteElementsPostProc();
528 CHKERR post_proc_fe->writeFile("out_" + boost::lexical_cast<std::string>(i) +
529 ".h5m");
531}
MoFEMErrorCode loopFiniteElementsPostProc(SmartPetscObj< DM > dm=nullptr)
Iterate postprocessing finite elements.
std::map< std::string, ScalarDataPtr > DataMapVec
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
boost::shared_ptr< FEMethod > & getDomainPostProcFE()
Get domain postprocessing finite element.

◆ outputResults() [12/12]

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

[Project results]

[Output results]

Definition at line 521 of file between_meshes_dg_projection.cpp.

521 {
523
524 auto pipeline_mng = mField.getInterface<PipelineManager>();
525
526 auto post_proc_fe = boost::make_shared<PostProcFaceEle>(mField);
528 post_proc_fe->getOpPtrVector(), {H1});
529
530 auto u_ptr = boost::make_shared<VectorDouble>();
531 post_proc_fe->getOpPtrVector().push_back(
533 auto s_ptr = boost::make_shared<VectorDouble>();
534 post_proc_fe->getOpPtrVector().push_back(
536
537 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
538 post_proc_fe->getOpPtrVector().push_back(
540 auto grad_s_ptr = boost::make_shared<MatrixDouble>();
541 post_proc_fe->getOpPtrVector().push_back(
543
544
546
547 post_proc_fe->getOpPtrVector().push_back(
548
549 new OpPPMap(
550 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
551
552 OpPPMap::DataMapVec{{FIELD_NAME_U, u_ptr}, {FIELD_NAME_S, s_ptr}},
553
555
556 {"GRAD_" + std::string(FIELD_NAME_U), grad_u_ptr},
557 {"GRAD_" + std::string(FIELD_NAME_S), grad_s_ptr}
558
559 },
560
562
564
565 )
566
567 );
568
569 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
570 CHKERR pipeline_mng->loopFiniteElementsPostProc();
571 CHKERR post_proc_fe->writeFile(file_name);
572
574}
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/integration.cpp, and mofem/tutorials/scl-8_heat_radiation/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() [1/2]

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

Post-process and output results.

[Solve]

[Postprocess results]

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

Definition at line 1326 of file adjoint.cpp.

1327 {
1329 auto simple = mField.getInterface<Simple>();
1332 mField, simple->getDM(), simple->getDomainFEName(),
1333 "out_elastic_" + std::to_string(iter) + ".h5m",
1334 {{"ADJOINT", adjoint_vector}}, {}, Sev::noisy);
1336}
MoFEMErrorCode postProcessElasticResults(MoFEM::Interface &mField, SmartPetscObj< DM > dm, const std::string &domain_fe_name, const std::string &out_file_name, std::vector< std::pair< std::string, SmartPetscObj< Vec > > > extra_vectors={}, const std::vector< std::string > &tags_to_transfer={}, const Sev hooke_ops_sev=Sev::verbose)
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:62
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::BoundaryEle BoundaryEle
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::DomainEle DomainEle

◆ postprocessElastic() [2/2]

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

Post-process and output results.

[Solve]

[Postprocess results]

Definition at line 678 of file gradient.cpp.

681 {
684 std::vector<std::pair<std::string, SmartPetscObj<Vec>>> additional_vecs;
685 if (gradient_vector) {
686 additional_vecs.emplace_back("GRADIENT", gradient_vector);
687 }
688 if (adjoint_vector) {
689 additional_vecs.emplace_back("ADJOINT", adjoint_vector);
690 }
691 if (dJ_du) {
692 additional_vecs.emplace_back("dJ_dU", dJ_du);
693 }
696 mField, simple->getDM(), simple->getDomainFEName(),
697 "out_elastic_" + std::to_string(iter) + ".h5m", additional_vecs,
698 {}, Sev::noisy);
700}

◆ projectResults()

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

[Solve]

[Project results]

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

Definition at line 256 of file between_meshes_dg_projection.cpp.

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

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/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6_dg_projection/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/mix-1_light_intensity_equation/phase.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp, and nonlinear_elastic.cpp.

Definition at line 459 of file dynamic_first_order_con_law.cpp.

459 {
462
464 CHKERR simple->loadFile();
466}
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180

◆ readMesh() [2/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [3/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [4/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [5/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [6/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [7/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [8/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [9/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [10/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [11/14]

MoFEMErrorCode Example::readMesh ( )
private

Read mesh from file and setup meshsets.

◆ readMesh() [12/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [13/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [14/14]

MoFEMErrorCode Example::readMesh ( )
private

◆ refineSkin()

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

[Edge flips]

[Refine skin]

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

Definition at line 766 of file between_meshes_dg_projection.cpp.

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

◆ reSetupProblem()

MoFEMErrorCode Example::reSetupProblem ( BitRefLevel  child_bit)
private

[Refine skin]

[Re-setup problem after mesh modification

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

Definition at line 798 of file between_meshes_dg_projection.cpp.

798 {
800 simpleInterface->getBitRefLevel() = child_bit;
803}
MoFEMErrorCode reSetUp(bool only_dm=false)
Rebuild internal MoFEM data structures.
Definition Simple.cpp:761
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_light_intensity_equation/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/19]

MoFEMErrorCode Example::runProblem ( )

[Run problem]

[Refine edges]

[Run topology optimization problem]

[Create common data]

[OpError def]

[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_plasticity/plastic.cpp, mofem/tutorials/adv-4_dynamic_first_order_con_law/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6_dg_projection/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-1_integration/integration.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/mix-1_light_intensity_equation/phase.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-8_heat_radiation/radiation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp, nonlinear_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 255 of file plastic.cpp.

255 {
259 CHKERR bC();
260 CHKERR OPs();
261 PetscBool test_ops = PETSC_FALSE;
262 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_operators", &test_ops,
263 PETSC_NULLPTR);
264 if (test_ops == PETSC_FALSE) {
265 CHKERR tsSolve();
266 } else {
268 }
270}
MoFEMErrorCode testOperators()
[Solve]
Definition plastic.cpp:1485
MoFEMErrorCode tsSolve()
Definition plastic.cpp:833
MoFEMErrorCode createCommonData()
[Set up problem]
Definition plastic.cpp:479
MoFEMErrorCode OPs()
[Boundary condition]
Definition plastic.cpp:649
MoFEMErrorCode setupProblem()
[Run problem]
Definition plastic.cpp:274
MoFEMErrorCode bC()
[Create common data]
Definition plastic.cpp:605

◆ runProblem() [2/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [3/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [4/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [5/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [6/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [7/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [8/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [9/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [10/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [11/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [12/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [13/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [14/19]

MoFEMErrorCode Example::runProblem ( )

Main driver function for the optimization process.

◆ runProblem() [15/19]

MoFEMErrorCode Example::runProblem ( )

Main driver function for the optimization process.

◆ runProblem() [16/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [17/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [18/19]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [19/19]

MoFEMErrorCode Example::runProblem ( )

◆ setFieldValues()

MoFEMErrorCode Example::setFieldValues ( )
private

[Create common data]

[Set density distribution]

Examples
mofem/tutorials/fun-1_integration/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

◆ 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/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() [1/2]

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

[Setup adjoint]

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

Definition at line 602 of file adjoint.cpp.

602 {
605
606 // Create adjoint data manager and field
607 auto create_adjoint_dm = [&]() {
608 auto adjoint_dm = createDM(mField.get_comm(), "DMMOFEM");
609
610 auto add_field = [&]() {
612 CHKERR mField.add_field("ADJOINT_FIELD", H1, base, SPACE_DIM);
614 "ADJOINT_FIELD");
615 for (auto tt = MBEDGE; tt <= moab::CN::TypeDimensionMap[SPACE_DIM].second;
616 ++tt)
617 CHKERR mField.set_field_order(simple->getMeshset(), tt, "ADJOINT_FIELD",
618 fieldOrder);
619 CHKERR mField.set_field_order(simple->getMeshset(), MBVERTEX,
620 "ADJOINT_FIELD", 1);
623 };
624
625 auto add_adjoint_fe_impl = [&]() {
627 CHKERR mField.add_finite_element("ADJOINT_DOMAIN_FE");
629 "ADJOINT_FIELD");
631 "ADJOINT_FIELD");
633 "ADJOINT_FIELD");
635 "GEOMETRY");
637 simple->getMeshset(), SPACE_DIM, "ADJOINT_DOMAIN_FE");
638 CHKERR mField.build_finite_elements("ADJOINT_DOMAIN_FE");
639
640 CHKERR mField.add_finite_element("ADJOINT_BOUNDARY_FE");
642 "ADJOINT_FIELD");
644 "ADJOINT_FIELD");
646 "ADJOINT_FIELD");
648 "GEOMETRY");
649
650 auto block_name = "OPTIMISE";
651 auto mesh_mng = mField.getInterface<MeshsetsManager>();
652 auto bcs = mesh_mng->getCubitMeshsetPtr(
653
654 std::regex((boost::format("%s(.*)") % block_name).str())
655
656 );
657
658 for (auto bc : bcs) {
660 bc->getMeshset(), SPACE_DIM - 1, "ADJOINT_BOUNDARY_FE");
661 }
662
663 CHKERR mField.build_finite_elements("ADJOINT_BOUNDARY_FE");
664
665 CHKERR mField.build_adjacencies(simple->getBitRefLevel(),
666 simple->getBitRefLevelMask());
667
669 };
670
671 auto set_adjoint_dm_imp = [&]() {
673 CHKERR DMMoFEMCreateMoFEM(adjoint_dm, &mField, "ADJOINT",
674 simple->getBitRefLevel(),
675 simple->getBitRefLevelMask());
676 CHKERR DMMoFEMSetDestroyProblem(adjoint_dm, PETSC_TRUE);
677 CHKERR DMSetFromOptions(adjoint_dm);
678 CHKERR DMMoFEMAddElement(adjoint_dm, "ADJOINT_DOMAIN_FE");
679 CHKERR DMMoFEMAddElement(adjoint_dm, "ADJOINT_BOUNDARY_FE");
680 CHKERR DMMoFEMSetSquareProblem(adjoint_dm, PETSC_TRUE);
681 CHKERR DMMoFEMSetIsPartitioned(adjoint_dm, PETSC_TRUE);
682 mField.getInterface<ProblemsManager>()->buildProblemFromFields =
683 PETSC_TRUE;
684 CHKERR DMSetUp(adjoint_dm);
685 mField.getInterface<ProblemsManager>()->buildProblemFromFields =
686 PETSC_FALSE;
688 };
689
690 CHK_THROW_MESSAGE(add_field(), "add adjoint field");
691 CHK_THROW_MESSAGE(add_adjoint_fe_impl(), "add adjoint fe");
692 CHK_THROW_MESSAGE(set_adjoint_dm_imp(), "set adjoint dm");
693
694 return adjoint_dm;
695 };
696
697 adjointDM = create_adjoint_dm();
698
700}
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:164
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.
Interface for managing meshsets containing materials and boundary conditions.
Problem manager is used to build and partition problems.

◆ setupAdJoint() [2/2]

MoFEMErrorCode Example::setupAdJoint ( )
private

◆ setupProblem() [1/18]

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_plasticity/plastic.cpp, mofem/tutorials/adv-4_dynamic_first_order_con_law/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6_dg_projection/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/mix-1_light_intensity_equation/phase.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-8_heat_radiation/radiation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp, nonlinear_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 274 of file plastic.cpp.

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

◆ setupProblem() [2/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [3/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [4/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [5/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [6/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [7/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [8/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [9/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [10/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [11/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [12/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [13/18]

MoFEMErrorCode Example::setupProblem ( )
private

Setup fields, approximation spaces and DOFs.

◆ setupProblem() [14/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [15/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [16/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [17/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [18/18]

MoFEMErrorCode Example::setupProblem ( )
private

◆ solveElastic() [1/2]

MoFEMErrorCode Example::solveElastic ( )
private

Solve forward elastic problem.

[Push operators to pipeline]

[Solve]

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

Definition at line 1198 of file adjoint.cpp.

1198 {
1200 auto simple = mField.getInterface<Simple>();
1201 auto dm = simple->getDM();
1202 auto f = createDMVector(dm);
1203 auto d = vectorDuplicate(f);
1204 CHKERR VecZeroEntries(d);
1205 CHKERR DMoFEMMeshToLocalVector(dm, d, INSERT_VALUES, SCATTER_REVERSE);
1206
1207 auto set_essential_bc = [&]() {
1209 // This is low level pushing finite elements (pipelines) to solver
1210
1211 auto ksp_ctx_ptr = getDMKspCtx(dm);
1212 auto pre_proc_rhs = boost::make_shared<FEMethod>();
1213 auto post_proc_rhs = boost::make_shared<FEMethod>();
1214 auto post_proc_lhs = boost::make_shared<FEMethod>();
1215
1216 auto get_pre_proc_hook = [&]() {
1218 {});
1219 };
1220 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
1221
1222 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
1224
1226 post_proc_rhs, 1.)();
1228 };
1229
1230 auto get_post_proc_hook_lhs = [this, post_proc_lhs]() {
1232
1234 post_proc_lhs, 1.)();
1236 };
1237
1238 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1239 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
1240
1241 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
1242 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
1243 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
1245 };
1246
1247 auto setup_and_solve = [&](auto solver) {
1249 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
1250 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSetUp";
1251 CHKERR KSPSetUp(solver);
1252 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSetUp <= Done";
1253 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSolve";
1254 CHKERR KSPSolve(solver, f, d);
1255 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSolve <= Done";
1257 };
1258
1259 MOFEM_LOG_CHANNEL("TIMER");
1260 MOFEM_LOG_TAG("TIMER", "timer");
1261
1262 CHKERR set_essential_bc();
1263 CHKERR setup_and_solve(kspElastic);
1264
1265 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
1266 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
1267 CHKERR DMoFEMMeshToLocalVector(dm, d, INSERT_VALUES, SCATTER_REVERSE);
1268
1269 auto evaluate_field_at_the_point = [&]() {
1271
1272 int coords_dim = 3;
1273 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
1274 PetscBool do_eval_field = PETSC_FALSE;
1275 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
1276 field_eval_coords.data(), &coords_dim,
1277 &do_eval_field);
1278
1279 if (do_eval_field) {
1280
1281 vectorFieldPtr = boost::make_shared<MatrixDouble>();
1282 auto field_eval_data =
1283 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
1284
1286 ->buildTree<SPACE_DIM>(field_eval_data, simple->getDomainFEName());
1287
1288 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1289 auto no_rule = [](int, int, int) { return -1; };
1290 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
1291 field_eval_fe_ptr->getRuleHook = no_rule;
1292
1293 field_eval_fe_ptr->getOpPtrVector().push_back(
1295
1297 ->evalFEAtThePoint<SPACE_DIM>(
1298 field_eval_coords.data(), 1e-12, simple->getProblemName(),
1299 simple->getDomainFEName(), field_eval_data,
1301 QUIET);
1302
1303 if (vectorFieldPtr->size1()) {
1304 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*vectorFieldPtr);
1305 if constexpr (SPACE_DIM == 2)
1306 MOFEM_LOG("FieldEvaluator", Sev::inform)
1307 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1);
1308 else
1309 MOFEM_LOG("FieldEvaluator", Sev::inform)
1310 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1)
1311 << " U_Z: " << t_disp(2);
1312 }
1313
1315 }
1317 };
1318
1319 CHKERR evaluate_field_at_the_point();
1320
1322}
#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:1251
boost::shared_ptr< MatrixDouble > vectorFieldPtr
Field values at evaluation points.
Definition adjoint.cpp:137
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:120

◆ solveElastic() [2/2]

MoFEMErrorCode Example::solveElastic ( )
private

Solve forward elastic problem.

◆ solveSystem() [1/12]

MoFEMErrorCode Example::solveSystem ( )
private

[Solve]

[Assemble system]

[Push operators to pipeline]

[Solve]

< Mass matrix

< Linear solver

Examples
mofem/tutorials/adv-4_dynamic_first_order_con_law/dynamic_first_order_con_law.cpp, mofem/tutorials/adv-6_dg_projection/between_meshes_dg_projection.cpp, mofem/tutorials/clx-0_acoustics/helmholtz.cpp, mofem/tutorials/fun-2_plot_base/plot_base.cpp, mofem/tutorials/mix-1_light_intensity_equation/phase.cpp, mofem/tutorials/scl-0_least_squares/approximation.cpp, mofem/tutorials/scl-9_heat_method/heat_method.cpp, mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp, mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp, and nonlinear_elastic.cpp.

Definition at line 873 of file dynamic_first_order_con_law.cpp.

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

◆ 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

◆ testGradient()

MoFEMErrorCode Example::testGradient ( Vec  gradient_vector)
private

[calculateGradient]

[Finite difference check]

Definition at line 1166 of file gradient.cpp.

1166 {
1168
1169 PetscBool gradient_fd_check = PETSC_FALSE;
1170 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, PETSC_NULLPTR, "-gradient_fd_check",
1171 &gradient_fd_check, PETSC_NULLPTR);
1172 if (gradient_fd_check) {
1173
1174 PetscInt nb_modes = 5;
1175 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, PETSC_NULLPTR,
1176 "-gradient_nb_modes", &nb_modes, PETSC_NULLPTR);
1177
1178 auto simple = mField.getInterface<Simple>();
1179 auto dm = simple->getDM();
1180 auto *adj_problem_ptr = getProblemPtr(adjointDM);
1181
1182 auto fe_rule = [](int, int, int p_data) { return 2 * p_data + p_data - 1; };
1183 auto get_objective_fe = [&](auto glob_objective_ptr, auto fe_rule) {
1184 auto fe_obj_fe = boost::make_shared<DomainEle>(mField);
1185 fe_obj_fe->getRuleHook = fe_rule;
1186 auto &pip = fe_obj_fe->getOpPtrVector();
1188 auto jac_ptr = boost::make_shared<MatrixDouble>();
1189 auto u_ptr = boost::make_shared<MatrixDouble>();
1191 "GEOMETRY", jac_ptr));
1192 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1193 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1194 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1195 pip.push_back(new OpObjective(pythonPtr, common_ptr, jac_ptr, u_ptr,
1196 glob_objective_ptr));
1197 return fe_obj_fe;
1198 };
1199
1200 auto f = boost::make_shared<double>(0.);
1201 auto fe_obj = get_objective_fe(f, fe_rule);
1202 CacheTupleSharedPtr tmp_cache_ptr = boost::make_shared<CacheTuple>();
1203 CHKERR mField.cache_problem_entities(simple->getProblemName(),
1204 tmp_cache_ptr);
1205
1206 auto evaluate_objective_terms = [&](auto objective_fe, auto objective_ptr,
1207 double &objective_value) {
1209 *objective_ptr = 0.0;
1210 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
1211 objective_fe);
1212 MPI_Allreduce(MPI_IN_PLACE, objective_ptr.get(), 1, MPI_DOUBLE, MPI_SUM,
1213 mField.get_comm());
1214 objective_value = *objective_ptr;
1216 };
1217
1218 auto geometry_bit_number = mField.get_field_bit_number("GEOMETRY");
1219 for (PetscInt mode = 0; mode < nb_modes; ++mode) {
1220 MOFEM_LOG_CHANNEL("WORLD");
1221 MOFEM_LOG("WORLD", Sev::verbose) << "Processing mode: " << mode;
1222
1223 auto &adj_dofs =
1224 adj_problem_ptr->getNumeredRowDofsPtr()->get<PetscGlobalIdx_mi_tag>();
1225 auto &dofs = mField.get_dofs()->get<Unique_mi_tag>();
1226
1227 auto a_dof = adj_dofs.find(mode);
1228 if (a_dof != adj_dofs.end()) {
1229 auto ent = (*a_dof)->getEnt();
1230 auto dof_idx = (*a_dof)->getEntDofIdx();
1232 dof_idx,
1233 FieldEntity::getLocalUniqueIdCalculate(geometry_bit_number, ent));
1234 auto dof = dofs.find(uid);
1235 if (dof != dofs.end()) {
1236 auto org_geom_val = (*dof)->getFieldData();
1237 constexpr double eps = 1e-6;
1238
1239 (*dof)->getFieldData() = org_geom_val + eps;
1240 CHKERR KSPReset(kspElastic);
1242 double f_plus;
1243 CHKERR evaluate_objective_terms(fe_obj, f, f_plus);
1244
1245 (*dof)->getFieldData() = org_geom_val - eps;
1246 CHKERR KSPReset(kspElastic);
1248 double f_minus;
1249 CHKERR evaluate_objective_terms(fe_obj, f, f_minus);
1250
1251 double *g_array;
1252 CHKERR VecGetArray(gradient_vector, &g_array);
1253 if ((*a_dof)->getHasLocalIndex()) {
1254 auto adjoint_grad = g_array[(*a_dof)->getPetscLocalDofIdx()];
1255 auto finite_diff_grad = (f_plus - f_minus) / (2 * eps);
1256 auto err = std::abs(adjoint_grad - finite_diff_grad) /
1257 std::max(std::abs(adjoint_grad),
1258 std::abs(finite_diff_grad));
1259 MOFEM_LOG("WORLD", Sev::inform)
1260 << "Mode: " << mode << ", Adjoint gradient: " << adjoint_grad
1261 << ", Finite difference gradient: " << finite_diff_grad
1262 << ", Relative error: "
1263 << std::abs(adjoint_grad - finite_diff_grad) /
1264 std::max(std::abs(adjoint_grad),
1265 std::abs(finite_diff_grad));
1266 constexpr double tol = 1e-4;
1267 if (err > tol) {
1268 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
1269 "Gradient check failed for mode %d: relative error %e is "
1270 "greater than tolerance %e",
1271 mode, err, tol);
1272 }
1273 }
1274
1275 CHKERR VecRestoreArray(gradient_vector, &g_array);
1276
1277 constexpr bool restore_solution = false;
1278 if constexpr (restore_solution) {
1279 (*dof)->getFieldData() = org_geom_val;
1280 CHKERR KSPReset(kspElastic);
1282 }
1283 }
1284 }
1285 }
1286 }
1287
1289}
virtual const DofEntity_multiIndex * get_dofs() const =0
Get the dofs object.
double tol
boost::shared_ptr< CacheTuple > CacheTupleSharedPtr
auto getProblemPtr(DM dm)
get problem pointer from DM
Definition DMMoFEM.hpp:1182
MoFEMErrorCode solveElastic()
Solve forward elastic problem.
Definition adjoint.cpp:1198
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
virtual MoFEMErrorCode cache_problem_entities(const std::string prb_name, CacheTupleWeakPtr cache_ptr)=0
Cache variables.
static UId getUniqueIdCalculate(const DofIdx dof, UId ent_uid)
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.

◆ testOperators() [1/2]

MoFEMErrorCode Example::testOperators ( )
private

[Solve]

[TestOperators]

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

Definition at line 1485 of file plastic.cpp.

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

◆ testOperators() [2/2]

MoFEMErrorCode Example::testOperators ( )
private

◆ thermalBC()

MoFEMErrorCode Example::thermalBC ( BitRefLevel  bit,
BitRefLevel  mask 
)
private

[Mechanical boundary conditions]

[Thermal boundary conditions]

Examples
thermoplastic.cpp.

Definition at line 3505 of file thermoplastic.cpp.

3505 {
3507
3508 MOFEM_LOG("SYNC", Sev::noisy) << "bC";
3510
3511 auto simple = mField.getInterface<Simple>();
3512 auto bc_mng = mField.getInterface<BcManager>();
3513
3514 auto get_skin = [&]() {
3515 Range body_ents;
3516 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
3517 CHKERR mField.getInterface<BitRefManager>()->filterEntitiesByRefLevel(
3518 bit, BitRefLevel().set(), body_ents);
3519 Skinner skin(&mField.get_moab());
3520 Range skin_ents;
3521 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
3522 return skin_ents;
3523 };
3524
3525 auto filter_flux_blocks = [&](auto skin, bool temp_bc = false) {
3526 auto remove_cubit_blocks = [&](auto c) {
3528 for (auto m :
3529
3530 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(c)
3531
3532 ) {
3533 Range ents;
3534 CHKERR mField.get_moab().get_entities_by_dimension(
3535 m->getMeshset(), SPACE_DIM - 1, ents, true);
3536 skin = subtract(skin, ents);
3537 }
3539 };
3540
3541 auto remove_named_blocks = [&](auto n) {
3543 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
3544 std::regex(
3545
3546 (boost::format("%s(.*)") % n).str()
3547
3548 ))
3549
3550 ) {
3551 Range ents;
3552 CHKERR mField.get_moab().get_entities_by_dimension(
3553 m->getMeshset(), SPACE_DIM - 1, ents, true);
3554 skin = subtract(skin, ents);
3555 }
3557 };
3558 if (!temp_bc) {
3559 CHK_THROW_MESSAGE(remove_cubit_blocks(NODESET | TEMPERATURESET),
3560 "remove_cubit_blocks");
3561 CHK_THROW_MESSAGE(remove_named_blocks("TEMPERATURE"),
3562 "remove_named_blocks");
3563 }
3564 CHK_THROW_MESSAGE(remove_cubit_blocks(SIDESET | HEATFLUXSET),
3565 "remove_cubit_blocks");
3566 CHK_THROW_MESSAGE(remove_named_blocks("HEATFLUX"), "remove_named_blocks");
3567 CHK_THROW_MESSAGE(remove_named_blocks("CONVECTION"), "remove_named_blocks");
3568 CHK_THROW_MESSAGE(remove_named_blocks("RADIATION"), "remove_named_blocks");
3569 return skin;
3570 };
3571
3572 auto filter_true_skin = [&](auto skin) {
3573 Range boundary_ents;
3574 ParallelComm *pcomm =
3575 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
3576 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
3577 PSTATUS_NOT, -1, &boundary_ents);
3578 return boundary_ents;
3579 };
3580
3581 auto remove_flux_ents = filter_true_skin(filter_flux_blocks(get_skin()));
3582 auto remove_temp_bc_ents =
3583 filter_true_skin(filter_flux_blocks(get_skin(), true));
3584
3585 // CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
3586 // remove_flux_ents);
3587 // CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
3588 // remove_temp_bc_ents);
3589
3590 MOFEM_LOG("SYNC", Sev::noisy) << remove_flux_ents << endl;
3592
3593 MOFEM_LOG("SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
3595
3596#ifndef NDEBUG
3597
3599 mField.get_moab(),
3600 (boost::format("flux_remove_%d.vtk") % mField.get_comm_rank()).str(),
3601 remove_flux_ents);
3602
3603#endif
3604
3605 if (is_distributed_mesh == PETSC_TRUE) {
3606 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
3607 simple->getProblemName(), "FLUX", remove_flux_ents);
3608 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
3609 simple->getProblemName(), "TBC", remove_temp_bc_ents);
3610 } else {
3612 ->removeDofsOnEntitiesNotDistributed(simple->getProblemName(), "FLUX",
3613 remove_flux_ents);
3615 ->removeDofsOnEntitiesNotDistributed(simple->getProblemName(), "TBC",
3616 remove_temp_bc_ents);
3617 }
3618
3619 // auto set_init_temp = [](boost::shared_ptr<FieldEntity> field_entity_ptr) {
3620 // field_entity_ptr->getEntFieldData()[0] = init_temp;
3621 // return 0;
3622 // };
3623 // CHKERR
3624 // mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(set_init_temp,
3625 // "T");
3626
3627 CHKERR bc_mng->pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
3628 simple->getProblemName(), "FLUX", false);
3629
3631}
#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_shape_optimisation/adjoint.cpp.

Definition at line 725 of file adjoint.cpp.

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

Definition at line 833 of file plastic.cpp.

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

Definition at line 168 of file adjoint.cpp.

◆ approxFunction

ApproxFieldFunction< FIELD_DIM > Example::approxFunction
staticprivate

◆ approxGradVals

boost::shared_ptr<MatrixDouble> Example::approxGradVals
private

◆ approxVals

boost::shared_ptr<VectorDouble> Example::approxVals
private

◆ aveMaxMin

std::array< double, Example::BoundingBox::LAST_BB > Example::aveMaxMin
staticprivate

◆ 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 933 of file thermoplastic.cpp.

◆ dispGradPtr

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

Definition at line 935 of file thermoplastic.cpp.

◆ domianLhsFEPtr

boost::shared_ptr<FEMethod> Example::domianLhsFEPtr
private

◆ domianRhsFEPtr

boost::shared_ptr<FEMethod> Example::domianRhsFEPtr
private

◆ ePS

SmartPetscObj<EPS> Example::ePS
private

◆ fieldOrder

int Example::fieldOrder = 2
private

Polynomial order for approximation.

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

Definition at line 164 of file adjoint.cpp.

◆ fluxFieldPtr

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

Definition at line 931 of file thermoplastic.cpp.

◆ focalIndex

int Example::focalIndex
staticprivate

◆ iI

std::vector< MatrixInt > Example::iI
staticprivate

◆ initialGeometry

SmartPetscObj<Vec> Example::initialGeometry
private

Initial geometry field.

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

Definition at line 179 of file adjoint.cpp.

◆ K

SmartPetscObj<Mat> Example::K
private

◆ kspElastic

SmartPetscObj< KSP > Example::kspElastic
private

Linear solver for elastic problem.

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

Definition at line 167 of file adjoint.cpp.

◆ M

SmartPetscObj<Mat> Example::M
private

◆ matDPtr

boost::shared_ptr<MatrixDouble> Example::matDPtr
private

◆ meshVolumeAndCount

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

Definition at line 224 of file plastic.cpp.

224{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_shape_optimisation/adjoint.cpp.

Definition at line 178 of file adjoint.cpp.

◆ modeCentroids

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

Centroids of optimization blocks.

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

Definition at line 176 of file adjoint.cpp.

◆ modeVecs

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

Topology mode vectors (design variables)

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

Definition at line 174 of file adjoint.cpp.

◆ pinchNodes

Range Example::pinchNodes
private

◆ plasticMultiplierFieldPtr

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

Definition at line 941 of file thermoplastic.cpp.

◆ plasticStrainFieldPtr

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

Definition at line 943 of file thermoplastic.cpp.

◆ pythonPtr

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

Interface to Python objective function.

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

Definition at line 170 of file adjoint.cpp.

◆ reactionFe

boost::shared_ptr< DomainEle > Example::reactionFe
private
Examples
plastic.cpp, and thermoplastic.cpp.

Definition at line 923 of file thermoplastic.cpp.

◆ rigidBodyMotion

std::array<SmartPetscObj<Vec>, 6> Example::rigidBodyMotion
private

◆ rZ

std::vector< double > Example::rZ
staticprivate

◆ savitzkyGolayNormalisation

int Example::savitzkyGolayNormalisation
staticprivate

◆ savitzkyGolayWeights

const int * Example::savitzkyGolayWeights
staticprivate

◆ simpleInterface

Simple * Example::simpleInterface
private

◆ space

FieldSpace Example::space
private
Examples
mofem/tutorials/fun-2_plot_base/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 937 of file thermoplastic.cpp.

◆ stressFieldPtr

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

Definition at line 939 of file thermoplastic.cpp.

◆ tempFieldPtr

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

Definition at line 929 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
private
Initial value:
=
nullptr

Field values at evaluation points.

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

Definition at line 137 of file adjoint.cpp.


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