v0.16.3
Loading...
Searching...
No Matches
MatHuHu.cpp
Go to the documentation of this file.
1/**
2 * @file MatHuHu.cpp
3 * @author your name (you@domain.com)
4 * @version 0.1
5 * @date 2026-03-29
6 *
7 * @copyright Copyright (c) 2026
8 *
9 */
10
11#include <MoFEM.hpp>
12
13using namespace MoFEM;
14
15#include "MatOps.hpp"
16#include "MatHuHu.hpp"
17
18namespace MatOps {
19
20template <int DIM>
21struct MatHuHu : public PhysicalEquations {
25 createOp(boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
26 bool eval_tangent, bool update) override;
27
28 MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr = nullptr) override {
30 MOFEM_LOG_CHANNEL("WORLD");
31
32 PetscOptionsBegin(PETSC_COMM_WORLD, "huhu_", "", "none");
33 CHKERR PetscOptionsScalar("-K", "Bulk modulus K", "", K, &K, PETSC_NULLPTR);
34 PetscOptionsEnd();
35
36 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "Default HuHu parameters:")
37 << " K = " << K;
39
40 std::string block_name = "MAT_HUHU";
41
42 for (auto &m :
43
44 m_field_ptr->getInterface<MeshsetsManager>()->
45
46 getCubitMeshsetPtr(
47 std::regex((boost::format("%s(.*)") % block_name).str()))
48
49 ) {
50
51 std::vector<double> block_data;
52 CHKERR m->getAttributes(block_data);
53 if (block_data.size() < 1) {
54 block_data.push_back(
55 K); // Use default K if not provided in block attributes
56 }
57 auto get_block_ents = [&]() {
58 Range ents;
59 CHK_MOAB_THROW(m_field_ptr->get_moab().get_entities_by_handle(
60 m->meshset, ents, true),
61 "can not get block entities");
62 return ents;
63 };
64
65 A::paramVecByRange.push_back({get_block_ents(), {block_data[0]}});
66
67 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock for HuHu")
68 << *m << " K = " << block_data[0];
69 }
70
72 };
73
74 MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override {
75 (void)gg;
76 const auto ent = fe_ptr->getFEEntityHandle();
77 for (auto &[range, param_vec] : A::paramVecByRange) {
78 if (std::find(range.begin(), range.end(), ent) != range.end()) {
79 set_param_vec(A::tAg, param_vec.size(), param_vec.data());
80 return 0;
81 }
82 }
83 set_param_vec(A::tAg, defaultMaterialParameters.size(),
85 return 0;
86 }
87
90
91 A::matOpsDataPtr->insertCommonData("grad", MatrixDouble(DIM * DIM, 1));
92 A::matOpsDataPtr->insertCommonData("k", MatrixDouble(1, 1));
93 A::matOpsDataPtr->insertCommonData("k_dF", MatrixDouble(DIM * DIM, 1));
94
95 A::matOpsDataPtr->insertActiveData("F", MatrixDouble(DIM, DIM));
96 A::matOpsDataPtr->insertDependentData("k", MatrixDouble(1, 1));
97 A::matOpsDataPtr->insertDependentDerivativesData("k_dF",
98 MatrixDouble(DIM, DIM));
99
100 auto t_F = getFTensor2FromPtr<DIM, DIM>(
101 A::matOpsDataPtr->getActiveDataPtr("F")->data().data());
102 auto k = (*A::matOpsDataPtr->getDependentDataPtr("k"))(0, 0);
103
105
106 FTENSOR_INDEX(DIM, i);
107 FTENSOR_INDEX(DIM, j);
108 FTENSOR_INDEX(DIM, I);
109 FTENSOR_INDEX(DIM, J);
110
111 t_F(i, J) = t_kd(i, J);
112
114 adouble ta_k;
115
116 adouble det_aF;
118
119 trace_on(A::tAg);
120 auto p_K = mkparam(K);
121 ta_F(i, J) <<= t_F(i, J);
122 ta_k = p_K;
123 ta_k >>= k;
124
125 trace_off();
126
128 }
129
130protected:
131 double K = 1e-6;
132 std::vector<double> defaultMaterialParameters = {K};
133};
134
135template <>
136boost::shared_ptr<PhysicalEquations>
138 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag) {
139 return boost::make_shared<MatHuHu<3>>(mat_ops_data_ptr, tag);
140}
141
142template <>
143boost::shared_ptr<PhysicalEquations>
145 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag) {
146 return boost::make_shared<MatHuHu<2>>(mat_ops_data_ptr, tag);
147}
148
149template <>
150boost::shared_ptr<PhysicalEquations>
152 boost::shared_ptr<MatOpsData>, int) {
154 "HuHu is not implemented for axisymmetric models");
155 return nullptr;
156}
157
158template <int DIM, typename DomainEleOp>
160
161 OpEvalMatHuHuImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
162 bool eval_stress, bool eval_tangent)
163 : DomainEleOp("U", DomainEleOp::OPROW), physicalPtr(physical_ptr),
164 evalStress(eval_stress), evalTangent(eval_tangent) {}
165
166 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
167
168protected:
169 boost::shared_ptr<PhysicalEquations> physicalPtr;
170 const bool evalStress;
171 const bool evalTangent;
172};
173
174template <int DIM, typename DomainEleOp>
176 EntityType type,
177 EntData &data) {
179 int nb_dofs = data.getIndices().size();
180 if (!nb_dofs)
182 int nb_integration_pts = data.getN().size1();
183 auto *fe_ptr = const_cast<FEMethod *>(this->getFEMethod());
184 const auto ent = fe_ptr->getFEEntityHandle();
185
186 auto get_tag = [&]() {
187 if (physicalPtr->tagVsRangePtr) {
188 for (const auto &tag_range_pair : *physicalPtr->tagVsRangePtr) {
189 if (tag_range_pair.second.find(ent) != tag_range_pair.second.end()) {
190 return tag_range_pair.first;
191 }
192 }
193 }
194 return physicalPtr->tAg; // Default tag if no range matches
195 };
196
197 const int current_tag = get_tag();
198
199 auto mat_grad_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("grad");
200 auto mat_k_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("k");
201 auto mat_k_dF_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("k_dF");
202
203#ifndef NDEBUG
204 if (!mat_grad_ptr || !mat_k_ptr || !mat_k_dF_ptr) {
205 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
206 "Missing common data for ADOL-C evaluation");
207 }
208 if (mat_grad_ptr->size2() != DIM * DIM) {
209 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
210 "Inconsistent size of gradient matrix for ADOL-C evaluation");
211 }
212 if (mat_grad_ptr->size1() != nb_integration_pts) {
213 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
214 "Inconsistent size of gradient matrix data for ADOL-C evaluation");
215 }
216#endif
217
219 auto get_grad_at_pts =
220 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
221 *mat_grad_ptr, nb_integration_pts);
222 auto get_k_at_pts =
224 *mat_k_ptr, nb_integration_pts);
225 auto get_k_dF_at_pts =
226 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::size(
227 *mat_k_dF_ptr, nb_integration_pts);
228
229 if (evalStress) {
230 FTENSOR_INDEX(DIM, i);
231 FTENSOR_INDEX(DIM, J);
232 FTENSOR_INDEX(DIM, K);
233 FTENSOR_INDEX(DIM, L);
234
235 auto t_grad_at_pts = get_grad_at_pts();
236 auto t_k_at_pts = get_k_at_pts();
237
238 auto next = [&]() {
239 ++t_grad_at_pts;
240 ++t_k_at_pts;
241 };
242
244
245 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
246 auto t_F = getFTensor2FromPtr<DIM, DIM>(
247 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
248 t_F(i, J) = t_grad_at_pts(i, J) + t_kd(i, J);
249 CHKERR physicalPtr->setParams(fe_ptr, gg);
250 CHKERR physicalPtr->evaluateVariable(current_tag, ent, gg);
251 t_k_at_pts(0) =
252 (*physicalPtr->matOpsDataPtr->getDependentDataPtr("k"))(0, 0);
253 next();
254 }
255 }
256
257 if (evalTangent) {
258 FTENSOR_INDEX(DIM, i);
259 FTENSOR_INDEX(DIM, J);
260 FTENSOR_INDEX(DIM, k);
261 FTENSOR_INDEX(DIM, L);
262
263 auto t_grad_at_pts = get_grad_at_pts();
264 auto t_k_dF_at_pts = get_k_dF_at_pts();
266
267 auto next = [&]() {
268 ++t_grad_at_pts;
269 ++t_k_dF_at_pts;
270 };
271
272 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
273 auto t_F = getFTensor2FromPtr<DIM, DIM>(
274 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
275 t_F(i, J) = t_grad_at_pts(i, J) + t_kd(i, J);
276 CHKERR physicalPtr->setParams(fe_ptr, gg);
277 CHKERR physicalPtr->evaluateDerivatives(current_tag, ent, gg);
278 auto t_k_dF = getFTensor2FromPtr<DIM, DIM>(
279 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("k_dF")
280 ->data()
281 .data());
282 t_k_dF_at_pts(i, J) = t_k_dF(i, J);
283 next();
284 }
285 }
286
288}
289
290template <int DIM, typename EleOp>
291static EleOp *createOpImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
292 bool eval_stress, bool eval_tangent, bool update) {
293 (void)update;
294 return new OpEvalMatHuHuImpl<DIM, EleOp>(physical_ptr, eval_stress,
295 eval_tangent);
296}
297
298template <>
300MatHuHu<3>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
301 bool eval_stress, bool eval_tangent, bool update) {
303 return createOpImpl<3, EleOp>(physical_ptr, eval_stress, eval_tangent,
304 update);
305}
306
307template <>
309MatHuHu<2>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
310 bool eval_stress, bool eval_tangent, bool update) {
312 return createOpImpl<2, EleOp>(physical_ptr, eval_stress, eval_tangent,
313 update);
314}
315
316} // namespace MatOps
std::string type
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
Kronecker Delta class.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#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
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_2D_PLANE_STRAIN >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatHuHu.cpp:144
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatHuHu.cpp:137
static EleOp * createOpImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update)
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_AXISYMMETRIC >(boost::shared_ptr< MatOpsData >, int)
Definition MatHuHu.cpp:151
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
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
constexpr IntegrationType I
FTensor::Index< 'm', 3 > m
MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr=nullptr) override
Definition MatHuHu.cpp:28
ForcesAndSourcesCore::UserDataOperator * createOp(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update) override
MoFEMErrorCode recordTape() override
Definition MatHuHu.cpp:88
PhysicalEquations()=delete
std::vector< double > defaultMaterialParameters
Definition MatHuHu.cpp:132
MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override
Definition MatHuHu.cpp:74
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Definition MatHuHu.cpp:175
OpEvalMatHuHuImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent)
Definition MatHuHu.cpp:161
boost::shared_ptr< PhysicalEquations > physicalPtr
Definition MatHuHu.cpp:169
std::vector< std::pair< Range, std::vector< double > > > paramVecByRange
Definition MatOps.hpp:174
boost::shared_ptr< MatOpsData > matOpsDataPtr
Definition MatOps.hpp:176
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
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.
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
Interface for managing meshsets containing materials and boundary conditions.