v0.16.3
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
22 typename OpBase>
23struct OpRhsHu;
24
26 typename OpBase>
27struct OpLhsHuHu;
28
30 typename OpBase>
32
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(
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(
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
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(
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 <>
172boost::shared_ptr<PhysicalEquations>
174 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag);
175
176template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
178 : public FormsIntegrators<OpBase>::template Assembly<A>::OpBase {
179
180 using OP = typename FormsIntegrators<OpBase>::template Assembly<A>::OpBase;
181
182 OpRhsHu(const std::string field_name,
183 boost::shared_ptr<MatrixDouble> mat_vals,
184 boost::shared_ptr<MatrixDouble> mat_K,
185 boost::shared_ptr<Range> ents_ptr = nullptr)
186 : OP(field_name, field_name, OP::OPROW), matVals(mat_vals), matK(mat_K) {}
187
188protected:
189 boost::shared_ptr<MatrixDouble> matVals;
190 boost::shared_ptr<MatrixDouble> matK;
192};
193
194template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
196 : public FormsIntegrators<OpBase>::template Assembly<A>::OpBase {
197
198 using OP = typename FormsIntegrators<OpBase>::template Assembly<A>::OpBase;
199 OpLhsHuHu(const std::string field_name, boost::shared_ptr<MatrixDouble> mat_K,
200 boost::shared_ptr<Range> ents_ptr = nullptr)
201 : OP(field_name, field_name, OP::OPROWCOL), matK(mat_K) {}
202
203protected:
204 boost::shared_ptr<MatrixDouble> matK;
205 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
207};
208
209template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
211 : public FormsIntegrators<OpBase>::template Assembly<A>::OpBase {
212 using OP = typename FormsIntegrators<OpBase>::template Assembly<A>::OpBase;
213 OpLhsHuGrad(const std::string field_name,
214 boost::shared_ptr<MatrixDouble> mat_vals,
215 boost::shared_ptr<MatrixDouble> mat_diff_K,
216 boost::shared_ptr<Range> ents_ptr = nullptr)
217 : OP(field_name, field_name, OP::OPROWCOL), matVals(mat_vals),
218 matDiffK(mat_diff_K) {
219 OP::sYmm = false;
220 }
221
222protected:
223 boost::shared_ptr<MatrixDouble> matVals;
224 boost::shared_ptr<MatrixDouble> matDiffK;
225 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
227};
228
229template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
231 EntitiesFieldData::EntData &row_data) {
233
237
238 auto get_val_grad_at_pts = MatrixSizeHelper<
240 DL>::get(*matVals, OP::nbIntegrationPts);
241 auto get_K_at_pts =
243 *matK, OP::nbIntegrationPts);
244
245 // get element volume
246 const double vol = OP::getMeasure();
247 // get integration weights
248 auto t_w = OP::getFTensor0IntegrationWeight();
249 // get base function gradient on rows
250 auto t_row_grad = row_data.getFTensor2DiffN2<SPACE_DIM>();
251 // get field gradient values
252 auto t_val_grad_at_pts =
253 get_val_grad_at_pts(); // tensor of second derivatives
254 // get K values
255 auto t_K_at_pts = get_K_at_pts(); // tensor of second derivatives
256 // get coordinate at integration points
257 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
258 // loop over integration points
259 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
260 // take into account Jacobian
261 const double alpha = t_w * vol * t_K_at_pts(0);
262 // calculate rhs
263 auto t_nf = getFTensor1FromArray<FIELD_DIM, FIELD_DIM>(OP::locF);
264 // loop over rows base functions
265 int rr = 0;
266 for (; rr != OP::nbRows / FIELD_DIM; rr++) {
267 // calculate element of local rhs vector
268 t_nf(i) += alpha * (t_row_grad(J, K) * t_val_grad_at_pts(i, J, K));
269 ++t_row_grad; // move to another element of gradient of base
270 // function on row
271 }
272 for (; rr < OP::nbRowBaseFunctions; ++rr)
273 ++t_row_grad;
274
275 ++t_coords;
276 ++t_val_grad_at_pts;
277 ++t_K_at_pts;
278 ++t_w; // move to another integration weight
279 }
281}
282
283template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
286 EntitiesFieldData::EntData &col_data) {
288
293
294 auto get_K_at_pts =
296 *matK, OP::nbIntegrationPts);
297
298 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
299
300 // get element volume
301 const double vol = OP::getMeasure();
302 // get integration weights
303 auto t_w = OP::getFTensor0IntegrationWeight();
304 // get base function gradient on rows
305 auto t_row_grad = row_data.getFTensor2DiffN2<SPACE_DIM>();
306 // get k values
307 auto t_K_at_pts = get_K_at_pts(); // tensor of second derivatives
308 // get coordinate at integration points
309 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
310 // loop over integration points
311 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
312 // take into account Jacobian
313 const double alpha = t_w * vol * t_K_at_pts(0);
314 // loop over rows base functions
315 int rr = 0;
316 for (; rr != OP::nbRows / FIELD_DIM; rr++) {
317
318 auto t_mat = getFTensor2FromArray<FIELD_DIM, FIELD_DIM, FIELD_DIM>(
319 OP::locMat, rr * FIELD_DIM, 0);
320 auto t_col_grad = col_data.getFTensor2DiffN2<SPACE_DIM>(gg, 0);
321
322 // calculate element of local matrix
323 for (int cc = 0; cc != OP::nbCols / FIELD_DIM; cc++) {
324 t_mat(i, j) +=
325 alpha * (t_row_grad(J, K) * t_col_grad(J, K)) * t_kd(i, j);
326 ++t_col_grad; // move to another element of gradient of base
327 // function on column
328 ++t_mat; // move to another element of local matrix
329 }
330 ++t_row_grad; // move to another element of gradient of base
331 // function on row
332 }
333 for (; rr < OP::nbRowBaseFunctions; ++rr)
334 ++t_row_grad;
335
336 ++t_coords;
337 ++t_K_at_pts;
338 ++t_w; // move to another integration weight
339 }
341}
342
343template <int FIELD_DIM, int SPACE_DIM, AssemblyType A, typename OpBase>
346 EntitiesFieldData::EntData &col_data) {
348
354
355 auto get_val_grad_at_pts = MatrixSizeHelper<
357 DL>::get(*matVals, OP::nbIntegrationPts);
358 auto get_diff_K_at_pts =
360 DL>::get(*matDiffK, OP::nbIntegrationPts);
361
362 // get element volume
363 const double vol = OP::getMeasure();
364 // get integration weights
365 auto t_w = OP::getFTensor0IntegrationWeight();
366 // get base function gradient on rows
367 auto t_row_grad = row_data.getFTensor2DiffN2<SPACE_DIM>();
368 // get field gradient values
369 auto t_val_grad_at_pts =
370 get_val_grad_at_pts(); // tensor of second derivatives
371 // get K values
372 auto t_diff_K_at_pts = get_diff_K_at_pts(); // tensor of second derivatives
373 // get coordinate at integration points
374 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
375 // loop over integration points
376 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
377 // take into account Jacobian
378 const double alpha = t_w * vol;
379 // loop over rows base functions
380 int rr = 0;
381 for (; rr != OP::nbRows / FIELD_DIM; rr++) {
382
383 auto t_mat = getFTensor2FromArray<FIELD_DIM, FIELD_DIM, FIELD_DIM>(
384 OP::locMat, rr * FIELD_DIM, 0);
385 auto t_col_grad = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
386 for (int bb = 0; bb != OP::nbCols / FIELD_DIM; ++bb) {
387 t_mat(i, j) += alpha * (t_row_grad(J, K) * t_val_grad_at_pts(i, J, K)) *
388 (t_diff_K_at_pts(j, M) * t_col_grad(M));
389
390 ++t_mat; // move to another element of local matrix
391 ++t_col_grad; // move to another element of gradient of base
392 // function on column
393 }
394
395 ++t_row_grad; // move to another element of gradient of base
396 // function on row
397 }
398 for (; rr < OP::nbRowBaseFunctions; ++rr)
399 ++t_row_grad;
400
401 ++t_coords;
402 ++t_val_grad_at_pts;
403 ++t_diff_K_at_pts;
404 ++t_w; // move to another integration weight
405 }
407}
408
409} // namespace MatOps
410
411#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
IntegrationType
Form integrator integration types.
AssemblyType
[Storage and set boundary conditions]
@ GAUSS
Gaussian quadrature integration.
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
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:193
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatHuHu.cpp:137
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_AXISYMMETRIC >(boost::shared_ptr< MatOpsData >, int)
Definition MatHuHu.cpp:151
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
decltype(GetFTensor3FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor3FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
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:213
OpLhsHuHu(const std::string field_name, boost::shared_ptr< MatrixDouble > mat_K, boost::shared_ptr< Range > ents_ptr=nullptr)
Definition MatHuHu.hpp:199
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:182
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
auto getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
auto getFTensor2DiffN2(const FieldApproximationBase base)
Get second derivatives of scalar base functions.
FieldApproximationBase getApproxBase() const
Get approximation basis type.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Operator for inverting matrices at integration points.
Execute "this" element in the operator.
Set inverse jacobian to base functions.