v0.16.3
Loading...
Searching...
No Matches
base_tensor_base.cpp
Go to the documentation of this file.
1/** @file base_tensor_base.cpp
2 * @brief Check mixed scalar/vector/tensor basis bilinear contractions.
3 */
4
5#define FTENSOR_DEBUG
6#include <MoFEM.hpp>
7using namespace MoFEM;
8
9namespace {
10
11using BilinearForm =
13 Assembly<AssemblyType::PETSC>::BiLinearForm<IntegrationType::GAUSS>;
14
15template <int BaseDim, int FieldDim, int SpaceDim, int S = -1>
16struct OpCheck
17 : BilinearForm::OpBaseTensorBase<BaseDim, FieldDim, SpaceDim, S> {
18 using Base = BilinearForm::OpBaseTensorBase<BaseDim, FieldDim, SpaceDim, S>;
19 using Base::Base;
20
24 const MatrixDouble &tensor, const double alpha,
25 const bool transpose, const bool only_transpose) {
27 constexpr bool tensor_basis = BaseDim == 4 || BaseDim == 9;
28 constexpr int col_dim = tensor_basis ? 1 : SpaceDim;
29 constexpr int extent = BaseDim == 4 ? 2 : 3;
30 CHKERR this->setPtrFE(&fe);
31 if (this->assembleTranspose != transpose ||
32 this->onlyTranspose != only_transpose || this->sYmm)
33 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
34 "Incorrect mixed-form assembly flags");
35 this->nbRows = row_data.getIndices().size();
36 this->nbCols = col_data.getIndices().size();
37 this->nbIntegrationPts = row_data.getN().size1();
38 this->nbRowBaseFunctions = row_data.getN().size2();
39 this->getGaussPts().resize(4, this->nbIntegrationPts, false);
40 this->getGaussPts().clear();
41 this->getMeasure() = 1.25;
42 for (int gg = 0; gg != this->nbIntegrationPts; ++gg)
43 this->getGaussPts()(3, gg) = .17 + .11 * gg;
44 this->locMat.resize(this->nbRows, this->nbCols, false);
45 std::fill(this->locMat.data().begin(), this->locMat.data().end(), .13);
46 CHKERR this->iNtegrate(row_data, col_data);
47
48 // Independent scalar oracle checks component order and every local block.
49 for (int row = 0; row != this->nbRows; ++row) {
50 const int rr = row / FieldDim;
51 const int a = row % FieldDim;
52 for (int col = 0; col != this->nbCols; ++col) {
53 const int cc = col / col_dim;
54 const int component = col % col_dim;
55 double expected = .13;
56 for (int gg = 0; gg != this->nbIntegrationPts; ++gg) {
57 const double scale = alpha * this->getMeasure() *
58 this->getGaussPts()(3, gg) *
59 row_data.getN()(gg, rr);
60 for (int i = 0; i != SpaceDim; ++i)
61 for (int j = 0; j != SpaceDim; ++j)
62 if (tensor_basis || i == component) {
63 const int basis_component = tensor_basis ? extent * i + j : j;
64 expected +=
65 scale *
66 tensor(S == 0 ? 0 : gg, (SpaceDim * i + j) * FieldDim + a) *
67 col_data.getN()(gg, BaseDim * cc + basis_component);
68 }
69 }
70 const double value = this->locMat(row, col);
71 if (!std::isfinite(value) ||
72 std::abs(value - expected) > 2.e-12 * (1. + std::abs(expected)))
73 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
74 "BASE_DIM=%d FIELD_DIM=%d SPACE_DIM=%d S=%d: block (%d,%d) "
75 "has value %g, expected %g",
76 BaseDim, FieldDim, SpaceDim, S, row, col, value, expected);
77 }
78 }
80 }
81};
82
83template <int BaseDim, int FieldDim, int SpaceDim, int S = -1>
84MoFEMErrorCode checkForm(MoFEM::Interface &m_field) {
86 constexpr int col_dim = BaseDim == 4 || BaseDim == 9 ? 1 : SpaceDim;
87 constexpr double alpha = -.7;
89 EntitiesFieldData::EntData row_data, col_data;
90 row_data.getBase() = col_data.getBase() = AINSWORTH_LEGENDRE_BASE;
91 row_data.getIndices().resize(2 * FieldDim, false);
92 col_data.getIndices().resize(3 * col_dim, false);
93 auto tensor = boost::make_shared<MatrixDouble>();
96
97 for (const int points : {3, 4}) {
98 MatrixSizeHelper<Tensor, DL>::size(*tensor, S == 0 ? 1 : points);
99 for (int gg = 0; gg != tensor->size1(); ++gg)
100 for (int i = 0; i != SpaceDim; ++i)
101 for (int j = 0; j != SpaceDim; ++j)
102 for (int a = 0; a != FieldDim; ++a)
103 (*tensor)(gg, (SpaceDim * i + j) * FieldDim + a) =
104 .1 * (1 + a) + .021 * (1 + i) * (2 + j) +
105 .037 * gg * (2 + i - a);
106 row_data.getN().resize(points, 3, false);
107 col_data.getN().resize(points, 4 * BaseDim, false);
108 for (int gg = 0; gg != points; ++gg) {
109 for (int rr = 0; rr != 3; ++rr)
110 row_data.getN()(gg, rr) = rr == 2 ? 37. : .2 * (gg + 1) - .13 * rr;
111 for (int cc = 0; cc != 4; ++cc)
112 for (int c = 0; c != BaseDim; ++c)
113 col_data.getN()(gg, BaseDim * cc + c) =
114 cc == 3 ? 53. : .09 * (gg + 1) * (c + 2) - .17 * (cc + 1);
115 }
116 for (const int mode : {0, 1, 2}) {
117 const bool transpose = mode != 0;
118 const bool only_transpose = mode == 2;
120 "row", "col", tensor, [alpha]() { return alpha; }, transpose,
121 only_transpose);
122 CHKERR op.check(fe, row_data, col_data, *tensor, alpha, transpose,
123 only_transpose);
124 }
125 }
127}
128
129} // namespace
130
131int main(int argc, char *argv[]) {
132 MoFEM::Core::Initialize(&argc, &argv, nullptr,
133 "Check mixed tensor bilinear integration\n");
134 try {
135 moab::Core moab;
136 MoFEM::Core core(moab);
137 CHKERR checkForm<2, 1, 2>(core);
138 CHKERR checkForm<2, 3, 2>(core);
139 CHKERR checkForm<3, 3, 2>(core);
140 CHKERR checkForm<4, 1, 2>(core);
141 CHKERR checkForm<4, 3, 2>(core);
142 CHKERR checkForm<9, 3, 2>(core);
143 CHKERR checkForm<3, 1, 3>(core);
144 CHKERR checkForm<3, 5, 3>(core);
145 CHKERR checkForm<9, 1, 3>(core);
146 CHKERR checkForm<9, 5, 3>(core);
147 CHKERR checkForm<3, 5, 3, 0>(core);
148 CHKERR checkForm<9, 3, 2, 0>(core);
149 }
152 return 0;
153}
int main()
constexpr double a
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
FTensor::Index< 'j', 3 > j
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
decltype(GetFTensor3FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor3FromMatType
double scale
Definition plastic.cpp:124
Core (interface) class.
Definition Core.hpp:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FieldApproximationBase & getBase()
Get approximation base.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
structure to get information from mofem into EntitiesFieldData