v0.13.1
FieldEntsMultiIndices.hpp
Go to the documentation of this file.
1/** \file FieldEntsMultiIndices.hpp
2 * \brief Multi-index contains, for mofem entities data structures and other
3 * low-level functions
4 */
5
6
7
8#ifndef __FIELD_ENTSMULTIINDICES_HPP__
9#define __FIELD_ENTSMULTIINDICES_HPP__
10
11namespace MoFEM {
12
13struct EntityCacheDofs;
15
17 virtual ~EntityStorage() = default;
18};
19
20/**
21 * \brief Struct keeps handle to entity in the field.
22 * \ingroup ent_multi_indices
23 */
24struct FieldEntity : public interface_Field<Field, RefEntity> {
25
28
29 UId localUId; ///< Global unique id for this entity
30
31 FieldEntity(const boost::shared_ptr<Field> field_ptr,
32 const boost::shared_ptr<RefEntity> ref_ents_ptr,
33 boost::shared_ptr<double *const> field_data_adaptor_ptr,
34 boost::shared_ptr<const int> t_max_order_ptr);
35
36 virtual ~FieldEntity() = default;
37
38 /**
39 * \brief Get number of active DOFs on entity
40 * @return Number of DOFs
41 */
42 inline int getNbDofsOnEnt() const {
43 return getOrderNbDofs(getMaxOrder()) * this->getNbOfCoeffs();
44 }
45
46 /**
47 * @brief Return shared pointer to entity field data vector adaptor
48 *
49 * @return boost::shared_ptr<VectorAdaptor>
50 */
51 static boost::shared_ptr<FieldData *const> makeSharedFieldDataAdaptorPtr(
52 const boost::shared_ptr<Field> &field_ptr,
53 const boost::shared_ptr<RefEntity> &ref_ents_ptr);
54
55 /**
56 * @brief Get shared ptr to vector adaptor pointing to the field tag data on
57 * entity
58 *
59 * @return boost::shared_ptr<VectorAdaptor>&
60 */
61 inline boost::shared_ptr<FieldData *const> &getEntFieldDataPtr() const {
63 }
64
65 /**
66 * \brief Get vector of DOFs active values on entity
67 * @return Vector of DOFs values
68 */
71 }
72
73 /**
74 * \brief Get number of DOFs on entity for given order of approximation
75 * @param order Order of approximation
76 * @return Number of DOFs
77 */
79 return (this->getFieldRawPtr()->forderTable[this->getEntType()])(order);
80 }
81
82 /**
83 * \brief Get difference of number of DOFs between order and order-1
84 * @param order Approximation order
85 * @return Difference number of DOFs
86 */
89 }
90
91 /**
92 * \brief Get pinter to Tag keeping approximation order
93 * @return Pointer to Tag
94 */
95 inline const ApproximationOrder *getMaxOrderPtr() const {
96 return tagMaxOrderPtr.get();
97 }
98
99 /**
100 * \brief Get order set to the entity (Allocated tag size for such number)
101 * @return Approximation order
102 */
104 return *tagMaxOrderPtr.get();
105 }
106
107 /**
108 * @brief Get the Local Unique Id Calculate
109 *
110 * @param bit_number
111 * @param handle
112 * @return UId
113 */
114 static inline UId getLocalUniqueIdCalculate(const char bit_number,
115 const EntityHandle handle) {
116 return
117
118 (static_cast<UId>(handle) << proc_shift | static_cast<UId>(bit_number)
120 << dof_shift;
121 }
122
123 /**
124 * @brief Get the Local Unique Id Calculate object
125 *
126 * @return UId
127 */
129 return getLocalUniqueIdCalculate(this->getBitNumber(), this->getEnt());
130 }
131
132 /**
133 * \brief Get global unique id
134 * @return Global UId
135 */
137
138 /**
139 * \brief Get global unique id
140 * @return Global UId
141 */
142 const UId &getLocalUniqueId() const { return localUId; }
143
144 /**
145 * \brief Calculate UId for field entity
146 *
147 * UId is constructed such that all DOFs are ordered by processor, entity,
148 * field.
149 *
150 * UId is 128 bit
151 *
152 * @param owner_proc owning processor
153 * @param bit_number field bit number
154 * @param moab_owner_handle entity handle on owning processor
155 * meshes
156 * @return UId
157 */
158 static inline UId
159 getGlobalUniqueIdCalculate(const int owner_proc, const char bit_number,
160 const EntityHandle moab_owner_handle) {
161 return
162
163 (static_cast<UId>(owner_proc) |
164 static_cast<UId>(moab_owner_handle) << proc_shift |
165 static_cast<UId>(bit_number) << proc_shift + ent_shift)
166 << dof_shift;
167 }
168
169 static inline auto getOwnerFromUniqueId(const UId uid) {
170 constexpr int proc_mask = MAX_PROCESSORS_NUMBER - 1;
171 return static_cast<int>(
172
173 (uid & getGlobalUniqueIdCalculate(proc_mask, 0, 0)) >> dof_shift
174
175 );
176 };
177
178 static inline auto getHandleFromUniqueId(const UId uid) {
179 constexpr EntityHandle handle_mask = ~(EntityHandle(0));
180 return static_cast<EntityHandle>(
181 (uid & getGlobalUniqueIdCalculate(0, 0, handle_mask)) >> proc_shift >>
182 dof_shift);
183 };
184
185 static inline auto getFieldBitNumberFromUniqueId(const UId uid) {
186 constexpr int bit_field_mask = ~(char(0));
187 return static_cast<char>(
188 (uid & getGlobalUniqueIdCalculate(0, bit_field_mask, 0)) >>
190 };
191
192 /**
193 * \brief Calculate global UId
194 * @return Global UId
195 */
198 this->getBitNumber(),
199 this->getRefEntityPtr()->getOwnerEnt());
200 }
201
202 static inline UId getLoBitNumberUId(const FieldBitNumber bit_number) {
203 return
204
205 static_cast<UId>(bit_number) << dof_shift + ent_shift + proc_shift;
206 }
207
208 static inline UId getHiBitNumberUId(const FieldBitNumber bit_number) {
209 return static_cast<UId>(MAX_DOFS_ON_ENTITY - 1) |
210 static_cast<UId>(MAX_PROCESSORS_NUMBER - 1) << dof_shift |
211 static_cast<UId>(std::numeric_limits<EntityHandle>::max())
212 << dof_shift + proc_shift |
213 static_cast<UId>(bit_number) << dof_shift + ent_shift + proc_shift;
214 }
215
216 static inline UId getLoFieldEntityUId(const UId &uid) {
217 return ((~static_cast<UId>(MAX_DOFS_ON_ENTITY - 1)) & uid);
218 }
219
220 static inline UId getHiFieldEntityUId(const UId &uid) {
221 return getLoFieldEntityUId(uid) | static_cast<UId>(MAX_DOFS_ON_ENTITY - 1);
222 }
223
224 template <typename T> void getLoFieldEntityUId(T &uid) = delete;
225 template <typename T> void getHiFieldEntityUId(T &uid) = delete;
226
227 static inline UId getLoLocalEntityBitNumber(const char bit_number,
228 const EntityHandle ent) {
230
231 bit_number,
232
233 ent
234
235 );
236 }
237
238 static inline UId getHiLocalEntityBitNumber(const char bit_number,
239 const EntityHandle ent) {
240 return getLoLocalEntityBitNumber(bit_number, ent) |
241 static_cast<UId>(MAX_DOFS_ON_ENTITY - 1);
242 }
243
244 /**
245 * \brief get hash-map relating dof index on entity with its order
246 *
247 * DOFs of given field are indexed on entity
248 * of the same type, same space, approximation base and number of
249 * coefficients, are sorted in the way.
250 *
251 */
252 inline const std::array<int, MAX_DOFS_ON_ENTITY> &getDofOrderMap() const {
253 return this->getFieldRawPtr()->getDofOrderMap(this->getEntType());
254 }
255
256 friend std::ostream &operator<<(std::ostream &os, const FieldEntity &e);
257
258 mutable boost::weak_ptr<EntityCacheDofs> entityCacheDataDofs;
259 mutable boost::weak_ptr<EntityCacheNumeredDofs> entityCacheRowDofs;
260 mutable boost::weak_ptr<EntityCacheNumeredDofs> entityCacheColDofs;
261
262 /**
263 * @brief Get the Weak Storage pointer
264 *
265 * @return boost::weak_ptr<EntityStorage>&
266 */
267 template <typename T = EntityStorage>
268 inline boost::shared_ptr<T> getSharedStoragePtr() const {
269 return boost::dynamic_pointer_cast<T>(weakStoragePtr.lock());
270 }
271
272 inline boost::weak_ptr<EntityStorage> &getWeakStoragePtr() const {
273 return weakStoragePtr;
274 }
275
276 mutable boost::weak_ptr<EntityStorage> weakStoragePtr;
277
278private:
279 mutable boost::shared_ptr<const ApproximationOrder> tagMaxOrderPtr;
280 mutable boost::shared_ptr<FieldData *const> fieldDataAdaptorPtr;
281 static constexpr int dof_shift = 9; // Maximal number of DOFs on entity
282 static constexpr int ent_shift = 64; // EntityHandle size
283 static constexpr int proc_shift = 10; // Maximal number of 1024 processors
284};
285
286template <>
287inline boost::shared_ptr<EntityStorage>
288FieldEntity::getSharedStoragePtr<EntityStorage>() const {
289 return weakStoragePtr.lock();
290}
291
292/**
293 * \brief Interface to FieldEntity
294 * \ingroup ent_multi_indices
295 *
296 * interface to FieldEntity
297 */
298template <typename T>
300
301 interface_FieldEntity(const boost::shared_ptr<T> &sptr)
302 : interface_Field<T, T>(sptr) {}
303
304 /// @return get number of dofs on entity
305 inline int getNbDofsOnEnt() const { return this->sPtr->getNbDofsOnEnt(); }
306
307 /// @return get field data on entity
309 return this->sPtr->getEntFieldData();
310 }
311
312 /// @return get number of DOFs for given order
314 return this->sPtr->getOrderNbDofs(order);
315 }
316
317 /// @return get increase of DOFs by increase to this order
319 return this->sPtr->getOrderNbDofsDiff(order);
320 }
321
322 /// @return get maximal order on entity
324 return this->sPtr->getMaxOrder();
325 }
326
327 /// @return get entity UId
328 inline UId getGlobalUniqueId() const {
329 return this->sPtr->getGlobalUniqueId();
330 }
331
332 /// @return get entity UId
333 inline UId &getLocalUniqueId() const {
334 return this->sPtr->getLocalUniqueId();
335 }
336
337 /// @return return pointer to reference entity data structure
338 inline boost::shared_ptr<RefEntity> &getRefEntityPtr() const {
339 return this->sPtr->getRefEntityPtr();
340 }
341
342 /// @return get pointer to mofem entity data structure
343 inline boost::shared_ptr<FieldEntity> &getFieldEntityPtr() const {
344 return this->sPtr;
345 };
346
347 /**
348 * \brief get hash-map relating dof index on entity with its order
349 *
350 * DOFs of given field are indexed on entity
351 * of the same type, same space, approximation base and number of
352 * coefficients, are sorted in the way.
353 *
354 */
355 inline const std::array<int, MAX_DOFS_ON_ENTITY> &getDofOrderMap() const {
356 return this->sPtr->getDofOrderMap();
357 }
358
359 /// @copydoc FieldEntity::getSharedStoragePtr
360 template <typename S = EntityStorage>
361 inline boost::shared_ptr<S> getSharedStoragePtr() const {
362 return this->sPtr->template getSharedStoragePtr<S>();
363 }
364
365 inline boost::weak_ptr<EntityStorage> &getWeakStoragePtr() const {
366 return this->sPtr->getWeakStoragePtr();
367 }
368};
369
370/**
371 * \brief structure to change FieldEntity order
372 * \ingroup ent_multi_indices
373 */
375
377 const bool reduce_tag_size = false)
378 : order(order), reduceTagSize(reduce_tag_size) {}
379 inline void operator()(boost::shared_ptr<FieldEntity> &e) {
380 (*this)(e.get());
381 }
382 void operator()(FieldEntity *e);
383
384private:
386 const bool reduceTagSize;
387 std::vector<FieldData> data;
388};
389
390/**
391 * @relates multi_index_container
392 * \brief MultiIndex container keeps FieldEntity
393 * \ingroup ent_multi_indices
394 *
395 */
396using FieldEntity_multiIndex = multi_index_container<
397 boost::shared_ptr<FieldEntity>,
398 indexed_by<
399 ordered_unique<tag<Unique_mi_tag>,
400 member<FieldEntity, UId, &FieldEntity::localUId>>,
401 ordered_non_unique<tag<Ent_mi_tag>,
403 EntityHandle, &FieldEntity::getEnt>>
404
405 >>;
406
407/** \brief Entity index by field name
408 *
409 * \ingroup ent_multi_indices
410 */
412
413/** \brief multi-index view on DofEntity by uid
414 \ingroup dof_multi_indices
415*/
416using FieldEntity_multiIndex_global_uid_view = multi_index_container<
417 boost::shared_ptr<FieldEntity>,
418 indexed_by<
419
420 ordered_unique<
421 tag<Unique_mi_tag>,
422 const_mem_fun<FieldEntity, UId, &FieldEntity::getGlobalUniqueId>>
423
424 >>;
425
426using FieldEntity_multiIndex_ent_view = multi_index_container<
427 boost::shared_ptr<FieldEntity>,
428 indexed_by<
429
430 sequenced<>,
431
432 ordered_non_unique<tag<Ent_mi_tag>,
434 EntityHandle, &FieldEntity::getEnt>>
435
436 >>;
437
438using FieldEntity_multiIndex_spaceType_view = multi_index_container<
439 boost::shared_ptr<FieldEntity>,
440 indexed_by<
441
442 sequenced<>,
443
444 ordered_non_unique<
445 tag<Composite_EntType_and_Space_mi_tag>,
446 composite_key<FieldEntity,
447
450
453
454 >>
455
456 >>;
457
458typedef std::vector<boost::weak_ptr<FieldEntity>> FieldEntity_vector_view;
459
460using FieldEntity_multiIndex = multi_index_container<
461 boost::shared_ptr<FieldEntity>,
462 indexed_by<
463 ordered_unique<tag<Unique_mi_tag>,
464 member<FieldEntity, UId, &FieldEntity::localUId>>,
465 ordered_non_unique<tag<Ent_mi_tag>,
467 EntityHandle, &FieldEntity::getEnt>>
468
469 >>;
470
471} // namespace MoFEM
472
473#endif // __FIELD_ENTSMULTIINDICES_HPP__
474
475/**
476 * \defgroup ent_multi_indices Entities structures and multi-indices
477 * \ingroup mofem
478 **/
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
Definition: definitions.h:236
#define MAX_PROCESSORS_NUMBER
Maximal number of processors.
Definition: definitions.h:237
FieldSpace
approximation spaces
Definition: definitions.h:82
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< FieldEntity, UId, &FieldEntity::getGlobalUniqueId > > > > FieldEntity_multiIndex_global_uid_view
multi-index view on DofEntity by uid
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, member< FieldEntity, UId, &FieldEntity::localUId > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity::interface_type_RefEntity, EntityHandle, &FieldEntity::getEnt > > > > FieldEntity_multiIndex
MultiIndex container keeps FieldEntity.
FieldEntity_multiIndex::index< Unique_mi_tag >::type FieldEntityByUId
Entity index by field name.
const double T
int ApproximationOrder
Approximation on the entity.
Definition: Types.hpp:26
VectorShallowArrayAdaptor< double > VectorAdaptor
Definition: Types.hpp:115
uint128_t UId
Unique Id.
Definition: Types.hpp:31
char FieldBitNumber
Field bit number.
Definition: Types.hpp:28
implementation of Data Operators for Forces and Sources
Definition: MoFEM.hpp:24
auto getVectorAdaptor(T1 ptr, const size_t n)
Get Vector adaptor.
Definition: Templates.hpp:31
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< sequenced<>, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity::interface_type_RefEntity, EntityHandle, &FieldEntity::getEnt > > > > FieldEntity_multiIndex_ent_view
std::vector< boost::weak_ptr< FieldEntity > > FieldEntity_vector_view
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< sequenced<>, ordered_non_unique< tag< Composite_EntType_and_Space_mi_tag >, composite_key< FieldEntity, const_mem_fun< FieldEntity::interface_type_RefEntity, EntityType, &FieldEntity::getEntType >, const_mem_fun< FieldEntity::interface_type_Field, FieldSpace, &FieldEntity::getSpace > > > > > FieldEntity_multiIndex_spaceType_view
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, member< FieldEntity, UId, &FieldEntity::localUId > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity::interface_type_RefEntity, EntityHandle, &FieldEntity::getEnt > > > > FieldEntity_multiIndex
virtual ~EntityStorage()=default
structure to change FieldEntity order
FieldEntity_change_order(const ApproximationOrder order, const bool reduce_tag_size=false)
void operator()(boost::shared_ptr< FieldEntity > &e)
Struct keeps handle to entity in the field.
static constexpr int dof_shift
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
friend std::ostream & operator<<(std::ostream &os, const FieldEntity &e)
static auto getHandleFromUniqueId(const UId uid)
static auto getFieldBitNumberFromUniqueId(const UId uid)
int getOrderNbDofsDiff(ApproximationOrder order) const
Get difference of number of DOFs between order and order-1.
int getNbDofsOnEnt() const
Get number of active DOFs on entity.
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
static UId getHiFieldEntityUId(const UId &uid)
boost::shared_ptr< FieldData *const > fieldDataAdaptorPtr
static boost::shared_ptr< FieldData *const > makeSharedFieldDataAdaptorPtr(const boost::shared_ptr< Field > &field_ptr, const boost::shared_ptr< RefEntity > &ref_ents_ptr)
Return shared pointer to entity field data vector adaptor.
static UId getLoBitNumberUId(const FieldBitNumber bit_number)
static constexpr int proc_shift
static UId getLoLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
boost::shared_ptr< FieldData *const > & getEntFieldDataPtr() const
Get shared ptr to vector adaptor pointing to the field tag data on entity.
boost::weak_ptr< EntityStorage > & getWeakStoragePtr() const
boost::weak_ptr< EntityCacheDofs > entityCacheDataDofs
FieldEntity(const boost::shared_ptr< Field > field_ptr, const boost::shared_ptr< RefEntity > ref_ents_ptr, boost::shared_ptr< double *const > field_data_adaptor_ptr, boost::shared_ptr< const int > t_max_order_ptr)
interface_Field< Field, RefEntity > interface_type_Field
ApproximationOrder getMaxOrder() const
Get order set to the entity (Allocated tag size for such number)
const ApproximationOrder * getMaxOrderPtr() const
Get pinter to Tag keeping approximation order.
interface_RefEntity< RefEntity > interface_type_RefEntity
void getHiFieldEntityUId(T &uid)=delete
UId localUId
Global unique id for this entity.
static UId getGlobalUniqueIdCalculate(const int owner_proc, const char bit_number, const EntityHandle moab_owner_handle)
Calculate UId for field entity.
void getLoFieldEntityUId(T &uid)=delete
static constexpr int ent_shift
static UId getLoFieldEntityUId(const UId &uid)
boost::weak_ptr< EntityCacheNumeredDofs > entityCacheRowDofs
const UId & getLocalUniqueId() const
Get global unique id.
boost::weak_ptr< EntityCacheNumeredDofs > entityCacheColDofs
boost::weak_ptr< EntityStorage > weakStoragePtr
int getOrderNbDofs(ApproximationOrder order) const
Get number of DOFs on entity for given order of approximation.
virtual ~FieldEntity()=default
static UId getLocalUniqueIdCalculate(const char bit_number, const EntityHandle handle)
Get the Local Unique Id Calculate.
UId getGlobalUniqueId() const
Get global unique id.
static UId getHiLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
static auto getOwnerFromUniqueId(const UId uid)
const std::array< int, MAX_DOFS_ON_ENTITY > & getDofOrderMap() const
get hash-map relating dof index on entity with its order
VectorAdaptor getEntFieldData() const
Get vector of DOFs active values on entity.
boost::shared_ptr< const ApproximationOrder > tagMaxOrderPtr
UId getGlobalUniqueIdCalculate() const
Calculate global UId.
boost::shared_ptr< T > getSharedStoragePtr() const
Get the Weak Storage pointer.
const std::array< ApproximationOrder, MAX_DOFS_ON_ENTITY > & getDofOrderMap(const EntityType type) const
get hash-map relating dof index on entity with its order
interface_FieldEntity(const boost::shared_ptr< T > &sptr)
const std::array< int, MAX_DOFS_ON_ENTITY > & getDofOrderMap() const
get hash-map relating dof index on entity with its order
boost::weak_ptr< EntityStorage > & getWeakStoragePtr() const
int getOrderNbDofsDiff(ApproximationOrder order) const
boost::shared_ptr< S > getSharedStoragePtr() const
Get the Weak Storage pointer.
boost::shared_ptr< FieldEntity > & getFieldEntityPtr() const
int getOrderNbDofs(ApproximationOrder order) const
ApproximationOrder getMaxOrder() const
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
FieldCoefficientsNumber getNbOfCoeffs() const
EntityType getEntType() const
Get entity type.
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
EntityHandle getEnt() const
Get the entity handle.