v0.16.3
Loading...
Searching...
No Matches
MatElastic.hpp
Go to the documentation of this file.
1/**
2 * @file MatElastic.hpp
3 * @brief
4 * @version 0.1
5 * @date 2026-04-02
6 *
7 * @copyright Copyright (c) 2026
8 *
9 */
10
11#ifndef MAT_ELASTIC_HPP
12#define MAT_ELASTIC_HPP
13
14#include <MatUmat.hpp>
15#include <MatAxisymmetric.hpp>
16
17namespace MatOps {
18
19/**
20 * @brief Conservative elastic response with a stored-energy density.
21 *
22 * Every concrete derived model records the scalar dependent datum "energy"
23 * consistently with P = dW/dF.
24 */
26 using MatPiolaResponse::MatPiolaResponse;
27
28 static constexpr auto energyDensityDataName = "energy";
29
31 return matOpsDataPtr->getDependentDataPtr(energyDensityDataName);
32 }
33};
34
36 PIOLA_RESPONSE() = delete;
37 struct META {};
39};
40
41struct ELASTICITY {
42 ELASTICITY() = delete;
43 // Behaviors
44 struct NEOHOOKEAN {};
47};
48
49/** \name First-Piola Response Operator Factory */
50/**@{*/
51template <int MODEL_TYPE> struct OpMaterialFactory<PIOLA_RESPONSE, MODEL_TYPE> {
53
54 static void
55 addKinematics(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
56 const std::string &field_name,
57 boost::shared_ptr<MatrixDouble> m_grad) {
58 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
59 if constexpr (MODEL_TYPE == MODEL_AXISYMMETRIC) {
60 auto m_disp = boost::make_shared<MatrixDouble>();
61 auto m_grad_2d = boost::make_shared<MatrixDouble>();
62 pip.push_back(new OpCalculateVectorFieldValues<2>(field_name, m_disp));
63 pip.push_back(
65 pip.push_back(
66 new OpCalculateAxisymmetricGradient(m_disp, m_grad_2d, m_grad));
67 } else {
68 pip.push_back(
70 }
71 }
72
73 template <AssemblyType A, IntegrationType I, typename DomainEleOp>
74 static MoFEMErrorCode
76 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
77 std::string field_name,
78 boost::shared_ptr<PhysicalEquations> physical_equations_ptr) {
80 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
81 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
82 A>::template LinearForm<I>;
83 using OpInternalForce = typename B::template OpGradTimesTensor<1, DIM, DIM>;
84 auto m_grad =
85 physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("grad");
86 auto m_P = physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("P");
87 addKinematics(pip, field_name, m_grad);
88 pip.push_back(physical_equations_ptr->createOp(physical_equations_ptr, true,
89 false, false));
90 if constexpr (MODEL_TYPE == MODEL_AXISYMMETRIC) {
91 auto data = boost::make_shared<AxisymmetricAssemblyData>();
92 auto jacobian = [](double r, double, double) { return 2 * M_PI * r; };
93 pip.push_back(new OpCalculateAxisymmetricStress(m_P, data));
94 pip.push_back(
95 new OpInternalForce(field_name, data->inPlaneStress, jacobian));
96 pip.push_back(new OpAxisymmetricRhs<A, DomainEleOp>(field_name, m_P));
97 } else {
98 pip.push_back(new OpInternalForce(field_name, m_P));
99 }
101 }
102
103 template <AssemblyType A, IntegrationType I, typename DomainEleOp>
104 static MoFEMErrorCode
106 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
107 std::string field_name,
108 boost::shared_ptr<PhysicalEquations> physical_equations_ptr) {
110 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
111 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
112 A>::template BiLinearForm<I>;
113 using OpKPiola = typename B::template OpGradTensorGrad<1, DIM, DIM, -1>;
114 auto m_grad =
115 physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("grad");
116 auto m_P_dF =
117 physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("P_dF");
118 addKinematics(pip, field_name, m_grad);
119 pip.push_back(physical_equations_ptr->createOp(physical_equations_ptr,
120 false, true, false));
121 if constexpr (MODEL_TYPE == MODEL_AXISYMMETRIC) {
122 auto data = boost::make_shared<AxisymmetricAssemblyData>();
123 auto jacobian = [](double r, double, double) { return 2 * M_PI * r; };
124 pip.push_back(new OpCalculateAxisymmetricTangent(m_P_dF, data));
125 pip.push_back(new OpKPiola(field_name, field_name, data->inPlaneTangent,
126 jacobian));
127 pip.push_back(
129 } else {
130 pip.push_back(new OpKPiola(field_name, field_name, m_P_dF));
131 }
133 }
134
135 static MoFEMErrorCode
137 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
138 std::string field_name,
139 boost::shared_ptr<PhysicalEquations> physical_equations_ptr) {
141 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
142 auto m_grad =
143 physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("grad");
144 auto m_P = physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("P");
145 addKinematics(pip, field_name, m_grad);
146 pip.push_back(physical_equations_ptr->createOp(physical_equations_ptr,
147 false, false, true));
149 }
150
152 MoFEM::Interface &m_field,
153 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
154 std::string field_name,
155 boost::shared_ptr<PhysicalEquations> physical_equations_ptr) {
157 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
158 auto m_grad =
159 physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("grad");
160 auto m_P = physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("P");
161 addKinematics(pip, field_name, m_grad);
162 pip.push_back(physical_equations_ptr->createOp(physical_equations_ptr, true,
163 false, false));
165 }
166};
167/**@}*/
168
169/** \name First-Piola Response and Elastic Model Creators */
170/**@{*/
171
172std::map<int, boost::shared_ptr<MatPiolaResponse>> &
173getMetaPiolaResponseMap(boost::shared_ptr<MatPiolaResponse> meta_ptr);
174
175template <>
176boost::shared_ptr<PhysicalEquations>
178 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
179
180template <>
181boost::shared_ptr<PhysicalEquations>
183 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
184
185template <>
186boost::shared_ptr<PhysicalEquations>
188 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
189
190template <>
191boost::shared_ptr<PhysicalEquations>
193 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
194
195template <>
196boost::shared_ptr<PhysicalEquations>
198 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
199
200template <>
201boost::shared_ptr<PhysicalEquations>
203 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
204
205template <>
206boost::shared_ptr<PhysicalEquations>
207createMatOpsPhysicalEquationsPtr<ELASTICITY::MOONEYRIVLINWRIGGERSEQ63,
208 MODEL_3D>(
209 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
210
211template <>
212boost::shared_ptr<PhysicalEquations>
214 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
215
216template <>
217boost::shared_ptr<PhysicalEquations>
218createMatOpsPhysicalEquationsPtr<ELASTICITY::STVENANTKIRCHHOFF,
220 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
221
222template <>
223boost::shared_ptr<PhysicalEquations>
224createMatOpsPhysicalEquationsPtr<ELASTICITY::STVENANTKIRCHHOFF,
226 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
227
235
236template <>
237boost::shared_ptr<PhysicalEquations>
239 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
240
241/**@}*/
242
243} // namespace MatOps
244
245#endif // MAT_ELASTIC_HPP
SmartPetscObj< Mat > jacobian
#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()
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< PIOLA_RESPONSE::VOLUMELENGTHQUALITY, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< PIOLA_RESPONSE::META, MODEL_AXISYMMETRIC >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< PIOLA_RESPONSE::META, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< ELASTICITY::NEOHOOKEAN, MODEL_AXISYMMETRIC >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< ELASTICITY::NEOHOOKEAN, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
@ MODEL_AXISYMMETRIC
Definition MatOps.hpp:212
@ MODEL_3D
Definition MatOps.hpp:209
@ MODEL_2D_PLANE_STRAIN
Definition MatOps.hpp:210
std::map< int, boost::shared_ptr< MatPiolaResponse > > & getMetaPiolaResponseMap(boost::shared_ptr< MatPiolaResponse > meta_ptr)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< ELASTICITY::STVENANTKIRCHHOFF, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< PIOLA_RESPONSE::META, MODEL_2D_PLANE_STRAIN >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
VolumeLengthQualityType
@ BARRIER_AND_CHANGE_QUALITY_SCALED_BY_VOLUME
@ BARRIER_AND_QUALITY
@ LASTOP_VOLUMELENGTHQUALITYTYPE
@ BARRIER_AND_CHANGE_QUALITY
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< ELASTICITY::NEOHOOKEAN, MODEL_2D_PLANE_STRAIN >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr AssemblyType A
constexpr auto field_name
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, -1 > OpKPiola
[Only used for dynamics]
Definition seepage.cpp:63
Conservative elastic response with a stored-energy density.
static constexpr auto energyDensityDataName
MatOpsData::MatrixPtr getEnergyDensityPtr() const
boost::shared_ptr< MatrixDouble > MatrixPtr
Definition MatOps.hpp:40
Constitutive response expressed by first Piola stress.
Definition MatOps.hpp:186
static MoFEMErrorCode opUpdateFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< PhysicalEquations > physical_equations_ptr)
static MoFEMErrorCode opPostProcFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< PhysicalEquations > physical_equations_ptr)
static MoFEMErrorCode opLhsFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< PhysicalEquations > physical_equations_ptr)
static MoFEMErrorCode opRhsFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< PhysicalEquations > physical_equations_ptr)
static void addKinematics(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, const std::string &field_name, boost::shared_ptr< MatrixDouble > m_grad)
boost::shared_ptr< MatOpsData > matOpsDataPtr
Definition MatOps.hpp:176
Deprecated interface functions.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for MatrixDouble vector field values calculation.