v0.13.1
MeshProjectionDataOperators.hpp
Go to the documentation of this file.
1/** \file MeshProjectionDataOperators.hpp
2 * \brief Mesh projection operators
3
4*/
5
6
7
8#ifndef __MESH_PROJECTION_DATA_OPERATORS_HPP__
9#define __MESH_PROJECTION_DATA_OPERATORS_HPP__
10
11namespace MoFEM {
12
13/**
14 * @brief Operator to execute finite element instance on parent element.
15 * This operator is typically used to project field from parent to child, or
16 * vice versa. It enables to evaluate filed data of parent entity on chile
17 * entity integration points.
18 */
20
21 /**
22 * @brief Construct a new Op Run Parent object
23 *
24 * @note Finite element instance usually has to be class which has overloaded
25 * method from projevting integration points from child tp parent.
26 *
27 * @note Typically parent_ele_ptr and bit_this_mask is the same instance
28 *
29 * @param parent_ele_ptr finite element instance executed on parent entity
30 * @param bit_parent bit of parent entity
31 * @param bit_parent_mask mask of parent entity
32 * @param this_ele_ptr "this" element instance
33 * @param bit_this bit of entity on which "this" finite element is executed
34 * @param bit_this_mask mask of entity on which "this" finite element instance
35 * is executed
36 * @param verb verbosity level
37 * @param sev logging severity level
38 */
39 OpRunParent(boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
40 BitRefLevel bit_parent, BitRefLevel bit_parent_mask,
41 boost::shared_ptr<ForcesAndSourcesCore> this_ele_ptr,
42 BitRefLevel bit_this, BitRefLevel bit_this_mask, int verb = QUIET,
43 Sev sev = Sev::noisy);
44
47
48private:
49 boost::shared_ptr<ForcesAndSourcesCore> parentElePtr;
50 boost::shared_ptr<ForcesAndSourcesCore> thisElePtr;
57};
58
59/**
60 * @brief Operator to project base functions from parent entity
61 *
62 * This operator project base functions, field data (i.e. indices, field values
63 * of dofs, etc.), into parent element. Operator can be called as a hierarchy to
64 * get access to information on lower refinement levels.
65 *
66 */
68
69 /**
70 * @brief Construct a new Op Add Parent Ent Data object
71 *
72 * @param field_name field name DOFs projected from parent
73 * @param op_parent_type type of user data operator
74 * @param parent_ele_ptr parent finite element instance
75 * @param bit_child bit of child entity
76 * @param bit_child_mask bit mask of child
77 * @param bit_parent_ent bit of parent entity
78 * @param bit_parent_ent_mask bit mask of parent
79 * @param verb verbosity level
80 * @param sev severity level for logging
81 */
82 OpAddParentEntData(std::string field_name, OpType op_parent_type,
83 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
84 BitRefLevel bit_child, BitRefLevel bit_child_mask,
85 BitRefLevel bit_parent_ent,
86 BitRefLevel bit_parent_ent_mask, int verb = QUIET,
87 Sev sev = Sev::noisy);
88
89 /**
90 * @brief Construct a new Op Add Parent Ent Data object
91 *
92 * @param space field space
93 * @param op_parent_type type of user data operator
94 * @param parent_ele_ptr parent finite element instance
95 * @param bit_child bit of child entity
96 * @param bit_child_mask bit mask of child
97 * @param bit_parent_ent bit of parent entity
98 * @param bit_parent_ent_mask bit mask of parent
99 * @param verb verbosity level
100 * @param sev severity level for logging
101 */
102 OpAddParentEntData(FieldSpace space, OpType op_parent_type,
103 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
104 BitRefLevel bit_child, BitRefLevel bit_child_mask,
105 BitRefLevel bit_parent_ent,
106 BitRefLevel bit_parent_ent_mask, int verb = QUIET,
107 Sev sev = Sev::noisy);
108
110 const bool error_if_no_base = false);
111
112private:
113 std::string fieldName;
116 boost::shared_ptr<ForcesAndSourcesCore> parentElePtr;
123
124 boost::ptr_deque<EntitiesFieldData::EntData> poolEntsVector;
125};
126
127/**
128 * @brief Create adjacency to parent elements.
129 *
130 * That class is used during entity finite element construction.
131 *
132 * \todo this function has to be extended to take cases of integration on
133 * skeleton for hanging node cases.
134 *
135 * @tparam DIM dimension of parent element
136 */
137template <int DIM> struct ParentFiniteElementAdjacencyFunction {
138
140 BitRefLevel bit_parent_mask,
141 BitRefLevel bit_ent,
142 BitRefLevel bit_ent_mask)
143 : bitParent(bit_parent), bitParentMask(bit_parent_mask), bitEnt(bit_ent),
144 bitEntMask(bit_ent_mask) {}
145
146 /**
147 * @brief Function setting adjacencies to DOFs of parent element
148 *
149 * @note elements form child, see dofs from parent, so DOFs located on
150 * adjacencies of parent entity has adjacent to dofs of child.
151 *
152 * @tparam DIM dimension of the element entity
153 * @param moab
154 * @param field
155 * @param fe
156 * @param adjacency
157 * @return MoFEMErrorCode
158 */
160 const EntFiniteElement &fe,
161 std::vector<EntityHandle> &adjacency) {
163
164 static_assert(DIM >= 0 && DIM <= 3, "DIM is out of scope");
165
166 auto check = [](auto &b, auto &m, auto &bit) {
167 return ((bit & b).any()) && ((bit & m) == bit);
168 };
169
170 adjTmp.clear();
171
172 if (field.getSpace() != NOFIELD) {
173
174 auto basic_entity_data_ptr = fe.getBasicDataPtr();
175 auto th_parent_handle = basic_entity_data_ptr->th_RefParentHandle;
176 auto th_bit_level = basic_entity_data_ptr->th_RefBitLevel;
177
178 using GetParent = boost::function<MoFEMErrorCode(
179 EntityHandle fe, std::vector<EntityHandle> & parents)>;
180
181 /**
182 * @brief this function os called recursively, until all stack of parents
183 * is found.
184 *
185 */
186 GetParent get_parent = [&](EntityHandle fe,
187 std::vector<EntityHandle> &parents) {
189 EntityHandle fe_parent;
190
191 CHKERR moab.tag_get_data(th_parent_handle, &fe, 1, &fe_parent);
192 auto parent_type = type_from_handle(fe_parent);
193 auto back_type = type_from_handle(fe);
194 BitRefLevel bit_parent;
195 CHKERR moab.tag_get_data(th_bit_level, &fe_parent, 1, &bit_parent);
196 if (check(bitParent, bitParentMask, bit_parent)) {
197 if ((fe_parent != 0) && (fe_parent != fe) &&
198 (parent_type == back_type)) {
199 parents.push_back(fe_parent);
200 CHKERR get_parent(parents.back(), parents);
201 }
202 }
204 };
205
206 std::vector<EntityHandle> parents;
207 parents.reserve(BITREFLEVEL_SIZE);
208
209 CHKERR get_parent(fe.getEnt(), parents);
210
211 adjacency.clear();
212 switch (field.getSpace()) {
213 case H1:
214 for (auto fe_ent : parents)
215 CHKERR moab.get_adjacencies(&fe_ent, 1, 0, false, adjacency,
216 moab::Interface::UNION);
217 case HCURL:
218 if constexpr (DIM >= 2)
219 for (auto fe_ent : parents)
220 CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
221 moab::Interface::UNION);
222 case HDIV:
223 if constexpr (DIM == 3)
224 for (auto fe_ent : parents)
225 CHKERR moab.get_adjacencies(&fe_ent, 1, 2, false, adjacency,
226 moab::Interface::UNION);
227 case L2:
228 for (auto fe_ent : parents)
229 adjacency.push_back(fe_ent);
230 break;
231 default:
232 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
233 "this field is not implemented for face finite element");
234 }
235
236
237 if (adjacency.size()) {
238
239 std::sort(adjacency.begin(), adjacency.end());
240 auto it = std::unique(adjacency.begin(), adjacency.end());
241 adjacency.resize(std::distance(adjacency.begin(), it));
242 bitLevels.resize(adjacency.size());
243 CHKERR moab.tag_get_data(th_bit_level, &*adjacency.begin(),
244 adjacency.size(), &*bitLevels.begin());
245
246 adjTmp.reserve(adjacency.size());
247 for (int i = 0; i != adjacency.size(); ++i) {
248 if (check(bitEnt, bitEntMask, bitLevels[i])) {
249 adjTmp.push_back(adjacency[i]);
250 }
251 }
252 }
253 }
254
255 adjacency.clear();
256
257 if constexpr (DIM == 3)
258 CHKERR DefaultElementAdjacency::defaultVolume(moab, field, fe, adjacency);
259 if constexpr (DIM == 2)
260 CHKERR DefaultElementAdjacency::defaultFace(moab, field, fe, adjacency);
261 else if constexpr (DIM == 1)
262 CHKERR DefaultElementAdjacency::defaultEdge(moab, field, fe, adjacency);
263 else if constexpr (DIM == 0)
264 CHKERR DefaultElementAdjacency::defaultVertex(moab, field, fe, adjacency);
265
266 adjacency.insert(adjacency.end(), adjTmp.begin(), adjTmp.end());
267
268 std::sort(adjacency.begin(), adjacency.end());
269 auto it = std::unique(adjacency.begin(), adjacency.end());
270 adjacency.resize(std::distance(adjacency.begin(), it));
271
272 for (auto e : adjacency) {
273 auto &side_table = fe.getSideNumberTable();
274 if (side_table.find(e) == side_table.end())
275 const_cast<SideNumber_multiIndex &>(side_table)
276 .insert(boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
277 }
278
280}
281
286std::vector<EntityHandle> adjTmp;
287std::vector<BitRefLevel> bitLevels;
288};
289
290} // namespace MoFEM
291
292#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: MoFEM.hpp:24
auto type_from_handle(const EntityHandle h)
get type from entity handle
Definition: Templates.hpp:1473
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1955
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.
MoFEMErrorCode opRhs(EntitiesFieldData &data, const bool error_if_no_base=false)
boost::ptr_deque< EntitiesFieldData::EntData > poolEntsVector
boost::shared_ptr< ForcesAndSourcesCore > parentElePtr
OpAddParentEntData(std::string field_name, OpType op_parent_type, boost::shared_ptr< ForcesAndSourcesCore > parent_ele_ptr, BitRefLevel bit_child, BitRefLevel bit_child_mask, BitRefLevel bit_parent_ent, BitRefLevel bit_parent_ent_mask, int verb=QUIET, Sev sev=Sev::noisy)
Construct a new Op Add Parent Ent Data object.
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.
OpRunParent(boost::shared_ptr< ForcesAndSourcesCore > parent_ele_ptr, BitRefLevel bit_parent, BitRefLevel bit_parent_mask, boost::shared_ptr< ForcesAndSourcesCore > this_ele_ptr, BitRefLevel bit_this, BitRefLevel bit_this_mask, int verb=QUIET, Sev sev=Sev::noisy)
Construct a new Op Run Parent object.
MoFEMErrorCode operator()(moab::Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
Function setting adjacencies to DOFs of parent element.
ParentFiniteElementAdjacencyFunction(BitRefLevel bit_parent, BitRefLevel bit_parent_mask, BitRefLevel bit_ent, BitRefLevel bit_ent_mask)
keeps information about side number for the finite element
SideNumber_multiIndex & getSideNumberTable() const
const boost::shared_ptr< BasicEntityData > getBasicDataPtr() const
Get pointer to basic data struture.