v0.16.3
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, typename DomainEleOp>
32
33 using OP = DomainEleOp;
34
36 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
37 bool eval_tangent, bool update)
38 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), physicalPtr(physical_ptr),
39 evalStress(eval_stress), evalTangent(eval_tangent),
40 updateState(update) {}
41
42 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
43
44protected:
45 boost::shared_ptr<PhysicalEquations> physicalPtr;
46 const bool evalStress;
47 const bool evalTangent;
48 const bool updateState;
49};
50
51template <int DIM, typename DomainEleOp>
53 int side, EntityType type, EntData &data) {
55
56 int nb_integration_pts = OP::getGaussPts().size2();
57
58 auto get_tag = [&]() {
59 if (physicalPtr->tagVsRangePtr) {
60 for (const auto &tag_range_pair : *(physicalPtr->tagVsRangePtr)) {
61 if (tag_range_pair.second.find(DomainEleOp::getFEEntityHandle()) !=
62 tag_range_pair.second.end()) {
63 return tag_range_pair.first;
64 }
65 }
66 }
67#ifndef NDEBUG
68 if (MatOpsTagsRegistry::getTagName(physicalPtr->tAg).empty()) {
70 "ADOL-C tag not found " +
71 std::to_string(physicalPtr->tAg));
72 }
73#endif
74 return physicalPtr->tAg; // Default tag if no range matches
75 };
76
77 const int current_tag = get_tag();
78 auto *fe_ptr = const_cast<FEMethod *>(this->getFEMethod());
79 const auto ent = fe_ptr->getFEEntityHandle();
80
81 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->resize(DIM, DIM, false);
82 physicalPtr->matOpsDataPtr->getDependentDataPtr("P")->resize(DIM, DIM, false);
83 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")->resize(
84 DIM * DIM, DIM * DIM, false);
85 auto mat_grad_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("grad");
86 auto mat_P_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("P");
87 auto mat_P_dF_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("P_dF");
88
89#ifndef NDEBUG
90 if (!mat_grad_ptr || !mat_P_ptr || !mat_P_dF_ptr) {
91 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
92 "Missing common data for ADOL-C evaluation");
93 }
94 if (mat_grad_ptr->size2() != DIM * DIM) {
95 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
96 "Inconsistent size of gradient matrix for ADOL-C evaluation");
97 }
98 if (mat_grad_ptr->size1() != nb_integration_pts) {
99 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
100 "Inconsistent size of gradient matrix data for ADOL-C evaluation "
101 "%zu != %d",
102 mat_grad_ptr->size1(), nb_integration_pts);
103 }
104#endif
105
107 auto get_grad_at_pts =
108 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
109 *mat_grad_ptr, nb_integration_pts);
110 auto get_P_at_pts =
111 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::size(
112 *mat_P_ptr, nb_integration_pts);
113 auto get_P_dF_at_pts =
114 MatrixSizeHelper<GetFTensor4FromMatType<DIM, DIM, DIM, DIM, -1, DL>,
115 DL>::size(*mat_P_dF_ptr, nb_integration_pts);
116
117 if (evalStress) {
118 FTENSOR_INDEX(DIM, i);
119 FTENSOR_INDEX(DIM, J);
120
121 auto t_grad_at_pts = get_grad_at_pts();
122 auto t_P_at_pts = get_P_at_pts();
123
124 auto next = [&]() {
125 ++t_grad_at_pts;
126 ++t_P_at_pts;
127 };
128
130
131 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
132 auto t_F = getFTensor2FromPtr<DIM, DIM>(
133 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
134 t_F(i, J) = t_grad_at_pts(i, J);
135 CHKERR physicalPtr->setParams(fe_ptr, gg);
136 CHKERR physicalPtr->evaluateVariable(current_tag, ent, gg);
137 auto t_P = getFTensor2FromPtr<DIM, DIM>(
138 physicalPtr->matOpsDataPtr->getDependentDataPtr("P")->data().data());
139 t_P_at_pts(i, J) = t_P(i, J);
140 next();
141 }
142 }
143
144 if (evalTangent) {
145 FTENSOR_INDEX(DIM, i);
146 FTENSOR_INDEX(DIM, J);
147 FTENSOR_INDEX(DIM, k);
148 FTENSOR_INDEX(DIM, L);
149
150 auto t_grad_at_pts = get_grad_at_pts();
151 auto t_P_dF_at_pts = get_P_dF_at_pts();
153
154 auto next = [&]() {
155 ++t_grad_at_pts;
156 ++t_P_dF_at_pts;
157 };
158
159 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
160 auto t_F = getFTensor2FromPtr<DIM, DIM>(
161 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
162 t_F(i, J) = t_grad_at_pts(i, J);
163 CHKERR physicalPtr->setParams(fe_ptr, gg);
164 CHKERR physicalPtr->evaluateDerivatives(current_tag, ent, gg);
165 auto t_P_dF = getFTensor4FromPtr<DIM, DIM, DIM, DIM>(
166 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")
167 ->data()
168 .data());
169 t_P_dF_at_pts(i, J, k, L) = t_P_dF(i, J, k, L);
170 next();
171 }
172 }
173
174 if (updateState) {
175 FTENSOR_INDEX(DIM, i);
176 FTENSOR_INDEX(DIM, J);
177
178 auto t_grad_at_pts = get_grad_at_pts();
179 auto next = [&]() { ++t_grad_at_pts; };
180
181 for (int gg = 0; gg != nb_integration_pts; ++gg) {
182 auto t_F = getFTensor2FromPtr<DIM, DIM>(
183 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
184 t_F(i, J) = t_grad_at_pts(i, J);
185 CHKERR physicalPtr->setParams(fe_ptr, gg);
186 CHKERR physicalPtr->updateState(current_tag, ent, gg);
187 next();
188 }
189 }
190
192}
193
194template <int DIM, typename EleOp>
195static EleOp *createOpImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
196 bool eval_stress, bool eval_tangent, bool update) {
198 physical_ptr, eval_stress, eval_tangent, update);
199}
200
201template <>
203MatElasticImpl<3>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
204 bool eval_stress, bool eval_tangent,
205 bool update) {
207 return createOpImpl<3, EleOp>(physical_ptr, eval_stress, eval_tangent,
208 update);
209}
210
211template <>
213MatElasticImpl<2>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
214 bool eval_stress, bool eval_tangent,
215 bool update) {
217 return createOpImpl<2, EleOp>(physical_ptr, eval_stress, eval_tangent,
218 update);
219}
220
221} // namespace MatOps
222
223#include "MatNeohookean.cpp"
224#include "MatMetaElastic.cpp"
228#include "MatGenericElastic.cpp"
std::string type
ADOL-C implementation of the volume-length quality material.
#define FTENSOR_INDEX(DIM, I)
Kronecker Delta class.
#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.
constexpr auto t_kd
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'k', 3 > k
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(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:90
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)
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.