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