v0.13.2
Loading...
Searching...
No Matches
check_base_functions_derivatives_tri.cpp
Go to the documentation of this file.
1#include <MoFEM.hpp>
2
3namespace bio = boost::iostreams;
4using bio::stream;
5using bio::tee_device;
6
7using namespace MoFEM;
8
9static char help[] = "...\n\n";
10
11static const double eps = 1e-6;
12static const double eps_diff = 1e-4;
13
14int main(int argc, char *argv[]) {
15
16 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
17
18 try {
19
20 enum spaces { H1TRI, HCURLTRI, LASTOP };
21
22 const char *list_spaces[] = {"h1tri", "hcurltri"};
23
24 PetscBool flg;
25 PetscInt choice_value = H1TRI;
26 CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-space", list_spaces, LASTOP,
27 &choice_value, &flg);
28
29 if (flg != PETSC_TRUE) {
30 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "base not set");
31 }
32
33 FieldSpace space = LASTSPACE;
34 if (choice_value == H1TRI) {
35 space = H1;
36 } else if (choice_value == HCURLTRI) {
37 space = HCURL;
38 }
39
40 // Select base
41 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOP };
42
43 const char *list_bases[] = {"ainsworth", "demkowicz"};
44
45 PetscInt choice_base_value = AINSWORTH;
46 CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-base", list_bases,
47 LASBASETOP, &choice_base_value, &flg);
48
49 if (flg != PETSC_TRUE) {
50 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "base not set");
51 }
52
54 if (choice_base_value == AINSWORTH) {
56 } else if (choice_base_value == DEMKOWICZ) {
58 }
59
60 moab::Core mb_instance;
61 moab::Interface &moab = mb_instance;
62 int rank;
63 MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
64
65 // create one tet
66 double tri_coords[] = {0, 0, 0,
67
68 0.5, 0, 0,
69
70 0, 2., 0};
71 EntityHandle nodes[3];
72 for (int nn = 0; nn < 3; nn++) {
73 CHKERR moab.create_vertex(&tri_coords[3 * nn], nodes[nn]);
74 }
75 EntityHandle tri;
76 CHKERR moab.create_element(MBTRI, nodes, 3, tri);
77
78 // Create adjacencies entities
79 Range adj;
80 CHKERR moab.get_adjacencies(&tri, 1, 1, true, adj);
81
82 // Create MoFEM database
83 MoFEM::Core core(moab);
84 MoFEM::Interface &m_field = core;
85
86 // set entities bit level
87 BitRefLevel bit_level0;
88 bit_level0.set(0);
89 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevelByDim(
90 0, 2, bit_level0);
91
92 // Fields
93 CHKERR m_field.add_field("FIELD", space, base, 1);
94
95 // FE TET
96 CHKERR m_field.add_finite_element("TRI_FE");
97
98 // Define rows/cols and element data
99 CHKERR m_field.modify_finite_element_add_field_row("TRI_FE", "FIELD");
100 CHKERR m_field.modify_finite_element_add_field_col("TRI_FE", "FIELD");
101 CHKERR m_field.modify_finite_element_add_field_data("TRI_FE", "FIELD");
102
103 // Problem
104 CHKERR m_field.add_problem("TEST_PROBLEM");
105
106 // set finite elements for problem
107 CHKERR m_field.modify_problem_add_finite_element("TEST_PROBLEM", "TRI_FE");
108
109 // set refinement level for problem
110 CHKERR m_field.modify_problem_ref_level_add_bit("TEST_PROBLEM", bit_level0);
111
112 // meshset consisting all entities in mesh
113 EntityHandle root_set = moab.get_root_set();
114 // add entities to field
115 CHKERR m_field.add_ents_to_field_by_type(root_set, MBTRI, "FIELD");
116
117 // add entities to finite element
118 CHKERR m_field.add_ents_to_finite_element_by_type(root_set, MBTRI,
119 "TRI_FE");
120
121 // set app. order
122 int order = 5;
123 if (space == H1) {
124 CHKERR m_field.set_field_order(root_set, MBTRI, "FIELD", order);
125 CHKERR m_field.set_field_order(root_set, MBEDGE, "FIELD", order);
126 CHKERR m_field.set_field_order(root_set, MBVERTEX, "FIELD", 1);
127 }
128 if (space == HCURL) {
129 CHKERR m_field.set_field_order(root_set, MBTRI, "FIELD", order);
130 CHKERR m_field.set_field_order(root_set, MBEDGE, "FIELD", order);
131 }
132
133 // build field
134 CHKERR m_field.build_fields();
135
136 // build finite elemnts
138
139 // build adjacencies
140 CHKERR m_field.build_adjacencies(bit_level0);
141
142 // build problem
143 ProblemsManager *prb_mng_ptr;
144 CHKERR m_field.getInterface(prb_mng_ptr);
145
146 CHKERR prb_mng_ptr->buildProblem("TEST_PROBLEM", true);
147
148 // partition
149 CHKERR prb_mng_ptr->partitionSimpleProblem("TEST_PROBLEM");
150 CHKERR prb_mng_ptr->partitionFiniteElements("TEST_PROBLEM");
151
152 // what are ghost nodes, see Petsc Manual
153 CHKERR prb_mng_ptr->partitionGhostDofs("TEST_PROBLEM");
154
155 typedef tee_device<std::ostream, std::ofstream> TeeDevice;
156 typedef stream<TeeDevice> TeeStream;
157
158 std::ofstream ofs("forces_and_sources_checking_derivatives.txt");
159 TeeDevice my_tee(std::cout, ofs);
160 TeeStream my_split(my_tee);
161
162 struct OpCheckingDerivatives
164
165 TeeStream &mySplit;
166 OpCheckingDerivatives(TeeStream &my_split)
168 "FIELD", UserDataOperator::OPROW),
169 mySplit(my_split) {}
170
171 MoFEMErrorCode doWork(int side, EntityType type,
174
175 if (data.getFieldData().size() == 0)
177 mySplit << "type " << type << " side " << side << endl;
178
179 if (data.getFieldDofs()[0]->getSpace() == H1) {
180
181 // mySplit << std::fixed << data.getN() << std::endl;
182 // mySplit << std::fixed << data.getDiffN() << std::endl;
183
184 const int nb_dofs = data.getN().size2();
185 for (int dd = 0; dd != nb_dofs; dd++) {
186 const double dksi =
187 (data.getN()(1, dd) - data.getN()(0, dd)) / (eps);
188 const double deta =
189 (data.getN()(3, dd) - data.getN()(2, dd)) / (4 * eps);
190 mySplit << "DKsi " << dksi << std::endl;
191 mySplit << "DEta " << deta << std::endl;
192 mySplit << "diffN " << data.getDiffN()(4, 2 * dd + 0) << std::endl;
193 mySplit << "diffN " << data.getDiffN()(4, 2 * dd + 1) << std::endl;
194 if (fabs(dksi - data.getDiffN()(4, 2 * dd + 0)) > eps_diff) {
195 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
196 "H1 inconsistent dKsi derivative");
197 }
198 if (fabs(deta - data.getDiffN()(4, 2 * dd + 1)) > eps_diff) {
199 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
200 "H1 inconsistent dEta derivative");
201 }
202 }
203 }
204
205 if (data.getFieldDofs()[0]->getSpace() == HCURL) {
206
207 FTensor::Tensor1<double *, 3> base_ksi_m(&data.getN()(0, HVEC0),
208 &data.getN()(0, HVEC1),
209 &data.getN()(0, HVEC2), 3);
210 FTensor::Tensor1<double *, 3> base_ksi_p(&data.getN()(1, HVEC0),
211 &data.getN()(1, HVEC1),
212 &data.getN()(1, HVEC2), 3);
213 FTensor::Tensor1<double *, 3> base_eta_m(&data.getN()(2, HVEC0),
214 &data.getN()(2, HVEC1),
215 &data.getN()(2, HVEC2), 3);
216 FTensor::Tensor1<double *, 3> base_eta_p(&data.getN()(3, HVEC0),
217 &data.getN()(3, HVEC1),
218 &data.getN()(3, HVEC2), 3);
219
220 // cerr << data.getN() << endl;
221 // cerr << data.getDiffN() << endl;
222
224 &data.getDiffN()(4, HVEC0_0), &data.getDiffN()(4, HVEC0_1),
225 &data.getDiffN()(4, HVEC1_0), &data.getDiffN()(4, HVEC1_1),
226 &data.getDiffN()(4, HVEC2_0), &data.getDiffN()(4, HVEC2_1));
227
231
232 const int nb_dofs = data.getN().size2() / 3;
233 for (int dd = 0; dd != nb_dofs; dd++) {
234
235 mySplit << "MoFEM " << diff_base(0, 0) << " " << diff_base(1, 0)
236 << " " << diff_base(2, 0) << endl;
237 mySplit << "MoFEM " << diff_base(0, 1) << " " << diff_base(1, 1)
238 << " " << diff_base(2, 1) << endl;
239
241 dksi(i) = (base_ksi_p(i) - base_ksi_m(i)) / (eps);
243 deta(i) = (base_eta_p(i) - base_eta_m(i)) / (4 * eps);
244 mySplit << "Finite difference dKsi " << dksi(0) << " " << dksi(1)
245 << " " << dksi(2) << endl;
246 mySplit << "Finite difference dEta " << deta(0) << " " << deta(1)
247 << " " << deta(2) << endl;
248
249 dksi(i) -= diff_base(i, N0);
250 deta(i) -= diff_base(i, N1);
251 if (sqrt(dksi(i) * dksi(i)) > eps_diff) {
252 // mySplit << "KSI ERROR\n";
253 SETERRQ2(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
254 "%s inconsistent dKsi derivative for type %d",
255 FieldSpaceNames[data.getFieldDofs()[0]->getSpace()],
256 type);
257 } else {
258 mySplit << "OK" << std::endl;
259 }
260 if (sqrt(deta(i) * deta(i)) > eps_diff) {
261 // mySplit << "ETA ERROR\n";
262 SETERRQ2(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
263 "%s inconsistent dEta derivative for type %d",
264 FieldSpaceNames[data.getFieldDofs()[0]->getSpace()],
265 type);
266 } else {
267 mySplit << "OK" << std::endl;
268 }
269
270 ++base_ksi_m;
271 ++base_ksi_p;
272 ++base_eta_m;
273 ++base_eta_p;
274 ++diff_base;
275 }
276 }
277
278 mySplit << endl;
279
281 }
282 };
283
284 struct MyFE : public FaceElementForcesAndSourcesCore {
285
286 MyFE(MoFEM::Interface &m_field)
288 int getRule(int order) { return -1; };
289
292
293 const double ksi = G_TRI_X1[0];
294 const double eta = G_TRI_Y1[0];
295
296 gaussPts.resize(3, 5);
297 gaussPts.clear();
298
299 gaussPts(0, 0) = ksi - eps;
300 gaussPts(1, 0) = eta;
301 gaussPts(0, 1) = ksi + eps;
302 gaussPts(1, 1) = eta;
303
304 gaussPts(0, 2) = ksi;
305 gaussPts(1, 2) = eta - eps;
306 gaussPts(0, 3) = ksi;
307 gaussPts(1, 3) = eta + eps;
308
309 gaussPts(0, 4) = ksi;
310 gaussPts(1, 4) = eta;
311
312 for (unsigned int ii = 0; ii != gaussPts.size2(); ii++) {
313 gaussPts(2, ii) = 1;
314 }
315
316 // cerr << gaussPts << endl;
317
319 }
320 };
321
322 MyFE tri_fe(m_field);
323
324 CHKERR AddHOOps<2, 2, 2>::add(tri_fe.getOpPtrVector(), {space});
325 tri_fe.getOpPtrVector().push_back(new OpCheckingDerivatives(my_split));
326 CHKERR m_field.loop_finite_elements("TEST_PROBLEM", "TRI_FE", tri_fe);
327
328 }
330
332}
static Number< 1 > N1
static Number< 0 > N0
int main()
Definition: adol-c_atom.cpp:46
static const double eps
static const double eps_diff
static const double eps
static const double eps_diff
#define CATCH_ERRORS
Catch errors.
Definition: definitions.h:372
FieldApproximationBase
approximation base
Definition: definitions.h:58
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition: definitions.h:60
@ NOBASE
Definition: definitions.h:59
@ DEMKOWICZ_JACOBI_BASE
Definition: definitions.h:66
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
FieldSpace
approximation spaces
Definition: definitions.h:82
@ LASTSPACE
FieldSpace in [ 0, LASTSPACE )
Definition: definitions.h:89
@ H1
continuous field
Definition: definitions.h:85
@ HCURL
field with continuous tangents
Definition: definitions.h:86
static const char *const FieldSpaceNames[]
Definition: definitions.h:92
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
@ HVEC0
Definition: definitions.h:186
@ HVEC1
Definition: definitions.h:186
@ HVEC2
Definition: definitions.h:186
@ MOFEM_IMPOSSIBLE_CASE
Definition: definitions.h:35
@ MOFEM_ATOM_TEST_INVALID
Definition: definitions.h:40
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
@ HVEC1_1
Definition: definitions.h:196
@ HVEC0_1
Definition: definitions.h:195
@ HVEC1_0
Definition: definitions.h:193
@ HVEC2_1
Definition: definitions.h:197
@ HVEC2_0
Definition: definitions.h:194
@ HVEC0_0
Definition: definitions.h:192
#define CHKERR
Inline error check.
Definition: definitions.h:535
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
static const double G_TRI_Y1[]
Definition: fem_tools.h:313
static const double G_TRI_X1[]
Definition: fem_tools.h:312
tee_device< std::ostream, std::ofstream > TeeDevice
constexpr double eta
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string &name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_filed)=0
set finite element field data
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode loop_finite_elements(const std::string problem_name, const std::string &fe_name, FEMethod &method, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr(), int verb=DEFAULT_VERBOSITY)=0
Make a loop over finite elements.
MoFEMErrorCode partitionGhostDofs(const std::string name, int verb=VERBOSE)
determine ghost nodes
MoFEMErrorCode partitionSimpleProblem(const std::string name, int verb=VERBOSE)
partition problem dofs
MoFEMErrorCode buildProblem(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures
MoFEMErrorCode partitionFiniteElements(const std::string name, bool part_from_moab=false, int low_proc=-1, int hi_proc=-1, int verb=VERBOSE)
partition finite elements
virtual MoFEMErrorCode add_problem(const std::string &name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add problem.
virtual MoFEMErrorCode modify_problem_ref_level_add_bit(const std::string &name_problem, const BitRefLevel &bit)=0
add ref level to problem
virtual MoFEMErrorCode modify_problem_add_finite_element(const std::string name_problem, const std::string &fe_name)=0
add finite element to problem, this add entities assigned to finite element to a particular problem
FTensor::Index< 'i', SPACE_DIM > i
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Types.hpp:40
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
Add operators pushing bases from local to physical configuration.
Managing BitRefLevels.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string &name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
Core (interface) class.
Definition: Core.hpp:82
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition: Core.cpp:72
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition: Core.cpp:112
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
MatrixDouble & getDiffN(const FieldApproximationBase base)
get derivatives of base functions
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 dofs values
const VectorDofs & getFieldDofs() const
get dofs data stature FEDofEntity
virtual MoFEMErrorCode setGaussPts(int order_row, int order_col, int order_data)
set user specific integration rule
virtual int getRule(int order_row, int order_col, int order_data)
another variant of getRule
MatrixDouble gaussPts
Matrix of integration points.
Problem manager is used to build and partition problems.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.