13 Assembly<AssemblyType::PETSC>::BiLinearForm<IntegrationType::GAUSS>;
15template <
int BaseDim,
int FieldDim,
int SpaceDim,
int S = -1>
17 : BilinearForm::OpBaseTensorBase<BaseDim, FieldDim, SpaceDim, S> {
18 using Base = BilinearForm::OpBaseTensorBase<BaseDim, FieldDim, SpaceDim, S>;
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)
34 "Incorrect mixed-form assembly flags");
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);
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;
66 tensor(S == 0 ? 0 : gg, (SpaceDim *
i +
j) * FieldDim +
a) *
67 col_data.
getN()(gg, BaseDim * cc + basis_component);
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)))
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);
83template <
int BaseDim,
int FieldDim,
int SpaceDim,
int S = -1>
86 constexpr int col_dim = BaseDim == 4 || BaseDim == 9 ? 1 : SpaceDim;
87 constexpr double alpha = -.7;
91 row_data.
getIndices().resize(2 * FieldDim,
false);
92 col_data.
getIndices().resize(3 * col_dim,
false);
93 auto tensor = boost::make_shared<MatrixDouble>();
97 for (
const int points : {3, 4}) {
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);
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,
122 CHKERR op.check(fe, row_data, col_data, *tensor, alpha, transpose,
131int main(
int argc,
char *argv[]) {
133 "Check mixed tensor bilinear integration\n");
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);
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
#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
decltype(GetFTensor3FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor3FromMatType
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
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
Volume finite element base.