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