v0.16.3
Loading...
Searching...
No Matches
ftensor_matrix_block_views.cpp
Go to the documentation of this file.
1/** @file ftensor_matrix_block_views.cpp
2 * @brief Check rectangular form blocks, row offsets and column cursor strides.
3 */
4
5#define FTENSOR_DEBUG
6#include <MoFEM.hpp>
7#include <type_traits>
8using namespace MoFEM;
9
10namespace {
11
12using FormBase =
14 Assembly<AssemblyType::PETSC>::OpBase;
15
16struct OpCheckBlocks : FormBase {
17 OpCheckBlocks() : FormBase("row", "col", OPROWCOL) {}
18
19 template <int RowDim, int ColDim> MoFEMErrorCode check() {
21 FTensor::Index<'i', RowDim> i;
22 FTensor::Index<'j', ColDim> j;
23 constexpr int row_offset = 1;
24 constexpr int block_count = 3;
25 locMat.resize(row_offset + 2 * RowDim + 1, block_count * ColDim + 1, false);
26 locMat.clear();
27 for (int row = 0; row != 2; ++row) {
28 auto t_block = getLocMat<RowDim, ColDim>(row_offset + row * RowDim);
29 for (int col = 0; col != block_count; ++col, ++t_block)
30 t_block(i, j) = 10. * (row + 1) + col;
31 }
32 // Scalar inspection is deliberately independent of the tensor adapter.
33 for (std::size_t row = 0; row != locMat.size1(); ++row) {
34 for (std::size_t col = 0; col != locMat.size2(); ++col) {
35 const double expected =
36 row < row_offset || row >= row_offset + 2 * RowDim ||
37 col >= block_count * ColDim
38 ? 0.
39 : 10. * (1 + (row - row_offset) / RowDim) + col / ColDim;
40 if (locMat(row, col) != expected)
41 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
42 "Incorrect %dx%d form block or cursor stride at (%zu,%zu)",
43 RowDim, ColDim, row, col);
44 }
45 }
47 }
48};
49
50/** Const matrices must produce read-only, zero-copy views with Gauss strides. */
51MoFEMErrorCode checkConstMatrixViews() {
54 using VectorView = GetFTensor1FromMatType<3, -1, DL, const MatrixDouble>;
55 using TensorView = GetFTensor2FromMatType<3, 3, -1, DL, const MatrixDouble>;
56 using SymmetricView =
58 static_assert(std::is_same_v<
59 VectorView,
61 static_assert(std::is_same_v<
62 TensorView,
64 static_assert(std::is_same_v<SymmetricView,
67
68 constexpr int count = 3;
69 MatrixDouble vector_values(count, 3), tensor_values(count, 9),
70 symmetric_values(count, 6);
71 // Independent scalar storage initialisation and indexing are the oracle.
72 for (int gg = 0; gg != count; ++gg) {
73 for (int col = 0; col != 3; ++col)
74 vector_values(gg, col) = 100. * gg + col + 1;
75 for (int col = 0; col != 9; ++col)
76 tensor_values(gg, col) = 100. * gg + col + 11;
77 for (int col = 0; col != 6; ++col)
78 symmetric_values(gg, col) = 100. * gg + col + 21;
79 }
80 const auto &vectors = vector_values;
81 const auto &tensors = tensor_values;
82 const auto &symmetric = symmetric_values;
83 auto t_vector = MatrixSizeHelper<VectorView, DL>::get(vectors, count)();
84 auto t_tensor = MatrixSizeHelper<TensorView, DL>::get(tensors, count)();
85 auto t_symmetric =
87 static_assert(!std::is_assignable_v<decltype(t_vector(0)), double>);
88 static_assert(!std::is_assignable_v<decltype(t_tensor(0, 0)), double>);
89 static_assert(!std::is_assignable_v<decltype(t_symmetric(0, 0)), double>);
90
91 auto t_vector_mutable = getFTensor1FromMat<3>(vector_values);
92 auto t_tensor_mutable = getFTensor2FromMat<3, 3>(tensor_values);
93 auto t_symmetric_mutable = getFTensor2SymmetricFromMat<3>(symmetric_values);
94 static_assert(std::is_assignable_v<decltype(t_vector_mutable(0)), double>);
95 static_assert(std::is_assignable_v<decltype(t_tensor_mutable(0, 0)), double>);
96 static_assert(
97 std::is_assignable_v<decltype(t_symmetric_mutable(0, 0)), double>);
98 // Updates after creating the const views must remain visible through them.
99 t_vector_mutable(0) = -31.;
100 t_tensor_mutable(0, 0) = -41.;
101 t_symmetric_mutable(0, 0) = -51.;
102 for (int gg = 0; gg != count; ++gg) {
103 for (int row = 0; row != 3; ++row) {
104 if (t_vector(row) != vector_values(gg, row))
105 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
106 "Incorrect const vector view or Gauss stride");
107 for (int col = 0; col != 3; ++col)
108 if (t_tensor(row, col) != tensor_values(gg, 3 * row + col))
109 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
110 "Incorrect const tensor view or Gauss stride");
111 for (int col = row; col != 3; ++col) {
112 const int packed = 3 * row - row * (row - 1) / 2 + col - row;
113 if (t_symmetric(row, col) != symmetric_values(gg, packed) ||
114 t_symmetric(col, row) != symmetric_values(gg, packed))
115 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
116 "Incorrect const symmetric view or Gauss stride");
117 }
118 }
119 ++t_vector;
120 ++t_tensor;
121 ++t_symmetric;
122 }
124}
125
126} // namespace
127
128int main(int argc, char *argv[]) {
129 MoFEM::Core::Initialize(&argc, &argv, nullptr,
130 "Check FTensor form matrix block views\n");
131 try {
132 CHKERR checkConstMatrixViews();
133 OpCheckBlocks op;
134 CHKERR op.check<2, 2>();
135 CHKERR op.check<3, 3>();
136 CHKERR op.check<5, 5>();
137 CHKERR op.check<6, 6>();
138 CHKERR op.check<5, 1>();
139 CHKERR op.check<1, 5>();
140 CHKERR op.check<5, 3>();
141 CHKERR op.check<1, 3>();
142 }
145 return 0;
146}
int main()
#define CATCH_ERRORS
Catch errors.
#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
FTensor::Index< 'j', 3 > j
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
decltype(GetFTensor2SymmetricFromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2SymmetricFromMatType
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
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