v0.15.0
Loading...
Searching...
No Matches
BiLinearFormsIntegratorsImpl.hpp
Go to the documentation of this file.
1/** \file BiLinearFormsIntegratorsImpl.hpp
2 * \brief Bilinear forms integrators (implementation)
3 * \ingroup mofem_form
4
5 \todo Some operators could be optimised. To do that, we need to write tests
6 and use Valgrind to profile code, shaking cache misses. For example, some
7 operators should have iteration first over columns, then rows. ome operators.
8 Since those operators are used in many problems, an implementation must be
9 efficient.
10
11*/
12
13#ifndef __BILINEAR_FORMS_INTEGRATORS_IMPL_HPP__
14#define __BILINEAR_FORMS_INTEGRATORS_IMPL_HPP__
15
16namespace MoFEM {
17
19 std::map<std::pair<int, int>, boost::shared_ptr<MatrixDouble>>;
20
21template <int BASE_DIM, int FIELD_DIM, int SPACE_DIM, IntegrationType I,
22 typename OpBase>
24
25template <int SPACE_DIM, typename OpBase>
26struct OpGradGradImpl<1, 1, SPACE_DIM, GAUSS, OpBase> : public OpBase {
27 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
28 OpGradGradImpl(const std::string row_field_name,
29 const std::string col_field_name,
31 boost::shared_ptr<Range> ents_ptr = nullptr)
32 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
33 betaCoeff(beta) {
34 if (row_field_name == col_field_name)
35 this->sYmm = true;
36 }
37
38protected:
42};
43
44template <int FIELD_DIM, int SPACE_DIM, typename OpBase>
46 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
47 OpGradGradImpl(const std::string row_field_name,
48 const std::string col_field_name,
50 boost::shared_ptr<Range> ents_ptr = nullptr)
51 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
52 betaCoeff(beta) {
53 if (row_field_name == col_field_name)
54 this->sYmm = true;
55 }
56
57protected:
61};
62
63template <int BASE_DIM, int FIELD_DIM, IntegrationType I, typename OpBase>
64struct OpMassImpl {};
65
66template <typename OpBase>
67struct OpMassImpl<1, 1, GAUSS, OpBase> : public OpBase {
68
70 const std::string row_field_name, const std::string col_field_name,
71 ScalarFun beta = [](double, double, double) constexpr { return 1; },
72 boost::shared_ptr<Range> ents_ptr = nullptr,
73 boost::shared_ptr<MatrixDouble> cache_mat = nullptr)
74 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
75 betaCoeff(beta) {
76 if (row_field_name == col_field_name)
77 this->sYmm = true;
78 }
79
80protected:
81 using OpBase::OpBase;
82
83 ScalarFun betaCoeff = [](double, double, double) constexpr { return 1; };
84 MoFEMErrorCode integrateImpl(EntitiesFieldData::EntData &row_data,
86 double vol);
89 return integrateImpl(row_data, col_data, OpBase::getMeasure());
90 }
91
92};
93
94template <int FIELD_DIM, typename OpBase>
96 : public OpMassImpl<1, 1, GAUSS, OpBase> {
97 using OpMassImpl<1, 1, GAUSS, OpBase>::OpMassImpl;
98
99protected:
100 using OpMassImpl<1, 1, GAUSS, OpBase>::betaCoeff;
101 MoFEMErrorCode integrateImpl(EntitiesFieldData::EntData &row_data,
103 double vol);
105 EntitiesFieldData::EntData &col_data) {
106 return integrateImpl(row_data, col_data, OpBase::getMeasure());
107 }
111};
112
113template <int FIELD_DIM, typename OpBase>
114struct OpMassImpl<3, FIELD_DIM, GAUSS, OpBase> : public OpBase {
115
116 OpMassImpl(const std::string row_field_name, const std::string col_field_name,
118 boost::shared_ptr<Range> ents_ptr = nullptr)
119 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
120 betaCoeff(beta) {
121 if (row_field_name == col_field_name)
122 this->sYmm = true;
123 }
124
125protected:
127 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
129};
130
131template <typename OpBase>
132struct OpMassImpl<3, 4, GAUSS, OpBase> : public OpBase {
133 OpMassImpl(const std::string row_field_name, const std::string col_field_name,
135 boost::shared_ptr<Range> ents_ptr = nullptr)
136 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
137 betaCoeff(beta) {
138 if (row_field_name == col_field_name)
139 this->sYmm = true;
140 }
141
142protected:
144 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
146};
147
148template <typename OpBase>
149struct OpMassImpl<3, 9, GAUSS, OpBase> : public OpBase {
150 OpMassImpl(const std::string row_field_name, const std::string col_field_name,
152 boost::shared_ptr<Range> ents_ptr = nullptr)
153 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
154 betaCoeff(beta) {
155 if (row_field_name == col_field_name)
156 this->sYmm = true;
157 }
158
159protected:
161 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
163};
164
165template <int BASE_DIM, int FIELD_DIM, IntegrationType I, typename OpBase>
167
168template <int FIELD_DIM, IntegrationType I, typename OpBase>
170 : public OpMassImpl<1, FIELD_DIM, I, OpBase> {
171 OpMassCacheImpl(CacheMatsTypeType cache, const std::string row_field_name,
172 const std::string col_field_name, const double beta,
173 boost::shared_ptr<Range> ents_ptr = nullptr)
175 row_field_name, col_field_name,
176 [](double, double, double) constexpr { return 1; }, ents_ptr),
177 cacheLocMats(cache), scalarBeta(beta) {}
178
179 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
180 EntitiesFieldData::EntData &col_data);
181
182protected:
185};
186
187template <int BASE_DIM, int FIELD_DIM, int SPACE_DIM, int S, IntegrationType I,
188 typename OpBase>
190
191template <int SPACE_DIM, int S, typename OpBase>
193 : public OpBase {
194 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
195 OpGradSymTensorGradImpl(const std::string row_field_name,
196 const std::string col_field_name,
197 boost::shared_ptr<MatrixDouble> mat_D,
198 boost::shared_ptr<Range> ents_ptr = nullptr,
199 ScalarFun beta = scalar_fun_one)
200 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
201 matD(mat_D), betaCoeff(beta) {
202 if (row_field_name == col_field_name)
203 this->sYmm = true;
204 }
205
206protected:
207 boost::shared_ptr<MatrixDouble> matD;
209 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
211};
212
213template <int BASE_DIM, int FIELD_DIM, int SPACE_DIM, int S, IntegrationType I,
214 typename OpBase>
216
217template <int SPACE_DIM, int S, typename OpBase>
219 : public OpBase {
220 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
221 OpGradTensorGradImpl(const std::string row_field_name,
222 const std::string col_field_name,
223 boost::shared_ptr<MatrixDouble> mat_D,
224 ScalarFun beta = scalar_fun_one)
225 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL), matD(mat_D),
226 betaCoeff(beta) {}
227
228protected:
229 boost::shared_ptr<MatrixDouble> matD;
231 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
233};
234
235template <int BASE_DIM, int FIELD_DIM, int SPACE_DIM, int S, IntegrationType I,
236 typename OpBase>
238
239template <int SPACE_DIM, int S, typename OpBase>
241 : public OpBase {
242 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
243 OpGradGradSymTensorGradGradImpl(const std::string row_field_name,
244 const std::string col_field_name,
245 boost::shared_ptr<MatrixDouble> mat_D,
246 boost::shared_ptr<Range> ents_ptr = nullptr)
247 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL, ents_ptr),
248 matD(mat_D) {
249 if (row_field_name == col_field_name)
250 this->sYmm = true;
251 }
252
253protected:
254 boost::shared_ptr<MatrixDouble> matD;
255 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
257};
258
259template <int SPACE_DIM, IntegrationType I, typename OpBase>
261
262template <int SPACE_DIM, typename OpBase>
264 OpMixDivTimesScalarImpl(const std::string row_field_name,
265 const std::string col_field_name,
266 ConstantFun alpha_fun,
267 const bool assemble_transpose = false,
268 const bool only_transpose = false)
269 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
270 alphaConstant(alpha_fun) {
271 this->assembleTranspose = assemble_transpose;
272 this->onlyTranspose = only_transpose;
273 }
274
275protected:
276 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
278 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
280};
281
282template <int SPACE_DIM, IntegrationType I, typename OpBase,
283 CoordinateTypes CoordSys>
285
286template <int SPACE_DIM, typename OpBase, CoordinateTypes CoordSys>
288 : public OpBase {
289
290 OpMixDivTimesVecImpl(const std::string row_field_name,
291 const std::string col_field_name, ConstantFun alpha_fun,
292 const bool assemble_transpose,
293 const bool only_transpose = false)
294 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
295 alphaConstant(alpha_fun) {
296 this->assembleTranspose = assemble_transpose;
297 this->onlyTranspose = only_transpose;
298 }
299
300 OpMixDivTimesVecImpl(const std::string row_field_name,
301 const std::string col_field_name, ConstantFun alpha_fun,
302 ScalarFun beta_fun, const bool assemble_transpose,
303 const bool only_transpose = false)
304 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
305 alphaConstant(alpha_fun), betaCoeff(beta_fun) {
306 this->assembleTranspose = assemble_transpose;
307 this->onlyTranspose = only_transpose;
308 }
309
310protected:
311 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
312
313 ConstantFun alphaConstant = []() constexpr { return 1; };
314 ScalarFun betaCoeff = [](double, double, double) constexpr { return 1; };
315
316 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
318};
319
320template <int SPACE_DIM, IntegrationType I, typename OpBase,
321 CoordinateTypes COORDINATE_SYSTEM>
323
324template <int SPACE_DIM, typename OpBase, CoordinateTypes COORDINATE_SYSTEM>
325struct OpMixScalarTimesDivImpl<SPACE_DIM, GAUSS, OpBase, COORDINATE_SYSTEM>
326 : public OpBase {
328 const std::string row_field_name, const std::string col_field_name,
329 ScalarFun alpha_fun = [](double, double, double) constexpr { return 1; },
330 const bool assemble_transpose = false, const bool only_transpose = false)
331 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
332 alphaConstant(alpha_fun) {
333 this->assembleTranspose = assemble_transpose;
334 this->onlyTranspose = only_transpose;
335 this->sYmm = false;
336 }
337
338protected:
339 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
341 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
343};
344
345template <int BASE_DIM, int FIELD_DIM, int SPACE_DIM, IntegrationType I,
346 typename OpBase>
348
349template <int SPACE_DIM, typename OpBase>
351 : public OpBase {
352 OpMixVectorTimesGradImpl(const std::string row_field_name,
353 const std::string col_field_name,
354 ConstantFun alpha_fun,
355 const bool assemble_transpose = false,
356 const bool only_transpose = false)
357 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
358 alphaConstant(alpha_fun) {
359 this->assembleTranspose = assemble_transpose;
360 this->onlyTranspose = only_transpose;
361 }
362
363protected:
364 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
366 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
368};
369
370template <int SPACE_DIM, typename OpBase>
372 : public OpBase {
373 OpMixVectorTimesGradImpl(const std::string row_field_name,
374 const std::string col_field_name,
375 ConstantFun alpha_fun,
376 const bool assemble_transpose = false,
377 const bool only_transpose = false)
378 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
379 alphaConstant(alpha_fun) {
380 this->assembleTranspose = assemble_transpose;
381 this->onlyTranspose = only_transpose;
382 }
383
384protected:
385 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
387 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
389};
390
391template <int SPACE_DIM, IntegrationType I, typename OpBase>
393
394template <int SPACE_DIM, typename OpBase>
396
397 OpMixTensorTimesGradImpl(const std::string row_field_name,
398 const std::string col_field_name,
399 ConstantFun alpha_fun, const bool assemble_transpose,
400 const bool only_transpose = false)
401 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
402 alphaConstant(alpha_fun) {
403 this->assembleTranspose = assemble_transpose;
404 this->onlyTranspose = only_transpose;
405 }
406
407 OpMixTensorTimesGradImpl(const std::string row_field_name,
408 const std::string col_field_name,
409 ConstantFun alpha_fun, ScalarFun beta_coeff,
410 const bool assemble_transpose,
411 const bool only_transpose = false)
412 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL),
413 alphaConstant(alpha_fun), betaCoeff(beta_coeff) {
414 this->assembleTranspose = assemble_transpose;
415 this->onlyTranspose = only_transpose;
416 }
417
418protected:
419 FTensor::Index<'i', SPACE_DIM> i; ///< summit Index
420 FTensor::Index<'j', SPACE_DIM> j; ///< summit Index
421 ConstantFun alphaConstant = []() constexpr { return 1; };
422 ScalarFun betaCoeff = [](double, double, double) constexpr { return 1; };
423 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
425};
426
427template <int SPACE_DIM, typename OpBase>
430 EntitiesFieldData::EntData &col_data) {
432
433 // get element volume
434 const double vol = OpBase::getMeasure();
435 // get integration weights
436 auto t_w = OpBase::getFTensor0IntegrationWeight();
437 // get base function gradient on rows
438 auto t_row_grad = row_data.getFTensor1DiffN<SPACE_DIM>();
439 // get coordinate at integration points
440 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
441
442 // loop over integration points
443 for (int gg = 0; gg != OpBase::nbIntegrationPts; gg++) {
444 const double beta = vol * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
445 // take into account Jacobian
446 const double alpha = t_w * beta;
447 // loop over ros base functions
448 int rr = 0;
449 for (; rr != OpBase::nbRows; rr++) {
450 // get column base functions gradient at gauss point gg
451 auto t_col_grad = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
452 // loop over columns
453 for (int cc = 0; cc != OpBase::nbCols; cc++) {
454 // calculate element of local matrix
455 OpBase::locMat(rr, cc) += alpha * (t_row_grad(i) * t_col_grad(i));
456 ++t_col_grad; // move to another gradient of base function
457 // on column
458 }
459 ++t_row_grad; // move to another element of gradient of base
460 // function on row
461 }
462 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
463 ++t_row_grad;
464
465 ++t_coords;
466 ++t_w; // move to another integration weight
467 }
469}
470
471template <int FIELD_DIM, int SPACE_DIM, typename OpBase>
475 EntitiesFieldData::EntData &col_data) {
477
478 // get element volume
479 const double vol = OpBase::getMeasure();
480 // get integration weights
481 auto t_w = OpBase::getFTensor0IntegrationWeight();
482 // get base function gradient on rows
483 auto t_row_grad = row_data.getFTensor1DiffN<SPACE_DIM>();
484 // get coordinate at integration points
485 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
486
489
490 auto get_t_vec = [&](const int rr) {
491 std::array<double *, FIELD_DIM> ptrs;
492 for (auto i = 0; i != FIELD_DIM; ++i)
493 ptrs[i] = &OpBase::locMat(rr + i, i);
495 ptrs);
496 };
497
498 // loop over integration points
499 for (int gg = 0; gg != OpBase::nbIntegrationPts; gg++) {
500 const double beta = vol * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
501 // take into account Jacobian
502 const double alpha = t_w * beta;
503 // loop over ros base functions
504 int rr = 0;
505 for (; rr != OpBase::nbRows / FIELD_DIM; rr++) {
506 // get diag vec
507 auto t_vec = get_t_vec(rr * FIELD_DIM);
508 // get column base functions gradient at gauss point gg
509 auto t_col_grad = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
510 // loop over columns
511 for (int cc = 0; cc != OpBase::nbCols / FIELD_DIM; cc++) {
512 // calculate element of local matrix
513 t_vec(j) += alpha * (t_row_grad(i) * t_col_grad(i));
514 ++t_col_grad; // move to another gradient of base function
515 // on column
516 ++t_vec;
517 }
518 ++t_row_grad; // move to another element of gradient of base
519 // function on row
520 }
521 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
522 ++t_row_grad;
523
524 ++t_coords;
525 ++t_w; // move to another integration weight
526 }
528}
529
530template <typename OpBase>
533 EntitiesFieldData::EntData &col_data, double vol) {
535
536#ifndef NDEBUG
537 auto log_error = [&]() {
538 MOFEM_LOG("SELF", Sev::error) << "Row side " << OpBase::rowSide << " "
539 << CN::EntityTypeName(OpBase::rowType);
540 MOFEM_LOG("SELF", Sev::error) << "Col side " << OpBase::colSide << " "
541 << CN::EntityTypeName(OpBase::colType);
542 };
543
544 if (row_data.getN().size2() < OpBase::nbRows) {
545 log_error();
546 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
547 "Wrong number of base functions on rows %lu < %d",
548 row_data.getN().size2(), OpBase::nbRows);
549 }
550 if (col_data.getN().size2() < OpBase::nbCols) {
551 log_error();
552 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
553 "Wrong number of base functions on cols %lu < %d",
554 col_data.getN().size2(), OpBase::nbCols);
555 }
556 if (row_data.getN().size1() != OpBase::nbIntegrationPts) {
557 log_error();
558 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
559 "Wrong number of integration points on rows %lu != %d",
560 row_data.getN().size1(), OpBase::nbIntegrationPts);
561 }
562 if (col_data.getN().size1() != OpBase::nbIntegrationPts) {
563 log_error();
564 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
565 "Wrong number of integration points on cols %lu != %d",
566 col_data.getN().size1(), OpBase::nbIntegrationPts);
567 }
568#endif
569
570 // get integration weights
571 auto t_w = OpBase::getFTensor0IntegrationWeight();
572 // get base function gradient on rows
573 auto t_row_base = row_data.getFTensor0N();
574 // get coordinate at integration points
575 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
576 // loop over integration points
577 for (int gg = 0; gg != OpBase::nbIntegrationPts; gg++) {
578 const double beta = betaCoeff(t_coords(0), t_coords(1), t_coords(2));
579 // take into account Jacobian
580 const double alpha = t_w * beta;
581 // loop over rows base functions
582 auto a_mat_ptr = &*OpBase::locMat.data().begin();
583 int rr = 0;
584 for (; rr != OpBase::nbRows; rr++) {
585 // get column base functions gradient at gauss point gg
586 auto t_col_base = col_data.getFTensor0N(gg, 0);
587 // loop over columns
588 for (int cc = 0; cc != OpBase::nbCols; cc++) {
589 // calculate element of local matrix
590 *a_mat_ptr += alpha * (t_row_base * t_col_base);
591 ++t_col_base;
592 ++a_mat_ptr;
593 }
594 ++t_row_base;
595 }
596 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
597 ++t_row_base;
598 ++t_coords;
599 ++t_w; // move to another integration weight
600 }
601
602 OpBase::locMat *= vol;
603
605};
606
607template <int FIELD_DIM, typename OpBase>
610 double vol) {
612
613 auto integrate = [&](auto &mat) {
615 // get integration weights
616 auto t_w = OpBase::getFTensor0IntegrationWeight();
617 // get base function gradient on rows
618 auto t_row_base = row_data.getFTensor0N();
619 // get coordinate at integration points
620 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
621
623 auto get_t_vec = [&](const int rr) {
624 std::array<double *, FIELD_DIM> ptrs;
625 for (auto i = 0; i != FIELD_DIM; ++i)
626 ptrs[i] = &mat(rr + i, i);
628 ptrs);
629 };
630
631 // loop over integration points
632 for (int gg = 0; gg != OpBase::nbIntegrationPts; gg++) {
633 const double beta = betaCoeff(t_coords(0), t_coords(1), t_coords(2));
634 // take into account Jacobian
635 const double alpha = t_w * beta;
636 // loop over rows base functions
637 int rr = 0;
638 for (; rr != OpBase::nbRows / FIELD_DIM; rr++) {
639 // get column base functions gradient at gauss point gg
640 auto t_col_base = col_data.getFTensor0N(gg, 0);
641 // get mat vec
642 auto t_vec = get_t_vec(FIELD_DIM * rr);
643 // loop over columns
644 for (int cc = 0; cc != OpBase::nbCols / FIELD_DIM; cc++) {
645 // calculate element of local matrix
646 t_vec(i) += alpha * (t_row_base * t_col_base);
647 ++t_col_base;
648 ++t_vec;
649 }
650 ++t_row_base;
651 }
652 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
653 ++t_row_base;
654 ++t_coords;
655 ++t_w; // move to another integration weight
656 }
658 };
659
660 CHKERR integrate(OpBase::locMat);
661 OpBase::locMat *= vol;
662
664};
665
666template <int FIELD_DIM, typename OpBase>
669 EntitiesFieldData::EntData &col_data) {
672 size_t nb_base_functions = row_data.getN().size2() / 3;
673 // // get element volume
674 const double vol = OpBase::getMeasure();
675 // get integration weights
676 auto t_w = OpBase::getFTensor0IntegrationWeight();
677 // get base function gradient on rows
678 auto t_row_base = row_data.getFTensor1N<3>();
679 // get coordinate at integration points
680 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
681 // loop over integration points
682 for (int gg = 0; gg != OpBase::nbIntegrationPts; gg++) {
683 const double beta = vol * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
684 // take into account Jacobian
685 const double alpha = t_w * beta;
686 // loop over rows base functions
687 auto a_mat_ptr = &*OpBase::locMat.data().begin();
688 int rr = 0;
689 for (; rr != OpBase::nbRows; rr++) {
690 // get column base functions gradient at gauss point gg
691 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
692 // loop over columns
693 for (int cc = 0; cc != OpBase::nbCols; cc++) {
694 // calculate element of local matrix
695 (*a_mat_ptr) += alpha * (t_row_base(i) * t_col_base(i));
696 ++t_col_base;
697 ++a_mat_ptr;
698 }
699 ++t_row_base;
700 }
701 for (; rr < nb_base_functions; ++rr)
702 ++t_row_base;
703 ++t_coords;
704 ++t_w; // move to another integration weight
705 }
707};
708
709template <typename OpBase>
712 EntitiesFieldData::EntData &col_data) {
714 FTensor::Index<'i', 2> I;
715 FTensor::Index<'k', 3> k;
716 auto get_t_vec = [&](const int rr) {
718 &OpBase::locMat(rr + 0, 0), &OpBase::locMat(rr + 1, 1)};
719 };
720 size_t nb_base_functions = row_data.getN().size2() / 3;
721 // // get element volume
722 const double vol = OpBase::getMeasure();
723 // get integration weights
724 auto t_w = OpBase::getFTensor0IntegrationWeight();
725 // get base function gradient on rows
726 auto t_row_base = row_data.getFTensor1N<3>();
727 // get coordinate at integration points
728 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
729 // loop over integration points
730 for (int gg = 0; gg != OpBase::nbIntegrationPts; gg++) {
731 const double beta = vol * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
732 // take into account Jacobian
733 const double alpha = t_w * beta;
734 // loop over rows base functions
735 int rr = 0;
736 for (; rr != OpBase::nbRows / 2; rr++) {
737 // get column base functions gradient at gauss point gg
738 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
739 auto t_vec = get_t_vec(2 * rr);
740 // loop over columns
741 for (int cc = 0; cc != OpBase::nbCols / 2; cc++) {
742 // calculate element of local matrix
743 t_vec(I) += alpha * (t_row_base(k) * t_col_base(k));
744 ++t_col_base;
745 ++t_vec;
746 }
747 ++t_row_base;
748 }
749 for (; rr < nb_base_functions; ++rr)
750 ++t_row_base;
751 ++t_coords;
752 ++t_w; // move to another integration weight
753 }
755}
756
757template <typename OpBase>
760 EntitiesFieldData::EntData &col_data) {
762 FTensor::Index<'i', 3> i;
763 FTensor::Index<'k', 3> k;
764 auto get_t_vec = [&](const int rr) {
766 &OpBase::locMat(rr + 0, 0), &OpBase::locMat(rr + 1, 1),
767 &OpBase::locMat(rr + 2, 2)};
768 };
769 size_t nb_base_functions = row_data.getN().size2() / 3;
770 // // get element volume
771 const double vol = OpBase::getMeasure();
772 // get integration weights
773 auto t_w = OpBase::getFTensor0IntegrationWeight();
774 // get base function gradient on rows
775 auto t_row_base = row_data.getFTensor1N<3>();
776 // get coordinate at integration points
777 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
778 // loop over integration points
779 for (int gg = 0; gg != OpBase::nbIntegrationPts; gg++) {
780 const double beta = vol * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
781 // take into account Jacobian
782 const double alpha = t_w * beta;
783 // loop over rows base functions
784 int rr = 0;
785 for (; rr != OpBase::nbRows / 3; rr++) {
786 // get column base functions gradient at gauss point gg
787 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
788 auto t_vec = get_t_vec(3 * rr);
789 // loop over columns
790 for (int cc = 0; cc != OpBase::nbCols / 3; cc++) {
791 // calculate element of local matrix
792 t_vec(i) += alpha * (t_row_base(k) * t_col_base(k));
793 ++t_col_base;
794 ++t_vec;
795 }
796 ++t_row_base;
797 }
798 for (; rr < nb_base_functions; ++rr)
799 ++t_row_base;
800 ++t_coords;
801 ++t_w; // move to another integration weight
802 }
804};
805
806template <int FIELD_DIM, IntegrationType I, typename OpBase>
809 EntitiesFieldData::EntData &col_data) {
811
812 const auto vol = this->getMeasure();
813 const auto row_type = this->rowType;
814 const auto col_type = this->colType;
815 auto &loc_mat = this->locMat;
816
817 auto p = std::make_pair(row_type, col_type);
818
819 if (cacheLocMats[p]) {
820 if (cacheLocMats[p]->size1() != loc_mat.size1() &&
821 cacheLocMats[p]->size2() != loc_mat.size2()) {
822 cacheLocMats[p]->resize(loc_mat.size1(), loc_mat.size2());
823 CHKERR this->integrateImpl(row_data, col_data, 1);
824 *(cacheLocMats[p]) = loc_mat;
825 } else {
826 loc_mat = *(cacheLocMats[p]);
827 }
828 loc_mat *= scalarBeta * this->getMeasure();
829 } else {
830 CHKERR this->integrateImpl(row_data, col_data,
831 scalarBeta * this->getMeasure());
832 }
834}
835
836template <int SPACE_DIM, int S, typename OpBase>
840 EntitiesFieldData::EntData &col_data) {
842
843 const size_t nb_row_dofs = row_data.getIndices().size();
844 const size_t nb_col_dofs = col_data.getIndices().size();
845
846 if (nb_row_dofs && nb_col_dofs) {
847
848 const bool diag = (row_data.getFieldEntities()[0]->getLocalUniqueId() ==
849 col_data.getFieldEntities()[0]->getLocalUniqueId());
850
855
856 // get element volume
857 double vol = OpBase::getMeasure();
858
859 // get intergrayion weights
860 auto t_w = OpBase::getFTensor0IntegrationWeight();
861
862 // get derivatives of base functions on rows
863 auto t_row_diff_base = row_data.getFTensor1DiffN<SPACE_DIM>();
864
865 // Elastic stiffness tensor (4th rank tensor with minor and major
866 // symmetry)
867 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(*matD);
868
869 // get coordinate at integration points
870 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
871
872 // iterate over integration points
873 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
874
875 // calculate scalar weight times element volume
876 double a = t_w * vol * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
877
878 // iterate over row base functions
879 int rr = 0;
880 for (; rr != OpBase::nbRows / SPACE_DIM; ++rr) {
881
882 // get sub matrix for the row
883 auto t_m = OpBase::template getLocMat<SPACE_DIM>(SPACE_DIM * rr);
884
886 // I mix up the indices here so that it behaves like a
887 // Dg. That way I don't have to have a separate wrapper
888 // class Christof_Expr, which simplifies things.
889 t_rowD(l, j, k) = t_D(i, j, k, l) * (a * t_row_diff_base(i));
890
891 // get derivatives of base functions for columns
892 auto t_col_diff_base = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
893
894 // iterate column base functions
895 const auto nb_cols = (diag) ? rr : OpBase::nbCols / SPACE_DIM - 1;
896 for (int cc = 0; cc <= nb_cols; ++cc) {
897
898 // integrate block local stiffens matrix
899 t_m(i, j) += t_rowD(i, j, k) * t_col_diff_base(k);
900
901 // move to next column base function
902 ++t_col_diff_base;
903
904 // move to next block of local stiffens matrix
905 ++t_m;
906 }
907
908 // move to next row base function
909 ++t_row_diff_base;
910 }
911
912 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
913 ++t_row_diff_base;
914
915 // move to next integration weight
916 ++t_w;
917 ++t_D;
918 ++t_coords;
919 }
920
921 // Copy symmetry
922 if (diag) {
923 for (int rr = 0; rr != OpBase::nbRows / SPACE_DIM - 1; ++rr) {
924 auto t_m_rr = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
925 this->locMat, SPACE_DIM * rr, SPACE_DIM * (rr + 1));
926 auto t_m_cc = getFTensor2FromArray<SPACE_DIM, SPACE_DIM>(
927 this->locMat, SPACE_DIM * (rr + 1), SPACE_DIM * rr,
929 for (int cc = rr + 1; cc < OpBase::nbCols / SPACE_DIM; ++cc) {
930 t_m_rr(i, j) = t_m_cc(j, i);
931 ++t_m_rr;
932 ++t_m_cc;
933 }
934 }
935 }
936 }
937
939}
940
941template <int SPACE_DIM, int S, typename OpBase>
945 EntitiesFieldData::EntData &col_data) {
947
949
954
955 auto &row_hessian = row_data.getN(BaseDerivatives::SecondDerivative);
956 auto &col_hessian = col_data.getN(BaseDerivatives::SecondDerivative);
957
958#ifndef NDEBUG
959 if (row_hessian.size1() != OpBase::nbIntegrationPts) {
960 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
961 "Wrong number of integration pts (%d != %d)",
962 row_hessian.size1(), OpBase::nbIntegrationPts);
963 }
964 if (row_hessian.size2() !=
966 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
967 "Wrong number of base functions (%d != %d)",
968 row_hessian.size2() / (SPACE_DIM * SPACE_DIM),
970 }
971 if (row_hessian.size2() < OpBase::nbRows * SPACE_DIM * SPACE_DIM) {
972 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
973 "Wrong number of base functions (%d < %d)", row_hessian.size2(),
975 }
976 if (col_hessian.size1() != OpBase::nbIntegrationPts) {
977 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
978 "Wrong number of integration pts (%d != %d)",
979 col_hessian.size1(), OpBase::nbIntegrationPts);
980 }
981 if (col_hessian.size2() < OpBase::nbCols * SPACE_DIM * SPACE_DIM) {
982 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
983 "Wrong number of base functions (%d < %d)", col_hessian.size2(),
985 }
986#endif
987
988 // get element volume
989 double vol = OpBase::getMeasure();
990
991 // get intergrayion weights
992 auto t_w = OpBase::getFTensor0IntegrationWeight();
993
994 auto t_row_diff2 = getFTensor2SymmetricLowerFromPtr<SPACE_DIM>(
995 &*row_hessian.data().begin());
996
997 // Elastic stiffness tensor (4th rank tensor with minor and major
998 // symmetry)
999 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(*matD);
1000
1001 // iterate over integration points
1002 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1003
1004 // calculate scalar weight times element volume
1005 double a = t_w * vol;
1006
1007 // get sub matrix for the row
1008 auto m_ptr = &*OpBase::locMat.data().begin();
1009
1010 // iterate over row base functions
1011 int rr = 0;
1012 for (; rr != OpBase::nbRows; ++rr) {
1013
1015 t_rowD(k, l) = t_D(i, j, k, l) * (a * t_row_diff2(i, j));
1016
1017 // get derivatives of base functions for columns
1018 auto t_col_diff2 =
1019 getFTensor2SymmetricLowerFromPtr<SPACE_DIM>(&col_hessian(gg, 0));
1020
1021 // iterate column base functions
1022 for (int cc = 0; cc != OpBase::nbCols; ++cc) {
1023
1024 // integrate block local stiffens matrix
1025 *m_ptr += t_rowD(i, j) * t_col_diff2(i, j);
1026
1027 // move to next column base function
1028 ++t_col_diff2;
1029
1030 // move to next block of local stiffens matrix
1031 ++m_ptr;
1032 }
1033
1034 // move to next row base function
1035 ++t_row_diff2;
1036 }
1037
1038 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
1039 ++t_row_diff2;
1040
1041 // move to next integration weight
1042 ++t_w;
1043 ++t_D;
1044 }
1045 }
1046
1048}
1049
1050template <int SPACE_DIM, int S, typename OpBase>
1054 EntitiesFieldData::EntData &col_data) {
1056
1057 const size_t nb_row_dofs = row_data.getIndices().size();
1058 const size_t nb_col_dofs = col_data.getIndices().size();
1059
1060 if (nb_row_dofs && nb_col_dofs) {
1061
1066
1067 // get element volume
1068 double vol = OpBase::getMeasure();
1069
1070 // get intergrayion weights
1071 auto t_w = OpBase::getFTensor0IntegrationWeight();
1072
1073 // get derivatives of base functions on rows
1074 auto t_row_diff_base = row_data.getFTensor1DiffN<SPACE_DIM>();
1075
1076 // stiffness tensor (4th rank tensor)
1077 auto t_D =
1078 getFTensor4FromMat<SPACE_DIM, SPACE_DIM, SPACE_DIM, SPACE_DIM, S>(
1079 *matD);
1080
1081 // get coordinate at integration points
1082 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
1083
1084 // iterate over integration points
1085 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1086
1087 // calculate scalar weight times element volume
1088 double a = t_w * vol * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1089
1090 // iterate over row base functions
1091 int rr = 0;
1092 for (; rr != OpBase::nbRows / SPACE_DIM; ++rr) {
1093
1094 // get sub matrix for the row
1095 auto t_m = OpBase::template getLocMat<SPACE_DIM>(SPACE_DIM * rr);
1096
1097 // calculate row
1099 t_row(i, k, l) = t_D(i, j, k, l) * (a * t_row_diff_base(j));
1100
1101 // get derivatives of base functions for columns
1102 auto t_col_diff_base = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
1103
1104 // iterate column base functions
1105 for (int cc = 0; cc != OpBase::nbCols / SPACE_DIM; ++cc) {
1106
1107 // integrate block local stiffens matrix
1108 t_m(i, k) += t_row(i, k, l) * t_col_diff_base(l);
1109
1110 // move to next column base function
1111 ++t_col_diff_base;
1112
1113 // move to next block of local stiffens matrix
1114 ++t_m;
1115 }
1116
1117 // move to next row base function
1118 ++t_row_diff_base;
1119 }
1120
1121 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
1122 ++t_row_diff_base;
1123
1124 // move to next integration weight
1125 ++t_w;
1126 ++t_D;
1127 ++t_coords;
1128 }
1129 }
1130
1132}
1133
1134template <int SPACE_DIM, typename OpBase>
1137 EntitiesFieldData::EntData &col_data) {
1139
1140 auto t_w = this->getFTensor0IntegrationWeight();
1141
1142 size_t nb_base_functions = row_data.getN().size2() / 3;
1143 auto t_row_diff_base = row_data.getFTensor2DiffN<3, SPACE_DIM>();
1144
1145 const double alpha_constant = alphaConstant();
1146
1147 for (size_t gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1148 const double alpha = alpha_constant * this->getMeasure() * t_w;
1149
1150 size_t rr = 0;
1151 for (; rr != OpBase::nbRows; ++rr) {
1152 const double t_row_div_base = t_row_diff_base(i, i);
1153 auto t_col_base = col_data.getFTensor0N(gg, 0);
1154 for (size_t cc = 0; cc != OpBase::nbCols; ++cc) {
1155 this->locMat(rr, cc) += alpha * t_row_div_base * t_col_base;
1156 ++t_col_base;
1157 }
1158 ++t_row_diff_base;
1159 }
1160 for (; rr < nb_base_functions; ++rr)
1161 ++t_row_diff_base;
1162
1163 ++t_w;
1164 }
1165
1167}
1168
1169template <int SPACE_DIM, typename OpBase, CoordinateTypes CoordSys>
1173 EntitiesFieldData::EntData &col_data) {
1175
1176 auto t_w = this->getFTensor0IntegrationWeight();
1177 auto t_coords = this->getFTensor1CoordsAtGaussPts();
1178
1179 size_t nb_base_functions = row_data.getN().size2() / 3;
1180 auto t_row_diff_base = row_data.getFTensor2DiffN<3, SPACE_DIM>();
1181 auto t_row_base = row_data.getFTensor1N<3>();
1182 const double alpha_constant = alphaConstant() * this->getMeasure();
1183 for (size_t gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1184
1185 const double alpha =
1186 alpha_constant * t_w * betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1187
1188 size_t rr = 0;
1189 for (; rr != OpBase::nbRows / SPACE_DIM; ++rr) {
1190 auto t_mat_diag = getFTensor1FromArrayDiag<SPACE_DIM, SPACE_DIM>(
1191 this->locMat, SPACE_DIM * rr);
1192 const double t_row_div_base = t_row_diff_base(i, i);
1193 auto t_col_base = col_data.getFTensor0N(gg, 0);
1194
1195 for (size_t cc = 0; cc != OpBase::nbCols / SPACE_DIM; ++cc) {
1196 t_mat_diag(i) += alpha * t_row_div_base * t_col_base;
1197 if constexpr (CoordSys == CYLINDRICAL) {
1198 t_mat_diag(i) += t_row_base(0) * (alpha / t_coords(0)) * t_col_base;
1199 }
1200 ++t_col_base;
1201 ++t_mat_diag;
1202 }
1203 ++t_row_base;
1204 ++t_row_diff_base;
1205 }
1206 for (; rr < nb_base_functions; ++rr) {
1207 ++t_row_diff_base;
1208 ++t_row_base;
1209 }
1210
1211 ++t_w;
1212 ++t_coords;
1213 }
1214
1216}
1217
1218template <int SPACE_DIM, typename OpBase, CoordinateTypes COORDINATE_SYSTEM>
1222 EntitiesFieldData::EntData &col_data) {
1224
1225#ifndef NDEBUG
1226 if (OpBase::locMat.size2() % SPACE_DIM)
1227 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1228 "Number of rows in matrix should be multiple of space dimensions");
1229#endif
1230
1231 // When we move to C++17 add if constexpr()
1232 if constexpr (COORDINATE_SYSTEM == POLAR || COORDINATE_SYSTEM == SPHERICAL)
1233 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1234 "%s coordiante not implemented",
1235 CoordinateTypesNames[COORDINATE_SYSTEM]);
1236
1237 auto t_w = this->getFTensor0IntegrationWeight();
1238 auto t_coords = this->getFTensor1CoordsAtGaussPts();
1239 size_t nb_base_functions_row = row_data.getN().size2();
1240 auto t_row_base = row_data.getFTensor0N();
1241 const double vol = this->getMeasure();
1242 for (size_t gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1243
1244 const double alpha =
1245 alphaConstant(t_coords(0), t_coords(1), t_coords(2)) * t_w * vol;
1246
1247 size_t rr = 0;
1248 auto t_m = getFTensor1FromPtr<SPACE_DIM>(OpBase::locMat.data().data());
1249
1250 // When we move to C++17 add if constexpr()
1251 if constexpr (COORDINATE_SYSTEM == CARTESIAN) {
1252 for (; rr != OpBase::nbRows; ++rr) {
1253 const double r_val = alpha * t_row_base;
1254 auto t_col_diff_base = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
1255 for (size_t cc = 0; cc != OpBase::nbCols / SPACE_DIM; ++cc) {
1256 t_m(i) += r_val * t_col_diff_base(i);
1257 ++t_col_diff_base;
1258 ++t_m;
1259 }
1260 ++t_row_base;
1261 }
1262 }
1263
1264 // When we move to C++17 add if constexpr()
1265 if constexpr (COORDINATE_SYSTEM == CYLINDRICAL) {
1266 for (; rr != OpBase::nbRows; ++rr) {
1267 const double r_val = alpha * t_row_base;
1268 auto t_col_base = col_data.getFTensor0N(gg, 0);
1269 auto t_col_diff_base = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
1270 for (size_t cc = 0; cc != OpBase::nbCols / SPACE_DIM; ++cc) {
1271 t_m(i) += r_val * t_col_diff_base(i);
1272 t_m(0) += (r_val / t_coords(0)) * t_col_base;
1273 ++t_col_base;
1274 ++t_col_diff_base;
1275 ++t_m;
1276 }
1277 ++t_row_base;
1278 }
1279 }
1280
1281 for (; rr < nb_base_functions_row; ++rr)
1282 ++t_row_base;
1283
1284 ++t_w;
1285 ++t_coords;
1286 }
1287
1289}
1290
1291template <int SPACE_DIM, typename OpBase>
1295 EntitiesFieldData::EntData &col_data) {
1297
1298 auto t_w = this->getFTensor0IntegrationWeight();
1299
1300 size_t nb_base_functions = row_data.getN().size2() / 3;
1301 auto t_row_base = row_data.getFTensor1N<3>();
1302 auto &mat = this->locMat;
1303 const double alpha_constant = alphaConstant();
1304 for (size_t gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1305
1306 const double alpha = alpha_constant * this->getMeasure() * t_w;
1307
1308 size_t rr = 0;
1309 for (; rr != OpBase::nbRows; ++rr) {
1310 auto t_col_diff_base = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
1311 for (size_t cc = 0; cc != OpBase::nbCols; ++cc) {
1312 mat(rr, cc) += alpha * t_row_base(i) * t_col_diff_base(i);
1313 ++t_col_diff_base;
1314 }
1315 ++t_row_base;
1316 }
1317 for (; rr < nb_base_functions; ++rr)
1318 ++t_row_base;
1319
1320 ++t_w;
1321 }
1322
1324}
1325
1326template <int SPACE_DIM, typename OpBase>
1330 EntitiesFieldData::EntData &col_data) {
1332
1333 auto t_w = this->getFTensor0IntegrationWeight();
1334
1335 size_t nb_base_functions = row_data.getN().size2();
1336 auto t_row_base = row_data.getFTensor0N();
1337
1338 auto get_t_vec = [&](const int rr) {
1339 std::array<double *, SPACE_DIM> ptrs;
1340 for (auto i = 0; i != SPACE_DIM; ++i)
1341 ptrs[i] = &OpBase::locMat(rr + i, 0);
1343 };
1344
1345 const double alpha_constant = alphaConstant();
1346 for (size_t gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1347
1348 const double alpha = alpha_constant * this->getMeasure() * t_w;
1349
1350 size_t rr = 0;
1351 for (; rr != OpBase::nbRows / SPACE_DIM; ++rr) {
1352 auto t_vec = get_t_vec(SPACE_DIM * rr);
1353 auto t_col_diff_base = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
1354 for (size_t cc = 0; cc != OpBase::nbCols; ++cc) {
1355 t_vec(i) += alpha * t_row_base * t_col_diff_base(i);
1356 ++t_col_diff_base;
1357 ++t_vec;
1358 }
1359 ++t_row_base;
1360 }
1361 for (; rr < nb_base_functions; ++rr)
1362 ++t_row_base;
1363
1364 ++t_w;
1365 }
1366
1368}
1369
1370template <int SPACE_DIM, typename OpBase>
1373 EntitiesFieldData::EntData &col_data) {
1375
1376 auto t_w = this->getFTensor0IntegrationWeight();
1377 auto t_coords = this->getFTensor1CoordsAtGaussPts();
1378
1379 size_t nb_base_functions = row_data.getN().size2() / 3;
1380 auto t_row_base = row_data.getFTensor1N<3>();
1381 const double alpha_constant = alphaConstant() * this->getMeasure();
1382 for (size_t gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
1383
1384 const double alpha =
1385 alpha_constant * betaCoeff(t_coords(0), t_coords(1), t_coords(2)) * t_w;
1386
1387 size_t rr = 0;
1388 for (; rr != OpBase::nbRows / SPACE_DIM; ++rr) {
1389 auto t_mat_diag = getFTensor1FromArrayDiag<SPACE_DIM, SPACE_DIM>(
1390 this->locMat, SPACE_DIM * rr);
1391 auto t_col_diff_base = col_data.getFTensor1DiffN<SPACE_DIM>(gg, 0);
1392
1393 for (size_t cc = 0; cc != OpBase::nbCols / SPACE_DIM; ++cc) {
1394 t_mat_diag(i) += alpha * t_row_base(j) * t_col_diff_base(j);
1395 ++t_col_diff_base;
1396 ++t_mat_diag;
1397 }
1398
1399 ++t_row_base;
1400 }
1401 for (; rr < nb_base_functions; ++rr)
1402 ++t_row_base;
1403
1404 ++t_w;
1405 ++t_coords;
1406 }
1407
1409}
1410
1411} // namespace MoFEM
1412
1413#endif //__BILINEAR_FORMS_INTEGRATORS_IMPL_HPP__
constexpr double a
constexpr int SPACE_DIM
[Define dimension]
constexpr int FIELD_DIM
static const char *const CoordinateTypesNames[]
Coordinate system names.
#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 ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
CoordinateTypes
Coodinate system.
@ CYLINDRICAL
@ POLAR
@ CARTESIAN
@ SPHERICAL
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int BASE_DIM
IntegrationType
Form integrator integration types.
boost::function< double(const double, const double, const double)> ScalarFun
Scalar function type.
double scalar_fun_one(const double, const double, const double)
Default scalar function returning 1.
@ GAUSS
Gaussian quadrature integration.
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
std::map< std::pair< int, int >, boost::shared_ptr< MatrixDouble > > CacheMatsTypeType
boost::function< double()> ConstantFun
Constant function type.
constexpr IntegrationType I
OpBaseImpl< PETSC, EdgeEleOp > OpBase
Definition radiation.cpp:29
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2DiffN(FieldApproximationBase base)
Get derivatives of base functions for Hdiv space.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
const VectorFieldEntities & getFieldEntities() const
Get field entities (const version)
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
int rowSide
row side number
int colSide
column side number
int nbRows
number of dofs on rows
EntityType colType
column type
int nbIntegrationPts
number of integration points
MatrixDouble locMat
local entity block matrix
int nbCols
number if dof on column
int nbRowBaseFunctions
number or row base functions
EntityType rowType
row type
OpGradGradImpl(const std::string row_field_name, const std::string col_field_name, ScalarFun beta=scalar_fun_one, boost::shared_ptr< Range > ents_ptr=nullptr)
OpGradGradImpl(const std::string row_field_name, const std::string col_field_name, ScalarFun beta=scalar_fun_one, boost::shared_ptr< Range > ents_ptr=nullptr)
OpGradGradSymTensorGradGradImpl(const std::string row_field_name, const std::string col_field_name, boost::shared_ptr< MatrixDouble > mat_D, boost::shared_ptr< Range > ents_ptr=nullptr)
OpGradSymTensorGradImpl(const std::string row_field_name, const std::string col_field_name, boost::shared_ptr< MatrixDouble > mat_D, boost::shared_ptr< Range > ents_ptr=nullptr, ScalarFun beta=scalar_fun_one)
OpGradTensorGradImpl(const std::string row_field_name, const std::string col_field_name, boost::shared_ptr< MatrixDouble > mat_D, ScalarFun beta=scalar_fun_one)
OpMassCacheImpl(CacheMatsTypeType cache, const std::string row_field_name, const std::string col_field_name, const double beta, boost::shared_ptr< Range > ents_ptr=nullptr)
OpMassImpl(const std::string row_field_name, const std::string col_field_name, ScalarFun beta=[](double, double, double) constexpr { return 1;}, boost::shared_ptr< Range > ents_ptr=nullptr, boost::shared_ptr< MatrixDouble > cache_mat=nullptr)
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
Integrate grad-grad operator.
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data)
Class dedicated to integrate operator.
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
Integrate grad-grad operator.
OpMassImpl(const std::string row_field_name, const std::string col_field_name, ScalarFun beta=scalar_fun_one, boost::shared_ptr< Range > ents_ptr=nullptr)
OpMassImpl(const std::string row_field_name, const std::string col_field_name, ScalarFun beta=scalar_fun_one, boost::shared_ptr< Range > ents_ptr=nullptr)
OpMassImpl(const std::string row_field_name, const std::string col_field_name, ScalarFun beta=scalar_fun_one, boost::shared_ptr< Range > ents_ptr=nullptr)
OpMixDivTimesScalarImpl(const std::string row_field_name, const std::string col_field_name, ConstantFun alpha_fun, const bool assemble_transpose=false, const bool only_transpose=false)
OpMixDivTimesVecImpl(const std::string row_field_name, const std::string col_field_name, ConstantFun alpha_fun, const bool assemble_transpose, const bool only_transpose=false)
OpMixDivTimesVecImpl(const std::string row_field_name, const std::string col_field_name, ConstantFun alpha_fun, ScalarFun beta_fun, const bool assemble_transpose, const bool only_transpose=false)
OpMixScalarTimesDivImpl(const std::string row_field_name, const std::string col_field_name, ScalarFun alpha_fun=[](double, double, double) constexpr { return 1;}, const bool assemble_transpose=false, const bool only_transpose=false)
OpMixTensorTimesGradImpl(const std::string row_field_name, const std::string col_field_name, ConstantFun alpha_fun, const bool assemble_transpose, const bool only_transpose=false)
OpMixTensorTimesGradImpl(const std::string row_field_name, const std::string col_field_name, ConstantFun alpha_fun, ScalarFun beta_coeff, const bool assemble_transpose, const bool only_transpose=false)
OpMixVectorTimesGradImpl(const std::string row_field_name, const std::string col_field_name, ConstantFun alpha_fun, const bool assemble_transpose=false, const bool only_transpose=false)
OpMixVectorTimesGradImpl(const std::string row_field_name, const std::string col_field_name, ConstantFun alpha_fun, const bool assemble_transpose=false, const bool only_transpose=false)