v0.10.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;
27 struct EntityCacheNumeredDofs;
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  constexpr int dof_shift = 9; // Maximal number of DOFs on entity
130  constexpr int ent_shift = 64; // EntityHandle size
131  constexpr int proc_shift = 10; // Maximal number of 1024 processors
132  return
133 
134  (static_cast<UId>(handle) << proc_shift | static_cast<UId>(bit_number)
135  << proc_shift + ent_shift)
136  << dof_shift;
137  }
138 
139  /**
140  * @brief Get the Local Unique Id Calculate object
141  *
142  * @return UId
143  */
145  return getLocalUniqueIdCalculate(this->getBitNumber(), this->getEnt());
146  }
147 
148  /**
149  * \brief Get global unique id
150  * @return Global UId
151  */
153 
154  /**
155  * \brief Get global unique id
156  * @return Global UId
157  */
158  const UId &getLocalUniqueId() const { return localUId; }
159 
160  /**
161  * \brief Calculate UId for field entity
162  *
163  * UId is constructed such that all DOFs are ordered by processor, entity,
164  * field.
165  *
166  * UId is 128 bit
167  *
168  * @param owner_proc owning processor
169  * @param bit_number field bit number
170  * @param moab_owner_handle entity handle on owning processor
171  * meshes
172  * @return UId
173  */
174  static inline UId
175  getGlobalUniqueIdCalculate(const int owner_proc, const char bit_number,
176  const EntityHandle moab_owner_handle) {
177  constexpr int dof_shift = 9; // Maximal number of DOFs on entity
178  constexpr int ent_shift = 64; // EntityHandle size
179  constexpr int proc_shift = 10; // Maximal number of 1024 processors
180  return
181 
182  (static_cast<UId>(owner_proc) |
183  static_cast<UId>(moab_owner_handle) << proc_shift |
184  static_cast<UId>(bit_number) << proc_shift + ent_shift)
185  << dof_shift;
186  }
187 
188  /**
189  * \brief Calculate global UId
190  * @return Global UId
191  */
194  this->getBitNumber(),
195  this->getRefEntityPtr()->getOwnerEnt());
196  }
197 
198  static inline UId getLoBitNumberUId(const FieldBitNumber bit_number) {
199  constexpr int dof_shift = 9; // Maximal number of DOFs on entity
200  constexpr int ent_shift = 64; // EntityHandle size
201  constexpr int proc_shift = 10; // Maximal number of 1024 processors
202  return
203 
204  static_cast<UId>(bit_number) << dof_shift + ent_shift + proc_shift;
205  }
206 
207  static inline UId getHiBitNumberUId(const FieldBitNumber bit_number) {
208  constexpr int dof_shift = 9; // Maximal number of DOFs on entity
209  constexpr int ent_shift = 64; // EntityHandle size
210  constexpr int proc_shift = 10; // Maximal number of 1024 processors
211 
212  return static_cast<UId>(MAX_DOFS_ON_ENTITY - 1) |
213  static_cast<UId>(MAX_PROCESSORS_NUMBER - 1) << dof_shift |
214  static_cast<UId>(std::numeric_limits<EntityHandle>::max())
215  << dof_shift + proc_shift |
216  static_cast<UId>(bit_number) << dof_shift + ent_shift + proc_shift;
217  }
218 
219  static inline UId getLoFieldEntityUId(const UId &uid) {
220  return ((~static_cast<UId>(MAX_DOFS_ON_ENTITY - 1)) & uid);
221  }
222 
223  static inline UId getHiFieldEntityUId(const UId &uid) {
224  return getLoFieldEntityUId(uid) | static_cast<UId>(MAX_DOFS_ON_ENTITY - 1);
225  }
226 
227  template <typename T> void getLoFieldEntityUId(T &uid) = delete;
228  template <typename T> void getHiFieldEntityUId(T &uid) = delete;
229 
230  static inline UId getLoLocalEntityBitNumber(const char bit_number,
231  const EntityHandle ent) {
233 
234  bit_number,
235 
236  ent
237 
238  );
239  }
240 
241  static inline UId getHiLocalEntityBitNumber(const char bit_number,
242  const EntityHandle ent) {
243  return getLoLocalEntityBitNumber(bit_number, ent) |
244  static_cast<UId>(MAX_DOFS_ON_ENTITY - 1);
245  }
246 
247  /**
248  * \brief get hash-map relating dof index on entity with its order
249  *
250  * DOFs of given field are indexed on entity
251  * of the same type, same space, approximation base and number of
252  * coefficients, are sorted in the way.
253  *
254  */
255  inline std::array<int, MAX_DOFS_ON_ENTITY> &getDofOrderMap() const {
256  return this->getFieldRawPtr()->getDofOrderMap(this->getEntType());
257  }
258 
259  friend std::ostream &operator<<(std::ostream &os, const FieldEntity &e);
260 
261  mutable boost::weak_ptr<EntityCacheDofs> entityCacheDataDofs;
262  mutable boost::weak_ptr<EntityCacheNumeredDofs> entityCacheRowDofs;
263  mutable boost::weak_ptr<EntityCacheNumeredDofs> entityCacheColDofs;
264 
265  /**
266  * @brief Get the Weak Storage pointer
267  *
268  * @return boost::weak_ptr<EntityStorage>&
269  */
270  template <typename T = EntityStorage>
271  inline boost::shared_ptr<T> getSharedStoragePtr() const {
272  return boost::dynamic_pointer_cast<T>(weakStoragePtr.lock());
273  }
274 
275  inline boost::weak_ptr<EntityStorage> &getWeakStoragePtr() const {
276  return weakStoragePtr;
277  }
278 
279  mutable boost::weak_ptr<EntityStorage> weakStoragePtr;
280 
281 private:
282  mutable boost::shared_ptr<const ApproximationOrder> tagMaxOrderPtr;
283  mutable boost::shared_ptr<FieldData *const> fieldDataAdaptorPtr;
284 };
285 
286 template <>
287 inline boost::shared_ptr<EntityStorage>
288 FieldEntity::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  */
298 template <typename T>
299 struct interface_FieldEntity : public interface_Field<T, 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 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 
384 private:
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  */
396 typedef 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>,
404 
405  >>
406 
408 
409 /** \brief Entity index by field name
410  *
411  * \ingroup ent_multi_indices
412  */
414 
415 typedef multi_index_container<
416  boost::shared_ptr<FieldEntity>,
417  indexed_by<
418 
419  sequenced<>,
420 
421  ordered_non_unique<tag<Ent_mi_tag>,
424 
425  >>
427 
428 typedef multi_index_container<
429  boost::shared_ptr<FieldEntity>,
430  indexed_by<
431 
432  sequenced<>,
433 
434  ordered_non_unique<
435  tag<Composite_EntType_and_Space_mi_tag>,
436  composite_key<FieldEntity,
437 
439  EntityType, &FieldEntity::getEntType>,
440 
441  const_mem_fun<FieldEntity::interface_type_Field,
443 
444  >>
445 
446  >>
448 
449 typedef std::vector<boost::weak_ptr<FieldEntity>> FieldEntity_vector_view;
450 
451 } // namespace MoFEM
452 
453 #endif // __FIELD_ENTSMULTIINDICES_HPP__
454 
455 /**
456  * \defgroup ent_multi_indices Entities structures and multi-indices
457  * \ingroup mofem
458  **/
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)
boost::weak_ptr< EntityCacheDofs > entityCacheDataDofs
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
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
int getOrderNbDofs(ApproximationOrder order) const
Get number of DOFs on entity for given order of approximation.
static UId getHiLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
FieldEntity_multiIndex::index< Unique_mi_tag >::type FieldEntityByUId
Entity index by field name.
interface_FieldEntity(const boost::shared_ptr< T > &sptr)
virtual ~FieldEntity()=default
EntityType getEntType() const
Get entity type.
std::array< int, MAX_DOFS_ON_ENTITY > & getDofOrderMap() const
get hash-map relating dof index on entity with its order
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
int ApproximationOrder
Approximation on the entity.
Definition: Types.hpp:37
int getOrderNbDofs(ApproximationOrder order) const
Interface to FieldEntityinterface to FieldEntity.
FieldCoefficientsNumber getNbOfCoeffs() const
std::vector< boost::weak_ptr< FieldEntity > > FieldEntity_vector_view
const UId getGlobalUniqueId() const
Get global unique id.
boost::shared_ptr< T > getSharedStoragePtr() const
Get the Weak Storage pointer.
static UId getLoLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
friend std::ostream & operator<<(std::ostream &os, const FieldEntity &e)
static UId getLocalUniqueIdCalculate(const char bit_number, const EntityHandle handle)
Get the Local Unique Id Calculate.
UId getGlobalUniqueIdCalculate() const
Calculate global 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.
boost::weak_ptr< EntityStorage > & getWeakStoragePtr() const
#define MAX_PROCESSORS_NUMBER
Maximal number of processors.
Definition: definitions.h:306
Struct keeps handle to entity in the field.
char FieldBitNumber
Field bit number.
Definition: Types.hpp:39
UId localUId
Global unique id for this entity.
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
ApproximationOrder getMaxOrder() const
boost::weak_ptr< EntityCacheNumeredDofs > entityCacheRowDofs
int getOrderNbDofsDiff(ApproximationOrder order) const
Get difference of number of DOFs between order and order-1.
interface_Field< Field, RefEntity > interface_type_Field
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
const ApproximationOrder * getMaxOrderPtr() const
Get pinter to Tag keeping approximation order.
ApproximationOrder getMaxOrder() const
Get order set to the entity (Allocated tag size for such number)
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
boost::shared_ptr< S > getSharedStoragePtr() const
Get the Weak Storage pointer.
constexpr int order
boost::weak_ptr< EntityStorage > & getWeakStoragePtr() const
boost::weak_ptr< EntityCacheNumeredDofs > entityCacheColDofs
auto getVectorAdaptor(T1 ptr, const size_t n)
Get Vector adaptor.
Definition: Templates.hpp:44
boost::shared_ptr< FieldData *const > & getEntFieldDataPtr() const
Get shared ptr to vector adaptor pointing to the field tag data on entity.
VectorShallowArrayAdaptor< double > VectorAdaptor
Definition: Types.hpp:109
std::array< ApproximationOrder, MAX_DOFS_ON_ENTITY > & getDofOrderMap(const EntityType type) const
get hash-map relating dof index on entity with its order
interface_RefEntity< RefEntity > interface_type_RefEntity
FieldSpace
approximation spaces
Definition: definitions.h:174
boost::shared_ptr< FieldEntity > & getFieldEntityPtr() const
static UId getGlobalUniqueIdCalculate(const int owner_proc, const char bit_number, const EntityHandle moab_owner_handle)
Calculate UId for field entity.
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.
boost::weak_ptr< EntityStorage > weakStoragePtr
void operator()(boost::shared_ptr< FieldEntity > &e)
structure to change FieldEntity order
EntityHandle getEnt() const
Get the entity handle.
static UId getLoBitNumberUId(const FieldBitNumber bit_number)
const UId & getLocalUniqueId() const
Get global unique id.
FieldEntity_change_order(const ApproximationOrder order, const bool reduce_tag_size=false)
static UId getLoFieldEntityUId(const UId &uid)
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
Definition: definitions.h:305
int getNbDofsOnEnt() const
Get number of active DOFs on entity.
int getOrderNbDofsDiff(ApproximationOrder order) const
virtual ~EntityStorage()=default
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< FieldData *const > fieldDataAdaptorPtr
boost::shared_ptr< const ApproximationOrder > tagMaxOrderPtr
uint128_t UId
Unique Id.
Definition: Types.hpp:42
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
static UId getHiFieldEntityUId(const UId &uid)