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
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 <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;
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,
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,
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<
235 DL>::get(*matVals, OP::nbIntegrationPts);
236 auto get_K_at_pts =
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>
281 EntitiesFieldData::EntData &col_data) {
283
288
289 auto get_K_at_pts =
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>
341 EntitiesFieldData::EntData &col_data) {
343
349
350 auto get_val_grad_at_pts = MatrixSizeHelper<
352 DL>::get(*matVals, OP::nbIntegrationPts);
353 auto get_diff_K_at_pts =
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
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:181
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr< HUHU, MODEL_3D >(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
Definition MatHuHu.cpp:137
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: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.
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.