v0.16.0
Loading...
Searching...
No Matches
MatElastic.cpp
Go to the documentation of this file.
1/**
2 * @file MatElastic.cpp
3 * @author your name (you@domain.com)
4 * @brief
5 * @version 0.1
6 * @date 2026-03-26
7 *
8 * @copyright Copyright (c) 2026
9 *
10 */
11
12#include <MoFEM.hpp>
13
14using namespace MoFEM;
15
16#include "MatOps.hpp"
17#include "MatElastic.hpp"
18
19namespace MatOps {
20
21template <int DIM> struct MatElasticImpl : public MatElastic {
22 using MatElastic::MatElastic;
24 createOp(boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
25 bool eval_tangent, bool update) override;
26
27protected:
28};
29
30template <int DIM> struct TopoMatElasticImpl : public MatElastic {
31 using MatElastic::MatElastic;
33 createOp(boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
34 bool eval_tangent, bool update) override;
35
36protected:
37};
38
39template <int DIM, typename DomainEleOp>
41
42 using OP = DomainEleOp;
43
45 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
46 bool eval_tangent, bool update)
47 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), physicalPtr(physical_ptr),
48 evalStress(eval_stress), evalTangent(eval_tangent),
49 updateState(update) {}
50
51 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
52
53protected:
54 boost::shared_ptr<PhysicalEquations> physicalPtr;
55 const bool evalStress;
56 const bool evalTangent;
57 const bool updateState;
58};
59
60template <int DIM, typename DomainEleOp>
62 int side, EntityType type, EntData &data) {
64
65 int nb_integration_pts = OP::getGaussPts().size2();
66
67 auto get_tag = [&]() {
68 if (physicalPtr->tagVsRangePtr) {
69 for (const auto &tag_range_pair : *(physicalPtr->tagVsRangePtr)) {
70 if (tag_range_pair.second.find(DomainEleOp::getFEEntityHandle()) !=
71 tag_range_pair.second.end()) {
72 return tag_range_pair.first;
73 }
74 }
75 }
76#ifndef NDEBUG
77 if (MatOpsTagsRegistry::getTagName(physicalPtr->tAg).empty()) {
79 "ADOL-C tag not found " +
80 std::to_string(physicalPtr->tAg));
81 }
82#endif
83 return physicalPtr->tAg; // Default tag if no range matches
84 };
85
86 const int current_tag = get_tag();
87 auto *fe_ptr = const_cast<FEMethod *>(this->getFEMethod());
88 const auto ent = fe_ptr->getFEEntityHandle();
89
90 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->resize(DIM, DIM, false);
91 physicalPtr->matOpsDataPtr->getDependentDataPtr("P")->resize(DIM, DIM, false);
92 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")->resize(
93 DIM * DIM, DIM * DIM, false);
94 auto mat_grad_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("grad");
95 auto mat_P_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("P");
96 auto mat_P_dF_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("P_dF");
97
98#ifndef NDEBUG
99 if (!mat_grad_ptr || !mat_P_ptr || !mat_P_dF_ptr) {
100 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
101 "Missing common data for ADOL-C evaluation");
102 }
103 if (mat_grad_ptr->size2() != DIM * DIM) {
104 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
105 "Inconsistent size of gradient matrix for ADOL-C evaluation");
106 }
107 if (mat_grad_ptr->size1() != nb_integration_pts) {
108 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
109 "Inconsistent size of gradient matrix data for ADOL-C evaluation "
110 "%zu != %d",
111 mat_grad_ptr->size1(), nb_integration_pts);
112 }
113#endif
114
116 auto get_grad_at_pts =
117 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
118 *mat_grad_ptr, nb_integration_pts);
119 auto get_P_at_pts =
120 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::size(
121 *mat_P_ptr, nb_integration_pts);
122 auto get_P_dF_at_pts =
123 MatrixSizeHelper<GetFTensor4FromMatType<DIM, DIM, DIM, DIM, -1, DL>,
124 DL>::size(*mat_P_dF_ptr, nb_integration_pts);
125
126 if (evalStress) {
127 FTENSOR_INDEX(DIM, i);
128 FTENSOR_INDEX(DIM, J);
129
130 auto t_grad_at_pts = get_grad_at_pts();
131 auto t_P_at_pts = get_P_at_pts();
132
133 auto next = [&]() {
134 ++t_grad_at_pts;
135 ++t_P_at_pts;
136 };
137
138 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
139 auto t_F = getFTensor2FromPtr<DIM, DIM>(
140 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
141 t_F(i, J) = t_grad_at_pts(i, J);
142 CHKERR physicalPtr->setParams(fe_ptr, gg);
143 CHKERR physicalPtr->evaluateVariable(current_tag, ent, gg);
144 auto t_P = getFTensor2FromPtr<DIM, DIM>(
145 physicalPtr->matOpsDataPtr->getDependentDataPtr("P")->data().data());
146 t_P_at_pts(i, J) = t_P(i, J);
147 next();
148 }
149 }
150
151 if (evalTangent) {
152 FTENSOR_INDEX(DIM, i);
153 FTENSOR_INDEX(DIM, J);
154 FTENSOR_INDEX(DIM, k);
155 FTENSOR_INDEX(DIM, L);
156
157 auto t_grad_at_pts = get_grad_at_pts();
158 auto t_P_dF_at_pts = get_P_dF_at_pts();
159 auto next = [&]() {
160 ++t_grad_at_pts;
161 ++t_P_dF_at_pts;
162 };
163
164 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
165 auto t_F = getFTensor2FromPtr<DIM, DIM>(
166 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
167 t_F(i, J) = t_grad_at_pts(i, J);
168 CHKERR physicalPtr->setParams(fe_ptr, gg);
169 CHKERR physicalPtr->evaluateDerivatives(current_tag, ent, gg);
170 auto t_P_dF = getFTensor4FromPtr<DIM, DIM, DIM, DIM>(
171 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")
172 ->data()
173 .data());
174 t_P_dF_at_pts(i, J, k, L) = t_P_dF(i, J, k, L);
175 next();
176 }
177 }
178
179 if (updateState) {
180 FTENSOR_INDEX(DIM, i);
181 FTENSOR_INDEX(DIM, J);
182
183 auto t_grad_at_pts = get_grad_at_pts();
184 auto next = [&]() { ++t_grad_at_pts; };
185
186 for (int gg = 0; gg != nb_integration_pts; ++gg) {
187 auto t_F = getFTensor2FromPtr<DIM, DIM>(
188 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
189 t_F(i, J) = t_grad_at_pts(i, J);
190 CHKERR physicalPtr->setParams(fe_ptr, gg);
191 CHKERR physicalPtr->updateState(current_tag, ent, gg);
192 next();
193 }
194 }
195
197}
198
199template <int DIM, typename DomainEleOp>
201
203
205 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
206 bool eval_tangent, bool update)
207 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), physicalPtr(physical_ptr),
208 evalStress(eval_stress), evalTangent(eval_tangent),
209 updateState(update) {}
210
211 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
212
213protected:
214 boost::shared_ptr<PhysicalEquations> physicalPtr;
215 const bool evalStress;
216 const bool evalTangent;
217 const bool updateState;
218};
219
220template <int DIM, typename DomainEleOp>
222 int side, EntityType type, EntData &data) {
224
225 int nb_integration_pts = OP::getGaussPts().size2();
226
227 auto get_tag = [&]() {
228 if (physicalPtr->tagVsRangePtr) {
229 for (const auto &tag_range_pair : *(physicalPtr->tagVsRangePtr)) {
230 if (tag_range_pair.second.find(DomainEleOp::getFEEntityHandle()) !=
231 tag_range_pair.second.end()) {
232 return tag_range_pair.first;
233 }
234 }
235 }
236#ifndef NDEBUG
237 if (MatOpsTagsRegistry::getTagName(physicalPtr->tAg).empty()) {
239 "ADOL-C tag not found " +
240 std::to_string(physicalPtr->tAg));
241 }
242#endif
243 return physicalPtr->tAg; // Default tag if no range matches
244 };
245
246 const int current_tag = get_tag();
247 auto *fe_ptr = const_cast<FEMethod *>(this->getFEMethod());
248 const auto ent = fe_ptr->getFEEntityHandle();
249
250 physicalPtr->matOpsDataPtr->getActiveDataPtr("Jac")->resize(DIM, DIM, false);
251 physicalPtr->matOpsDataPtr->getDependentDataPtr("Obj")->resize(1, false);
252 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("dObj")->resize(
253 DIM, DIM, false);
254 auto mat_jac_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("Jac");
255 auto mat_grad_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("grad");
256 auto mat_var_grad_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("var_grad");
257 auto mat_obj_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("Obj");
258 auto mat_dObj_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("dObj");
259
260#ifndef NDEBUG
261 if (!mat_jac_ptr || !mat_grad_ptr || !mat_var_grad_ptr || !mat_obj_ptr ||
262 !mat_dObj_ptr) {
263 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
264 "Missing common data for ADOL-C evaluation");
265 }
266#endif
267
269 auto get_jac_at_pts =
270 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
271 *mat_jac_ptr, nb_integration_pts);
272 [[maybe_unused]] auto get_grad_at_pts =
273 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
274 *mat_grad_ptr, nb_integration_pts);
275 [[maybe_unused]] auto get_var_grad_at_pts =
276 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
277 *mat_var_grad_ptr, nb_integration_pts);
278 auto get_obj_at_pts =
280 *mat_obj_ptr, nb_integration_pts);
281 auto get_dObj_at_pts =
282 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::size(
283 *mat_dObj_ptr, nb_integration_pts);
284
285 if (evalStress) {
286 FTENSOR_INDEX(DIM, i);
287 FTENSOR_INDEX(DIM, J);
288
289 auto t_jac_at_pts = get_jac_at_pts();
290 auto t_obj_at_pts = get_obj_at_pts();
291
292 auto next = [&]() {
293 ++t_jac_at_pts;
294 ++t_obj_at_pts;
295 };
296
297 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
298 auto t_jac = getFTensor2FromPtr<DIM, DIM>(
299 physicalPtr->matOpsDataPtr->getActiveDataPtr("Jac")->data().data());
300 t_jac(i, J) = t_jac_at_pts(i, J);
301 CHKERR physicalPtr->setParams(fe_ptr, gg);
302 CHKERR physicalPtr->evaluateVariable(current_tag, ent, gg);
303 auto t_obj = getFTensor1FromPtr<1, 1>(
304 physicalPtr->matOpsDataPtr->getDependentDataPtr("Obj")
305 ->data()
306 .data());
307 t_obj_at_pts(0) = t_obj(0);
308 next();
309 }
310 }
311
312 if (evalTangent) {
313 FTENSOR_INDEX(DIM, i);
314 FTENSOR_INDEX(DIM, J);
315 FTENSOR_INDEX(DIM, k);
316 FTENSOR_INDEX(DIM, L);
317
318 auto t_jac_at_pts = get_jac_at_pts();
319 auto t_dObj_at_pts = get_dObj_at_pts();
320 auto next = [&]() {
321 ++t_jac_at_pts;
322 ++t_dObj_at_pts;
323 };
324
325 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
326 auto t_jac = getFTensor2FromPtr<DIM, DIM>(
327 physicalPtr->matOpsDataPtr->getActiveDataPtr("Jac")->data().data());
328 t_jac(i, J) = t_jac_at_pts(i, J);
329 CHKERR physicalPtr->setParams(fe_ptr, gg);
330 CHKERR physicalPtr->evaluateDerivatives(current_tag, ent, gg);
331 auto t_dObj = getFTensor2FromPtr<DIM, DIM>(
332 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("dObj")
333 ->data()
334 .data());
335 t_dObj_at_pts(i, J) = t_dObj(i, J);
336 next();
337 }
338 }
339
340 if (updateState) {
341 }
342
344}
345
346template <int DIM, typename EleOp>
347static EleOp *createOpImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
348 bool eval_stress, bool eval_tangent, bool update) {
350 physical_ptr, eval_stress, eval_tangent, update);
351}
352
353template <>
355MatElasticImpl<3>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
356 bool eval_stress, bool eval_tangent,
357 bool update) {
359 return createOpImpl<3, EleOp>(physical_ptr, eval_stress, eval_tangent,
360 update);
361}
362
363template <>
365MatElasticImpl<2>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
366 bool eval_stress, bool eval_tangent,
367 bool update) {
369 return createOpImpl<2, EleOp>(physical_ptr, eval_stress, eval_tangent,
370 update);
371}
372
373template <int DIM, typename EleOp>
374static EleOp *
375createTopoOpImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
376 bool eval_stress, bool eval_tangent, bool update) {
378 physical_ptr, eval_stress, eval_tangent, update);
379}
380
381template <>
383 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
384 bool eval_tangent, bool update) {
386 return createTopoOpImpl<3, EleOp>(physical_ptr, eval_stress, eval_tangent,
387 update);
388}
389
390template <>
392 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
393 bool eval_tangent, bool update) {
395 return createTopoOpImpl<2, EleOp>(physical_ptr, eval_stress, eval_tangent,
396 update);
397}
398
399} // namespace MatOps
400
401#include "MatNeohookean.cpp"
402#include "MatMetaElastic.cpp"
406#include "MatGenericElastic.cpp"
std::string type
ADOL-C implementation of the volume-length quality material.
#define FTENSOR_INDEX(DIM, I)
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'k', 3 > k
static EleOp * createTopoOpImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update)
static EleOp * createOpImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
decltype(GetFTensor4FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor4FromMatType
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
ForcesAndSourcesCore::UserDataOperator * createOp(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update) override
static std::string getTagName(int tag)
Definition MatOps.cpp:83
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< PhysicalEquations > physicalPtr
OpEvalMatSimpleMaterialImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update)
OpEvalTopoMatSimpleMaterialImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update)
boost::shared_ptr< PhysicalEquations > physicalPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
ForcesAndSourcesCore::UserDataOperator * createOp(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update) override
Data on single entity (This is passed as argument to DataOperator::doWork)
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.