v0.16.3
Loading...
Searching...
No Matches
MatUmat.cpp
Go to the documentation of this file.
1/**
2 * @file MatUmat.cpp
3 * @brief UMAT material model within MoFEM material impl.
4 */
5
6#include <MoFEM.hpp>
7
8using namespace MoFEM;
9
10#include "MatOps.hpp"
11#include "MatUmatImpl.hpp"
12
13namespace MatOps {
14
15template <int DIM, typename EleOp>
16static EleOp *createOpImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
17 bool eval_stress, bool eval_tangent, bool update);
18
19template <int DIM, int MODEL_TYPE>
22 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
23 bool eval_tangent, bool update) {
25 return createOpImpl<DIM, EleOp>(physical_ptr, eval_stress, eval_tangent,
26 update);
27}
28
29template <>
30boost::shared_ptr<PhysicalEquations>
32 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag) {
33 return boost::make_shared<MatUmatImpl<3, MODEL_3D>>(mat_ops_data_ptr, tag);
34}
35
36template <>
37boost::shared_ptr<PhysicalEquations>
39 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag) {
40 return boost::make_shared<MatUmatImpl<2, MODEL_2D_PLANE_STRAIN>>(
41 mat_ops_data_ptr, tag);
42}
43
44template <>
45boost::shared_ptr<PhysicalEquations>
47 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag) {
48 return boost::make_shared<MatUmatImpl<2, MODEL_2D_PLANE_STRESS>>(
49 mat_ops_data_ptr, tag);
50}
51
52template <>
53boost::shared_ptr<PhysicalEquations>
55 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag) {
56 return boost::make_shared<MatUmatImpl<3, MODEL_AXISYMMETRIC>>(
57 mat_ops_data_ptr, tag);
58}
59
60template <int DIM, typename DomainEleOp>
62
63 using OP = DomainEleOp;
64
65 OpEvalMatUmatMaterialImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
66 bool eval_stress, bool eval_tangent, bool update)
67 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), physicalPtr(physical_ptr),
68 evalStress(eval_stress), evalTangent(eval_tangent),
69 updateState(update) {}
70
71 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
72
73protected:
74 boost::shared_ptr<PhysicalEquations> physicalPtr;
75 const bool evalStress;
76 const bool evalTangent;
77 const bool updateState;
78};
79
80template <int DIM, typename DomainEleOp>
83 EntData &data) {
85
86 auto umat_op_data_ptr = boost::make_shared<UMatOpData>(this);
87 physicalPtr->matOpsDataPtr->setUserDataPtr(umat_op_data_ptr);
88
89 int nb_integration_pts = OP::getGaussPts().size2();
90
91 auto get_tag = [&]() {
92 if (physicalPtr->tagVsRangePtr) {
93 for (const auto &tag_range_pair : *(physicalPtr->tagVsRangePtr)) {
94 if (tag_range_pair.second.find(DomainEleOp::getFEEntityHandle()) !=
95 tag_range_pair.second.end()) {
96 return tag_range_pair.first;
97 }
98 }
99 }
100#ifndef NDEBUG
101 if (MatOpsTagsRegistry::getTagName(physicalPtr->tAg).empty()) {
103 "ADOL-C tag not found " +
104 std::to_string(physicalPtr->tAg));
105 }
106#endif
107 return physicalPtr->tAg; // Default tag if no range matches
108 };
109
110 const int current_tag = get_tag();
111 auto *fe_ptr = const_cast<FEMethod *>(this->getFEMethod());
112 const auto ent = fe_ptr->getFEEntityHandle();
113
114 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->resize(DIM, DIM, false);
115 physicalPtr->matOpsDataPtr->getDependentDataPtr("P")->resize(DIM, DIM, false);
116 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")->resize(
117 DIM * DIM, DIM * DIM, false);
118 auto mat_grad_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("grad");
119 auto mat_P_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("P");
120 auto mat_P_dF_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("P_dF");
121
122#ifndef NDEBUG
123 if (!mat_grad_ptr || !mat_P_ptr || !mat_P_dF_ptr) {
124 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
125 "Missing common data for ADOL-C evaluation");
126 }
127 if (mat_grad_ptr->size2() != DIM * DIM) {
128 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
129 "Inconsistent size of gradient matrix for ADOL-C evaluation");
130 }
131 if (mat_grad_ptr->size1() != nb_integration_pts) {
132 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
133 "Inconsistent size of gradient matrix data for ADOL-C evaluation "
134 "%zu != %d",
135 mat_grad_ptr->size1(), nb_integration_pts);
136 }
137#endif
138
140 auto get_grad_at_pts =
141 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
142 *mat_grad_ptr, nb_integration_pts);
143 auto get_P_at_pts =
144 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::size(
145 *mat_P_ptr, nb_integration_pts);
146 auto get_P_dF_at_pts =
147 MatrixSizeHelper<GetFTensor4FromMatType<DIM, DIM, DIM, DIM, -1, DL>,
148 DL>::size(*mat_P_dF_ptr, nb_integration_pts);
149
150 if (evalStress) {
151 FTENSOR_INDEX(DIM, i);
152 FTENSOR_INDEX(DIM, J);
153
154 auto t_grad_at_pts = get_grad_at_pts();
155 auto t_P_at_pts = get_P_at_pts();
156
157 auto next = [&]() {
158 ++t_grad_at_pts;
159 ++t_P_at_pts;
160 };
161
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->evaluateVariable(current_tag, ent, gg);
170 auto t_P = getFTensor2FromPtr<DIM, DIM>(
171 physicalPtr->matOpsDataPtr->getDependentDataPtr("P")->data().data());
172 t_P_at_pts(i, J) = t_P(i, J);
173 next();
174 }
175 }
176
177 if (evalTangent) {
178 FTENSOR_INDEX(DIM, i);
179 FTENSOR_INDEX(DIM, J);
180 FTENSOR_INDEX(DIM, k);
181 FTENSOR_INDEX(DIM, L);
182
183 auto t_grad_at_pts = get_grad_at_pts();
184 auto t_P_dF_at_pts = get_P_dF_at_pts();
186
187 auto next = [&]() {
188 ++t_grad_at_pts;
189 ++t_P_dF_at_pts;
190 };
191
192 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
193 auto t_F = getFTensor2FromPtr<DIM, DIM>(
194 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
195 t_F(i, J) = t_grad_at_pts(i, J);
196 CHKERR physicalPtr->setParams(fe_ptr, gg);
197 CHKERR physicalPtr->evaluateDerivatives(current_tag, ent, gg);
198 auto t_P_dF = getFTensor4FromPtr<DIM, DIM, DIM, DIM>(
199 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")
200 ->data()
201 .data());
202 t_P_dF_at_pts(i, J, k, L) = t_P_dF(i, J, k, L);
203 next();
204 }
205 }
206
207 if (updateState) {
208 FTENSOR_INDEX(DIM, i);
209 FTENSOR_INDEX(DIM, J);
210
211 auto t_grad_at_pts = get_grad_at_pts();
212 auto next = [&]() { ++t_grad_at_pts; };
213
214 for (int gg = 0; gg != nb_integration_pts; ++gg) {
215 auto t_F = getFTensor2FromPtr<DIM, DIM>(
216 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
217 t_F(i, J) = t_grad_at_pts(i, J);
218 CHKERR physicalPtr->setParams(fe_ptr, gg);
219 CHKERR physicalPtr->updateState(current_tag, ent, gg);
220 next();
221 }
222 }
223
225}
226
227template <int DIM, typename EleOp>
228static EleOp *createOpImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
229 bool eval_stress, bool eval_tangent, bool update) {
230 return new OpEvalMatUmatMaterialImpl<DIM, EleOp>(physical_ptr, eval_stress,
231 eval_tangent, update);
232}
233
236 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
237 bool eval_tangent, bool update);
238
241 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
242 bool eval_tangent, bool update);
243
246 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
247 bool eval_tangent, bool update);
248
251 boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
252 bool eval_tangent, bool update);
253
254} // namespace MatOps
std::string type
Shared UMAT implementation details for built-in and user-defined UMATs.
#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
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< UMAT, MODEL_2D_PLANE_STRESS >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatUmat.cpp:46
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< UMAT, MODEL_AXISYMMETRIC >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatUmat.cpp:54
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< UMAT, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatUmat.cpp:31
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< UMAT, MODEL_2D_PLANE_STRAIN >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatUmat.cpp:38
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
static std::string getTagName(int tag)
Definition MatOps.cpp:90
ForcesAndSourcesCore::UserDataOperator * createOp(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update) override
Definition MatUmat.cpp:21
OpEvalMatUmatMaterialImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update)
Definition MatUmat.cpp:65
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Definition MatUmat.cpp:82
boost::shared_ptr< PhysicalEquations > physicalPtr
Definition MatUmat.cpp:74
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.