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