v0.16.3
Loading...
Searching...
No Matches
symmetric_deviator_field_values.cpp
Go to the documentation of this file.
1/** @file symmetric_deviator_field_values.cpp
2 * @brief Check planar and spatial deviator interpolation and vector sources.
3 */
4
5#define FTENSOR_DEBUG
6#include <MoFEM.hpp>
7using namespace MoFEM;
8
9#include <array>
10#include <cmath>
11
12namespace {
13
14template <int Dim>
17 using Base::Base;
18
19 MoFEMErrorCode attach(ForcesAndSourcesCore &fe, const int points) {
21 CHKERR this->setPtrFE(&fe);
22 this->getGaussPts().resize(4, points, false);
24 }
25};
26
27MoFEMErrorCode checkNear(const double value, const double expected) {
29 if (!std::isfinite(value) || std::abs(value - expected) > 2.e-13)
30 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
31 "Deviator field value %g differs from %g", value, expected);
33}
34
35template <int Dim>
36MoFEMErrorCode checkValues(const MatrixDouble &tensor,
37 const MatrixDouble &coordinates,
39 const VectorDouble &coefficients,
40 const double scale) {
42 constexpr int size = Dim == 2 ? 3 : 5;
43 const int points = data.getN().size1();
44 if (tensor.size1() != points || tensor.size2() != 6 ||
45 coordinates.size1() != points || coordinates.size2() != size)
46 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
47 "Incorrect deviator output layout");
48 for (int gg = 0; gg != points; ++gg) {
49 std::array<double, 5> d{};
50 // Independent scalar oracle for interpolation and the documented basis.
51 for (int c = 0; c != size; ++c) {
52 for (int b = 0; b != 2; ++b)
53 d[c] += scale * coefficients[b * size + c] * data.getN()(gg, b);
54 CHKERR checkNear(coordinates(gg, c), d[c]);
55 }
56 const std::array<double, 6> expected{
57 d[0] / std::sqrt(2.) + d[1] / std::sqrt(6.),
58 d[2] / std::sqrt(2.), d[3] / std::sqrt(2.),
59 -d[0] / std::sqrt(2.) + d[1] / std::sqrt(6.),
60 d[4] / std::sqrt(2.), -2. * d[1] / std::sqrt(6.)};
61 for (int c = 0; c != 6; ++c)
62 CHKERR checkNear(tensor(gg, c), expected[c]);
63 CHKERR checkNear(tensor(gg, 0) + tensor(gg, 3) + tensor(gg, 5), 0.);
64 const double norm = tensor(gg, 0) * tensor(gg, 0) +
65 tensor(gg, 3) * tensor(gg, 3) +
66 tensor(gg, 5) * tensor(gg, 5) +
67 2. * (tensor(gg, 1) * tensor(gg, 1) +
68 tensor(gg, 2) * tensor(gg, 2) +
69 tensor(gg, 4) * tensor(gg, 4));
70 double coordinate_norm = 0;
71 for (const auto value : d)
72 coordinate_norm += value * value;
73 CHKERR checkNear(norm, coordinate_norm);
74 }
76}
77
78template <int Dim> MoFEMErrorCode checkField(MoFEM::Interface &m_field) {
80 constexpr int size = Dim == 2 ? 3 : 5;
84 data.getFieldData().resize(2 * size, false);
85 for (int c = 0; c != 2 * size; ++c)
86 data.getFieldData()[c] = .07 * (c + 1);
87 const VectorDouble original = data.getFieldData();
88 auto tensor = boost::make_shared<MatrixDouble>();
89 auto coordinates = boost::make_shared<MatrixDouble>();
90 TestOp<Dim> op("D", tensor, SmartPetscObj<Vec>(), MBVERTEX, 0, coordinates);
91
92 for (const int points : {3, 4}) {
93 CHKERR op.attach(fe, points);
94 data.getN().resize(points, 3, false);
95 for (int gg = 0; gg != points; ++gg) {
96 data.getN()(gg, 0) = .2 * (gg + 1);
97 data.getN()(gg, 1) = -.1 * (gg + 2);
98 data.getN()(gg, 2) = 17.; // Inactive basis tail must be skipped.
99 }
100 CHKERR op.doWork(0, MBVERTEX, data);
101 CHKERR checkValues<Dim>(*tensor, *coordinates, data, original, 1.);
102 CHKERR op.doWork(1, MBVERTEX, data);
103 CHKERR checkValues<Dim>(*tensor, *coordinates, data, original, 2.);
104 CHKERR op.doWork(0, MBVERTEX, data);
105 CHKERR checkValues<Dim>(*tensor, *coordinates, data, original, 1.);
106 }
107
108 Vec raw_vector;
109 CHKERR VecCreateSeq(PETSC_COMM_SELF, 2 * size, &raw_vector);
110 SmartPetscObj<Vec> vector(raw_vector);
111 PetscScalar *array;
112 CHKERR VecGetArray(vector, &array);
113 data.getLocalIndices().resize(2 * size, false);
114 VectorDouble from_vector(2 * size);
115 for (int c = 0; c != 2 * size; ++c)
116 array[c] = -.03 * (c + 1);
117 for (int c = 0; c != 2 * size; ++c) {
118 const int index = c == 1 ? -1 : 2 * size - c - 1;
119 data.getLocalIndices()[c] = index;
120 from_vector[c] = index == -1 ? 0. : array[index];
121 }
122 CHKERR VecRestoreArray(vector, &array);
123 TestOp<Dim> vector_op("D", tensor, vector, MBVERTEX, 0, coordinates);
124 CHKERR vector_op.attach(fe, data.getN().size1());
125 CHKERR vector_op.doWork(0, MBVERTEX, data);
126 CHKERR checkValues<Dim>(*tensor, *coordinates, data, from_vector, 1.);
127 for (int c = 0; c != 2 * size; ++c)
128 CHKERR checkNear(data.getFieldData()[c], original[c]);
129
130 data.getFieldData().resize(0, false);
131 CHKERR vector_op.doWork(0, MBVERTEX, data);
132 CHKERR checkValues<Dim>(*tensor, *coordinates, data, original, 0.);
133 CHKERR PetscPrintf(PETSC_COMM_SELF, "%dD deviator field evaluation passed\n", Dim);
135}
136
137} // namespace
138
139int main(int argc, char *argv[]) {
140 MoFEM::Core::Initialize(&argc, &argv, nullptr,
141 "Check symmetric deviator field interpolation\n");
142 try {
143 moab::Core moab;
144 MoFEM::Core core(moab);
145 CHKERR checkField<2>(core);
146 CHKERR checkField<3>(core);
147 }
150 return 0;
151}
PetscInt size
int main()
#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.
const double c
speed of light (cm/ns)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
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 VectorDouble & getFieldData() const
Get DOF values on entity.
const VectorInt & getLocalIndices() const
Get local indices of degrees of freedom on entity.
structure to get information from mofem into EntitiesFieldData
intrusive_ptr for managing petsc objects