v0.16.0
Loading...
Searching...
No Matches
MatHuHu.hpp
Go to the documentation of this file.
1/**
2 * @file MatHuHu.hpp
3 * @author your name (you@domain.com)
4 * @brief
5 * @version 0.1
6 * @date 2026-03-29
7 *
8 * @copyright Copyright (c) 2026
9 *
10 */
11
12#ifndef MAT_HUHU_HPP
13#define MAT_HUHU_HPP
14
15namespace MatOps {
16
17struct HUHU {
18 HUHU() = delete;
19};
20
21template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, IntegrationType I,
22 typename OpBase>
23struct OpRhsHu;
24
25template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, IntegrationType I,
26 typename OpBase>
27struct OpLhsHuHu;
28
29template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, IntegrationType I,
30 typename OpBase>
32
33using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
34
35template <int MODEL_TYPE> struct OpMaterialFactory<HUHU, MODEL_TYPE> {
37
38 template <AssemblyType A, IntegrationType I, typename DomainEleOp>
39 static MoFEMErrorCode
41 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
42 std::string fe_name, std::string field_name,
43 boost::shared_ptr<PhysicalEquations> physical_equations_ptr,
44 Sev sev = Sev::noisy) {
46 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
47 auto op_this = getPipThis<DomainEleOp>(m_field, pip, fe_name, field_name,
48 physical_equations_ptr, sev);
49 auto m_grad_grad = boost::make_shared<MatrixDouble>();
50 op_this->getOpPtrVector().push_back(
51 new OpCalculateVectorFieldHessian<DIM, DIM>(field_name, m_grad_grad));
52 op_this->getOpPtrVector().push_back(physical_equations_ptr->createOp(
53 physical_equations_ptr, true, false, false));
54 auto m_k = physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("k");
55 op_this->getOpPtrVector().push_back(
58 }
59
60 template <AssemblyType A, IntegrationType I, typename DomainEleOp>
61 static MoFEMErrorCode
63 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
64 std::string fe_name, std::string field_name,
65 boost::shared_ptr<PhysicalEquations> physical_equations_ptr,
66 Sev sev = Sev::noisy) {
68 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
69 auto op_this = getPipThis<DomainEleOp>(m_field, pip, fe_name, field_name,
70 physical_equations_ptr, sev);
71 auto m_grad_grad = boost::make_shared<MatrixDouble>();
72 op_this->getOpPtrVector().push_back(
73 new OpCalculateVectorFieldHessian<DIM, DIM>(field_name, m_grad_grad));
74 op_this->getOpPtrVector().push_back(physical_equations_ptr->createOp(
75 physical_equations_ptr, true, true, false));
76 auto m_k = physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("k");
77 auto m_diff_k =
78 physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("k_dF");
79 op_this->getOpPtrVector().push_back(
81 op_this->getOpPtrVector().push_back(
83 m_diff_k));
85 }
86
87private:
88 template <typename DomainEleOp>
89 static auto
91 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
92 std::string fe_name, std::string field_name,
93 boost::shared_ptr<PhysicalEquations> physical_equations_ptr,
94 Sev sev) {
95
96 auto &param_vec_by_range = physical_equations_ptr->paramVecByRange;
97 // range only if parameters are set via blockset
98 auto r = boost::make_shared<Range>();
99 for (auto &p : param_vec_by_range) {
100 r->merge(p.first);
101 }
102 MOFEM_LOG("WORLD", Sev::inform) << "HuHu number of entities " << r->size();
103
104 constexpr int DIM = (MODEL_TYPE == MODEL_3D) ? 3 : 2;
105
106 auto field_structure = m_field.get_field_structure(field_name);
107 auto base = field_structure->getApproxBase();
108 auto space = field_structure->getSpace();
109
110 using DomainEle = typename parent_of<DomainEleOp>::type;
111 auto op_this = new OpLoopThis<DomainEle>(m_field, fe_name, r, sev);
112 pip.push_back(op_this);
113 auto this_fe_ptr = op_this->getThisFEPtr();
114 auto &this_pip = op_this->getOpPtrVector();
115 this_fe_ptr->getRuleHook = [](int order_row, int order_col,
116 int order_data) {
117 return 2 * (order_data - 1);
118 };
119
120 auto base_mass = boost::make_shared<MatrixDouble>();
121 auto data_l2 = boost::make_shared<EntitiesFieldData>(MBENTITYSET);
122 auto jac_ptr = boost::make_shared<MatrixDouble>();
123 auto det_ptr = boost::make_shared<VectorDouble>();
124 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
125
126 // calculate jacobian at integration points
127 this_pip.push_back(new OpCalculateHOJac<DIM>(jac_ptr));
128 // calculate jacobian at integration points
129 this_pip.push_back(new OpInvertMatrix<DIM>(jac_ptr, det_ptr, inv_jac_ptr));
130 // calculate mass matrix to project derivatives
131 this_pip.push_back(
132 new OpBaseDerivativesMass<1>(base_mass, data_l2, base, L2));
133 // calculate second derivative of base functions, i.e. hessian
134 this_pip.push_back(new OpBaseDerivativesNext<1>(
135 BaseDerivatives::SecondDerivative, base_mass, data_l2, base, space));
136
137 switch (space) {
138 case H1:
139 // push first base derivatives tp physical element shape
140 this_pip.push_back(
141 new OpSetHOInvJacToScalarBases<DIM, 1>(space, inv_jac_ptr));
142 // push second base derivatives tp physical element shape
143 this_pip.push_back(
144 new OpSetHOInvJacToScalarBases<DIM, 2>(space, inv_jac_ptr));
145 break;
146 default:
147 MOFEM_LOG("WORLD", Sev::error)
148 << "Unsupported space: " << space << " for field: " << field_name;
150 }
151
152 auto m_grad =
153 physical_equations_ptr->matOpsDataPtr->getCommonDataPtr("grad");
154 this_pip.push_back(
155 new OpCalculateVectorFieldGradient<DIM, DIM>(field_name, m_grad));
156
157 return op_this;
158 }
159};
160
161template <>
162boost::shared_ptr<PhysicalEquations>
164 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
165
166template <>
167boost::shared_ptr<PhysicalEquations>
169 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
170
171template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
173 : public FormsIntegrators<OpBase>::template Assembly<A>::OpBase {
174
175 using OP = typename FormsIntegrators<OpBase>::template Assembly<A>::OpBase;
176
177 OpRhsHu(const std::string field_name,
178 boost::shared_ptr<MatrixDouble> mat_vals,
179 boost::shared_ptr<MatrixDouble> mat_K,
180 boost::shared_ptr<Range> ents_ptr = nullptr)
181 : OP(field_name, field_name, OP::OPROW), matVals(mat_vals), matK(mat_K) {}
182
183protected:
184 boost::shared_ptr<MatrixDouble> matVals;
185 boost::shared_ptr<MatrixDouble> matK;
186 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data);
187};
188
189template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
191 : public FormsIntegrators<OpBase>::template Assembly<A>::OpBase {
192
193 using OP = typename FormsIntegrators<OpBase>::template Assembly<A>::OpBase;
194 OpLhsHuHu(const std::string field_name, boost::shared_ptr<MatrixDouble> mat_K,
195 boost::shared_ptr<Range> ents_ptr = nullptr)
196 : OP(field_name, field_name, OP::OPROWCOL), matK(mat_K) {}
197
198protected:
199 boost::shared_ptr<MatrixDouble> matK;
200 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
201 EntitiesFieldData::EntData &col_data);
202};
203
204template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
206 : public FormsIntegrators<OpBase>::template Assembly<A>::OpBase {
207 using OP = typename FormsIntegrators<OpBase>::template Assembly<A>::OpBase;
208 OpLhsHuGrad(const std::string field_name,
209 boost::shared_ptr<MatrixDouble> mat_vals,
210 boost::shared_ptr<MatrixDouble> mat_diff_K,
211 boost::shared_ptr<Range> ents_ptr = nullptr)
212 : OP(field_name, field_name, OP::OPROWCOL), matVals(mat_vals),
213 matDiffK(mat_diff_K) {
214 OP::sYmm = false;
215 }
216
217protected:
218 boost::shared_ptr<MatrixDouble> matVals;
219 boost::shared_ptr<MatrixDouble> matDiffK;
220 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
221 EntitiesFieldData::EntData &col_data);
222};
223
224template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
226 EntitiesFieldData::EntData &row_data) {
228
232
233 auto get_val_grad_at_pts = MatrixSizeHelper<
234 GetFTensor3FromMatType<FIELD_DIM, SPACE_DIM, SPACE_DIM, -1, DL>,
235 DL>::get(*matVals, OP::nbIntegrationPts);
236 auto get_K_at_pts =
237 MatrixSizeHelper<GetFTensor1FromMatType<1, -1, DL>, DL>::get(
238 *matK, OP::nbIntegrationPts);
239
240 // get element volume
241 const double vol = OP::getMeasure();
242 // get integration weights
243 auto t_w = OP::getFTensor0IntegrationWeight();
244 // get base function gradient on rows
245 auto t_row_grad = row_data.getFTensor2DiffN2<SPACE_DIM>();
246 // get field gradient values
247 auto t_val_grad_at_pts =
248 get_val_grad_at_pts(); // tensor of second derivatives
249 // get K values
250 auto t_K_at_pts = get_K_at_pts(); // tensor of second derivatives
251 // get coordinate at integration points
252 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
253 // loop over integration points
254 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
255 // take into account Jacobian
256 const double alpha = t_w * vol * t_K_at_pts(0);
257 // calculate rhs
258 auto t_nf = getFTensor1FromArray<FIELD_DIM, FIELD_DIM>(OP::locF);
259 // loop over rows base functions
260 int rr = 0;
261 for (; rr != OP::nbRows / FIELD_DIM; rr++) {
262 // calculate element of local rhs vector
263 t_nf(i) += alpha * (t_row_grad(J, K) * t_val_grad_at_pts(i, J, K));
264 ++t_row_grad; // move to another element of gradient of base
265 // function on row
266 }
267 for (; rr < OP::nbRowBaseFunctions; ++rr)
268 ++t_row_grad;
269
270 ++t_coords;
271 ++t_val_grad_at_pts;
272 ++t_K_at_pts;
273 ++t_w; // move to another integration weight
274 }
276}
277
278template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
280 EntitiesFieldData::EntData &row_data,
281 EntitiesFieldData::EntData &col_data) {
283
288
289 auto get_K_at_pts =
290 MatrixSizeHelper<GetFTensor1FromMatType<1, -1, DL>, DL>::get(
291 *matK, OP::nbIntegrationPts);
292
293 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
294
295 // get element volume
296 const double vol = OP::getMeasure();
297 // get integration weights
298 auto t_w = OP::getFTensor0IntegrationWeight();
299 // get base function gradient on rows
300 auto t_row_grad = row_data.getFTensor2DiffN2<SPACE_DIM>();
301 // get k values
302 auto t_K_at_pts = get_K_at_pts(); // tensor of second derivatives
303 // get coordinate at integration points
304 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
305 // loop over integration points
306 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
307 // take into account Jacobian
308 const double alpha = t_w * vol * t_K_at_pts(0);
309 // loop over rows base functions
310 int rr = 0;
311 for (; rr != OP::nbRows / FIELD_DIM; rr++) {
312
313 auto t_mat = getFTensor2FromArray<FIELD_DIM, FIELD_DIM, FIELD_DIM>(
314 OP::locMat, rr * FIELD_DIM, 0);
315 auto t_col_grad = col_data.getFTensor2DiffN2<SPACE_DIM>(gg, 0);
316
317 // calculate element of local matrix
318 for (int cc = 0; cc != OP::nbCols / FIELD_DIM; cc++) {
319 t_mat(i, j) +=
320 alpha * (t_row_grad(J, K) * t_col_grad(J, K)) * t_kd(i, j);
321 ++t_col_grad; // move to another element of gradient of base
322 // function on column
323 ++t_mat; // move to another element of local matrix
324 }
325 ++t_row_grad; // move to another element of gradient of base
326 // function on row
327 }
328 for (; rr < OP::nbRowBaseFunctions; ++rr)
329 ++t_row_grad;
330
331 ++t_coords;
332 ++t_K_at_pts;
333 ++t_w; // move to another integration weight
334 }
336}
337
338template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
340 EntitiesFieldData::EntData &row_data,
341 EntitiesFieldData::EntData &col_data) {
343
349
350 auto get_val_grad_at_pts = MatrixSizeHelper<
351 GetFTensor3FromMatType<FIELD_DIM, SPACE_DIM, SPACE_DIM, -1, DL>,
352 DL>::get(*matVals, OP::nbIntegrationPts);
353 auto get_diff_K_at_pts =
354 MatrixSizeHelper<GetFTensor2FromMatType<FIELD_DIM, SPACE_DIM, -1, DL>,
355 DL>::get(*matDiffK, OP::nbIntegrationPts);
356
357 // get element volume
358 const double vol = OP::getMeasure();
359 // get integration weights
360 auto t_w = OP::getFTensor0IntegrationWeight();
361 // get base function gradient on rows
362 auto t_row_grad = row_data.getFTensor2DiffN2<SPACE_DIM>();
363 // get field gradient values
364 auto t_val_grad_at_pts =
365 get_val_grad_at_pts(); // tensor of second derivatives
366 // get K values
367 auto t_diff_K_at_pts = get_diff_K_at_pts(); // tensor of second derivatives
368 // get coordinate at integration points
369 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
370 // loop over integration points
371 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
372 // take into account Jacobian
373 const double alpha = t_w * vol;
374 // loop over rows base functions
375 int rr = 0;
376 for (; rr != OP::nbRows / FIELD_DIM; rr++) {
377
378 auto t_mat = getFTensor2FromArray<FIELD_DIM, FIELD_DIM, FIELD_DIM>(
379 OP::locMat, rr * FIELD_DIM, 0);
380 auto t_col_grad = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
381 for (int bb = 0; bb != OP::nbCols / FIELD_DIM; ++bb) {
382 t_mat(i, j) += alpha * (t_row_grad(J, K) * t_val_grad_at_pts(i, J, K)) *
383 (t_diff_K_at_pts(j, M) * t_col_grad(M));
384
385 ++t_mat; // move to another element of local matrix
386 ++t_col_grad; // move to another element of gradient of base
387 // function on column
388 }
389
390 ++t_row_grad; // move to another element of gradient of base
391 // function on row
392 }
393 for (; rr < OP::nbRowBaseFunctions; ++rr)
394 ++t_row_grad;
395
396 ++t_coords;
397 ++t_val_grad_at_pts;
398 ++t_diff_K_at_pts;
399 ++t_w; // move to another integration weight
400 }
402}
403
404} // namespace MatOps
405
406#endif // MAT_HUHU_HPP
#define FTENSOR_INDEX(DIM, I)
constexpr int SPACE_DIM
constexpr int FIELD_DIM
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
Kronecker Delta class.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
#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()
constexpr auto t_kd
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'j', 3 > j
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_2D_PLANE_STRAIN >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatHuHu.cpp:144
@ MODEL_3D
Definition MatOps.hpp:171
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatHuHu.cpp:137
constexpr IntegrationType I
constexpr AssemblyType A
constexpr auto field_name
HUHU()=delete
OpLhsHuGrad(const std::string field_name, boost::shared_ptr< MatrixDouble > mat_vals, boost::shared_ptr< MatrixDouble > mat_diff_K, boost::shared_ptr< Range > ents_ptr=nullptr)
Definition MatHuHu.hpp:208
OpLhsHuHu(const std::string field_name, boost::shared_ptr< MatrixDouble > mat_K, boost::shared_ptr< Range > ents_ptr=nullptr)
Definition MatHuHu.hpp:194
static auto getPipThis(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string fe_name, std::string field_name, boost::shared_ptr< PhysicalEquations > physical_equations_ptr, Sev sev)
Definition MatHuHu.hpp:90
static MoFEMErrorCode opLhsFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string fe_name, std::string field_name, boost::shared_ptr< PhysicalEquations > physical_equations_ptr, Sev sev=Sev::noisy)
Definition MatHuHu.hpp:62
static MoFEMErrorCode opRhsFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string fe_name, std::string field_name, boost::shared_ptr< PhysicalEquations > physical_equations_ptr, Sev sev=Sev::noisy)
Definition MatHuHu.hpp:40
OpRhsHu(const std::string field_name, boost::shared_ptr< MatrixDouble > mat_vals, boost::shared_ptr< MatrixDouble > mat_K, boost::shared_ptr< Range > ents_ptr=nullptr)
Definition MatHuHu.hpp:177
Deprecated interface functions.
FieldApproximationBase getApproxBase() const
Get approximation basis type.