v0.16.3
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 }
 

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 ()
 
 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.
 

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 readMesh ()
 
MoFEMErrorCode setupProblem ()
 
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 checkResults (Vec gradient_vector)
 [calculateGradient]
 

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)
 
static int integrationRule (int, int, int order)
 

Private Attributes

MoFEM::Interface & mField
 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
 
Simple * simpleInterface
 
boost::shared_ptr< std::vector< unsigned char > > boundaryMarker
 
boost::shared_ptr< CommonData > commonDataPtr
 
FieldApproximationBase base
 Choice of finite element basis functions.
 
FieldSpace space
 
Simple * simple
 
SmartPetscObj< Mat > M
 
SmartPetscObj< Mat > H
 
SmartPetscObj< EPS > eps
 
boost::shared_ptr< VectorDouble > approxVals
 
boost::shared_ptr< MatrixDouble > approxGradVals
 
Range pinchNodes
 
boost::shared_ptr< MatrixDouble > matDPtr
 
SmartPetscObj< Mat > K
 
SmartPetscObj< EPS > ePS
 
std::array< SmartPetscObj< Vec >, 6 > rigidBodyMotion
 
boost::shared_ptr< FEMethod > domianLhsFEPtr
 
boost::shared_ptr< FEMethod > domianRhsFEPtr
 
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< ObjectiveFunctionData > pythonPtr
 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.
 

Static Private Attributes

static std::vector< double > rZ
 
static std::vector< MatrixInt > iI
 
static std::array< double, LAST_BB > aveMaxMin
 
static int focalIndex
 
static int savitzkyGolayNormalisation
 
static const int * savitzkyGolayWeights
 
static ApproxFieldFunction< FIELD_DIM > approxFunction
 

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, and mofem/tutorials/vec-7_shape_optimisation/adjoint.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 };

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

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/16]

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/16]

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

Definition at line 42 of file between_meshes_dg_projection.cpp.

42: mField(m_field) {}

◆ Example() [4/16]

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

Definition at line 35 of file helmholtz.cpp.

35: mField(m_field) {}

◆ Example() [5/16]

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

Definition at line 25 of file integration.cpp.

25: mField(m_field) {}

◆ Example() [6/16]

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

Definition at line 50 of file plot_base.cpp.

50: mField(m_field) {}

◆ Example() [7/16]

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

Definition at line 81 of file phase.cpp.

81: mField(m_field) {}

◆ Example() [8/16]

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

Definition at line 51 of file approximation.cpp.

51: mField(m_field) {}

◆ Example() [9/16]

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

Definition at line 57 of file schrod_eig.cpp.

57: mField(m_field) {}

◆ Example() [10/16]

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

Definition at line 45 of file radiation.cpp.

45: mField(m_field) {}

◆ Example() [11/16]

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

Definition at line 47 of file heat_method.cpp.

47: mField(m_field) {}

◆ Example() [12/16]

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

Definition at line 54 of file eigen_elastic.cpp.

54: mField(m_field) {}

◆ Example() [13/16]

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

Definition at line 52 of file nonlinear_dynamic_elastic.cpp.

52: mField(m_field) {}

◆ Example() [14/16]

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

Definition at line 339 of file shallow_wave.cpp.

339: mField(m_field) {}

◆ Example() [15/16]

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

Definition at line 129 of file adjoint.cpp.

129: mField(m_field) {}

◆ Example() [16/16]

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

Definition at line 116 of file gradient.cpp.

116: mField(m_field) {}

Member Function Documentation

◆ assembleSystem() [1/12]

MoFEMErrorCode Example::assembleSystem ( )
private

[Push operators to pipeline]

[Adjoint modes]

[Boundary condition]

[Applying essential BC]

[Set up problem]

[Push operators to pipeline]

[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, and mofem/tutorials/vec-7_shape_optimisation/adjoint.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.
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
auto integration_rule
constexpr int SPACE_DIM
[Define dimension]
Definition gradient.cpp:19
constexpr double shear_modulus_G
Shear modulus G = E/(2(1+ν))
Definition gradient.cpp:34
constexpr double bulk_modulus_K
Bulk modulus K = E/(3(1-2ν))
Definition gradient.cpp:31
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.
DomainNaturalBCRhs::OpFlux< NaturalMeshsetType< BLOCKSET >, 1, SPACE_DIM > OpBodyForce

◆ assembleSystem() [2/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [3/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [4/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [5/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [6/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [7/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [8/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [9/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [10/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystem() [11/12]

MoFEMErrorCode Example::assembleSystem ( )
private

Setup operators in finite element pipeline.

◆ assembleSystem() [12/12]

MoFEMErrorCode Example::assembleSystem ( )
private

◆ assembleSystemFlux()

MoFEMErrorCode Example::assembleSystemFlux ( )
private

◆ assembleSystemIntensity()

MoFEMErrorCode Example::assembleSystemIntensity ( )
private

[Calculate flux on boundary]

[Push operators to pipeline]

Examples
mofem/tutorials/mix-1_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/2]

MoFEMErrorCode Example::bC ( )
private

[Create common data]

[Boundary condition]

Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp, and mofem/tutorials/scl-8_heat_radiation/radiation.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}
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
Simple * simple
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
const std::string getProblemName() const
Get the Problem Name.
Definition Simple.hpp:450

◆ bC() [2/2]

MoFEMErrorCode Example::bC ( )
private

◆ boundaryCondition() [1/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

[Set up problem]

[Setup adjoint]

[Create common data]

[Boundary condition]

[Applying essential BC]

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, and mofem/tutorials/vec-7_shape_optimisation/adjoint.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/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [3/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [4/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [5/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [6/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [7/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [8/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [9/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ boundaryCondition() [10/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

Apply essential boundary conditions.

◆ boundaryCondition() [11/11]

MoFEMErrorCode Example::boundaryCondition ( )
private

◆ calculateFlux()

MoFEMErrorCode Example::calculateFlux ( double &  calc_flux)
private

[Set up problem]

[Calculate flux on boundary]

Examples
mofem/tutorials/mix-1_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 1768 of file adjoint.cpp.

1770 {
1771 MOFEM_LOG_CHANNEL("WORLD");
1773 auto simple = mField.getInterface<Simple>();
1774
1775 auto ents = get_range_from_block(mField, "OPTIMISE", SPACE_DIM - 1);
1776
1777 auto get_essential_fe = [this]() {
1778 auto post_proc_rhs = boost::make_shared<FEMethod>();
1779 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
1781
1783 post_proc_rhs, 0)();
1785 };
1786 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1787 return post_proc_rhs;
1788 };
1789
1790 auto get_fd_direvative_fe = [&]() {
1791 auto fe = boost::make_shared<DomainEle>(mField);
1792 fe->getRuleHook = integrationRule;
1793 auto &pip = fe->getOpPtrVector();
1795 // Add RHS operators for internal forces
1796 HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
1797 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1798
1799 return fe;
1800 };
1801
1802 auto calulate_fd_residual = [&](auto eps, auto diff_vec, auto fd_vec) {
1804
1805 constexpr bool debug = false;
1806
1807 auto geom_norm = [](MoFEM::Interface &mField) {
1809 auto field_blas = mField.getInterface<FieldBlas>();
1810 double nrm2 = 0.0;
1811 auto norm2_field = [&](const double val) {
1812 nrm2 += val * val;
1813 return val;
1814 };
1815 CHKERR field_blas->fieldLambdaOnValues(norm2_field, "GEOMETRY");
1816 MPI_Allreduce(MPI_IN_PLACE, &nrm2, 1, MPI_DOUBLE, MPI_SUM,
1817 mField.get_comm());
1818 MOFEM_LOG("WORLD", Sev::inform) << "Geometry norm: " << sqrt(nrm2);
1820 };
1821
1822 if constexpr (debug)
1823 CHKERR geom_norm(mField);
1824
1825 auto initial_current_geometry = createDMVector(adjointDM);
1826 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1827 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
1828 initial_current_geometry, INSERT_VALUES, SCATTER_FORWARD);
1829 CHKERR VecAssemblyBegin(initial_current_geometry);
1830 CHKERR VecAssemblyEnd(initial_current_geometry);
1831
1832 if constexpr (debug)
1833 CHKERR geom_norm(mField);
1834
1835 auto perturb_geometry = [&](auto eps, auto diff_vec) {
1837 auto current_geometry = vectorDuplicate(initial_current_geometry);
1838 CHKERR VecCopy(initial_current_geometry, current_geometry);
1839 CHKERR VecAXPY(current_geometry, eps, diff_vec);
1840 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1841 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
1842 current_geometry, INSERT_VALUES, SCATTER_REVERSE);
1844 };
1845
1846 auto fe = get_fd_direvative_fe();
1847 auto fp = vectorDuplicate(diff_vec);
1848 auto fm = vectorDuplicate(diff_vec);
1849 auto calc_impl = [&](auto f, auto eps) { // is this finite difference!
1851 CHKERR VecZeroEntries(f);
1852 fe->f = f;
1853 CHKERR perturb_geometry(eps, diff_vec);
1855 simple->getDomainFEName(), fe);
1856 CHKERR VecAssemblyBegin(f);
1857 CHKERR VecAssemblyEnd(f);
1858 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
1859 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
1860 auto post_proc_rhs = get_essential_fe();
1861 post_proc_rhs->f = f;
1863 post_proc_rhs.get());
1865 };
1866 CHKERR calc_impl(fp, eps);
1867 CHKERR calc_impl(fm, -eps);
1868 CHKERR VecWAXPY(fd_vec, -1.0, fm, fp);
1869 CHKERR VecScale(fd_vec, 1.0 / (2.0 * eps));
1870
1871 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1872 "ADJOINT", "ADJOINT_FIELD", "GEOMETRY", RowColData::ROW,
1873 initial_current_geometry, INSERT_VALUES, SCATTER_REVERSE);
1874
1875 if constexpr (debug)
1876 CHKERR geom_norm(mField);
1877
1879 };
1880 // here starts the preperation for the derivative
1881 auto get_direvative_fe = [&](auto diff_vec) {
1882 auto fe_adjoint = boost::make_shared<DomainEle>(mField);
1883 fe_adjoint->getRuleHook = integrationRule;
1884 auto &pip = fe_adjoint->getOpPtrVector();
1885
1886 auto jac_ptr = boost::make_shared<MatrixDouble>();
1887 auto det_ptr = boost::make_shared<VectorDouble>();
1888 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1889 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
1890 auto cof_ptr = boost::make_shared<VectorDouble>();
1891
1892 using OpCoFactor =
1893 AdJoint<DomainEleOp>::Integration<GAUSS>::OpGetCoFactor<SPACE_DIM>;
1894
1896
1898 "GEOMETRY", jac_ptr));
1900 "U", diff_jac_ptr, diff_vec));
1901
1902 pip.push_back(new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
1903
1904 // Add RHS operators for internal forces
1905 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1906 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1908 "U", common_ptr, jac_ptr, diff_jac_ptr, cof_ptr));
1909
1910 return fe_adjoint;
1911 };
1912
1913 auto get_objective_fe = [&](auto diff_vec, auto grad_vec,
1914 auto glob_objective_ptr,
1915 auto glob_objective_grad_ptr) {
1916 auto fe_adjoint = boost::make_shared<DomainEle>(mField);
1917 fe_adjoint->getRuleHook = integrationRule;
1918 auto &pip = fe_adjoint->getOpPtrVector();
1920
1921 auto jac_ptr = boost::make_shared<MatrixDouble>();
1922 auto det_ptr = boost::make_shared<VectorDouble>();
1923 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1924 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
1925 auto cof_ptr = boost::make_shared<VectorDouble>();
1926 auto d_grad_ptr = boost::make_shared<MatrixDouble>();
1927 auto d_u_ptr = boost::make_shared<MatrixDouble>();
1928 auto u_ptr = boost::make_shared<MatrixDouble>();
1929
1930 using OpCoFactor =
1931 AdJoint<DomainEleOp>::Integration<GAUSS>::OpGetCoFactor<SPACE_DIM>;
1933 "GEOMETRY", jac_ptr));
1935 "U", diff_jac_ptr,
1936 diff_vec)); // Note: that vector is stored on displacemnt vector, that
1937 // why is used here
1938 pip.push_back(new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
1940 "U", d_grad_ptr, grad_vec));
1941 pip.push_back(
1942 new OpCalculateVectorFieldValues<SPACE_DIM>("U", d_u_ptr, grad_vec));
1943 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1944
1945 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1946 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1947 pip.push_back(new OpAdJointObjective(
1948 pythonPtr, common_ptr, jac_ptr, diff_jac_ptr, cof_ptr, d_grad_ptr,
1949 d_u_ptr, u_ptr, glob_objective_ptr, glob_objective_grad_ptr));
1950
1951 return fe_adjoint;
1952 };
1953
1954 auto dm = simple->getDM();
1955 auto f = createDMVector(dm);
1956 auto d = vectorDuplicate(f);
1957 auto dm_diff_vec = vectorDuplicate(d);
1958 auto zero_diff_vec = vectorDuplicate(dm_diff_vec);
1959 auto zero_state_sensitivity = vectorDuplicate(d);
1960 CHKERR VecZeroEntries(zero_diff_vec);
1961 CHKERR VecZeroEntries(zero_state_sensitivity);
1962 CHKERR VecGhostUpdateBegin(zero_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1963 CHKERR VecGhostUpdateEnd(zero_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1964 CHKERR VecGhostUpdateBegin(zero_state_sensitivity, INSERT_VALUES,
1965 SCATTER_FORWARD);
1966 CHKERR VecGhostUpdateEnd(zero_state_sensitivity, INSERT_VALUES,
1967 SCATTER_FORWARD);
1968
1969 auto adjoint_fe = get_direvative_fe(dm_diff_vec);
1970 auto objective_ptr_direct = boost::make_shared<double>(0.0);
1971 auto objective_grad_ptr_direct = boost::make_shared<double>(0.0);
1972 auto objective_fe_direct = get_objective_fe(
1973 dm_diff_vec, d, objective_ptr_direct, objective_grad_ptr_direct);
1974 auto objective_ptr_explicit = boost::make_shared<double>(0.0);
1975 auto objective_grad_ptr_explicit = boost::make_shared<double>(0.0);
1976 auto objective_fe_explicit =
1977 get_objective_fe(dm_diff_vec, zero_state_sensitivity,
1978 objective_ptr_explicit, objective_grad_ptr_explicit);
1979 auto objective_ptr_value = boost::make_shared<double>(0.0);
1980 auto objective_grad_ptr_value = boost::make_shared<double>(0.0);
1981 auto objective_fe_value =
1982 get_objective_fe(zero_diff_vec, zero_state_sensitivity,
1983 objective_ptr_value, objective_grad_ptr_value);
1984
1985 auto set_variance_of_geometry =
1986 [&](auto mode, auto mod_vec) { // think of mod_vec as X(tau) = X + tau*v_h
1987 // take the mod_vec and write it into the adjoint DM then copy that
1988 // field to dm_diff_vec using the same layout as U
1990 CHKERR DMoFEMMeshToLocalVector(adjointDM, mod_vec, INSERT_VALUES,
1991 SCATTER_REVERSE);
1992 CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1993 simple->getProblemName(), "U", "ADJOINT_FIELD", RowColData::ROW,
1994 dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1995 CHKERR VecGhostUpdateBegin(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1996 CHKERR VecGhostUpdateEnd(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1998 };
1999
2000 auto calculate_variance_internal_forces = [&](auto mode, auto mod_vec) {
2002 CHKERR VecZeroEntries(f);
2003 CHKERR VecGhostUpdateBegin(f, INSERT_VALUES, SCATTER_FORWARD);
2004 CHKERR VecGhostUpdateEnd(f, INSERT_VALUES, SCATTER_FORWARD);
2005 adjoint_fe->f = f;
2007 CHKERR VecAssemblyBegin(f);
2008 CHKERR VecAssemblyEnd(f);
2009 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
2010 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
2011 auto post_proc_rhs = get_essential_fe();
2012 post_proc_rhs->f = f;
2014 post_proc_rhs.get());
2015 CHKERR VecScale(f, -1.0);
2016
2017#ifndef NDEBUG
2018 constexpr bool debug = true;
2019 if constexpr (debug) {
2020 double norm0;
2021 CHKERR VecNorm(f, NORM_2, &norm0);
2022 auto fd_check = vectorDuplicate(f);
2023 double eps = 1e-5;
2024 CHKERR calulate_fd_residual(eps, dm_diff_vec, fd_check);
2025 double nrm;
2026 CHKERR VecAXPY(fd_check, -1.0, f);
2027 CHKERR VecNorm(fd_check, NORM_2, &nrm);
2028 MOFEM_LOG("WORLD", Sev::inform)
2029 << " FD check for internal forces [ " << mode << " ]: " << nrm
2030 << " / " << norm0 << " ( " << (nrm / norm0) << " )";
2031 }
2032#endif
2033
2035 };
2036
2037 auto calculate_variance_of_displacement = [&](auto mode, auto mod_vec) {
2039 CHKERR KSPSolve(kspElastic, f, d);
2040
2041 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
2042 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
2044 };
2045
2046 auto evaluate_objective_terms =
2047 [&](auto objective_fe, auto objective_ptr, auto objective_grad_ptr,
2048 double &objective_value, double &objective_gradient) {
2050 *objective_ptr = 0.0;
2051 *objective_grad_ptr = 0.0;
2053 objective_fe);
2054 std::array<double, 2> array = {*objective_ptr, *objective_grad_ptr};
2055 MPI_Allreduce(MPI_IN_PLACE, array.data(), 2, MPI_DOUBLE, MPI_SUM,
2056 mField.get_comm());
2057 objective_value = array[0];
2058 objective_gradient = array[1];
2060 };
2061
2062 auto calculate_objective_value = [&]() {
2064 double objective_value = 0;
2065 double objective_gradient = 0;
2066 CHKERR evaluate_objective_terms(objective_fe_value, objective_ptr_value,
2067 objective_grad_ptr_value, objective_value,
2068 objective_gradient);
2069 *objective_function_value = objective_value;
2071 };
2072
2073 auto calculate_variance_of_objective_function_dJ_du = [&](Vec dJ_du) {
2075
2076 auto fe = boost::make_shared<DomainEle>(mField);
2077 fe->getRuleHook = integrationRule;
2078 auto &pip = fe->getOpPtrVector();
2080
2081 auto u_ptr = boost::make_shared<MatrixDouble>();
2082 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
2083
2084 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
2085 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
2086 pip.push_back(new OpStateSensitivity("U", pythonPtr, common_ptr, u_ptr));
2087
2088 CHKERR VecZeroEntries(dJ_du);
2089 fe->f = dJ_du;
2091 CHKERR VecAssemblyBegin(dJ_du);
2092 CHKERR VecAssemblyEnd(dJ_du);
2093
2094 auto post_proc_rhs = get_essential_fe();
2095 post_proc_rhs->f = dJ_du;
2097 post_proc_rhs.get());
2098
2100 };
2101
2102 auto calculate_adjoint_lambda = [&](auto lambda, auto dJ_du) {
2104
2105 MOFEM_LOG("WORLD", Sev::inform) << "Solving for adjoint variable lambda";
2106 CHKERR VecZeroEntries(lambda);
2107 CHKERR KSPSolveTranspose(kspElastic, dJ_du, lambda);
2108 CHKERR VecGhostUpdateBegin(lambda, INSERT_VALUES, SCATTER_FORWARD);
2109 CHKERR VecGhostUpdateEnd(lambda, INSERT_VALUES, SCATTER_FORWARD);
2111 };
2112
2113 CHKERR VecZeroEntries(objective_function_gradient);
2114 CHKERR VecZeroEntries(adjoint_vector);
2115
2116 CHKERR calculate_objective_value();
2117 MOFEM_LOG("WORLD", Sev::verbose)
2118 << "Objective function: " << *objective_function_value;
2119
2120 auto direct = [&]() {
2122 int mode = 0;
2123 for (auto mod_vec : modeVecs) {
2124 CHKERR set_variance_of_geometry(mode, mod_vec);
2125 CHKERR calculate_variance_internal_forces(mode, mod_vec);
2126 CHKERR calculate_variance_of_displacement(mode, mod_vec);
2127 double objective_value = 0;
2128 double objective_gradient = 0;
2129 CHKERR evaluate_objective_terms(objective_fe_direct, objective_ptr_direct,
2130 objective_grad_ptr_direct,
2131 objective_value, objective_gradient);
2132 CHKERR VecSetValue(objective_function_gradient, mode, objective_gradient,
2133 INSERT_VALUES);
2134 CHKERR VecAXPY(adjoint_vector, objective_gradient, dm_diff_vec);
2135 ++mode;
2136 }
2138 };
2139
2140 auto lambda = vectorDuplicate(f);
2141 auto dJ_du = vectorDuplicate(f);
2142
2143 auto adjoint = [&]() {
2145
2146 CHKERR calculate_variance_of_objective_function_dJ_du(dJ_du);
2147 CHKERR calculate_adjoint_lambda(lambda, dJ_du);
2148
2149 int mode = 0;
2150
2151 for (auto mod_vec : modeVecs) {
2152
2153 CHKERR set_variance_of_geometry(mode, mod_vec);
2154 CHKERR calculate_variance_internal_forces(mode, mod_vec);
2155 double objective_value = 0;
2156 double objective_gradient_explicit = 0;
2157 CHKERR evaluate_objective_terms(
2158 objective_fe_explicit, objective_ptr_explicit,
2159 objective_grad_ptr_explicit, objective_value,
2160 objective_gradient_explicit);
2161 double lambda_dot_residual_variation = 0;
2162 CHKERR VecDot(lambda, f, &lambda_dot_residual_variation);
2163 const double dJ_dp =
2164 objective_gradient_explicit + lambda_dot_residual_variation;
2165 CHKERR VecSetValue(objective_function_gradient, mode, dJ_dp,
2166 INSERT_VALUES);
2167 CHKERR VecAXPY(adjoint_vector, dJ_dp, dm_diff_vec);
2168 ++mode;
2169 }
2170 CHKERR VecAssemblyBegin(objective_function_gradient);
2171 CHKERR VecAssemblyEnd(objective_function_gradient);
2173 };
2174
2175 switch (derivative_type) {
2176 case DIRECT:
2177 MOFEM_LOG("WORLD", Sev::inform) << "Running Direct Sensitivity...";
2178 CHKERR direct();
2179 break;
2180
2181 case ADJOINT:
2182 MOFEM_LOG("WORLD", Sev::inform) << "Running Adjoint Sensitivity...";
2183 CHKERR adjoint();
2184 break;
2185
2186 default:
2187 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
2188 "Wrong sensitivity type selected");
2189 }
2190
2191 CHKERR VecAssemblyBegin(objective_function_gradient);
2192 CHKERR VecAssemblyEnd(objective_function_gradient);
2193
2194 CHKERR VecAssemblyBegin(adjoint_vector);
2195 CHKERR VecAssemblyEnd(adjoint_vector);
2196 CHKERR VecGhostUpdateBegin(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2197 CHKERR VecGhostUpdateEnd(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2198
2200}
@ 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 ...
static const bool debug
SensitivityMethod derivative_type
Definition gradient.cpp:96
@ DIRECT
Definition gradient.cpp:94
@ ADJOINT
Definition gradient.cpp:94
Range get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:575
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:543
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:605
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1250
@ GAUSS
Gaussian quadrature integration.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
static double lambda
const FTensor::Tensor2< T, Dim, Dim > Vec
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
static int integrationRule(int, int, int p_data)
Definition radiation.cpp:52
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
SmartPetscObj< EPS > eps
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.
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:429
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 1016 of file gradient.cpp.

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

◆ checkResults() [1/12]

MoFEMErrorCode Example::checkResults ( )
private

[Postprocess results]

[Print results]

[Check]

[Check results]

[Test example]

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-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-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp, and mofem/tutorials/vec-4_shallow_wave/shallow_wave.cpp.

Definition at line 1172 of file dynamic_first_order_con_law.cpp.

1172 {
1175 CHKERR testing->addTestCommandLine("", 1, "solution coefficient norm", [&]() {
1177 auto *simple = mField.getInterface<Simple>();
1178 auto T = createDMVector(simple->getDM());
1179 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
1180 SCATTER_FORWARD);
1181 double nrm2;
1182 CHKERR VecNorm(T, NORM_2, &nrm2);
1183 MOFEM_LOG("EXAMPLE", Sev::inform) << "Regression norm " << nrm2;
1184 constexpr double regression_value = 0.0194561;
1185 CHKERR testing->checkValue<TestType::SCALAR>(
1186 "solution coefficient norm", nrm2, regression_value, {1e-2, 0.});
1188 });
1189 CHKERR testing->runTests();
1191}
PetscBool testing
virtual MoFEMErrorCode addTestCommandLine(const std::string &prefix, int number, const std::string &name, TestHook hook)=0

◆ 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 ( Vec  gradient_vector)
private

[calculateGradient]

[Finite difference check]

Definition at line 1162 of file gradient.cpp.

1162 {
1165
1166 CHKERR testing->addTestCommandLine("", 1, "gradient_fd", [&]() {
1168
1169 PetscInt nb_modes = 5;
1170 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, PETSC_NULLPTR,
1171 "-gradient_nb_modes", &nb_modes, PETSC_NULLPTR);
1172 PetscReal eps = 1e-6;
1173 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, PETSC_NULLPTR, "-gradient_fd_eps",
1174 &eps, PETSC_NULLPTR);
1175
1176 auto simple = mField.getInterface<Simple>();
1177 auto dm = simple->getDM();
1178 auto *adj_problem_ptr = getProblemPtr(adjointDM);
1179
1180 auto get_objective_fe = [&](auto glob_objective_ptr) {
1181 auto fe_obj_fe = boost::make_shared<DomainEle>(mField);
1182 fe_obj_fe->getRuleHook = [](int, int, int p_data) {
1183 return 2 * p_data + p_data - 1;
1184 };
1185 auto &pip = fe_obj_fe->getOpPtrVector();
1187 auto jac_ptr = boost::make_shared<MatrixDouble>();
1188 auto u_ptr = boost::make_shared<MatrixDouble>();
1190 "GEOMETRY", jac_ptr));
1191 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1192 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, I, DomainEleOp>(
1193 mField, pip, "U", "MAT_ELASTIC", Sev::noisy);
1194 pip.push_back(new OpObjective(pythonPtr, common_ptr, jac_ptr, u_ptr,
1195 glob_objective_ptr));
1196 return fe_obj_fe;
1197 };
1198
1199 auto f = boost::make_shared<double>(0.);
1200 auto fe_obj = get_objective_fe(f);
1201 CacheTupleSharedPtr tmp_cache_ptr = boost::make_shared<CacheTuple>();
1203 tmp_cache_ptr);
1204
1205 auto evaluate_objective = [&](double &objective_value) {
1207 *f = 0.0;
1209 MPI_Allreduce(MPI_IN_PLACE, f.get(), 1, MPI_DOUBLE, MPI_SUM,
1210 mField.get_comm());
1211 objective_value = *f;
1213 };
1214
1215 auto &adj_dofs =
1216 adj_problem_ptr->getNumeredRowDofsPtr()->get<PetscGlobalIdx_mi_tag>();
1217 auto &dofs = mField.get_dofs()->get<Unique_mi_tag>();
1218 auto geometry_bit_number = mField.get_field_bit_number("GEOMETRY");
1219
1220 // Returns the geometry DOF perturbed by adjoint DOF "mode" on this rank,
1221 // or nullptr when the entity is not present locally. Every rank still
1222 // takes part in the collective solves below.
1223 auto get_geometry_dof = [&](PetscInt mode) -> const DofEntity * {
1224 auto a_dof = adj_dofs.find(mode);
1225 if (a_dof == adj_dofs.end())
1226 return nullptr;
1228 (*a_dof)->getEntDofIdx(),
1229 FieldEntity::getLocalUniqueIdCalculate(geometry_bit_number,
1230 (*a_dof)->getEnt()));
1231 auto dof = dofs.find(uid);
1232 return dof != dofs.end() ? dof->get() : nullptr;
1233 };
1234
1235 auto solve_and_evaluate = [&](const DofEntity *dof, double geom_val,
1236 double &objective_value) {
1238 if (dof)
1239 dof->getFieldData() = geom_val;
1240 CHKERR KSPReset(kspElastic);
1242 CHKERR evaluate_objective(objective_value);
1244 };
1245
1246 for (PetscInt mode = 0; mode < nb_modes; ++mode) {
1247 auto dof = get_geometry_dof(mode);
1248 const double org_geom_val = dof ? dof->getFieldData() : 0.;
1249
1250 double f_plus, f_minus;
1251 CHKERR solve_and_evaluate(dof, org_geom_val + eps, f_plus);
1252 CHKERR solve_and_evaluate(dof, org_geom_val - eps, f_minus);
1253 if (dof)
1254 dof->getFieldData() = org_geom_val;
1255 const double finite_diff_grad = (f_plus - f_minus) / (2 * eps);
1256
1257 // The adjoint gradient entry lives on the owning rank only; share it so
1258 // the collective check below sees one value everywhere.
1259 double owner_data[2] = {0., 0.};
1260 auto a_dof = adj_dofs.find(mode);
1261 if (a_dof != adj_dofs.end() && (*a_dof)->getHasLocalIndex()) {
1262 const double *g_array;
1263 CHKERR VecGetArrayRead(gradient_vector, &g_array);
1264 owner_data[0] = g_array[(*a_dof)->getPetscLocalDofIdx()];
1265 owner_data[1] = 1.;
1266 CHKERR VecRestoreArrayRead(gradient_vector, &g_array);
1267 }
1268 CHKERR MPI_Allreduce(MPI_IN_PLACE, owner_data, 2, MPI_DOUBLE, MPI_SUM,
1269 mField.get_comm());
1270 if (owner_data[1] == 0.)
1272 "Adjoint DOF for mode %d not found on any rank", mode);
1273 const double adjoint_grad = owner_data[0] / owner_data[1];
1274
1275 MOFEM_LOG("WORLD", Sev::inform)
1276 << "Mode: " << mode << ", Adjoint gradient: " << adjoint_grad
1277 << ", Finite difference gradient: " << finite_diff_grad;
1278 CHKERR testing->checkValue<TestType::DERIVATIVE>(
1279 "gradient mode " + std::to_string(mode), adjoint_grad,
1280 finite_diff_grad, {0., 1e-4});
1281 }
1282
1284 });
1285
1286 CHKERR testing->runTests();
1287
1289}
virtual const DofEntity_multiIndex * get_dofs() const =0
Get the dofs object.
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
boost::shared_ptr< CacheTuple > CacheTupleSharedPtr
auto getProblemPtr(DM dm)
get problem pointer from DM
Definition DMMoFEM.hpp:1195
MoFEMErrorCode solveElastic()
Solve forward elastic problem.
Definition adjoint.cpp:1240
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.
keeps information about DOF on the entity
FieldData & getFieldData() const
static UId getUniqueIdCalculate(const DofIdx dof, UId ent_uid)
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.

◆ createCommonData() [1/8]

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, and mofem/tutorials/vec-4_shallow_wave/shallow_wave.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}
constexpr double poisson_ratio
Poisson's ratio ν
Definition gradient.cpp:30
constexpr double young_modulus
[Material properties for linear elasticity]
Definition gradient.cpp:29
double cn_contact
Definition contact.cpp:95
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 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
PetscBool set_timer
Set timer.
Definition plastic.cpp:119
double scale
Definition plastic.cpp:124
double zeta
Viscous hardening.
Definition plastic.cpp:131
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
SmartPetscObj< Mat > H

◆ createCommonData() [2/8]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [3/8]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [4/8]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [5/8]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [6/8]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [7/8]

MoFEMErrorCode Example::createCommonData ( )
private

◆ createCommonData() [8/8]

MoFEMErrorCode Example::createCommonData ( )
private

◆ edgeFlips()

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

[Output results]

[Edge flips]

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

Definition at line 582 of file between_meshes_dg_projection.cpp.

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

◆ 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

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

static int Example::integrationRule ( int  ,
int  ,
int  order 
)
inlinestaticprivate

Definition at line 138 of file adjoint.cpp.

138{ return 2 * order + 1; }

◆ integrationRule() [2/2]

static int Example::integrationRule ( int  ,
int  ,
int  p_data 
)
inlinestaticprivate

◆ 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 // Solver convergence is cheap to check and carries no magic numbers, so it
247 // stands alone rather than waiting on a "-test_nb"/"-test_name" selector.
248 {
249 PetscReal expected_time;
250 CHKERR TSGetTime(ts, &expected_time);
252 ts, expected_time, {1e-12, 1e-12}, "heat radiation");
253 }
254 CHKERR TSGetTime(ts, &ftime);
255
256 PetscInt steps, snesfails, rejects, nonlinits, linits;
257 CHKERR TSGetStepNumber(ts, &steps);
258 CHKERR TSGetSNESFailures(ts, &snesfails);
259 CHKERR TSGetStepRejections(ts, &rejects);
260 CHKERR TSGetSNESIterations(ts, &nonlinits);
261 CHKERR TSGetKSPIterations(ts, &linits);
262 MOFEM_LOG_C("EXAMPLE", Sev::inform,
263 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
264 "%d, linits %d",
265 steps, rejects, snesfails, ftime, nonlinits, linits);
266
268}
#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

◆ OPs() [1/2]

MoFEMErrorCode Example::OPs ( )
private

[Boundary condition]

[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, and mofem/tutorials/scl-8_heat_radiation/radiation.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
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
Definition seepage.cpp:56
Class (Function) to calculate residual side diagonal.
Definition Essential.hpp:49
Approximate field values for given petsc vector.
constexpr AssemblyType AT

◆ OPs() [2/2]

MoFEMErrorCode Example::OPs ( )
private

◆ outputResults() [1/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [2/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [3/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [4/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [5/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [6/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [7/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [8/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [9/11]

MoFEMErrorCode Example::outputResults ( )
private

◆ outputResults() [10/11]

MoFEMErrorCode Example::outputResults ( const int  i)
private

[Solve]

[Postprocess results]

Definition at line 493 of file phase.cpp.

493 {
496
498
499 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
500 CHKERR AddHOOps<2, 2, 2>::add(post_proc_fe->getOpPtrVector(), {HDIV, L2});
501
502 auto phi_ptr = boost::make_shared<VectorDouble>();
503 auto s_ptr = boost::make_shared<MatrixDouble>();
504 post_proc_fe->getOpPtrVector().push_back(
505 new OpCalculateScalarFieldValues("PHI", phi_ptr));
506 post_proc_fe->getOpPtrVector().push_back(
507 new OpCalculateHVecVectorField<3>("S", s_ptr));
508
510
511 post_proc_fe->getOpPtrVector().push_back(
512
513 new OpPPMap(post_proc_fe->getPostProcMesh(),
514 post_proc_fe->getMapGaussPts(),
515
516 OpPPMap::DataMapVec{{"PHI", phi_ptr}},
517
518 OpPPMap::DataMapMat{{"S", s_ptr}},
519
521
523
524 )
525
526 );
527
528 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
529 CHKERR pipeline_mng->loopFiniteElementsPostProc();
530 CHKERR post_proc_fe->writeFile("out_" + boost::lexical_cast<std::string>(i) +
531 ".h5m");
533}
MoFEMErrorCode loopFiniteElementsPostProc(SmartPetscObj< DM > dm=nullptr)
Iterate postprocessing finite elements.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Specialization for double precision scalar field values calculation.
Post post-proc data at points from hash maps.
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() [11/11]

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

[Project results]

[Output results]

Definition at line 525 of file between_meshes_dg_projection.cpp.

525 {
527
528 auto pipeline_mng = mField.getInterface<PipelineManager>();
529
530 auto post_proc_fe = boost::make_shared<PostProcFaceEle>(mField);
532 post_proc_fe->getOpPtrVector(), {H1});
533
534 auto u_ptr = boost::make_shared<VectorDouble>();
535 post_proc_fe->getOpPtrVector().push_back(
537 auto s_ptr = boost::make_shared<VectorDouble>();
538 post_proc_fe->getOpPtrVector().push_back(
540
541 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
542 post_proc_fe->getOpPtrVector().push_back(
544 auto grad_s_ptr = boost::make_shared<MatrixDouble>();
545 post_proc_fe->getOpPtrVector().push_back(
547
548
550
551 post_proc_fe->getOpPtrVector().push_back(
552
553 new OpPPMap(
554 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
555
556 OpPPMap::DataMapVec{{FIELD_NAME_U, u_ptr}, {FIELD_NAME_S, s_ptr}},
557
559
560 {"GRAD_" + std::string(FIELD_NAME_U), grad_u_ptr},
561 {"GRAD_" + std::string(FIELD_NAME_S), grad_s_ptr}
562
563 },
564
566
568
569 )
570
571 );
572
573 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
574 CHKERR pipeline_mng->loopFiniteElementsPostProc();
575 CHKERR post_proc_fe->writeFile(file_name);
576
578}
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.

◆ 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}
virtual int get_comm_rank() const =0

◆ 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 1368 of file adjoint.cpp.

1369 {
1371 auto simple = mField.getInterface<Simple>();
1375 "out_elastic_" + std::to_string(iter) + ".h5m",
1376 {{"ADJOINT", adjoint_vector}}, {}, Sev::noisy);
1378}
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::DomainEle DomainEle
Domain finite elements.
Definition gradient.cpp:45
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::BoundaryEle BoundaryEle
Boundary finite elements.
Definition gradient.cpp:47
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

◆ 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 674 of file gradient.cpp.

677 {
680 std::vector<std::pair<std::string, SmartPetscObj<Vec>>> additional_vecs;
681 if (gradient_vector) {
682 additional_vecs.emplace_back("GRADIENT", gradient_vector);
683 }
684 if (adjoint_vector) {
685 additional_vecs.emplace_back("ADJOINT", adjoint_vector);
686 }
687 if (dJ_du) {
688 additional_vecs.emplace_back("dJ_dU", dJ_du);
689 }
693 "out_elastic_" + std::to_string(iter) + ".h5m", additional_vecs,
694 {}, Sev::noisy);
696}

◆ 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 258 of file between_meshes_dg_projection.cpp.

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

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

MoFEMErrorCode Example::readMesh ( )
private

[Run problem]

[run problem]

[Run programme]

[Read mesh]

[Read mesh]

Read mesh from file and setup material/boundary condition meshsets

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

Meshsets are used to group elements/faces by:

  • Material properties (for different material blocks)
  • Boundary conditions (for applying loads and constraints)
  • Optimization regions (for topology optimization)
Returns
MoFEMErrorCode Success or error code
Examples
mofem/tutorials/adv-4_dynamic_first_order_con_law/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 mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp.

Definition at line 459 of file dynamic_first_order_con_law.cpp.

459 {
462
466}
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:191
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180

◆ readMesh() [2/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [3/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [4/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [5/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [6/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [7/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [8/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [9/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [10/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [11/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ readMesh() [12/13]

MoFEMErrorCode Example::readMesh ( )
private

Read mesh from file and setup meshsets.

◆ readMesh() [13/13]

MoFEMErrorCode Example::readMesh ( )
private

◆ refineSkin()

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

[Edge flips]

[Refine skin]

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

Definition at line 770 of file between_meshes_dg_projection.cpp.

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

◆ 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 802 of file between_meshes_dg_projection.cpp.

802 {
804 simpleInterface->getBitRefLevel() = child_bit;
807}
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}
const double v
phase velocity of light in medium (cm/ns)
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/16]

MoFEMErrorCode Example::runProblem ( )

[Run problem]

[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, and mofem/tutorials/vec-7_shape_optimisation/adjoint.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:1493
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/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [3/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [4/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [5/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [6/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [7/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [8/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [9/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [10/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [11/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [12/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [13/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [14/16]

MoFEMErrorCode Example::runProblem ( )

◆ runProblem() [15/16]

MoFEMErrorCode Example::runProblem ( )

Main driver function for the optimization process.

◆ runProblem() [16/16]

MoFEMErrorCode Example::runProblem ( )

Main driver function for the optimization process.

◆ 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 {
142 // Add field
144 constexpr int order = 1;
148}
MoFEMErrorCode addDomainField(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_ZERO, int verb=-1)
Add field on domain.
Definition Simple.cpp:261
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:575
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:735

◆ 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 652 of file adjoint.cpp.

652 {
655
656 // Create adjoint data manager and field
657 auto create_adjoint_dm = [&]() {
658 auto adjoint_dm = createDM(mField.get_comm(), "DMMOFEM");
659
660 auto add_field = [&]() {
662 CHKERR mField.add_field("ADJOINT_FIELD", H1, base, SPACE_DIM);
664 "ADJOINT_FIELD");
665 for (auto tt = MBEDGE; tt <= moab::CN::TypeDimensionMap[SPACE_DIM].second;
666 ++tt)
667 CHKERR mField.set_field_order(simple->getMeshset(), tt, "ADJOINT_FIELD",
668 fieldOrder);
670 "ADJOINT_FIELD", 1);
673 };
674
675 auto add_adjoint_fe_impl = [&]() {
677 CHKERR mField.add_finite_element("ADJOINT_DOMAIN_FE");
679 "ADJOINT_FIELD");
681 "ADJOINT_FIELD");
683 "ADJOINT_FIELD");
685 "GEOMETRY");
687 simple->getMeshset(), SPACE_DIM, "ADJOINT_DOMAIN_FE");
688 CHKERR mField.build_finite_elements("ADJOINT_DOMAIN_FE");
689
690 CHKERR mField.add_finite_element("ADJOINT_BOUNDARY_FE");
692 "ADJOINT_FIELD");
694 "ADJOINT_FIELD");
696 "ADJOINT_FIELD");
698 "GEOMETRY");
699
700 auto block_name = "OPTIMISE";
701 auto mesh_mng = mField.getInterface<MeshsetsManager>();
702 auto bcs = mesh_mng->getCubitMeshsetPtr(
703
704 std::regex((boost::format("%s(.*)") % block_name).str())
705
706 );
707
708 for (auto bc : bcs) {
710 bc->getMeshset(), SPACE_DIM - 1, "ADJOINT_BOUNDARY_FE");
711 }
712
713 CHKERR mField.build_finite_elements("ADJOINT_BOUNDARY_FE");
714
717
719 };
720
721 auto set_adjoint_dm_imp = [&]() {
723 CHKERR DMMoFEMCreateMoFEM(adjoint_dm, &mField, "ADJOINT",
726 CHKERR DMMoFEMSetDestroyProblem(adjoint_dm, PETSC_TRUE);
727 CHKERR DMSetFromOptions(adjoint_dm);
728 CHKERR DMMoFEMAddElement(adjoint_dm, "ADJOINT_DOMAIN_FE");
729 CHKERR DMMoFEMAddElement(adjoint_dm, "ADJOINT_BOUNDARY_FE");
730 CHKERR DMMoFEMSetSquareProblem(adjoint_dm, PETSC_TRUE);
731 CHKERR DMMoFEMSetIsPartitioned(adjoint_dm, PETSC_TRUE);
732 mField.getInterface<ProblemsManager>()->buildProblemFromFields =
733 PETSC_TRUE;
734 CHKERR DMSetUp(adjoint_dm);
735 mField.getInterface<ProblemsManager>()->buildProblemFromFields =
736 PETSC_FALSE;
738 };
739
740 CHK_THROW_MESSAGE(add_field(), "add adjoint field");
741 CHK_THROW_MESSAGE(add_adjoint_fe_impl(), "add adjoint fe");
742 CHK_THROW_MESSAGE(set_adjoint_dm_imp(), "set adjoint dm");
743
744 return adjoint_dm;
745 };
746
747 adjointDM = create_adjoint_dm();
748
750}
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
Definition DMMoFEM.cpp:1142
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:143
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:463
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.
EntityHandle & getMeshset()
Get the MeshSet object.
Definition Simple.hpp:394
BitRefLevel & getBitRefLevelMask()
Get the BitRefLevelMask.
Definition Simple.hpp:422

◆ setupAdJoint() [2/2]

MoFEMErrorCode Example::setupAdJoint ( )
private

◆ setupProblem() [1/15]

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, and mofem/tutorials/vec-7_shape_optimisation/adjoint.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
320 CHKERR simple->addDomainField("TAU", L2, base, 1);
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
335 if (order_edge || order_face || order_volume) {
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 {
357 }
360
362
363#ifdef ADD_CONTACT
365 SPACE_DIM);
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
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();
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
#define MYPCOMM_INDEX
default communicator number PCOMM
@ 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
constexpr auto size_symm
Definition plastic.cpp:42
constexpr FieldSpace CONTACT_SPACE
Definition plastic.cpp:52
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.
MoFEMErrorCode addBoundaryField(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_ZERO, int verb=-1)
Add field on boundary.
Definition Simple.cpp:355
MoFEMErrorCode addFieldToEmptyFieldBlocks(const std::string row_field, const std::string col_field) const
Add empty block to problem.
Definition Simple.cpp:834
MoFEMErrorCode addDataField(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_ZERO, int verb=-1)
Add data field.
Definition Simple.cpp:393
VolEle::UserDataOperator VolOp

◆ setupProblem() [2/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [3/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [4/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [5/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [6/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [7/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [8/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [9/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [10/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [11/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [12/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [13/15]

MoFEMErrorCode Example::setupProblem ( )
private

◆ setupProblem() [14/15]

MoFEMErrorCode Example::setupProblem ( )
private

Setup fields, approximation spaces and DOFs.

◆ setupProblem() [15/15]

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 1240 of file adjoint.cpp.

1240 {
1242 auto simple = mField.getInterface<Simple>();
1243 auto dm = simple->getDM();
1244 auto f = createDMVector(dm);
1245 auto d = vectorDuplicate(f);
1246 CHKERR VecZeroEntries(d);
1247 CHKERR DMoFEMMeshToLocalVector(dm, d, INSERT_VALUES, SCATTER_REVERSE);
1248
1249 auto set_essential_bc = [&]() {
1251 // This is low level pushing finite elements (pipelines) to solver
1252
1253 auto ksp_ctx_ptr = getDMKspCtx(dm);
1254 auto pre_proc_rhs = boost::make_shared<FEMethod>();
1255 auto post_proc_rhs = boost::make_shared<FEMethod>();
1256 auto post_proc_lhs = boost::make_shared<FEMethod>();
1257
1258 auto get_pre_proc_hook = [&]() {
1260 {});
1261 };
1262 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
1263
1264 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
1266
1268 post_proc_rhs, 1.)();
1270 };
1271
1272 auto get_post_proc_hook_lhs = [this, post_proc_lhs]() {
1274
1276 post_proc_lhs, 1.)();
1278 };
1279
1280 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1281 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
1282
1283 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
1284 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
1285 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
1287 };
1288
1289 auto setup_and_solve = [&](auto solver) {
1291 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
1292 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSetUp";
1293 CHKERR KSPSetUp(solver);
1294 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSetUp <= Done";
1295 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSolve";
1296 CHKERR KSPSolve(solver, f, d);
1297 MOFEM_LOG("TIMER", Sev::noisy) << "KSPSolve <= Done";
1299 };
1300
1301 MOFEM_LOG_CHANNEL("TIMER");
1302 MOFEM_LOG_TAG("TIMER", "timer");
1303
1304 CHKERR set_essential_bc();
1305 CHKERR setup_and_solve(kspElastic);
1306
1307 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
1308 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
1309 CHKERR DMoFEMMeshToLocalVector(dm, d, INSERT_VALUES, SCATTER_REVERSE);
1310
1311 auto evaluate_field_at_the_point = [&]() {
1313
1314 int coords_dim = 3;
1315 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
1316 PetscBool do_eval_field = PETSC_FALSE;
1317 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
1318 field_eval_coords.data(), &coords_dim,
1319 &do_eval_field);
1320
1321 if (do_eval_field) {
1322
1323 auto vector_field_ptr = boost::make_shared<MatrixDouble>();
1324 auto field_eval_data =
1325 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
1326
1328 ->buildTree<SPACE_DIM>(field_eval_data, simple->getDomainFEName());
1329
1330 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1331 auto no_rule = [](int, int, int) { return -1; };
1332 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
1333 field_eval_fe_ptr->getRuleHook = no_rule;
1334
1335 field_eval_fe_ptr->getOpPtrVector().push_back(
1336 new OpCalculateVectorFieldValues<SPACE_DIM>("U", vector_field_ptr));
1337
1339 ->evalFEAtThePoint<SPACE_DIM>(
1340 field_eval_coords.data(), 1e-12, simple->getProblemName(),
1341 simple->getDomainFEName(), field_eval_data,
1343 QUIET);
1344
1345 if (vector_field_ptr->size1()) {
1346 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*vector_field_ptr);
1347 if constexpr (SPACE_DIM == 2)
1348 MOFEM_LOG("FieldEvaluator", Sev::inform)
1349 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1);
1350 else
1351 MOFEM_LOG("FieldEvaluator", Sev::inform)
1352 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1)
1353 << " U_Z: " << t_disp(2);
1354 }
1355
1357 }
1359 };
1360
1361 CHKERR evaluate_field_at_the_point();
1362
1364}
#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:1264
PetscBool do_eval_field
Evaluate field.
Definition plastic.cpp:120
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition Essential.hpp:33

◆ solveElastic() [2/2]

MoFEMErrorCode Example::solveElastic ( )
private

Solve forward elastic problem.

◆ solveSystem() [1/11]

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, and mofem/tutorials/vec-4_shallow_wave/shallow_wave.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 =
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
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)
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
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 // Solver convergence is cheap to check and carries no magic numbers, so
1149 // it stands alone rather than waiting on a "-test_nb"/"-test_name"
1150 // selector.
1151 {
1152 PetscReal expected_time;
1153 CHKERR TSGetMaxTime(ts, &expected_time);
1155 ts, expected_time, {1e-12, 1e-12}, "conservation law");
1156 }
1157 CHKERR TSGetTime(ts, &ftime);
1158 }
1159
1161}
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:1217
double D
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
Definition DMMoFEM.cpp:1075
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/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [3/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [4/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [5/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [6/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [7/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [8/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [9/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [10/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ solveSystem() [11/11]

MoFEMErrorCode Example::solveSystem ( )
private

◆ testOperators()

MoFEMErrorCode Example::testOperators ( )
private

[Solve]

[TestOperators]

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

Definition at line 1493 of file plastic.cpp.

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

◆ 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 775 of file adjoint.cpp.

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

MoFEMErrorCode Example::tsSolve ( )
private
Examples
mofem/tutorials/adv-0_plasticity/plastic.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
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);
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);
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 // Solver convergence is cheap to check and carries no magic numbers, so it
1473 // stands alone rather than waiting on a "-test_nb"/"-test_name" selector.
1474 {
1475 PetscReal expected_time;
1476 CHKERR TSGetTime(solver, &expected_time);
1478 solver, expected_time, {1e-12, 1e-12}, "plasticity");
1479 }
1480 MOFEM_LOG("TIMER", Sev::verbose) << "TSSolve <= done";
1481
1482 if (mField.get_comm_rank() == 0) {
1483 auto ts_ctx_ptr = getDMTsCtx(dm);
1485 "ts_manager_graph.dot");
1486 }
1487
1489}
#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:1292
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:1308
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create block matrix structure.
Definition Schur.cpp:2415
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)
Create structure of nested matrix [A11 A10; A01 A00].
Definition Schur.cpp:3667
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition DMMoFEM.cpp:1584
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:1278
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
Definition plastic.cpp:238
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
Definition plastic.cpp:236
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
Definition plastic.cpp:237
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)

Friends And Related Symbol Documentation

◆ TSPrePostProc

friend struct 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

◆ domianLhsFEPtr

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

◆ domianRhsFEPtr

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

◆ eps

SmartPetscObj<EPS> Example::eps
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.

◆ focalIndex

int Example::focalIndex
staticprivate

◆ H

SmartPetscObj<Mat> Example::H
private
Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp.

Definition at line 74 of file schrod_eig.cpp.

◆ 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

std::array<double, 2> Example::meshVolumeAndCount = {0, 0}
inlinestatic
Examples
mofem/tutorials/adv-0_plasticity/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

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

◆ 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

◆ simple

Simple* Example::simple
private

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

◆ uXScatter

std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter> > Example::uXScatter
private
Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp.

Definition at line 236 of file plastic.cpp.

◆ uYScatter

std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter> > Example::uYScatter
private
Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp.

Definition at line 237 of file plastic.cpp.

◆ uZScatter

std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter> > Example::uZScatter
private
Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp.

Definition at line 238 of file plastic.cpp.


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