v0.9.1
EntsMultiIndices.hpp
Go to the documentation of this file.
1 /** \file EntsMultiIndices.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 __ENTSMULTIINDICES_HPP__
22 #define __ENTSMULTIINDICES_HPP__
23 
24 namespace MoFEM {
25 
26 /**
27  * \brief keeps information about side number for the finite element
28  * \ingroup ent_multi_indices
29  */
30 struct __attribute__((__packed__)) SideNumber {
31  EntityHandle ent;
32  char side_number;
33  char sense;
34  char offset;
35  char brother_side_number;
36  inline EntityType getEntType() const {
37  return (EntityType)((ent & MB_TYPE_MASK) >> MB_ID_WIDTH);
38  }
39 
40  SideNumber(EntityHandle _ent, int _side_number, int _sense, int _offset)
41  : ent(_ent), side_number(_side_number), sense(_sense), offset(_offset),
42  brother_side_number(-1) {}
43  virtual ~SideNumber() = default;
44 
45 };
46 
47 /**
48  * @relates multi_index_container
49  * \brief SideNumber_multiIndex for SideNumber
50  * \ingroup ent_multi_indices
51  *
52  */
53 typedef multi_index_container<
54  boost::shared_ptr<SideNumber>,
55  indexed_by<
56  hashed_unique<member<SideNumber, EntityHandle, &SideNumber::ent>>,
57  ordered_non_unique<
58 
59  composite_key<
60  SideNumber,
61  const_mem_fun<SideNumber, EntityType, &SideNumber::getEntType>,
62  member<SideNumber, char, &SideNumber::side_number>
63 
64  >>,
65  ordered_non_unique<
66  const_mem_fun<SideNumber, EntityType, &SideNumber::getEntType>>
67 
68  >>
70 
71 /**
72  * \brief PipelineManager data. like access to moab interface and basic tag handlers.
73  */
76  int pcommID;
79  BasicEntityData(const moab::Interface &mfield,
80  const int pcomm_id = MYPCOMM_INDEX);
81  virtual ~BasicEntityData() = default;
82  inline void setDistributedMesh() { distributedMesh = true; }
83  inline void unSetDistributedMesh() { distributedMesh = false; }
84  inline bool trueIfDistributedMesh() const { return distributedMesh; }
85 
86 private:
88 };
89 
90 /**
91  * \brief this struct keeps basic methods for moab entity
92  * \ingroup ent_multi_indices
93 
94  \todo BasicEntity in should be linked to directly to MoAB data structures
95  such that connectivity and nodal coordinates could be quickly accessed,
96  without need of using native MoAB functions.
97 
98  */
99 struct BasicEntity {
100 
101  mutable boost::shared_ptr<BasicEntityData> basicDataPtr;
102 
104 
105  int owner_proc; ///< this never can not be changed if distributed mesh
106  int part_proc; ///< this can be changed on distributed
107 
109 
110  BasicEntity(const boost::shared_ptr<BasicEntityData> &basic_data_ptr,
111  const EntityHandle ent);
112  virtual ~BasicEntity() = default;
113 
114  inline boost::shared_ptr<BasicEntityData> &getBasicDataPtr() {
115  return basicDataPtr;
116  }
117 
118  inline const boost::shared_ptr<BasicEntityData> &getBasicDataPtr() const {
119  return basicDataPtr;
120  }
121 
122  /** \brief Get entity type
123  */
124  inline EntityType getEntType() const {
125  return (EntityType)((ent & MB_TYPE_MASK) >> MB_ID_WIDTH);
126  }
127 
128  /** \brief get entity id
129  */
130  inline EntityID getEntId() const { return (EntityID)(ent & MB_ID_MASK); };
131 
132  /** \brief Owner handle on this or other processors
133  */
134  inline EntityHandle getOwnerEnt() const { return moab_owner_handle; }
135 
136  /** \brief Owner handle on this or other processors
137  */
139 
140  /** \brief Get processor owning entity
141  */
142  inline int getOwnerProc() const { return owner_proc; }
143 
144  /** \brief Get processor owning entity
145  */
146  inline int &getOwnerProc() { return owner_proc; }
147 
148  /** \brief Get processor
149  */
150  inline int getPartProc() const { return part_proc; }
151 
152  /** \brief Get processor owning entity
153  */
154  inline int &getPartProc() { return part_proc; }
155 
156  /** \brief get pstatus
157  * This tag stores various aspects of parallel status in bits; see also
158  * define following, to be used in bit mask operations. If an entity is
159  * not shared with any other processors, the pstatus is 0, otherwise it's > 0
160  *
161  * bit 0: !owned (0=owned, 1=not owned)
162  * bit 1: shared (0=not shared, 1=shared)
163  * bit 2: multishared (shared by > 2 procs; 0=not shared, 1=shared)
164  * bit 3: interface (0=not interface, 1=interface)
165  * bit 4: ghost (0=not ghost, 1=ghost)
166  *
167  */
168  unsigned char getPStatus() const;
169 
170  /** \brief get shared processors
171 
172  Returning list to shared processors. Lists end with -1. Returns NULL if not
173  sharing processors.
174 
175  DO NOT MODIFY LIST.
176 
177  \code
178  BasicEntity *ent_ptr = BasicEntity(moan,entity_handle);
179  for(int proc = 0; proc<MAX_SHARING_PROCS && -1 !=
180  ent_ptr->getSharingProcsPtr[proc]; proc++) {
181  if(ent_ptr->getSharingProcsPtr[proc] == -1) {
182  // End of the list
183  break;
184  }
185  int sharing_proc = ent_ptr->getSharingProcsPtr[proc];
186  EntityHandle sharing_ent = ent_ptr->getSharingHandlersPtr[proc];
187  if(!(ent_ptr->getPStatus()&PSTATUS_MULTISHARED)) {
188  break;
189  }
190  }
191  \endcode
192 
193  */
194  int *getSharingProcsPtr() const {
195  moab::Interface &moab = basicDataPtr->moab;
196  int *sharing_procs_ptr = NULL;
197  ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, basicDataPtr->pcommID);
198  if (getPStatus() & PSTATUS_MULTISHARED) {
199  // entity is multi shared
200  rval = moab.tag_get_by_ptr(pcomm->sharedps_tag(), &ent, 1,
201  (const void **)&sharing_procs_ptr);
202  MOAB_THROW(rval);
203  } else if (getPStatus() & PSTATUS_SHARED) {
204  // shared
205  rval = moab.tag_get_by_ptr(pcomm->sharedp_tag(), &ent, 1,
206  (const void **)&sharing_procs_ptr);
207  MOAB_THROW(rval);
208  }
209  return sharing_procs_ptr;
210  }
211 
212  /** \brief get sharid entity handlers
213 
214  Returning list to shared entity handlers. Use it with getSharingProcsPtr()
215 
216  DO NOT MODIFY LIST.
217 
218  \code
219  BasicEntity *ent_ptr = BasicEntity(moan,entity_handle);
220  for(int proc = 0; proc<MAX_SHARING_PROCS && -1 !=
221  ent_ptr->getSharingProcsPtr[proc]; proc++) {
222  if(ent_ptr->getSharingProcsPtr[proc] == -1) {
223  // End of the list
224  break;
225  }
226  int sharing_proc = ent_ptr->getSharingProcsPtr[proc];
227  EntityHandle sharing_ent = ent_ptr->getSharingHandlersPtr[proc];
228  if(!(ent_ptr->getPStatus()&PSTATUS_MULTISHARED)) {
229  break;
230  }
231  }
232 \endcode
233 
234  */
236  EntityHandle *sharing_handlers_ptr = NULL;
237  moab::Interface &moab = basicDataPtr->moab;
238  ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, basicDataPtr->pcommID);
239  if (getPStatus() & PSTATUS_MULTISHARED) {
240  // entity is multi shared
241  rval = moab.tag_get_by_ptr(pcomm->sharedhs_tag(), &ent, 1,
242  (const void **)&sharing_handlers_ptr);
243  MOAB_THROW(rval);
244  } else if (getPStatus() & PSTATUS_SHARED) {
245  // shared
246  rval = moab.tag_get_by_ptr(pcomm->sharedh_tag(), &ent, 1,
247  (const void **)&sharing_handlers_ptr);
248  MOAB_THROW(rval);
249  }
250  return sharing_handlers_ptr;
251  }
252 };
253 
254 /**
255  * \brief Struct keeps handle to refined handle.
256  * \ingroup ent_multi_indices
257 
258  \todo th_RefType "_RefType" is set as two integers, need to be fixed, it is
259  waste of space.
260 
261  */
262 struct RefEntity : public BasicEntity {
263 
264  RefEntity(const boost::shared_ptr<BasicEntityData> &basic_data_ptr,
265  const EntityHandle ent);
266 
267  virtual ~RefEntity() = default;
268 
269  static MoFEMErrorCode getParentEnt(Interface &moab, Range ents,
270  std::vector<EntityHandle> vec_patent_ent);
271 
272  static MoFEMErrorCode
273  getBitRefLevel(Interface &moab, Range ents,
274  std::vector<BitRefLevel> &vec_bit_ref_level);
275 
276  static MoFEMErrorCode
277  getBitRefLevel(Interface &moab, Range ents,
278  std::vector<const BitRefLevel *> &vec_ptr_bit_ref_level);
279 
280  /**
281  * \brief Get pointer to parent entity tag.
282  *
283  * Each refined entity has his parent. Such information is stored on tags.
284  * This function get pinter to tag.
285  *
286  * @return Pointer to tag on entity
287  */
288  EntityHandle *getParentEntPtr() const;
289 
290  /**
291  * \brief Get pointer to bit ref level tag
292 
293  * Every entity belongs to some refinement level or levels. Each level is
294  marked
295  * by bit set in BitRefLevel() (bitset) structure.
296  *
297  * See \ref mix_mesh_refinement for explanation.
298 
299  * @return Return pointer to tag.
300  */
302 
303  /** \brief Get entity
304  */
305  inline EntityHandle getRefEnt() const { return ent; }
306 
307  /** \brief Get patent entity
308  */
309  inline EntityType getParentEntType() const {
310  EntityHandle *tag_parent_ent = getParentEntPtr();
311  if (*tag_parent_ent == 0)
312  return MBMAXTYPE;
313  return (EntityType)((*tag_parent_ent & MB_TYPE_MASK) >> MB_ID_WIDTH);
314  }
315 
316  /** \brief Get parent entity, i.e. entity form one refinement level up
317  */
318  inline EntityHandle getParentEnt() const { return *(getParentEntPtr()); }
319 
320  /** \brief Get entity ref bit refinement signature
321  */
322  inline const BitRefLevel &getBitRefLevel() const {
323  return *getBitRefLevelPtr();
324  }
325 
326  /** \brief Get entity ref bit refinement as ulong
327  */
328  inline unsigned long int getBitRefLevelULong() const {
329  return getBitRefLevel().to_ulong();
330  }
331 
332  friend std::ostream &operator<<(std::ostream &os, const RefEntity &e);
333 };
334 
335 /**
336  * \brief interface to RefEntity
337  * \ingroup ent_multi_indices
338  */
339 template <typename T> struct interface_RefEntity {
340 
341  mutable boost::shared_ptr<T> sPtr;
342 
343  interface_RefEntity(const boost::shared_ptr<T> &sptr) : sPtr(sptr) {}
344 
346  : sPtr(interface.getRefEntityPtr()) {}
347 
348  virtual ~interface_RefEntity() = default;
349 
350  inline boost::shared_ptr<BasicEntityData> &getBasicDataPtr() {
351  return this->sPtr->getBasicDataPtr();
352  }
353 
354  inline const boost::shared_ptr<BasicEntityData> &getBasicDataPtr() const {
355  return this->sPtr->getBasicDataPtr();
356  }
357 
358  inline EntityHandle getRefEnt() const { return this->sPtr->getRefEnt(); }
359 
360  inline EntityType getParentEntType() const {
361  return this->sPtr->getParentEntType();
362  };
363 
364  inline EntityHandle getParentEnt() const {
365  return this->sPtr->getParentEnt();
366  }
367 
368  inline BitRefLevel *getBitRefLevelPtr() const {
369  return this->sPtr->getBitRefLevelPtr();
370  }
371 
372  inline const BitRefLevel &getBitRefLevel() const {
373  return this->sPtr->getBitRefLevel();
374  }
375 
376  inline unsigned long int getBitRefLevelULong() const {
377  return this->sPtr->getBitRefLevelULong();
378  }
379 
380  inline EntityType getEntType() const { return this->sPtr->getEntType(); };
381 
382  inline EntityID getEntId() const { return this->sPtr->getEntId(); };
383 
384  inline EntityHandle getOwnerEnt() const { return this->sPtr->getOwnerEnt(); }
385 
386  inline EntityHandle &getOwnerEnt() { return this->sPtr->getOwnerEnt(); }
387 
388  inline int getOwnerProc() const { return this->sPtr->getOwnerProc(); }
389 
390  inline int &getOwnerProc() { return this->sPtr->getOwnerProc(); }
391 
392  inline int getPartProc() const { return this->sPtr->getPartProc(); }
393 
394  inline int &getPartProc() { return this->sPtr->getPartProc(); }
395 
396  inline unsigned char getPStatus() const { return this->sPtr->getPStatus(); }
397 
398  inline int *getSharingProcsPtr() const {
399  return this->sPtr->getSharingProcsPtr();
400  }
401 
403  return this->sPtr->getSharingHandlersPtr();
404  }
405 
406  inline boost::shared_ptr<T> &getRefEntityPtr() const { return this->sPtr; }
407 };
408 
409 /**
410  * \typedef RefEntity_multiIndex
411  * type multiIndex container for RefEntity
412  * \ingroup ent_multi_indices
413  *
414  * \param hashed_unique Ent_mi_tag
415  * \param ordered_non_unique Meshset_mi_tag
416  * \param ordered_non_unique Ent_Ent_mi_tag
417  * \param ordered_non_unique EntType_mi_tag
418  * \param ordered_non_unique ParentEntType_mi_tag
419  * \param ordered_non_unique Composite_EntType_And_ParentEntType_mi_tag
420  * \param ordered_non_unique Composite_ParentEnt_And_EntType_mi_tag
421  */
422 typedef multi_index_container<
423  boost::shared_ptr<RefEntity>,
424  indexed_by<
425  ordered_unique<tag<Ent_mi_tag>, member<RefEntity::BasicEntity,
427  ordered_non_unique<
428  tag<Ent_Ent_mi_tag>,
429  const_mem_fun<RefEntity, EntityHandle, &RefEntity::getParentEnt>>,
430  ordered_non_unique<tag<EntType_mi_tag>,
431  const_mem_fun<RefEntity::BasicEntity, EntityType,
433  ordered_non_unique<
434  tag<ParentEntType_mi_tag>,
435  const_mem_fun<RefEntity, EntityType, &RefEntity::getParentEntType>>,
436  ordered_non_unique<
437  tag<Composite_EntType_and_ParentEntType_mi_tag>,
438  composite_key<RefEntity,
439  const_mem_fun<RefEntity::BasicEntity, EntityType,
441  const_mem_fun<RefEntity, EntityType,
443  ordered_non_unique<
444  tag<Composite_ParentEnt_And_EntType_mi_tag>,
445  composite_key<RefEntity,
446  const_mem_fun<RefEntity::BasicEntity, EntityType,
448  const_mem_fun<RefEntity, EntityHandle,
451 
452 /** \brief multi-index view of RefEntity by parent entity
453  \ingroup ent_multi_indices
454 */
455 typedef multi_index_container<
456  boost::shared_ptr<RefEntity>,
457  indexed_by<
458  hashed_non_unique<
459  const_mem_fun<RefEntity, EntityHandle, &RefEntity::getParentEnt>>,
460  hashed_unique<tag<Composite_EntType_and_ParentEntType_mi_tag>,
461  composite_key<boost::shared_ptr<RefEntity>,
462  const_mem_fun<RefEntity, EntityHandle,
464  const_mem_fun<RefEntity, EntityHandle,
466 
467  >
469 
470 typedef multi_index_container<
471  boost::shared_ptr<RefEntity>,
472  indexed_by<
473  ordered_non_unique<
474  const_mem_fun<RefEntity, EntityHandle, &RefEntity::getParentEnt>>,
475  hashed_unique<tag<Composite_EntType_and_ParentEntType_mi_tag>,
476  composite_key<boost::shared_ptr<RefEntity>,
477  const_mem_fun<RefEntity, EntityHandle,
479  const_mem_fun<RefEntity, EntityHandle,
481 
482  >
484 
485 typedef multi_index_container<
486  boost::shared_ptr<RefEntity>,
487  indexed_by<
488  sequenced<>,
489  ordered_unique<tag<Ent_mi_tag>, member<RefEntity::BasicEntity,
492 
493 template <class T> struct Entity_update_pcomm_data {
494  const int pcommID;
496  : pcommID(pcomm_id) {}
497  void operator()(boost::shared_ptr<T> &e) {
498  e->getBasicDataPtr()->pcommID = pcommID;
499  ParallelComm *pcomm =
500  ParallelComm::get_pcomm(&e->getBasicDataPtr()->moab, pcommID);
501  if (pcomm == NULL)
502  THROW_MESSAGE("pcomm is null");
503  if (e->getBasicDataPtr()->trueIfDistributedMesh()) {
504  THROW_MESSAGE("Can not change owner proc if distributed mesh, this will "
505  "make undetermined behavior");
506  }
507  rval = pcomm->get_owner_handle(e->getRefEnt(), e->getOwnerProc(),
508  e->getOwnerEnt());
509  MOAB_THROW(rval);
510  EntityHandle ent = e->getRefEnt();
511  rval = e->getBasicDataPtr()->moab.tag_get_data(pcomm->part_tag(), &ent, 1,
512  &e->getPartProc());
513  MOAB_THROW(rval);
514  }
515 };
516 
517 /** \brief change parent
518  * \ingroup ent_multi_indices
519  *
520  * Use this function with care. Some other multi-indices can deponent on this.
521 
522  Known dependent multi-indices (verify if that list is full):
523  - RefEntity_multiIndex
524  - RefElement_multiIndex
525 
526  */
530  inline void operator()(boost::shared_ptr<RefEntity> &e) {
531  rval = e->getBasicDataPtr()->moab.tag_set_data(
532  e->getBasicDataPtr()->th_RefParentHandle, &e->ent, 1, &pArent);
533  MOAB_THROW(rval);
534  }
535 };
536 
537 /** \brief ref mofem entity, left shift
538  * \ingroup ent_multi_indices
539  */
541  int shift;
543  RefEntity_change_left_shift(const int _shift,
544  const BitRefLevel _mask = BitRefLevel().set())
545  : shift(_shift), mask(_mask) {}
546  inline void operator()(boost::shared_ptr<RefEntity> &e) {
547  BitRefLevel bit = *(e->getBitRefLevelPtr());
548  (*e->getBitRefLevelPtr()) = ((bit & mask) << shift) | (bit & ~mask);
549  };
550 };
551 
552 /** \brief ref mofem entity, right shift
553  * \ingroup ent_multi_indices
554  */
556  int shift;
559  const BitRefLevel _mask = BitRefLevel().set())
560  : shift(_shift), mask(_mask) {}
561  inline void operator()(boost::shared_ptr<RefEntity> &e) {
562  BitRefLevel bit = *(e->getBitRefLevelPtr());
563  *(e->getBitRefLevelPtr()) = ((bit & mask) >> shift) | (bit & ~mask);
564  };
565 };
566 
567 struct DofEntity;
568 
569 /**
570  * \brief Struct keeps handle to entity in the field.
571  * \ingroup ent_multi_indices
572  */
573 struct FieldEntity : public interface_Field<Field>,
574  interface_RefEntity<RefEntity> {
575 
578  UId globalUId; ///< Global unique id for this entity
579 
580  FieldEntity(const boost::shared_ptr<Field> &field_ptr,
581  const boost::shared_ptr<RefEntity> &ref_ents_ptr,
582  boost::shared_ptr<double *const> &&field_data_adaptor_ptr,
583  boost::shared_ptr<const int> &&t_max_order_ptr);
584 
585  virtual ~FieldEntity() = default;
586 
587  /**
588  * \brief Get entity handle
589  * @return EntityHandle
590  */
591  inline EntityHandle getEnt() const { return getRefEnt(); }
592 
593  /**
594  * \brief Get number of active DOFs on entity
595  * @return Number of DOFs
596  */
597  inline int getNbDofsOnEnt() const {
599  }
600 
601  /**
602  * @brief Return shared pointer to entity field data vector adaptor
603  *
604  * @return boost::shared_ptr<VectorAdaptor>
605  */
606  static boost::shared_ptr<FieldData *const> makeSharedFieldDataAdaptorPtr(
607  const boost::shared_ptr<Field> &field_ptr,
608  const boost::shared_ptr<RefEntity> &ref_ents_ptr);
609 
610  /**
611  * @brief Get shared ptr to vector adaptor pointing to the field tag data on
612  * entity
613  *
614  * @return boost::shared_ptr<VectorAdaptor>&
615  */
616  inline boost::shared_ptr<FieldData *const> &getEntFieldDataPtr() const {
617  return fieldDataAdaptorPtr;
618  }
619 
620  /**
621  * \brief Get vector of DOFs active values on entity
622  * @return Vector of DOFs values
623  */
626  }
627 
628  /**
629  * \brief Get number of DOFs on entity for given order of approximation
630  * @param order Order of approximation
631  * @return Number of DOFs
632  */
634  return (this->sFieldPtr->forderTable[getEntType()])(order);
635  }
636 
637  /**
638  * \brief Get difference of number of DOFs between order and order-1
639  * @param order Approximation order
640  * @return Difference number of DOFs
641  */
643  return getOrderNbDofs(order) - getOrderNbDofs(order - 1);
644  }
645 
646  /**
647  * \brief Get pinter to Tag keeping approximation order
648  * @return Pointer to Tag
649  */
650  inline const ApproximationOrder *getMaxOrderPtr() const {
651  return tagMaxOrderPtr.get();
652  }
653 
654  /**
655  * \brief Get order set to the entity (Allocated tag size for such number)
656  * @return Approximation order
657  */
659  return *tagMaxOrderPtr.get();
660  }
661 
662  /**
663  * \brief Get global unique id
664  * @return Global UId
665  */
666  const UId &getGlobalUniqueId() const { return globalUId; }
667 
668  /**
669  * \brief Calculate UId for field entity
670  *
671  * UId is constructed such that all DOFs are ordered by processor, entity,
672  * field.
673  *
674  * @param owner_proc owning processor
675  * @param bit_number field bit number
676  * @param moab_owner_handle entity handle on owning processor
677  * @param true_if_distributed_mesh if true UId is constructed for distributed
678  * meshes
679  * @return UId
680  */
681  static inline UId
682  getGlobalUniqueIdCalculate(const int owner_proc, const char bit_number,
683  const EntityHandle moab_owner_handle,
684  const bool true_if_distributed_mesh) {
685  // assert(bit_number < 32);
686  // assert(owner_proc < 1024);
687  constexpr int ent_shift = 8 * sizeof(EntityHandle);
688  if (true_if_distributed_mesh)
689  return (static_cast<UId>(moab_owner_handle) |
690  static_cast<UId>(bit_number) << ent_shift |
691  static_cast<UId>(owner_proc) << 5 + ent_shift)
692  << 9;
693  else
694  return (static_cast<UId>(moab_owner_handle) | static_cast<UId>(bit_number)
695  << ent_shift)
696  << 9;
697  }
698 
699  static inline UId getGlobalUniqueIdCalculate_Low_Proc(const int owner_proc) {
700  return getGlobalUniqueIdCalculate(owner_proc, 0, 0, true);
701  }
702 
703  static inline UId getGlobalUniqueIdCalculate_Hi_Proc(const int owner_proc) {
704  return getGlobalUniqueIdCalculate(owner_proc, BITFIELDID_SIZE - 1,
705  MBMAXTYPE, true);
706  }
707 
708  /**
709  * \brief Calculate global UId
710  * @return Global UId
711  */
714  sPtr->owner_proc, getBitNumber(), sPtr->moab_owner_handle,
715  getBasicDataPtr()->trueIfDistributedMesh());
716  }
717 
718  /**
719  * \brief Get pointer to RefEntity
720  */
721  inline boost::shared_ptr<RefEntity> &getRefEntityPtr() { return this->sPtr; }
722 
723  /**
724  * \brief Get pointer to Field data structure associated with this entity
725  */
726  inline boost::shared_ptr<Field> &getFieldPtr() const {
727  return this->sFieldPtr;
728  }
729 
730  friend std::ostream &operator<<(std::ostream &os, const FieldEntity &e);
731 
732  /**
733  * \brief get hash-map relating dof index on entity with its order
734  *
735  * DOFs of given field are indexed on entity
736  * of the same type, same space, approximation base and number of
737  * coefficients, are sorted in the way.
738  *
739  */
740  inline std::array<int, MAX_DOFS_ON_ENTITY> &getDofOrderMap() const {
741  return getFieldPtr()->getDofOrderMap(getEntType());
742  }
743 
744 private:
745  mutable boost::shared_ptr<const ApproximationOrder> tagMaxOrderPtr;
746  mutable boost::shared_ptr<FieldData *const> fieldDataAdaptorPtr;
747 };
748 
749 /**
750  * \brief Interface to FieldEntity
751  * \ingroup ent_multi_indices
752  *
753  * interface to FieldEntity
754  */
755 template <typename T>
758 
759  interface_FieldEntity(const boost::shared_ptr<T> &sptr)
760  : interface_Field<T>(sptr), interface_RefEntity<T>(sptr) {}
761 
762  /// @return get entity handle
763  inline EntityHandle getEnt() const { return this->sPtr->getEnt(); }
764 
765  /// @return get number of dofs on entity
766  inline int getNbDofsOnEnt() const { return this->sPtr->getNbDofsOnEnt(); }
767 
768  /// @return get field data on entity
770  return this->sPtr->getEntFieldData();
771  }
772 
773  /// @return get number of DOFs for given order
775  return this->sPtr->getOrderNbDofs(order);
776  }
777 
778  /// @return get increase of DOFs by increase to this order
780  return this->sPtr->getOrderNbDofsDiff(order);
781  }
782 
783  /// @return get maximal order on entity
785  return this->sPtr->getMaxOrder();
786  }
787 
788  /// @return get entity UId
789  inline UId getGlobalUniqueId() const {
790  return this->sPtr->getGlobalUniqueId();
791  }
792 
793  /// @return return pointer to reference entity data structure
794  inline boost::shared_ptr<RefEntity> &getRefEntityPtr() const {
795  return this->sPtr->getRefEntityPtr();
796  }
797 
798  /// @return get pointer to field data structure
799  inline boost::shared_ptr<Field> &getFieldPtr() const {
800  return this->sFieldPtr->getFieldPtr();
801  }
802 
803  /// @return get pointer to mofem entity data structure
804  inline boost::shared_ptr<FieldEntity> &getFieldEntityPtr() const {
805  return this->sPtr;
806  };
807 
808  /**
809  * \brief get hash-map relating dof index on entity with its order
810  *
811  * DOFs of given field are indexed on entity
812  * of the same type, same space, approximation base and number of
813  * coefficients, are sorted in the way.
814  *
815  */
816  inline std::array<int, MAX_DOFS_ON_ENTITY> &getDofOrderMap() const {
817  return this->sPtr->getDofOrderMap();
818  }
819 };
820 
821 /**
822  * \brief structure to change FieldEntity order
823  * \ingroup ent_multi_indices
824  */
826 
828  const bool reduce_tag_size = false)
829  : order(order), reduceTagSize(reduce_tag_size) {}
830  inline void operator()(boost::shared_ptr<FieldEntity> &e) {
831  (*this)(e.get());
832  }
833  void operator()(FieldEntity *e);
834 
835 private:
837  const bool reduceTagSize;
838  std::vector<FieldData> data;
839 };
840 
841 /**
842  * @relates multi_index_container
843  * \brief MultiIndex container keeps FieldEntity
844  * \ingroup ent_multi_indices
845  *
846  */
847 typedef multi_index_container<
848  boost::shared_ptr<FieldEntity>,
849  indexed_by<
850  ordered_unique<tag<Unique_mi_tag>,
851  member<FieldEntity, UId, &FieldEntity::globalUId>>,
852  ordered_non_unique<
853  tag<FieldName_mi_tag>,
854  const_mem_fun<FieldEntity::interface_type_Field, boost::string_ref,
856  ordered_non_unique<
857  tag<Ent_mi_tag>,
858  const_mem_fun<FieldEntity, EntityHandle, &FieldEntity::getEnt>>,
859  ordered_non_unique<
860  tag<Composite_Name_And_Ent_mi_tag>,
861  composite_key<
862  FieldEntity,
863  const_mem_fun<FieldEntity::interface_type_Field,
864  boost::string_ref, &FieldEntity::getNameRef>,
865  const_mem_fun<FieldEntity, EntityHandle,
866  &FieldEntity::getEnt>>>>>
868 
869 /** \brief Entity index by field name
870  *
871  * \ingroup ent_multi_indices
872  */
875 
876 typedef multi_index_container<
877  boost::shared_ptr<FieldEntity>,
878  indexed_by<
879 
880  sequenced<>,
881 
882  ordered_non_unique<
883  tag<Ent_mi_tag>,
884  const_mem_fun<FieldEntity, EntityHandle, &FieldEntity::getEnt>>
885 
886  >>
888 
889 typedef multi_index_container<
890  boost::shared_ptr<FieldEntity>,
891  indexed_by<
892 
893  sequenced<>,
894 
895  ordered_non_unique<
896  tag<Composite_EntType_and_Space_mi_tag>,
897  composite_key<FieldEntity,
898 
900  EntityType, &FieldEntity::getEntType>,
901 
902  const_mem_fun<FieldEntity::interface_type_Field,
904 
905  >>
906 
907  >>
909 
910 typedef std::vector<boost::weak_ptr<FieldEntity>> FieldEntity_vector_view;
911 
912 /**
913  * \brief Keeps basic information about entity on the finite element
914  */
915 struct BaseFEEntity {
916  BaseFEEntity(const boost::shared_ptr<SideNumber> &side_number_ptr)
917  : sideNumberPtr(side_number_ptr){};
918  virtual ~BaseFEEntity() = default;
919  boost::shared_ptr<SideNumber> sideNumberPtr;
920  inline int getSideNumber() { return sideNumberPtr->side_number; }
921 };
922 
923 } // namespace MoFEM
924 
925 #endif // __ENTSMULTIINDICES_HPP__
926 
927 /***************************************************************************/ /**
928  * \defgroup ent_multi_indices Entities structures and multi-indices
929  * \ingroup mofem
930  ******************************************************************************/
EntityHandle getRefEnt() const
Get entity.
interface_RefEntity(const interface_RefEntity< T > &interface)
int & getPartProc()
Get processor owning entity.
const BitRefLevel & getBitRefLevel() const
Get entity ref bit refinement signature.
Keeps basic information about entity on the finite element.
unsigned char getPStatus() const
get pstatus This tag stores various aspects of parallel status in bits; see also define following,...
RefEntity_change_left_shift(const int _shift, const BitRefLevel _mask=BitRefLevel().set())
boost::shared_ptr< T > sPtr
Deprecated interface functions.
RefEntity(const boost::shared_ptr< BasicEntityData > &basic_data_ptr, const EntityHandle ent)
boost::shared_ptr< BasicEntityData > & getBasicDataPtr()
EntityHandle getRefEnt() const
change parentUse this function with care. Some other multi-indices can deponent on this.
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
int getOrderNbDofs(ApproximationOrder order) const
Get number of DOFs on entity for given order of approximation.
EntityID getEntId() const
get entity id
interface_FieldEntity(const boost::shared_ptr< T > &sptr)
virtual ~FieldEntity()=default
this struct keeps basic methods for moab entity
const boost::shared_ptr< BasicEntityData > & getBasicDataPtr() const
std::array< int, MAX_DOFS_ON_ENTITY > & getDofOrderMap() const
get hash-map relating dof index on entity with its order
int ApproximationOrder
Approximation on the entity.
Definition: Types.hpp:37
boost::shared_ptr< SideNumber > sideNumberPtr
RefEntity_change_right_shift(const int _shift, const BitRefLevel _mask=BitRefLevel().set())
int getOrderNbDofs(ApproximationOrder order) const
Interface to FieldEntityinterface to FieldEntity.
friend std::ostream & operator<<(std::ostream &os, const RefEntity &e)
std::vector< boost::weak_ptr< FieldEntity > > FieldEntity_vector_view
EntityHandle * getParentEntPtr() const
Get pointer to parent entity tag.
#define MB_TYPE_MASK
Definition: definitions.h:296
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, member< FieldEntity, UId, &FieldEntity::globalUId > >, ordered_non_unique< tag< FieldName_mi_tag >, const_mem_fun< FieldEntity::interface_type_Field, boost::string_ref, &FieldEntity::getNameRef > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity, EntityHandle, &FieldEntity::getEnt > >, ordered_non_unique< tag< Composite_Name_And_Ent_mi_tag >, composite_key< FieldEntity, const_mem_fun< FieldEntity::interface_type_Field, boost::string_ref, &FieldEntity::getNameRef >, const_mem_fun< FieldEntity, EntityHandle, &FieldEntity::getEnt > > > > > FieldEntity_multiIndex
MultiIndex container keeps FieldEntity.
friend std::ostream & operator<<(std::ostream &os, const FieldEntity &e)
UId getGlobalUniqueIdCalculate() const
Calculate global UId.
FieldCoefficientsNumber getNbOfCoeffs() const
virtual ~RefEntity()=default
FieldEntity_multiIndex::index< FieldName_mi_tag >::type FieldEntityByFieldName
Entity index by field name.
BasicEntity(const boost::shared_ptr< BasicEntityData > &basic_data_ptr, const EntityHandle ent)
EntityHandle * getSharingHandlersPtr() const
#define THROW_MESSAGE(a)
Throw MoFEM exception.
Definition: definitions.h:626
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)
Struct keeps handle to entity in the field.
multi_index_container< boost::shared_ptr< RefEntity >, indexed_by< hashed_non_unique< const_mem_fun< RefEntity, EntityHandle, &RefEntity::getParentEnt > >, hashed_unique< tag< Composite_EntType_and_ParentEntType_mi_tag >, composite_key< boost::shared_ptr< RefEntity >, const_mem_fun< RefEntity, EntityHandle, &RefEntity::getRefEnt >, const_mem_fun< RefEntity, EntityHandle, &RefEntity::getParentEnt > > > > > RefEntity_multiIndex_view_by_hashed_parent_entity
multi-index view of RefEntity by parent entity
UId globalUId
Global unique id for this entity.
#define MOAB_THROW(a)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:608
Pointer interface for MoFEM::Field.
const UId & getGlobalUniqueId() const
Get global unique id.
Struct keeps handle to refined handle.
int & getOwnerProc()
Get processor owning entity.
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
ApproximationOrder getMaxOrder() const
int getOrderNbDofsDiff(ApproximationOrder order) const
Get difference of number of DOFs between order and order-1.
moab::Interface & moab
boost::string_ref getNameRef() const
PipelineManager data. like access to moab interface and basic tag handlers.
interface_RefEntity< RefEntity > interface_type_RefEntity
EntityHandle getOwnerEnt() const
boost::shared_ptr< Field > & getFieldPtr() const
Get pointer to Field data structure associated with this entity.
const BitRefLevel & getBitRefLevel() const
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:85
multi_index_container< boost::shared_ptr< RefEntity >, indexed_by< sequenced<>, ordered_unique< tag< Ent_mi_tag >, member< RefEntity::BasicEntity, EntityHandle, &RefEntity::ent > > > > RefEntity_multiIndex_view_sequence_ordered_view
EntityHandle getParentEnt() const
boost::shared_ptr< T > & getRefEntityPtr() const
struct __attribute__((__packed__)) SideNumber
keeps information about side number for the finite element
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)
int part_proc
this can be changed on distributed
boost::shared_ptr< BasicEntityData > & getBasicDataPtr()
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
EntityType getEntType() const
Get entity type.
static UId getGlobalUniqueIdCalculate_Hi_Proc(const int owner_proc)
int owner_proc
this never can not be changed if distributed mesh
Entity_update_pcomm_data(const int pcomm_id=MYPCOMM_INDEX)
EntityHandle getOwnerEnt() const
Owner handle on this or other processors.
unsigned long int getBitRefLevelULong() const
#define BITFIELDID_SIZE
max number of fields
Definition: definitions.h:286
virtual ~BasicEntityData()=default
interface_RefEntity(const boost::shared_ptr< T > &sptr)
multi_index_container< boost::shared_ptr< RefEntity >, indexed_by< ordered_non_unique< const_mem_fun< RefEntity, EntityHandle, &RefEntity::getParentEnt > >, hashed_unique< tag< Composite_EntType_and_ParentEntType_mi_tag >, composite_key< boost::shared_ptr< RefEntity >, const_mem_fun< RefEntity, EntityHandle, &RefEntity::getRefEnt >, const_mem_fun< RefEntity, EntityHandle, &RefEntity::getParentEnt > > > > > RefEntity_multiIndex_view_by_ordered_parent_entity
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:67
BasicEntityData(const moab::Interface &mfield, const int pcomm_id=MYPCOMM_INDEX)
virtual ~BaseFEEntity()=default
#define MB_ID_MASK
Definition: definitions.h:302
auto getVectorAdaptor(T1 ptr, const size_t n)
Get Vector adaptor.
Definition: Templates.hpp:42
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:108
EntityType getParentEntType() const
Get patent entity.
interface to RefEntity
int getPartProc() const
Get processor.
int * getSharingProcsPtr() const
get shared processors
unsigned long int getBitRefLevelULong() const
Get entity ref bit refinement as ulong.
static UId getGlobalUniqueIdCalculate_Low_Proc(const int owner_proc)
virtual ~BasicEntity()=default
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< sequenced<>, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity, EntityHandle, &FieldEntity::getEnt > > > > FieldEntity_multiIndex_ent_view
EntityHandle moab_owner_handle
FieldSpace
approximation spaces
Definition: definitions.h:174
boost::shared_ptr< FieldEntity > & getFieldEntityPtr() const
BitRefLevel * getBitRefLevelPtr() const
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 getGlobalUniqueIdCalculate(const int owner_proc, const char bit_number, const EntityHandle moab_owner_handle, const bool true_if_distributed_mesh)
Calculate UId for field entity.
unsigned char getPStatus() const
void operator()(boost::shared_ptr< FieldEntity > &e)
constexpr int order
structure to change FieldEntity order
void operator()(boost::shared_ptr< T > &e)
EntityType getParentEntType() const
#define MYPCOMM_INDEX
default communicator number PCOMM
Definition: definitions.h:291
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Types.hpp:50
const ApproximationOrder order
bool trueIfDistributedMesh() const
EntityHandle & getOwnerEnt()
Owner handle on this or other processors.
multi_index_container< boost::shared_ptr< RefEntity >, indexed_by< ordered_unique< tag< Ent_mi_tag >, member< RefEntity::BasicEntity, EntityHandle, &RefEntity::ent > >, ordered_non_unique< tag< Ent_Ent_mi_tag >, const_mem_fun< RefEntity, EntityHandle, &RefEntity::getParentEnt > >, ordered_non_unique< tag< EntType_mi_tag >, const_mem_fun< RefEntity::BasicEntity, EntityType, &RefEntity::getEntType > >, ordered_non_unique< tag< ParentEntType_mi_tag >, const_mem_fun< RefEntity, EntityType, &RefEntity::getParentEntType > >, ordered_non_unique< tag< Composite_EntType_and_ParentEntType_mi_tag >, composite_key< RefEntity, const_mem_fun< RefEntity::BasicEntity, EntityType, &RefEntity::getEntType >, const_mem_fun< RefEntity, EntityType, &RefEntity::getParentEntType > > >, ordered_non_unique< tag< Composite_ParentEnt_And_EntType_mi_tag >, composite_key< RefEntity, const_mem_fun< RefEntity::BasicEntity, EntityType, &RefEntity::getEntType >, const_mem_fun< RefEntity, EntityHandle, &RefEntity::getParentEnt > > > > > RefEntity_multiIndex
ref mofem entity, right shift
ref mofem entity, left shift
BaseFEEntity(const boost::shared_ptr< SideNumber > &side_number_ptr)
void operator()(boost::shared_ptr< RefEntity > &e)
EntityHandle getParentEnt() const
Get parent entity, i.e. entity form one refinement level up.
FieldEntity_change_order(const ApproximationOrder order, const bool reduce_tag_size=false)
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1879
int getNbDofsOnEnt() const
Get number of active DOFs on entity.
EntityHandle getEnt() const
Get entity handle.
boost::shared_ptr< RefEntity > & getRefEntityPtr()
Get pointer to RefEntity.
int getOrderNbDofsDiff(ApproximationOrder order) const
int getOwnerProc() const
Get processor owning entity.
void operator()(boost::shared_ptr< RefEntity > &e)
void operator()(boost::shared_ptr< RefEntity > &e)
boost::shared_ptr< BasicEntityData > basicDataPtr
std::array< int, MAX_DOFS_ON_ENTITY > & getDofOrderMap() const
get hash-map relating dof index on entity with its order
RefEntity_change_parent(EntityHandle parent)
VectorAdaptor getEntFieldData() const
Get vector of DOFs active values on entity.
interface_Field< Field > interface_type_Field
multi_index_container< boost::shared_ptr< SideNumber >, indexed_by< hashed_unique< member< SideNumber, EntityHandle, &SideNumber::ent > >, ordered_non_unique< composite_key< SideNumber, const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType >, member< SideNumber, char, &SideNumber::side_number > > >, ordered_non_unique< const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType > > > > SideNumber_multiIndex
SideNumber_multiIndex for SideNumber.
boost::shared_ptr< Field > & getFieldPtr() const
#define MB_ID_WIDTH
Definition: definitions.h:295
boost::shared_ptr< FieldData *const > fieldDataAdaptorPtr
boost::shared_ptr< const ApproximationOrder > tagMaxOrderPtr
uint128_t UId
Unique Id.
Definition: Types.hpp:41
virtual ~interface_RefEntity()=default
boost::shared_ptr< Field > sFieldPtr
EntityHandle * getSharingHandlersPtr() const
get sharid entity handlers
const boost::shared_ptr< BasicEntityData > & getBasicDataPtr() const
std::vector< FieldData > data
VectorAdaptor getEntFieldData() const
BitRefLevel * getBitRefLevelPtr() const
Get pointer to bit ref level tag.