v0.13.2
Loading...
Searching...
No Matches
MeshProjectionDataOperators.hpp
Go to the documentation of this file.
1/** \file MeshProjectionDataOperators.hpp
2 * \brief Mesh projection operators
3
4*/
5
6#ifndef __MESH_PROJECTION_DATA_OPERATORS_HPP__
7#define __MESH_PROJECTION_DATA_OPERATORS_HPP__
8
9namespace MoFEM {
10
11/**
12 * @brief Operator to execute finite element instance on parent element.
13 * This operator is typically used to project field from parent to child, or
14 * vice versa. It enables to evaluate filed data of parent entity on chile
15 * entity integration points.
16 */
18
19 /**
20 * @brief Construct a new Op Run Parent object
21 *
22 * @note Finite element instance usually has to be class which has overloaded
23 * method from projecting integration points from child tp parent.
24 *
25 * @note Typically parent_ele_ptr and bit_this_mask is the same instance
26 *
27 * @param parent_ele_ptr finite element instance executed on parent entity
28 * @param bit_parent bit of parent entity
29 * @param bit_parent_mask mask of parent entity
30 * @param this_ele_ptr "this" element instance
31 * @param bit_this bit of entity on which "this" finite element is executed
32 * @param bit_this_mask mask of entity on which "this" finite element instance
33 * is executed
34 * @param verb verbosity level
35 * @param sev logging severity level
36 */
37 OpRunParent(boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
38 BitRefLevel bit_parent, BitRefLevel bit_parent_mask,
39 boost::shared_ptr<ForcesAndSourcesCore> this_ele_ptr,
40 BitRefLevel bit_this, BitRefLevel bit_this_mask, int verb = QUIET,
41 Sev sev = Sev::noisy);
42
43 MoFEMErrorCode doWork(int side, EntityType type,
45
46private:
47 boost::shared_ptr<ForcesAndSourcesCore> parentElePtr;
48 boost::shared_ptr<ForcesAndSourcesCore> thisElePtr;
55};
56
57/**
58 * @brief Operator to project base functions from parent entity to child
59 *
60 * This operator project/collect base functions, field data (i.e. indices, field
61 * values of dofs, etc.), from parent element, into child. Operator can be
62 * called as a hierarchy to get access to information on lower refinement
63 * levels.
64 *
65 */
67
68 /**
69 * @brief Construct a new Op Add Parent Ent Data object
70 *
71 * @param field_name field name DOFs projected from parent
72 * @param op_parent_type type of user data operator
73 * @param parent_ele_ptr parent finite element instance
74 * @param bit_child bit of child finite element entity
75 * @param bit_child_mask bit mask of child child finite element
76 * @param bit_parent_ent bit of parent entity
77 * @param bit_parent_ent_mask bit mask of parent
78 * @param verb verbosity level
79 * @param sev severity level for logging
80 */
81 OpAddParentEntData(std::string field_name, OpType op_parent_type,
82 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
83 BitRefLevel bit_child, BitRefLevel bit_child_mask,
84 BitRefLevel bit_parent_ent,
85 BitRefLevel bit_parent_ent_mask, int verb = QUIET,
86 Sev sev = Sev::noisy);
87
88 /**
89 * @brief Construct a new Op Add Parent Ent Data object
90 *
91 * @param space field space
92 * @param op_parent_type type of user data operator
93 * @param parent_ele_ptr parent finite element instance
94 * @param bit_child bit of child entity
95 * @param bit_child_mask bit mask of child
96 * @param bit_parent_ent bit of parent entity
97 * @param bit_parent_ent_mask bit mask of parent
98 * @param verb verbosity level
99 * @param sev severity level for logging
100 */
101 OpAddParentEntData(FieldSpace space, OpType op_parent_type,
102 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
103 BitRefLevel bit_child, BitRefLevel bit_child_mask,
104 BitRefLevel bit_parent_ent,
105 BitRefLevel bit_parent_ent_mask, int verb = QUIET,
106 Sev sev = Sev::noisy);
107
109 const bool error_if_no_base = false);
110
111private:
112 std::string fieldName;
115 boost::shared_ptr<ForcesAndSourcesCore> parentElePtr;
122
123 boost::ptr_deque<EntitiesFieldData::EntData> poolEntsVector;
124};
125
126/**
127 * @brief Create adjacency to parent elements.
128 *
129 * That class is used during entity finite element construction.
130 *
131 * @tparam DIM dimension of parent element
132 */
133template <int DIM> struct ParentFiniteElementAdjacencyFunction {
134
136 BitRefLevel bit_parent_mask,
137 BitRefLevel bit_ent,
138 BitRefLevel bit_ent_mask)
139 : bitParent(bit_parent), bitParentMask(bit_parent_mask), bitEnt(bit_ent),
140 bitEntMask(bit_ent_mask) {}
141
142 /**
143 * @brief Function setting adjacencies to DOFs of parent element
144 *
145 * @note elements form child, see dofs from parent, so DOFs located on
146 * adjacencies of parent entity has adjacent to dofs of child.
147 *
148 * @tparam DIM dimension of the element entity
149 * @param moab
150 * @param field
151 * @param fe
152 * @param adjacency
153 * @return MoFEMErrorCode
154 */
155 MoFEMErrorCode operator()(moab::Interface &moab, const Field &field,
156 const EntFiniteElement &fe,
157 std::vector<EntityHandle> &adjacency) {
159
160 static_assert(DIM >= 0 && DIM <= 3, "DIM is out of scope");
161
162 adjacency.clear();
163
164 if (field.getSpace() != NOFIELD) {
165
166 auto basic_entity_data_ptr = fe.getBasicDataPtr();
167 auto th_parent_handle = basic_entity_data_ptr->th_RefParentHandle;
168 auto th_bit_level = basic_entity_data_ptr->th_RefBitLevel;
169
170 std::vector<EntityHandle> parents;
171 parents.reserve(BITREFLEVEL_SIZE);
172
173 CHKERR getParent(fe.getEnt(), parents, moab, th_parent_handle,
174 th_bit_level);
175
176 CHKERR getParentsAdjacencies(field, moab, parents, adjacency);
177 }
178
179 adjTmp.clear();
180 CHKERR getDefaultAdjacencies(moab, field, fe, adjTmp);
181 adjacency.insert(adjacency.end(), adjTmp.begin(), adjTmp.end());
182
183 std::sort(adjacency.begin(), adjacency.end());
184 auto it = std::unique(adjacency.begin(), adjacency.end());
185 adjacency.resize(std::distance(adjacency.begin(), it));
186
187 for (auto e : adjacency) {
188 auto &side_table = fe.getSideNumberTable();
189 if (side_table.find(e) == side_table.end())
190 const_cast<SideNumber_multiIndex &>(side_table)
191 .insert(boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
192 }
193
195 }
196
197protected:
198 MoFEMErrorCode getParent(EntityHandle fe, std::vector<EntityHandle> &parents,
199 moab::Interface &moab, Tag th_parent_handle,
200 Tag th_bit_level) {
202
203 auto check = [](auto &b, auto &m, auto &bit) {
204 return ((bit & b).any()) && ((bit & m) == bit);
205 };
206
207 BitRefLevel bit_fe;
208 CHKERR moab.tag_get_data(th_bit_level, &fe, 1, &bit_fe);
209 if (check(bitEnt, bitEntMask, bit_fe)) {
210
211 using GetParent = boost::function<MoFEMErrorCode(
212 EntityHandle fe, std::vector<EntityHandle> & parents)>;
213 /**
214 * @brief this function os called recursively, until all stack of parents
215 * is found.
216 *
217 */
218 GetParent get_parent = [&](EntityHandle fe,
219 std::vector<EntityHandle> &parents) {
221 EntityHandle fe_parent;
222
223 CHKERR moab.tag_get_data(th_parent_handle, &fe, 1, &fe_parent);
224 auto parent_type = type_from_handle(fe_parent);
225 auto back_type = type_from_handle(fe);
226 BitRefLevel bit_parent;
227 CHKERR moab.tag_get_data(th_bit_level, &fe_parent, 1, &bit_parent);
228 if (check(bitParent, bitParentMask, bit_parent)) {
229 if ((fe_parent != 0) && (fe_parent != fe) &&
230 (parent_type == back_type)) {
231 parents.push_back(fe_parent);
232 CHKERR get_parent(parents.back(), parents);
233 }
234 }
236 };
237
238 CHKERR get_parent(fe, parents);
239 }
241 }
242
244 moab::Interface &moab,
245 std::vector<EntityHandle> &parents,
246 std::vector<EntityHandle> &adjacency) {
248
249 switch (field.getSpace()) {
250 case H1:
251 for (int i = 0; i != parents.size(); ++i)
252 CHKERR moab.get_connectivity(&*parents.begin(), parents.size(),
253 adjacency, true);
254 case HCURL:
255 if constexpr (DIM >= 1)
256 for (auto fe_ent : parents)
257 CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
258 moab::Interface::UNION);
259 case HDIV:
260 if constexpr (DIM == 2)
261 for (auto fe_ent : parents)
262 CHKERR moab.get_adjacencies(&fe_ent, 1, 2, false, adjacency,
263 moab::Interface::UNION);
264 case L2:
265 for (auto fe_ent : parents)
266 adjacency.push_back(fe_ent);
267 break;
268 default:
269 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
270 "this field is not implemented for face finite element");
271 }
272
273 if (adjacency.size()) {
274 std::sort(adjacency.begin(), adjacency.end());
275 auto it = std::unique(adjacency.begin(), adjacency.end());
276 adjacency.resize(std::distance(adjacency.begin(), it));
277 }
278
280 }
281
283 const Field &field,
284 const EntFiniteElement &fe,
285 std::vector<EntityHandle> &adjacency) {
287 if constexpr (DIM == 3)
288 CHKERR DefaultElementAdjacency::defaultVolume(moab, field, fe, adjacency);
289 if constexpr (DIM == 2)
290 CHKERR DefaultElementAdjacency::defaultFace(moab, field, fe, adjacency);
291 else if constexpr (DIM == 1)
292 CHKERR DefaultElementAdjacency::defaultEdge(moab, field, fe, adjacency);
293 else if constexpr (DIM == 0)
294 CHKERR DefaultElementAdjacency::defaultVertex(moab, field, fe, adjacency);
296 };
297
302 std::vector<EntityHandle> adjTmp;
303};
304
305/**
306 * @brief Create adjacency to parent skeleton elements.
307 *
308 * That class is used during entity finite element construction.
309 *
310 * @tparam DIM dimension of parent element
311 */
312template <int DIM>
315
317 BitRefLevel bit_parent_mask,
318 BitRefLevel bit_ent,
319 BitRefLevel bit_ent_mask)
320 : ParentFiniteElementAdjacencyFunction<DIM>(bit_parent, bit_parent_mask,
321 bit_ent, bit_ent_mask) {}
322
323 /**
324 * @brief Function setting adjacencies to DOFs of parent element
325 *
326 * @note elements form child, see dofs from parent, so DOFs located on
327 * adjacencies of parent entity has adjacent to dofs of child.
328 *
329 * @tparam DIM dimension of the element entity
330 * @param moab
331 * @param field
332 * @param fe
333 * @param adjacency
334 * @return MoFEMErrorCode
335 */
336 MoFEMErrorCode operator()(moab::Interface &moab, const Field &field,
337 const EntFiniteElement &fe,
338 std::vector<EntityHandle> &adjacency) {
340
341 adjacency.clear();
342 CHKERR this->getDefaultAdjacencies(moab, field, fe, adjacency);
343
344 if (field.getSpace() != NOFIELD) {
345
346 const auto fe_ent = fe.getEnt();
347 brideAdjacencyEdge.clear();
348 CHKERR moab.get_adjacencies(&fe_ent, 1, DIM + 1, false,
350
351 std::vector<EntityHandle> parents;
352
353 if (this->bitParent.any()) {
354 auto basic_entity_data_ptr = fe.getBasicDataPtr();
355 auto th_parent_handle = basic_entity_data_ptr->th_RefParentHandle;
356 auto th_bit_level = basic_entity_data_ptr->th_RefBitLevel;
357 parents.reserve(BITREFLEVEL_SIZE);
358 for (auto bridge_fe : brideAdjacencyEdge) {
359 CHKERR this->getParent(bridge_fe, parents, moab, th_parent_handle,
360 th_bit_level);
361 };
362 parents.insert(parents.end(), brideAdjacencyEdge.begin(),
363 brideAdjacencyEdge.end());
364 } else {
365 parents.swap(brideAdjacencyEdge);
366 }
367
368 CHKERR this->getParentsAdjacencies(field, moab, parents, adjacency);
369
370 std::sort(adjacency.begin(), adjacency.end());
371 auto it = std::unique(adjacency.begin(), adjacency.end());
372 adjacency.resize(std::distance(adjacency.begin(), it));
373
374 for (auto e : adjacency) {
375 auto &side_table = fe.getSideNumberTable();
376 if (side_table.find(e) == side_table.end())
377 const_cast<SideNumber_multiIndex &>(side_table)
378 .insert(
379 boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
380 }
381 }
382
384 }
385
386protected:
387 std::vector<EntityHandle> brideAdjacencyEdge;
388};
389
390} // namespace MoFEM
391
392#endif //__MESH_PROJECTION_DATA_OPERATORS_HPP__
@ QUIET
Definition: definitions.h:208
#define BITREFLEVEL_SIZE
max number of refinements
Definition: definitions.h:219
FieldSpace
approximation spaces
Definition: definitions.h:82
@ L2
field with C-1 continuity
Definition: definitions.h:88
@ NOFIELD
scalar or vector of scalars describe (no true field)
Definition: definitions.h:84
@ H1
continuous field
Definition: definitions.h:85
@ HCURL
field with continuous tangents
Definition: definitions.h:86
@ HDIV
field with continuous normal traction
Definition: definitions.h:87
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
FTensor::Index< 'm', SPACE_DIM > m
multi_index_container< boost::shared_ptr< SideNumber >, indexed_by< ordered_unique< member< SideNumber, EntityHandle, &SideNumber::ent > >, ordered_non_unique< composite_key< SideNumber, const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType >, member< SideNumber, signed char, &SideNumber::side_number > > > > > SideNumber_multiIndex
SideNumber_multiIndex for SideNumber.
SeverityLevel
Severity levels.
Definition: LogManager.hpp:33
auto bit
set bit
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
auto type_from_handle(const EntityHandle h)
get type from entity handle
Definition: Templates.hpp:1634
constexpr auto field_name
static MoFEMErrorCode defaultVertex(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static MoFEMErrorCode defaultVolume(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static MoFEMErrorCode defaultEdge(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static MoFEMErrorCode defaultFace(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
Finite element data for entity.
Data on single entity (This is passed as argument to DataOperator::doWork)
data structure for finite element entity
Provide data structure for (tensor) field approximation.
FieldSpace getSpace() const
Get field approximation space.
OpType
Controls loop over entities on element.
Operator to project base functions from parent entity to child.
MoFEMErrorCode opRhs(EntitiesFieldData &data, const bool error_if_no_base=false)
boost::ptr_deque< EntitiesFieldData::EntData > poolEntsVector
boost::shared_ptr< ForcesAndSourcesCore > parentElePtr
Operator to execute finite element instance on parent element. This operator is typically used to pro...
boost::shared_ptr< ForcesAndSourcesCore > parentElePtr
boost::shared_ptr< ForcesAndSourcesCore > thisElePtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
MoFEMErrorCode operator()(moab::Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
Function setting adjacencies to DOFs of parent element.
MoFEMErrorCode getParent(EntityHandle fe, std::vector< EntityHandle > &parents, moab::Interface &moab, Tag th_parent_handle, Tag th_bit_level)
MoFEMErrorCode getParentsAdjacencies(const Field &field, moab::Interface &moab, std::vector< EntityHandle > &parents, std::vector< EntityHandle > &adjacency)
ParentFiniteElementAdjacencyFunction(BitRefLevel bit_parent, BitRefLevel bit_parent_mask, BitRefLevel bit_ent, BitRefLevel bit_ent_mask)
MoFEMErrorCode getDefaultAdjacencies(moab::Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
ParentFiniteElementAdjacencyFunctionSkeleton(BitRefLevel bit_parent, BitRefLevel bit_parent_mask, BitRefLevel bit_ent, BitRefLevel bit_ent_mask)
MoFEMErrorCode operator()(moab::Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
Function setting adjacencies to DOFs of parent element.
keeps information about side number for the finite element
SideNumber_multiIndex & getSideNumberTable() const
const boost::shared_ptr< BasicEntityData > getBasicDataPtr() const