v0.16.3
Loading...
Searching...
No Matches
field_evaluator.cpp
Go to the documentation of this file.
1/** \file field_evaluator.cpp
2 * \example mofem/atom_tests/field_evaluator.cpp
3 * \brief test segments distance
4 *
5 * \ingroup field_evaluator
6 */
7
8
9
10#include <MoFEM.hpp>
11
12using namespace MoFEM;
13
14static char help[] = "testing field evaluator\n\n";
15
16/**
17 * @brief Operator used to check consistency between local coordinates
18 * and global cooridnates for integrated points and evaluated points
19 *
20 */
21template <typename OP> struct MyOp : public OP {
22
24
25 MyOp(std::array<double, 12> &eval_points)
26 : OP("FIELD1", OP::OPROW),
28 getMatrixAdaptor(eval_points.data(), eval_points.size() / 3, 3)) {}
29
30 MoFEMErrorCode doWork(int side, EntityType type,
33 if (type == MBVERTEX) {
34
35 MOFEM_LOG("SELF", Sev::inform) << "FE " << OP::getFEEntityHandle();
36
37 MOFEM_LOG("SELF", Sev::inform) << "Integration pts" << std::endl;
38 MOFEM_LOG("SELF", Sev::inform) << OP::getGaussPts() << endl;
39
40 MOFEM_LOG("SELF", Sev::inform) << "Global coordinates " << endl;
41 MOFEM_LOG("SELF", Sev::inform) << OP::getCoordsAtGaussPts() << std::endl;
42
43 for (int gg = 0; gg != OP::getCoordsAtGaussPts().size1(); ++gg) {
44 int pt_number = OP::getGaussPts()(OP::getGaussPts().size1() - 1, gg);
45
46 MOFEM_LOG("SELF", Sev::inform) << "gg " << gg << std::endl;
47 MOFEM_LOG("SELF", Sev::inform) << "pt " << pt_number << std::endl;
48
49 ublas::matrix_row<MatrixDouble> coord_at_gauss_pt(
50 OP::getCoordsAtGaussPts(), gg);
51 ublas::matrix_row<MatrixShallowArrayAdaptor<double>> eval_coord(
52 evalPoints, pt_number);
53
54 MOFEM_LOG("SELF", Sev::inform) << "coord_at_gauss_pt ";
55 MOFEM_LOG("SELF", Sev::inform) << coord_at_gauss_pt << std::endl;
56
57 MOFEM_LOG("SELF", Sev::inform) << "eval_coord ";
58 MOFEM_LOG("SELF", Sev::inform) << eval_coord << std::endl;
59
60 double error = norm_2(coord_at_gauss_pt - eval_coord);
61
62 if (error > 1e-12)
63 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
64 "Difference at %d error = %3.4e", pt_number, error);
65 }
66 }
68 }
69};
70
71// Lambda function is used to set integration rule to -1, that indicates
72// that finite element instace will use non-standard integration points.
73auto get_rule = [](int order_row, int order_col, int order_data) {
74 return -1;
75};
76
77int main(int argc, char *argv[]) {
78
79 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
80
81 try {
82
83 // Read mesh and create moab and mofem data structures
84 moab::Core mb_instance;
85 moab::Interface &moab = mb_instance;
86
87 MoFEM::Core core(moab, PETSC_COMM_WORLD);
88 MoFEM::Interface &m_field = core;
89
90 // Register DM Manager
91 DMType dm_name = "DMMOFEM";
92 CHKERR DMRegister_MoFEM(dm_name);
93
94 // Simple interface
95 Simple *simple_interface;
96 CHKERR m_field.getInterface(simple_interface);
97 {
98
99 // get options from command line
100 CHKERR simple_interface->getOptions();
101 // load mesh file
102 CHKERR simple_interface->loadFile();
103 // add fields
104 CHKERR simple_interface->addDomainField("FIELD1", H1,
106 // set fields order
107 CHKERR simple_interface->setFieldOrder("FIELD1", 1);
108 // setup problem
109 CHKERR simple_interface->setUp();
110
111 // Exercise the TestingInterface adapter with a known constant field.
112 CHKERR m_field.getInterface<FieldBlas>()->setField(1.25, "FIELD1");
113 auto test_point = [&]<int DIM>() {
115 auto testing = m_field.getInterface<TestingInterface>();
116 auto values = boost::make_shared<MatrixDouble>();
117 auto add_ops = [&](auto &pipeline) {
119 pipeline.push_back(new OpCalculateVectorFieldValues<3>("FIELD1", values));
121 };
122 CHKERR testing->addFieldEvaluator<DIM>(
123 simple_interface->getProblemName(), simple_interface->getDomainFEName(),
124 {0., 0.01, 0.}, add_ops);
126 auto t_value = MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>,
127 DL>::get(*values, 1)();
128 FTENSOR_INDEX(3, i);
129 FTensor::Tensor1<double, 3> t_expected{1.25, 1.25, 1.25};
131 t_error(i) = t_value(i) - t_expected(i);
132 CHKERR testing->checkError<TestType::POINTWISE>(
133 "constant field evaluation", std::sqrt(t_error(i) * t_error(i)),
134 0., {1e-12, 0.});
135
136 CHKERR PetscPushErrorHandler(PetscReturnErrorHandler, nullptr);
137 const auto missing_error = testing->addFieldEvaluator<DIM>(
138 simple_interface->getProblemName(), simple_interface->getDomainFEName(),
139 {1e6, 1e6, 1e6}, add_ops);
140 CHKERR PetscPopErrorHandler();
141 if (missing_error != MOFEM_ATOM_TEST_INVALID)
142 SETERRQ(m_field.get_comm(), MOFEM_ATOM_TEST_INVALID,
143 "Missing evaluation point did not fail the test");
144
145 CHKERR PetscPushErrorHandler(PetscReturnErrorHandler, nullptr);
146 const auto hook_error = testing->addFieldEvaluator<DIM>(
147 simple_interface->getProblemName(), simple_interface->getDomainFEName(),
148 {0., 0.01, 0.}, [](auto &) -> MoFEMErrorCode {
150 });
151 CHKERR PetscPopErrorHandler();
152 if (hook_error != MOFEM_ATOM_TEST_INVALID)
153 SETERRQ(m_field.get_comm(), MOFEM_ATOM_TEST_INVALID,
154 "Pipeline hook failure was not propagated");
156 };
157 if (simple_interface->getDim() == 3)
158 CHKERR test_point.template operator()<3>();
159 else if (simple_interface->getDim() == 2)
160 CHKERR test_point.template operator()<2>();
161
162 FieldEvaluatorInterface *field_eval_ptr;
163 CHKERR m_field.getInterface(field_eval_ptr);
164
165
166 auto dm = simple_interface->getDM();
167 const MoFEM::Problem *prb_ptr;
168 CHKERR DMMoFEMGetProblemPtr(dm, &prb_ptr);
169
170 if (simple_interface->getDim() == 3) {
171
172 std::array<double, 3> point = {0, 0, 0};
173 const double dist = 0.1;
174
175 std::array<double, 12> eval_points = {0.0, 0.0, 0.0, 0.0, 0.01, 0.0,
176 -0.1, 0.0, 0.0, 0.1, 0.0, 0.0};
177
180
181 // Get pointer of FieldEvaluator data. Note finite element and method
182 // set integrating points is destroyed when this pointer is releases
183 auto data = field_eval_ptr->getData<VolEle>();
184
185 // Set operators and integration rule
186 if (auto fe_method = data->feMethodPtr) {
187 fe_method->getRuleHook = get_rule;
188 fe_method->getOpPtrVector().push_back(new MyOp<VolOp>(eval_points));
189 } else
190 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
191 "Pointer to element does not exists");
192
193 // Build tree for particular element
194 CHKERR field_eval_ptr->buildTree<3>(data,
195 simple_interface->getDomainFEName());
196 // Set points to set on finite elements
197 data->setEvalPoints(eval_points.data(), eval_points.size() / 3);
198
199 // Evaluate points on finite elements
200 CHKERR field_eval_ptr->evalFEAtThePoint<3>(
201 &point[0], dist, prb_ptr->getName(),
202 simple_interface->getDomainFEName(), data, m_field.get_comm_rank(),
203 m_field.get_comm_rank(), nullptr, MF_EXIST, VERY_NOISY);
204 }
205
206 if (simple_interface->getDim() == 2) {
207
208 std::array<double, 3> point = {0, 0, 0};
209 const double dist = 0.1;
210
211 std::array<double, 12> eval_points = {
212 0.0, 0.0, 0.0,
213 0.0, 0.01, 0.0,
214 -0.1, 0.0, 0.0,
215 0.1, 0.0, 0.0};
216
219
220 // Get pointer of FieldEvaluator data. Note finite element and method
221 // set integrating points is destroyed when this pointer is releases
222 auto data = field_eval_ptr->getData<FaceEle>();
223
224 // Set operators and integration rule
225 if (auto fe_method = data->feMethodPtr) {
226 fe_method->getRuleHook = get_rule;
227 fe_method->getOpPtrVector().push_back(new MyOp<FaceOp>(eval_points));
228 } else
229 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
230 "Pointer to element does not exists");
231
232 // Build tree for particular element
233 CHKERR field_eval_ptr->buildTree<2>(data,
234 simple_interface->getDomainFEName());
235 // Set points to set on finite elements
236 data->setEvalPoints(eval_points.data(), eval_points.size() / 3);
237
238 // Evaluate points on finite elements
239 CHKERR field_eval_ptr->evalFEAtThePoint<2>(
240 &point[0], dist, prb_ptr->getName(),
241 simple_interface->getDomainFEName(), data, m_field.get_comm_rank(),
242 m_field.get_comm_rank(), nullptr, MF_EXIST, VERY_NOISY);
243 }
244
245 }
246 }
248
250
251 return 0;
252}
std::string type
SmartPetscObj< Vec > values
PetscInt size
#define FTENSOR_INDEX(DIM, I)
int main()
@ VERY_NOISY
#define CATCH_ERRORS
Catch errors.
@ MF_EXIST
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ H1
continuous field
Definition definitions.h:85
#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
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
static char help[]
auto get_rule
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:451
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
PetscBool testing
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
ublas::matrix< T, ublas::row_major, ublas::shallow_array_adaptor< T > > MatrixShallowArrayAdaptor
Definition Types.hpp:120
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
auto getMatrixAdaptor(T1 ptr, const size_t n, const size_t m)
Get Matrix adaptor.
Definition Templates.hpp:75
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
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)
Basic algebra on fields.
Definition FieldBlas.hpp:21
Field evaluator interface.
MoFEMErrorCode evalFEAtThePoint(const double *const point, const double distance, const std::string problem, const std::string finite_element, boost::shared_ptr< SetIntegrationPtsMethodData > data_ptr, int lower_rank, int upper_rank, boost::shared_ptr< CacheTuple > cache_ptr, MoFEMTypes bh=MF_EXIST, VERBOSITY_LEVELS verb=QUIET)
Evaluate field at arbitrary position.
boost::shared_ptr< SPD > getData(const double *ptr=nullptr, const int nb_eval_points=0, const double eps=1e-12, VERBOSITY_LEVELS verb=QUIET)
Get the Data object.
MoFEMErrorCode buildTree(boost::shared_ptr< SetIntegrationPtsMethodData > spd_ptr, const std::string finite_element)
Build spatial tree.
@ OPROW
operator doWork function is executed on FE rows
RuleHookFun getRuleHook
Hook to get rule.
Specialization for MatrixDouble vector field values calculation.
keeps basic data about problem
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode addDomainField(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_ZERO, int verb=-1)
Add field on domain.
Definition Simple.cpp:261
int getDim() const
Get the problem dimension.
Definition Simple.hpp:373
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:191
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:575
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:735
const std::string getProblemName() const
Get the Problem Name.
Definition Simple.hpp:450
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:429
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Operator used to check consistency between local coordinates and global cooridnates for integrated po...
MatrixShallowArrayAdaptor< double > evalPoints
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
MyOp(std::array< double, 12 > &eval_points)