v0.15.0
Loading...
Searching...
No Matches
FieldEvaluator.cpp
Go to the documentation of this file.
1/** \file FieldEvaluator.cpp
2 * \brief Field evaluator
3 *
4 */
5
6namespace MoFEM {
7
9 : cOre(const_cast<MoFEM::Core &>(core)) {
10
11 if (!LogManager::checkIfChannelExist("FieldEvaluatorWorld")) {
12 auto core_log = logging::core::get();
13
15 "FieldEvaluatorWorld"));
17 "FieldEvaluatorSync"));
19 "FieldEvaluatorSelf"));
20
21 LogManager::setLog("FieldEvaluatorWorld");
22 LogManager::setLog("FieldEvaluatorSync");
23 LogManager::setLog("FieldEvaluatorSelf");
24
25 MOFEM_LOG_TAG("FieldEvaluatorWorld", "FieldEvaluator");
26 MOFEM_LOG_TAG("FieldEvaluatorSync", "FieldEvaluator");
27 MOFEM_LOG_TAG("FieldEvaluatorSelf", "FieldEvaluator");
28 }
29
30 MOFEM_LOG("FieldEvaluatorWorld", Sev::noisy) << "Field evaluator intreface";
31}
32
34 boost::typeindex::type_index type_index, UnknownInterface **iface) const {
36 *iface = const_cast<FieldEvaluatorInterface *>(this);
38}
39
40template <int D>
42FieldEvaluatorInterface::buildTreeImpl(boost::shared_ptr<SetPtsData> spd_ptr,
43 const std::string finite_element) {
44 CoreInterface &m_field = cOre;
46 EntityHandle fe_meshset;
47 fe_meshset = m_field.get_finite_element_meshset(finite_element);
48 Range entities;
49 CHKERR m_field.get_moab().get_entities_by_dimension(fe_meshset, D, entities,
50 true);
51 spd_ptr->treePtr.reset(new AdaptiveKDTree(&m_field.get_moab()));
52 CHKERR spd_ptr->treePtr->build_tree(entities, &spd_ptr->rooTreeSet);
54}
55
56template <>
58FieldEvaluatorInterface::buildTree<2>(boost::shared_ptr<SetPtsData> spd_ptr,
59 const std::string finite_element) {
60 return buildTreeImpl<2>(spd_ptr, finite_element);
61}
62
63template <>
65FieldEvaluatorInterface::buildTree<3>(boost::shared_ptr<SetPtsData> spd_ptr,
66 const std::string finite_element) {
67 return buildTreeImpl<3>(spd_ptr, finite_element);
68}
69
71FieldEvaluatorInterface::buildTree3D(boost::shared_ptr<SetPtsData> spd_ptr,
72 const std::string finite_element) {
73 return buildTree<3>(spd_ptr, finite_element);
74}
75
77FieldEvaluatorInterface::buildTree2D(boost::shared_ptr<SetPtsData> spd_ptr,
78 const std::string finite_element) {
79 return buildTree<2>(spd_ptr, finite_element);
80}
81
84 int order_row, int order_col,
85 int order_data) {
87
88 if (auto data_ptr = dataPtr.lock()) {
89
90 const auto nb_eval_points = data_ptr->nbEvalPoints;
91 const auto &shape_functions = data_ptr->shapeFunctions;
92 const auto &eval_pointentity_handle = data_ptr->evalPointEntityHandle;
93
94 if (auto fe_ptr = data_ptr->feMethodPtr.lock()) {
95
96 auto &fe = static_cast<ForcesAndSourcesCore &>(*fe_ptr);
97
98#ifndef NDEBUG
99 if (fe_ptr.get() != fe_raw_ptr)
100 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong FE ptr");
101#endif
102
103 const auto fe_ent = fe.numeredEntFiniteElementPtr->getEnt();
104 const auto fe_type = type_from_handle(fe_ent);
105 const auto fe_dim = moab::CN::Dimension(fe_type);
106
107 auto &gauss_pts = fe.gaussPts;
108 int nb_gauss_pts;
109
110 if (fe_dim == 3) {
111 gauss_pts.resize(4, nb_eval_points, false);
113 &shape_functions(0, 0), &shape_functions(0, 1),
114 &shape_functions(0, 2), &shape_functions(0, 3)};
116 &gauss_pts(0, 0), &gauss_pts(1, 0), &gauss_pts(2, 0)};
117
118 nb_gauss_pts = 0;
119 for (int nn = 0; nn != nb_eval_points; ++nn) {
120 if (eval_pointentity_handle[nn] == fe_ent) {
121 for (const int i : {0, 1, 2}) {
122 t_gauss_pts(i) = t_shape(i + 1);
123 }
124 gauss_pts(3, nb_gauss_pts) = nn;
125 ++t_gauss_pts;
126 ++nb_gauss_pts;
127 }
128 ++t_shape;
129 }
130 gauss_pts.resize(4, nb_gauss_pts, true);
131 } else if (fe_dim == 2) {
132 gauss_pts.resize(3, nb_eval_points, false);
134 &shape_functions(0, 0), &shape_functions(0, 1),
135 &shape_functions(0, 2)};
137 &gauss_pts(0, 0), &gauss_pts(1, 0)};
138 nb_gauss_pts = 0;
139 for (int nn = 0; nn != nb_eval_points; ++nn) {
140 if (eval_pointentity_handle[nn] == fe_ent) {
141 for (const int i : {0, 1}) {
142 t_gauss_pts(i) = t_shape(i + 1);
143 }
144 gauss_pts(2, nb_gauss_pts) = nn;
145 ++t_gauss_pts;
146 ++nb_gauss_pts;
147 }
148 ++t_shape;
149 }
150 gauss_pts.resize(3, nb_gauss_pts, true);
151 } else {
152 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
153 "Dimension not implemented");
154 }
155
156#ifndef NDEBUG
157 MOFEM_LOG("SELF", Sev::noisy)
158 << "nbEvalOPoints / nbGau_sspt_s: " << nb_eval_points << " / "
159 << nb_gauss_pts;
160 MOFEM_LOG("SELF", Sev::noisy) << "gauss pts: " << gauss_pts;
161#endif
162
163 } else
164 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
165 "Pointer to element does not exists");
166
167 } else
168 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
169 "Pointer to data does not exists");
170
172}
173
174template <int D>
176 const double *const point, const double distance, const std::string problem,
177 const std::string finite_element, boost::shared_ptr<SetPtsData> data_ptr,
178 int lower_rank, int upper_rank, boost::shared_ptr<CacheTuple> cache_ptr,
179 MoFEMTypes bh, VERBOSITY_LEVELS verb) {
180 CoreInterface &m_field = cOre;
182
183 std::vector<EntityHandle> leafs_out;
184 CHKERR data_ptr->treePtr->distance_search(point, distance, leafs_out);
185 Range tree_ents;
186 for (auto lit : leafs_out) //{
187 CHKERR m_field.get_moab().get_entities_by_dimension(lit, D, tree_ents,
188 true);
189
190 if (verb >= NOISY)
191 MOFEM_LOG("SELF", Sev::noisy) << "tree entities: " << tree_ents;
192
193 data_ptr->evalPointEntityHandle.resize(data_ptr->nbEvalPoints);
194 std::fill(data_ptr->evalPointEntityHandle.begin(),
195 data_ptr->evalPointEntityHandle.end(), 0);
196
197 std::vector<double> local_coords;
198 std::vector<double> shape;
199
200 auto nb_eval_points = data_ptr->nbEvalPoints;
201
202 for (auto tet : tree_ents) {
203 if ((type_from_handle(tet) != moab::MBTRI) &&
204 (type_from_handle(tet) != moab::MBTET)) {
205 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
206 "Wrong element type, Field Evaluator not implemented for Quads and Hexes");
207 }
208 const EntityHandle *conn;
209 int num_nodes;
210 CHKERR m_field.get_moab().get_connectivity(tet, conn, num_nodes, true);
211
212 if constexpr (D == 3) {
213
214 local_coords.resize(3 * nb_eval_points);
215 shape.resize(4 * nb_eval_points);
216
217 std::array<double, 12> coords;
218 CHKERR m_field.get_moab().get_coords(conn, num_nodes, coords.data());
219
221 coords.data(), &data_ptr->evalPoints[0], nb_eval_points,
222 &local_coords[0]);
223 CHKERR Tools::shapeFunMBTET<3>(&shape[0], &local_coords[0],
224 &local_coords[1], &local_coords[2],
225 nb_eval_points);
226
227 FTensor::Index<'i', 4> i4;
229 &shape[0], &shape[1], &shape[2], &shape[3]};
231 &data_ptr->shapeFunctions(0, 0), &data_ptr->shapeFunctions(0, 1),
232 &data_ptr->shapeFunctions(0, 2), &data_ptr->shapeFunctions(0, 3)};
233
234 FTensor::Index<'j', 3> j3;
236 &local_coords[0], &local_coords[1], &local_coords[2]};
238 &(data_ptr->localCoords(0, 0)), &(data_ptr->localCoords(0, 1)),
239 &(data_ptr->localCoords(0, 2))};
240
241 for (int n = 0; n != nb_eval_points; ++n) {
242
243 const double eps = data_ptr->eps;
244 if (t_shape(0) >= 0 - eps && t_shape(0) <= 1 + eps &&
245
246 t_shape(1) >= 0 - eps && t_shape(1) <= 1 + eps &&
247
248 t_shape(2) >= 0 - eps && t_shape(2) <= 1 + eps &&
249
250 t_shape(3) >= 0 - eps && t_shape(3) <= 1 + eps) {
251
252 data_ptr->evalPointEntityHandle[n] = tet;
253 t_shape_data(i4) = t_shape(i4);
254 t_local_data(j3) = t_local(j3);
255 }
256
257 ++t_shape;
258 ++t_shape_data;
259 ++t_local;
260 ++t_local_data;
261 }
262 }
263
264 if constexpr (D == 2) {
265
266 local_coords.resize(2 * nb_eval_points);
267 shape.resize(3 * nb_eval_points);
268
269 std::array<double, 9> coords;
270 CHKERR m_field.get_moab().get_coords(conn, num_nodes, coords.data());
271
273 coords.data(), &data_ptr->evalPoints[0], nb_eval_points,
274 &local_coords[0]);
275 CHKERR Tools::shapeFunMBTRI<2>(&shape[0], &local_coords[0],
276 &local_coords[1], nb_eval_points);
277
278 FTensor::Index<'i', 3> i3;
280 &shape[0], &shape[1], &shape[2]};
282 &data_ptr->shapeFunctions(0, 0), &data_ptr->shapeFunctions(0, 1),
283 &data_ptr->shapeFunctions(0, 2)};
284
285 FTensor::Index<'j', 2> j2;
287 &local_coords[0], &local_coords[1]};
288 data_ptr->localCoords.resize(nb_eval_points, 2);
290 &(data_ptr->localCoords(0, 0)), &(data_ptr->localCoords(0, 1))};
291
292 for (int n = 0; n != nb_eval_points; ++n) {
293
294 const double eps = data_ptr->eps;
295 if (t_shape(0) >= 0 - eps && t_shape(0) <= 1 + eps &&
296
297 t_shape(1) >= 0 - eps && t_shape(1) <= 1 + eps &&
298
299 t_shape(2) >= 0 - eps && t_shape(2) <= 1 + eps) {
300
301 data_ptr->evalPointEntityHandle[n] = tet;
302 t_shape_data(i3) = t_shape(i3);
303 t_local_data(j2) = t_local(j2);
304 }
305
306 ++t_shape;
307 ++t_shape_data;
308 ++t_local;
309 ++t_local_data;
310 }
311 }
312 }
313
314 const Problem *prb_ptr;
315 CHKERR m_field.get_problem(problem, &prb_ptr);
316 boost::shared_ptr<NumeredEntFiniteElement_multiIndex> numered_fes(
318
319 Range in_tets;
320 in_tets.insert_list(data_ptr->evalPointEntityHandle.begin(),
321 data_ptr->evalPointEntityHandle.end());
322 in_tets = in_tets.subset_by_dimension(D);
323
324 if (verb >= NOISY)
325 MOFEM_LOG("SELF", Sev::noisy) << "in tets: " << in_tets << endl;
326
327 auto fe_miit =
328 m_field.get_finite_elements()->get<FiniteElement_name_mi_tag>().find(
329 finite_element);
330 if (fe_miit !=
331 m_field.get_finite_elements()->get<FiniteElement_name_mi_tag>().end()) {
332
333 for (auto peit = in_tets.pair_begin(); peit != in_tets.pair_end(); ++peit) {
334
335 auto lo =
336 prb_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>().lower_bound(
338 peit->first, (*fe_miit)->getFEUId()));
339 auto hi =
340 prb_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>().upper_bound(
342 peit->second, (*fe_miit)->getFEUId()));
343 numered_fes->insert(lo, hi);
344
345 if (verb >= VERY_NOISY)
346 std::cerr << "numered elements:" << std::endl;
347 for (; lo != hi; ++lo)
348 if (verb >= VERY_NOISY)
349 std::cerr << **lo << endl;
350 }
351 if (verb >= VERY_NOISY)
352 std::cerr << std::endl;
353
354 if (auto fe_ptr = data_ptr->feMethodPtr.lock()) {
355
356 MOFEM_LOG_C("FieldEvaluatorSync", Sev::verbose,
357 "Number elements %d to evaluate at proc %d",
358 numered_fes->size(), m_field.get_comm_rank());
360
361 if (!cache_ptr) {
362 cache_ptr = boost::make_shared<CacheTuple>();
363 CHKERR m_field.cache_problem_entities(prb_ptr->getName(), cache_ptr);
364
365 MOFEM_LOG("FieldEvaluatorSync", Sev::noisy)
366 << "If you call that function many times in the loop consider to "
367 "set "
368 "cache_ptr outside of the loop. Otherwise code can be slow.";
369 }
370
371 CHKERR m_field.loop_finite_elements(prb_ptr, finite_element, *fe_ptr,
372 lower_rank, upper_rank, numered_fes,
373 bh, cache_ptr, verb);
374
375 } else
376 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
377 "Pointer to element does not exists");
378 }
379
381}
382
383template <>
385 const double *const point, const double distance, const std::string problem,
386 const std::string finite_element, boost::shared_ptr<SetPtsData> data_ptr,
387 int lower_rank, int upper_rank, boost::shared_ptr<CacheTuple> cache_ptr,
388 MoFEMTypes bh, VERBOSITY_LEVELS verb) {
389 return evalFEAtThePointImpl<2>(point, distance, problem, finite_element,
390 data_ptr, lower_rank, upper_rank, cache_ptr,
391 bh, verb);
392}
393
394template <>
396 const double *const point, const double distance, const std::string problem,
397 const std::string finite_element, boost::shared_ptr<SetPtsData> data_ptr,
398 int lower_rank, int upper_rank, boost::shared_ptr<CacheTuple> cache_ptr,
399 MoFEMTypes bh, VERBOSITY_LEVELS verb) {
400 return evalFEAtThePointImpl<3>(point, distance, problem, finite_element,
401 data_ptr, lower_rank, upper_rank, cache_ptr,
402 bh, verb);
403}
404
406 const double *const point, const double distance, const std::string problem,
407 const std::string finite_element, boost::shared_ptr<SetPtsData> data_ptr,
408 int lower_rank, int upper_rank, boost::shared_ptr<CacheTuple> cache_ptr,
409 MoFEMTypes bh, VERBOSITY_LEVELS verb) {
410 return evalFEAtThePoint<3>(point, distance, problem, finite_element, data_ptr,
411 lower_rank, upper_rank, cache_ptr, bh, verb);
412}
413
415 const double *const point, const double distance, const std::string problem,
416 const std::string finite_element, boost::shared_ptr<SetPtsData> data_ptr,
417 int lower_rank, int upper_rank, boost::shared_ptr<CacheTuple> cache_ptr,
418 MoFEMTypes bh, VERBOSITY_LEVELS verb) {
419 return evalFEAtThePoint<2>(point, distance, problem, finite_element, data_ptr,
420 lower_rank, upper_rank, cache_ptr, bh, verb);
421}
422
423} // namespace MoFEM
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
static const double eps
VERBOSITY_LEVELS
Verbosity levels.
@ NOISY
@ VERY_NOISY
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
multi_index_container< boost::shared_ptr< NumeredEntFiniteElement >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< NumeredEntFiniteElement::interface_type_EntFiniteElement, UId, &NumeredEntFiniteElement::getLocalUniqueId > >, ordered_non_unique< tag< Part_mi_tag >, member< NumeredEntFiniteElement, unsigned int, &NumeredEntFiniteElement::part > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< NumeredEntFiniteElement::interface_type_RefEntity, EntityHandle, &NumeredEntFiniteElement::getEnt > >, ordered_non_unique< tag< Composite_Name_And_Part_mi_tag >, composite_key< NumeredEntFiniteElement, const_mem_fun< NumeredEntFiniteElement::interface_type_FiniteElement, boost::string_ref, &NumeredEntFiniteElement::getNameRef >, member< NumeredEntFiniteElement, unsigned int, &NumeredEntFiniteElement::part > > > > > NumeredEntFiniteElement_multiIndex
MultiIndex for entities for NumeredEntFiniteElement.
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual const FiniteElement_multiIndex * get_finite_elements() const =0
Get the finite elements object.
virtual EntityHandle get_finite_element_meshset(const std::string name) const =0
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
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.
FTensor::Index< 'i', SPACE_DIM > i
double D
const double n
refractive index of diffusive medium
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
auto type_from_handle(const EntityHandle h)
get type from entity handle
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode cache_problem_entities(const std::string prb_name, CacheTupleWeakPtr cache_ptr)=0
Cache variables.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Core (interface) class.
Definition Core.hpp:82
UId getLocalUniqueIdCalculate() const
Generate UId for finite element entity.
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
boost::weak_ptr< SetPtsData > dataPtr
Field evaluator interface.
DEPRECATED MoFEMErrorCode buildTree3D(boost::shared_ptr< SetPtsData > spd_ptr, const std::string finite_element)
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
DEPRECATED MoFEMErrorCode buildTree2D(boost::shared_ptr< SetPtsData > spd_ptr, const std::string finite_element)
MoFEMErrorCode evalFEAtThePointImpl(const double *const point, const double distance, const std::string problem, const std::string finite_element, boost::shared_ptr< SetPtsData > data_ptr, int lower_rank, int upper_rank, boost::shared_ptr< CacheTuple > cache_ptr, MoFEMTypes bh=MF_EXIST, VERBOSITY_LEVELS verb=QUIET)
DEPRECATED MoFEMErrorCode evalFEAtThePoint2D(const double *const point, const double distance, const std::string problem, const std::string finite_element, boost::shared_ptr< SetPtsData > data_ptr, int lower_rank, int upper_rank, boost::shared_ptr< CacheTuple > cache_ptr, MoFEMTypes bh=MF_EXIST, VERBOSITY_LEVELS verb=QUIET)
FieldEvaluatorInterface(const MoFEM::Core &core)
MoFEMErrorCode buildTreeImpl(boost::shared_ptr< SetPtsData > spd_ptr, const std::string finite_element)
DEPRECATED MoFEMErrorCode evalFEAtThePoint3D(const double *const point, const double distance, const std::string problem, const std::string finite_element, boost::shared_ptr< SetPtsData > data_ptr, int lower_rank, int upper_rank, boost::shared_ptr< CacheTuple > cache_ptr, MoFEMTypes bh=MF_EXIST, VERBOSITY_LEVELS verb=QUIET)
MoFEMErrorCode buildTree(boost::shared_ptr< SetPtsData > spd_ptr, const std::string finite_element)
Build spatial tree.
MoFEMErrorCode evalFEAtThePoint(const double *const point, const double distance, const std::string problem, const std::string finite_element, boost::shared_ptr< SetPtsData > 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 artbitray position.
structure to get information form mofem into EntitiesFieldData
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
static bool checkIfChannelExist(const std::string channel)
Check if channel exist.
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
keeps basic data about problem
boost::shared_ptr< NumeredEntFiniteElement_multiIndex > numeredFiniteElementsPtr
store finite elements
static MoFEMErrorCode getLocalCoordinatesOnReferenceFourNodeTet(const double *elem_coords, const double *glob_coords, const int nb_nodes, double *local_coords)
Get the local coordinates on reference four node tet object.
Definition Tools.cpp:88
static MoFEMErrorCode getLocalCoordinatesOnReferenceThreeNodeTri(const double *elem_coords, const double *glob_coords, const int nb_nodes, double *local_coords)
Get the local coordinates on reference three node tri object.
Definition Tools.cpp:188
static MoFEMErrorCode shapeFunMBTET(double *shape, const double *ksi, const double *eta, const double *zeta, const double nb)
Calculate shape functions on tetrahedron.
Definition Tools.hpp:747
static MoFEMErrorCode shapeFunMBTRI(double *shape, const double *ksi, const double *eta, const int nb)
Calculate shape functions on triangle.
Definition Tools.hpp:716
base class for all interface classes