v0.16.0
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 <int DIM, typename DomainEleOp>
151
152 OpEvalMatHuHuImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
153 bool eval_stress, bool eval_tangent)
154 : DomainEleOp("U", DomainEleOp::OPROW), physicalPtr(physical_ptr),
155 evalStress(eval_stress), evalTangent(eval_tangent) {}
156
157 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
158
159protected:
160 boost::shared_ptr<PhysicalEquations> physicalPtr;
161 const bool evalStress;
162 const bool evalTangent;
163};
164
165template <int DIM, typename DomainEleOp>
167 EntityType type,
168 EntData &data) {
170 int nb_dofs = data.getIndices().size();
171 if (!nb_dofs)
173 int nb_integration_pts = data.getN().size1();
174 auto *fe_ptr = const_cast<FEMethod *>(this->getFEMethod());
175 const auto ent = fe_ptr->getFEEntityHandle();
176
177 auto get_tag = [&]() {
178 if (physicalPtr->tagVsRangePtr) {
179 for (const auto &tag_range_pair : *physicalPtr->tagVsRangePtr) {
180 if (tag_range_pair.second.find(ent) != tag_range_pair.second.end()) {
181 return tag_range_pair.first;
182 }
183 }
184 }
185 return physicalPtr->tAg; // Default tag if no range matches
186 };
187
188 const int current_tag = get_tag();
189
190 auto mat_grad_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("grad");
191 auto mat_k_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("k");
192 auto mat_k_dF_ptr = physicalPtr->matOpsDataPtr->getCommonDataPtr("k_dF");
193
194#ifndef NDEBUG
195 if (!mat_grad_ptr || !mat_k_ptr || !mat_k_dF_ptr) {
196 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
197 "Missing common data for ADOL-C evaluation");
198 }
199 if (mat_grad_ptr->size2() != DIM * DIM) {
200 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
201 "Inconsistent size of gradient matrix for ADOL-C evaluation");
202 }
203 if (mat_grad_ptr->size1() != nb_integration_pts) {
204 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
205 "Inconsistent size of gradient matrix data for ADOL-C evaluation");
206 }
207#endif
208
210 auto get_grad_at_pts =
211 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::get(
212 *mat_grad_ptr, nb_integration_pts);
213 auto get_k_at_pts =
215 *mat_k_ptr, nb_integration_pts);
216 auto get_k_dF_at_pts =
217 MatrixSizeHelper<GetFTensor2FromMatType<DIM, DIM, -1, DL>, DL>::size(
218 *mat_k_dF_ptr, nb_integration_pts);
219
220 if (evalStress) {
221 FTENSOR_INDEX(DIM, i);
222 FTENSOR_INDEX(DIM, J);
223 FTENSOR_INDEX(DIM, K);
224 FTENSOR_INDEX(DIM, L);
225
226 auto t_grad_at_pts = get_grad_at_pts();
227 auto t_k_at_pts = get_k_at_pts();
228
229 auto next = [&]() {
230 ++t_grad_at_pts;
231 ++t_k_at_pts;
232 };
233
235
236 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
237 auto t_F = getFTensor2FromPtr<DIM, DIM>(
238 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
239 t_F(i, J) = t_grad_at_pts(i, J) + t_kd(i, J);
240 CHKERR physicalPtr->setParams(fe_ptr, gg);
241 CHKERR physicalPtr->evaluateVariable(current_tag, ent, gg);
242 t_k_at_pts(0) =
243 (*physicalPtr->matOpsDataPtr->getDependentDataPtr("k"))(0, 0);
244 next();
245 }
246 }
247
248 if (evalTangent) {
249 FTENSOR_INDEX(DIM, i);
250 FTENSOR_INDEX(DIM, J);
251 FTENSOR_INDEX(DIM, k);
252 FTENSOR_INDEX(DIM, L);
253
254 auto t_grad_at_pts = get_grad_at_pts();
255 auto t_k_dF_at_pts = get_k_dF_at_pts();
257
258 auto next = [&]() {
259 ++t_grad_at_pts;
260 ++t_k_dF_at_pts;
261 };
262
263 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
264 auto t_F = getFTensor2FromPtr<DIM, DIM>(
265 physicalPtr->matOpsDataPtr->getActiveDataPtr("F")->data().data());
266 t_F(i, J) = t_grad_at_pts(i, J) + t_kd(i, J);
267 CHKERR physicalPtr->setParams(fe_ptr, gg);
268 CHKERR physicalPtr->evaluateDerivatives(current_tag, ent, gg);
269 auto t_k_dF = getFTensor2FromPtr<DIM, DIM>(
270 physicalPtr->matOpsDataPtr->getDependentDerivativesDataPtr("k_dF")
271 ->data()
272 .data());
273 t_k_dF_at_pts(i, J) = t_k_dF(i, J);
274 next();
275 }
276 }
277
279}
280
281template <int DIM, typename EleOp>
282static EleOp *createOpImpl(boost::shared_ptr<PhysicalEquations> physical_ptr,
283 bool eval_stress, bool eval_tangent, bool update) {
284 (void)update;
285 return new OpEvalMatHuHuImpl<DIM, EleOp>(physical_ptr, eval_stress,
286 eval_tangent);
287}
288
289template <>
291MatHuHu<3>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
292 bool eval_stress, bool eval_tangent, bool update) {
294 return createOpImpl<3, EleOp>(physical_ptr, eval_stress, eval_tangent,
295 update);
296}
297
298template <>
300MatHuHu<2>::createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
301 bool eval_stress, bool eval_tangent, bool update) {
303 return createOpImpl<2, EleOp>(physical_ptr, eval_stress, eval_tangent,
304 update);
305}
306
307} // 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 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
#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)
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:166
OpEvalMatHuHuImpl(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent)
Definition MatHuHu.cpp:152
boost::shared_ptr< PhysicalEquations > physicalPtr
Definition MatHuHu.cpp:160
std::vector< std::pair< Range, std::vector< double > > > paramVecByRange
Definition MatOps.hpp:152
boost::shared_ptr< MatOpsData > matOpsDataPtr
Definition MatOps.hpp:154
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.