v0.9.0
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 Basic data. like access to moab interface and basic tag handlers.
71  */
73  moab::Interface &moab;
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 {
314  return *(getParentEntPtr());
315  }
316 
317  /** \brief Get entity ref bit refinement signature
318  */
319  inline const BitRefLevel &getBitRefLevel() const {
320  return *getBitRefLevelPtr();
321  }
322 
323  /** \brief Get entity ref bit refinement as ulong
324  */
325  inline unsigned long int getBitRefLevelULong() const {
326  return getBitRefLevel().to_ulong();
327  }
328 
329  friend std::ostream &operator<<(std::ostream &os, const RefEntity &e);
330 };
331 
332 /**
333  * \brief interface to RefEntity
334  * \ingroup ent_multi_indices
335  */
336 template <typename T> struct interface_RefEntity {
337 
338  mutable boost::shared_ptr<T> sPtr;
339 
340  interface_RefEntity(const boost::shared_ptr<T> &sptr) : sPtr(sptr) {}
341 
343  : sPtr(interface.getRefEntityPtr()) {}
344 
345  virtual ~interface_RefEntity() {}
346 
347  inline boost::shared_ptr<BasicEntityData> &getBasicDataPtr() {
348  return this->sPtr->getBasicDataPtr();
349  }
350 
351  inline const boost::shared_ptr<BasicEntityData> &getBasicDataPtr() const {
352  return this->sPtr->getBasicDataPtr();
353  }
354 
355  inline EntityHandle getRefEnt() const { return this->sPtr->getRefEnt(); }
356 
357  inline EntityType getParentEntType() const {
358  return this->sPtr->getParentEntType();
359  };
360 
361  inline EntityHandle getParentEnt() const {
362  return this->sPtr->getParentEnt();
363  }
364 
365  inline BitRefLevel *getBitRefLevelPtr() const {
366  return this->sPtr->getBitRefLevelPtr();
367  }
368 
369  inline const BitRefLevel &getBitRefLevel() const {
370  return this->sPtr->getBitRefLevel();
371  }
372 
373  inline unsigned long int getBitRefLevelULong() const {
374  return this->sPtr->getBitRefLevelULong();
375  }
376 
377  inline EntityType getEntType() const { return this->sPtr->getEntType(); };
378 
379  inline EntityID getEntId() const { return this->sPtr->getEntId(); };
380 
381  inline EntityHandle getOwnerEnt() const { return this->sPtr->getOwnerEnt(); }
382 
383  inline EntityHandle &getOwnerEnt() { return this->sPtr->getOwnerEnt(); }
384 
385  inline int getOwnerProc() const { return this->sPtr->getOwnerProc(); }
386 
387  inline int &getOwnerProc() { return this->sPtr->getOwnerProc(); }
388 
389  inline int getPartProc() const { return this->sPtr->getPartProc(); }
390 
391  inline int &getPartProc() { return this->sPtr->getPartProc(); }
392 
393  inline unsigned char getPStatus() const { return this->sPtr->getPStatus(); }
394 
395  inline int *getSharingProcsPtr() const {
396  return this->sPtr->getSharingProcsPtr();
397  }
398 
400  return this->sPtr->getSharingHandlersPtr();
401  }
402 
403  inline boost::shared_ptr<T> &getRefEntityPtr() const { return this->sPtr; }
404 };
405 
406 /**
407  * \typedef RefEntity_multiIndex
408  * type multiIndex container for RefEntity
409  * \ingroup ent_multi_indices
410  *
411  * \param hashed_unique Ent_mi_tag
412  * \param ordered_non_unique Meshset_mi_tag
413  * \param ordered_non_unique Ent_Ent_mi_tag
414  * \param ordered_non_unique EntType_mi_tag
415  * \param ordered_non_unique ParentEntType_mi_tag
416  * \param ordered_non_unique Composite_EntType_And_ParentEntType_mi_tag
417  * \param ordered_non_unique Composite_ParentEnt_And_EntType_mi_tag
418  */
419 typedef multi_index_container<
420  boost::shared_ptr<RefEntity>,
421  indexed_by<
422  ordered_unique<tag<Ent_mi_tag>, member<RefEntity::BasicEntity,
424  ordered_non_unique<
425  tag<Ent_Ent_mi_tag>,
426  const_mem_fun<RefEntity, EntityHandle, &RefEntity::getParentEnt> >,
427  ordered_non_unique<tag<EntType_mi_tag>,
428  const_mem_fun<RefEntity::BasicEntity, EntityType,
430  ordered_non_unique<tag<ParentEntType_mi_tag>,
431  const_mem_fun<RefEntity, EntityType,
433  ordered_non_unique<
434  tag<Composite_EntType_and_ParentEntType_mi_tag>,
435  composite_key<RefEntity,
436  const_mem_fun<RefEntity::BasicEntity, EntityType,
438  const_mem_fun<RefEntity, EntityType,
440  ordered_non_unique<
441  tag<Composite_ParentEnt_And_EntType_mi_tag>,
442  composite_key<RefEntity,
443  const_mem_fun<RefEntity::BasicEntity, EntityType,
445  const_mem_fun<RefEntity, EntityHandle,
446  &RefEntity::getParentEnt> > > > >
448 
449 /** \brief multi-index view of RefEntity by parent entity
450  \ingroup ent_multi_indices
451 */
452 typedef multi_index_container<
453  boost::shared_ptr<RefEntity>,
454  indexed_by<
455  hashed_non_unique<
456  const_mem_fun<RefEntity, EntityHandle, &RefEntity::getParentEnt> >,
457  hashed_unique<
458  tag<Composite_EntType_and_ParentEntType_mi_tag>,
459  composite_key<
460  boost::shared_ptr<RefEntity>,
461  const_mem_fun<RefEntity, EntityHandle, &RefEntity::getRefEnt>,
462  const_mem_fun<RefEntity, EntityHandle,
464 
465  >
467 
468 typedef multi_index_container<
469  boost::shared_ptr<RefEntity>,
470  indexed_by<
471  ordered_non_unique<
472  const_mem_fun<RefEntity, EntityHandle, &RefEntity::getParentEnt>>,
473  hashed_unique<tag<Composite_EntType_and_ParentEntType_mi_tag>,
474  composite_key<boost::shared_ptr<RefEntity>,
475  const_mem_fun<RefEntity, EntityHandle,
477  const_mem_fun<RefEntity, EntityHandle,
479 
480  >
482 
483 typedef multi_index_container<
484  boost::shared_ptr<RefEntity>,
485  indexed_by<sequenced<>,
486  ordered_unique<tag<Ent_mi_tag>,
488  &RefEntity::ent> > > >
490 
491 template <class T> struct Entity_update_pcomm_data {
492  const int pcommID;
494  : pcommID(pcomm_id) {}
495  void operator()(boost::shared_ptr<T> &e) {
496  e->getBasicDataPtr()->pcommID = pcommID;
497  ParallelComm *pcomm =
498  ParallelComm::get_pcomm(&e->getBasicDataPtr()->moab, pcommID);
499  if (pcomm == NULL)
500  THROW_MESSAGE("pcomm is null");
501  if (e->getBasicDataPtr()->trueIfDistributedMesh()) {
502  THROW_MESSAGE("Can not change owner proc if distributed mesh, this will "
503  "make undetermined behavior");
504  }
505  rval = pcomm->get_owner_handle(e->getRefEnt(), e->getOwnerProc(),
506  e->getOwnerEnt());
507  MOAB_THROW(rval);
508  EntityHandle ent = e->getRefEnt();
509  rval = e->getBasicDataPtr()->moab.tag_get_data(pcomm->part_tag(), &ent, 1,
510  &e->getPartProc());
511  MOAB_THROW(rval);
512  }
513 };
514 
515 /** \brief change parent
516  * \ingroup ent_multi_indices
517  *
518  * Use this function with care. Some other multi-indices can deponent on this.
519 
520  Known dependent multi-indices (verify if that list is full):
521  - RefEntity_multiIndex
522  - RefElement_multiIndex
523 
524  */
528  inline void operator()(boost::shared_ptr<RefEntity> &e) {
529  rval = e->getBasicDataPtr()->moab.tag_set_data(
530  e->getBasicDataPtr()->th_RefParentHandle, &e->ent, 1, &pArent);
531  MOAB_THROW(rval);
532  }
533 };
534 
535 /** \brief ref mofem entity, left shift
536  * \ingroup ent_multi_indices
537  */
539  int shift;
541  RefEntity_change_left_shift(const int _shift,
542  const BitRefLevel _mask = BitRefLevel().set())
543  : shift(_shift), mask(_mask) {}
544  inline void operator()(boost::shared_ptr<RefEntity> &e) {
545  BitRefLevel bit = *(e->getBitRefLevelPtr());
546  (*e->getBitRefLevelPtr()) = ((bit & mask) << shift) | (bit & ~mask);
547  };
548 };
549 
550 /** \brief ref mofem entity, right shift
551  * \ingroup ent_multi_indices
552  */
554  int shift;
557  const BitRefLevel _mask = BitRefLevel().set())
558  : shift(_shift), mask(_mask) {}
559  inline void operator()(boost::shared_ptr<RefEntity> &e) {
560  BitRefLevel bit = *(e->getBitRefLevelPtr());
561  *(e->getBitRefLevelPtr()) = ((bit & mask) >> shift) | (bit & ~mask);
562  };
563 };
564 
565 struct DofEntity;
566 
567 /**
568  * \brief Struct keeps handle to entity in the field.
569  * \ingroup ent_multi_indices
570  */
571 struct FieldEntity : public interface_Field<Field>,
572  interface_RefEntity<RefEntity> {
573 
576  UId globalUId; ///< Global unique id for this entity
577 
578  FieldEntity(const boost::shared_ptr<Field> &field_ptr,
579  const boost::shared_ptr<RefEntity> &ref_ent_ptr,
580  boost::shared_ptr<double *const> &&field_data_adaptor_ptr,
581  boost::shared_ptr<const int> &&t_max_order_ptr);
582 
583 
584  ~FieldEntity();
585 
586  /**
587  * \brief Get entity handle
588  * @return EntityHandle
589  */
590  inline EntityHandle getEnt() const { return getRefEnt(); }
591 
592  /**
593  * \brief Get number of active DOFs on entity
594  * @return Number of DOFs
595  */
596  inline int getNbDofsOnEnt() const {
598  }
599 
600  /**
601  * @brief Return shared pointer to entity field data vector adaptor
602  *
603  * @return boost::shared_ptr<VectorAdaptor>
604  */
605  static boost::shared_ptr<FieldData *const> makeSharedFieldDataAdaptorPtr(
606  const boost::shared_ptr<Field> &field_ptr,
607  const boost::shared_ptr<RefEntity> &ref_ent_ptr);
608 
609  /**
610  * @brief Get shared ptr to vector adaptor pointing to the field tag data on
611  * entity
612  *
613  * @return boost::shared_ptr<VectorAdaptor>&
614  */
615  inline boost::shared_ptr<FieldData * const> &getEntFieldDataPtr() const {
616  return fieldDataAdaptorPtr;
617  }
618 
619  /**
620  * \brief Get vector of DOFs active values on entity
621  * @return Vector of DOFs values
622  */
625  }
626 
627  /**
628  * \brief Get number of DOFs on entity for given order of approximation
629  * @param order Order of approximation
630  * @return Number of DOFs
631  */
632  inline int getOrderNbDofs(int order) const {
633  return (this->sFieldPtr->forderTable[getEntType()])(order);
634  }
635 
636  /**
637  * \brief Get difference of number of DOFs between order and order-1
638  * @param order Approximation order
639  * @return Difference number of DOFs
640  */
641  inline int getOrderNbDofsDiff(int order) const {
642  return getOrderNbDofs(order) - getOrderNbDofs(order - 1);
643  }
644 
645  /**
646  * \brief Get pinter to Tag keeping approximation order
647  * @return Pointer to Tag
648  */
649  inline const ApproximationOrder *getMaxOrderPtr() const {
650  return tagMaxOrderPtr.get();
651  }
652 
653  /**
654  * \brief Get order set to the entity (Allocated tag size for such number)
655  * @return Approximation order
656  */
658  return *tagMaxOrderPtr.get();
659  }
660 
661  /**
662  * \brief Get global unique id
663  * @return Global UId
664  */
665  const UId &getGlobalUniqueId() const { return globalUId; }
666 
667  /**
668  * \brief Calculate UId for field entity
669  *
670  * UId is constructed such that all DOFs are ordered by processor, entity,
671  * field.
672  *
673  * @param owner_proc owning processor
674  * @param bit_number field bit number
675  * @param moab_owner_handle entity handle on owning processor
676  * @param true_if_distributed_mesh if true UId is constructed for distributed
677  * meshes
678  * @return UId
679  */
680  static inline UId
681  getGlobalUniqueIdCalculate(const int owner_proc, const char bit_number,
682  const EntityHandle moab_owner_handle,
683  const bool true_if_distributed_mesh) {
684  // assert(bit_number < 32);
685  // assert(owner_proc < 1024);
686  constexpr int ent_shift = 8 * sizeof(EntityHandle);
687  if (true_if_distributed_mesh)
688  return (static_cast<UId>(moab_owner_handle) |
689  static_cast<UId>(bit_number) << ent_shift |
690  static_cast<UId>(owner_proc) << 5 + ent_shift)
691  << 9;
692  else
693  return (static_cast<UId>(moab_owner_handle) | static_cast<UId>(bit_number)
694  << ent_shift)
695  << 9;
696  }
697 
698  static inline UId getGlobalUniqueIdCalculate_Low_Proc(const int owner_proc) {
699  return getGlobalUniqueIdCalculate(owner_proc, 0, 0, true);
700  }
701 
702  static inline UId getGlobalUniqueIdCalculate_Hi_Proc(const int owner_proc) {
703  return getGlobalUniqueIdCalculate(owner_proc, BITFIELDID_SIZE - 1,
704  MBMAXTYPE, true);
705  }
706 
707  /**
708  * \brief Calculate global UId
709  * @return Global UId
710  */
713  sPtr->owner_proc, getBitNumber(), sPtr->moab_owner_handle,
714  getBasicDataPtr()->trueIfDistributedMesh());
715  }
716 
717  /**
718  * \brief Get pointer to RefEntity
719  */
720  inline boost::shared_ptr<RefEntity> &getRefEntityPtr() { return this->sPtr; }
721 
722  /**
723  * \brief Get pointer to Field data structure associated with this entity
724  */
725  inline boost::shared_ptr<Field> &getFieldPtr() const {
726  return this->sFieldPtr;
727  }
728 
729  friend std::ostream &operator<<(std::ostream &os, const FieldEntity &e);
730 
731  /**
732  * \brief get hash-map relating dof index on entity with its order
733  *
734  * DOFs of given field are indexed on entity
735  * of the same type, same space, approximation base and number of
736  * coefficients, are sorted in the way.
737  *
738  */
739  inline std::array<int, MAX_DOFS_ON_ENTITY> &getDofOrderMap() const {
740  return getFieldPtr()->getDofOrderMap(getEntType());
741  }
742 
743 private:
744 
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
774  inline int getOrderNbDofs(int order) const {
775  return this->sPtr->getOrderNbDofs(order);
776  }
777 
778  /// @return get increase of DOFs by increase to this order
779  inline int getOrderNbDofsDiff(int order) const {
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 
827  FieldEntity_change_order(const int order, const bool reduce_tag_size = false)
828  : order(order), reduceTagSize(reduce_tag_size) {}
829  inline void operator()(boost::shared_ptr<FieldEntity> &e) {
830  (*this)(e.get());
831  }
832  void operator()(FieldEntity *e);
833 
834 private:
836  const bool reduceTagSize;
837  std::vector<FieldData> data;
838 };
839 
840 /**
841  * @relates multi_index_container
842  * \brief MultiIndex container keeps FieldEntity
843  * \ingroup ent_multi_indices
844  *
845  */
846 typedef multi_index_container<
847  boost::shared_ptr<FieldEntity>,
848  indexed_by<
849  ordered_unique<tag<Unique_mi_tag>,
850  member<FieldEntity, UId, &FieldEntity::globalUId> >,
851  ordered_non_unique<
852  tag<FieldName_mi_tag>,
853  const_mem_fun<FieldEntity::interface_type_Field, boost::string_ref,
855  ordered_non_unique<
856  tag<Ent_mi_tag>,
857  const_mem_fun<FieldEntity, EntityHandle, &FieldEntity::getEnt> >,
858  ordered_non_unique<
859  tag<Composite_Name_And_Ent_mi_tag>,
860  composite_key<
861  FieldEntity,
862  const_mem_fun<FieldEntity::interface_type_Field,
863  boost::string_ref, &FieldEntity::getNameRef>,
864  const_mem_fun<FieldEntity, EntityHandle,
865  &FieldEntity::getEnt> > > > >
867 
868 /** \brief Entity index by field name
869  *
870  * \ingroup ent_multi_indices
871  */
872 typedef FieldEntity_multiIndex::index<FieldName_mi_tag>::type
874 
875 typedef multi_index_container<
876  boost::shared_ptr<FieldEntity>,
877  indexed_by<
878 
879  sequenced<>,
880 
881  ordered_non_unique<
882  tag<Ent_mi_tag>,
883  const_mem_fun<FieldEntity, EntityHandle, &FieldEntity::getEnt>>
884 
885  >>
887 
888 typedef multi_index_container<
889  boost::shared_ptr<FieldEntity>,
890  indexed_by<
891 
892  sequenced<>,
893 
894  ordered_non_unique<
895  tag<Composite_EntType_and_Space_mi_tag>,
896  composite_key<FieldEntity,
897 
899  EntityType, &FieldEntity::getEntType>,
900 
901  const_mem_fun<FieldEntity::interface_type_Field,
903 
904  >>
905 
906  >>
908 
909 typedef std::vector<boost::weak_ptr<FieldEntity>> FieldEntity_vector_view;
910 
911 /**
912  * \brief Keeps basic information about entity on the finite element
913  */
914 struct BaseFEEntity {
915  BaseFEEntity(const boost::shared_ptr<SideNumber> &side_number_ptr)
916  : sideNumberPtr(side_number_ptr){};
917  boost::shared_ptr<SideNumber> sideNumberPtr;
918  inline int getSideNumber() { return sideNumberPtr->side_number; }
919 };
920 
921 } // namespace MoFEM
922 
923 #endif // __ENTSMULTIINDICES_HPP__
924 
925 /***************************************************************************/ /**
926 * \defgroup ent_multi_indices Entities structures and multi-indices
927 * \ingroup mofem
928 ******************************************************************************/
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:290
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)
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:620
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:602
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:280
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:296
auto getVectorAdaptor(T1 ptr, const size_t n)
Get Vector adaptor.
Definition: Templates.hpp:42
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:168
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:285
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
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:289
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
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.