Sierra Toolkit  Version of the Day
Entity.hpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #ifndef stk_mesh_base_Entity_hpp
10 #define stk_mesh_base_Entity_hpp
11 
12 #include <utility>
13 #include <vector>
14 #include <iosfwd>
15 #include <string>
16 
17 #include <stk_mesh/base/Types.hpp>
18 
19 #include <stk_mesh/baseImpl/EntityImpl.hpp>
20 
21 #include <boost/range.hpp>
22 
23 #ifdef SIERRA_MIGRATION
24 #include <stk_mesh/base/Relation.hpp>
25 
26 namespace stk_classic {
27 namespace mesh {
28 typedef RelationVector::const_iterator RelationIterator;
29 typedef boost::iterator_range<RelationIterator> RelationRange;
30 class Entity;
31 
32 //On a *strictly temporary* basis, we need to stick the following
33 //fmwk stuff on an entity, just to help us through the sierra migration.
34 //Move along folks, there's nothing to see here.
35 struct fmwk_attributes {
36  // Each member has an explanation of why it can't be handled by Entity.
37 
38  // Relations of this mesh object that can't be managed by STK such as PARENT/CHILD
39  RelationVector aux_relations;
40 
41  // Not a supported STK_Mesh concept
42  const void* shared_attr;
43 
44  // Cannot just use the id embedded in the entity-key because of negative global-ids
45  // for temporaries.
46  int global_id;
47 
48  // Can't use STK_Mesh's notion of this entity's owner because STK_Mesh is being used
49  // in serial mode and therefore every process will thinks it owns everything.
50  int owner;
51 
52  // Not a supported STK_Mesh concept
53  unsigned short connect_count;
54 };
55 
56 }
57 }
58 
59 namespace sierra {
60 namespace Fmwk {
61 
62 class MeshObjRoster;
63 class MeshObjSharedAttr;
64 class MeshBulkData;
65 
66 extern const unsigned int INVALID_LOCAL_ID;
67 extern const stk_classic::mesh::RelationIterator INVALID_RELATION_ITR;
68 
69 namespace detail {
70 bool set_attributes( stk_classic::mesh::Entity & , const int , const MeshObjSharedAttr*, const int);
71 bool set_attributes( stk_classic::mesh::Entity & , const MeshObjSharedAttr*, const int);
72 void unset_shared_attr(stk_classic::mesh::Entity& );
73 }
74 
75 namespace roster_only {
76 void destroy_meshobj(stk_classic::mesh::Entity*);
77 void set_shared_attr(stk_classic::mesh::Entity&, const MeshObjSharedAttr*);
78 }
79 
80 const MeshObjSharedAttr * get_shared_attr(const stk_classic::mesh::Entity&);
81 bool insert_relation( stk_classic::mesh::Entity * const, const stk_classic::mesh::Relation::RelationType, stk_classic::mesh::Entity * const, const unsigned, const unsigned, const bool, MeshBulkData &);
82 bool remove_relation(stk_classic::mesh::Entity &, const stk_classic::mesh::RelationIterator, MeshBulkData &);
83 bool verify_relations(const stk_classic::mesh::Entity &);
84 }
85 }
86 #endif
87 
88 namespace stk_classic {
89 namespace mesh {
90 
91 namespace impl {
92 
93 class EntityRepository;
94 class BucketRepository;
95 
96 }
97 
102 //----------------------------------------------------------------------
103 
104 //----------------------------------------------------------------------
120 class Entity {
121 public:
122  ~Entity() {}
123 
125  EntityModificationLog log_query() const { return m_entityImpl.log_query(); }
126 
128  EntityRank entity_rank() const { return m_entityImpl.entity_rank(); }
129 
133  EntityId identifier() const { return m_entityImpl.identifier(); }
134 
138  const EntityKey & key() const { return m_entityImpl.key(); }
139 
141  Bucket & bucket() const { return m_entityImpl.bucket(); }
142  Bucket * bucket_ptr() const { return m_entityImpl.bucket_ptr(); }
143 
145  unsigned bucket_ordinal() const { return m_entityImpl.bucket_ordinal(); }
146 
154  size_t synchronized_count() const { return m_entityImpl.synchronized_count(); }
155 
156  //------------------------------------
161  PairIterRelation relations() const { return m_entityImpl.relations(); }
162 
166  PairIterRelation relations( EntityRank type ) const { return m_entityImpl.relations(type); }
167  PairIterRelation node_relations() const { return m_entityImpl.node_relations(); }
168 
169 #ifdef SIERRA_MIGRATION
170  RelationIterator node_relation(unsigned ordinal) const { return m_entityImpl.node_relation(ordinal); }
171 #endif
172 
173  //------------------------------------
175  unsigned owner_rank() const { return m_entityImpl.owner_rank(); }
176 
178  PairIterEntityComm sharing() const { return m_entityImpl.sharing(); }
179 
181  PairIterEntityComm comm() const { return m_entityImpl.comm(); }
182 
184  PairIterEntityComm comm( const Ghosting & sub ) const { return m_entityImpl.comm( sub ); }
185 
186 // RelationVector& rel_vec() { return m_entityImpl.rel_vec(); }
187  void compress_relation_capacity();
188 
189 private:
190 
191  void set_key(const EntityKey& arg_key) { m_entityImpl.set_key(arg_key); }
192 
193  impl::EntityImpl m_entityImpl;
194 
195  explicit Entity( const EntityKey & arg_key );
196 
197  Entity();
198  Entity & operator = ( const Entity & );
199 
200 #ifndef DOXYGEN_COMPILE
201  friend class impl::EntityRepository ;
202  friend class impl::EntityImpl ;
203 #endif /* DOXYGEN_COMPILE */
204 
205 
206 
207 // Issue: We began the migration of Fmwk MeshObj with an implementation that
208 // had a stk entity pointer underneath the MeshObj that could be used to manage
209 // the state that stk entities can manage while leaving the rest to MeshObj.
210 // This proved to be a performance killer since many operations required an
211 // extra dereference (the entity pointer) compared to before, causing lots of
212 // additional cache misses even for simple operations.
213 //
214 // The solution is similar to what we did with Relation; we will use the preprocessor
215 // to add in the Fmwk pieces of the class API when the class is being compiled
216 // with Sierra.
217 #ifdef SIERRA_MIGRATION
218  public:
219  friend class sierra::Fmwk::MeshObjRoster;
220  // These are free functions to facilitate the stk migration:
221  friend const sierra::Fmwk::MeshObjSharedAttr * sierra::Fmwk::get_shared_attr(const Entity &);
222  friend bool sierra::Fmwk::detail::set_attributes( Entity &, const int, const sierra::Fmwk::MeshObjSharedAttr *, const int);
223  friend bool sierra::Fmwk::detail::set_attributes( Entity &, const sierra::Fmwk::MeshObjSharedAttr *, const int);
224  friend void sierra::Fmwk::detail::unset_shared_attr(Entity &);
225  friend bool sierra::Fmwk::insert_relation( Entity * const, const stk_classic::mesh::Relation::RelationType, Entity * const, const unsigned, const unsigned, const bool, sierra::Fmwk::MeshBulkData &);
226  friend bool sierra::Fmwk::remove_relation(Entity &, const stk_classic::mesh::RelationIterator, sierra::Fmwk::MeshBulkData &);
227  friend bool sierra::Fmwk::verify_relations(const Entity &);
228  friend void sierra::Fmwk::roster_only::destroy_meshobj(stk_classic::mesh::Entity*);
229  friend void sierra::Fmwk::roster_only::set_shared_attr(stk_classic::mesh::Entity&, const sierra::Fmwk::MeshObjSharedAttr*);
230 
231  typedef unsigned DerivedType;
232 
236  enum ObjectTypeEnum {
237  NODE = 0, EDGE = 1, FACE = 2, ELEMENT = 3, CONSTRAINT = 4, NUM_TYPES = 5, BASE_CLASS = 0x00ff
238  };
239  static std::string TypeToString (ObjectTypeEnum type);
240 
241 
242 
243  template <class SharedAttr>
244  void init_fmwk(
245  const int id,
246  const SharedAttr* attr,
247  const int owner,
248  const int parallel_rank,
249  const int parallel_size)
250  {
251  ThrowAssertMsg(aux_relations().capacity() == 0, "Leftover memory found in relation vector");
252 
253  m_fmwk_attrs->global_id = id;
254  m_fmwk_attrs->shared_attr = attr;
255  m_fmwk_attrs->owner = owner;
256  m_fmwk_attrs->connect_count = 0;
257  m_local_id = sierra::Fmwk::INVALID_LOCAL_ID;
258 
259  if (attr->locally_owned() && owner_processor_rank() == -1) {
260  m_fmwk_attrs->owner = parallel_rank;
261  ThrowAssert(owner_processor_rank() < parallel_size);
262  }
263 
264  internal_verify_initialization_invariant();
265  }
266 
270  int global_id() const {
271  return m_fmwk_attrs->global_id;
272  }
273 
287  inline unsigned local_id() const { return m_local_id; }
288  void set_local_id(unsigned int l_id) { m_local_id = l_id; }
289 
290  int owner_processor_rank() const { return m_fmwk_attrs->owner; }
291  void set_owner_processor_rank(int owner) { m_fmwk_attrs->owner = owner; }
292 
299  unsigned size_connection() const {
300  return m_fmwk_attrs->connect_count;
301  }
302 
306  unsigned inc_connection() {
307  ++m_fmwk_attrs->connect_count;
308  ThrowAssert(m_fmwk_attrs->connect_count /* Did not roll over */);
309  return m_fmwk_attrs->connect_count;
310  }
311 
315  unsigned dec_connection() {
316  ThrowAssert(m_fmwk_attrs->connect_count /* Will not roll-under */);
317  --m_fmwk_attrs->connect_count;
318  return m_fmwk_attrs->connect_count;
319  }
320 
321  RelationIterator aux_relation_begin() const { return m_fmwk_attrs->aux_relations.begin(); }
322  RelationIterator aux_relation_end() const { return m_fmwk_attrs->aux_relations.end(); }
323 
324  RelationVector& aux_relations() { return m_fmwk_attrs->aux_relations; }
325 
330  RelationIterator internal_begin_relation(const Relation::RelationType relation_type) const {
331  if (internal_is_handled_generically(relation_type)) {
332  return relations().first;
333  }
334  else {
335  return aux_relation_begin();
336  }
337  }
338 
343  RelationIterator internal_end_relation(const Relation::RelationType relation_type) const {
344  if (internal_is_handled_generically(relation_type)) {
345  return relations().second;
346  }
347  else {
348  return aux_relation_end();
349  }
350  }
351 
352  void set_shared_attr(const void* attr) { m_fmwk_attrs->shared_attr = attr; }
353  const void* get_shared_attr() const { return m_fmwk_attrs->shared_attr; }
354 
355  // TODO: Refactor clients so that this method is no longer needed
356  void set_relation_orientation(RelationIterator rel, unsigned orientation);
357 
358  private:
359 
367  void reserve_relation(const unsigned num);
368 
377  bool update_relation(const RelationIterator ir, const bool back_rel_flag) const;
378 
379  RelationIterator find_relation(const Relation& relation) const;
380 
381  void erase_and_clear_if_empty(RelationIterator rel_itr);
382 
383  void internal_verify_meshobj_invariant() const;
384 
385  void internal_swap_in_real_entity(const int globalId);
386 
387  void internal_verify_initialization_invariant() {
388  // If this MeshObj has a proper ID (fully initialized), then the id should match
389  // the id in the entity-key; otherwise they should not match.
390  ThrowAssert( !(m_fmwk_attrs->global_id < 0 && key().id() == static_cast<uint64_t>(m_fmwk_attrs->global_id)) &&
391  !(m_fmwk_attrs->global_id > 0 && key().id() != static_cast<uint64_t>(m_fmwk_attrs->global_id)) );
392 
393  }
394 
395  unsigned stk_entity_rank() const { return key().rank(); }
396 
397  bool internal_is_handled_generically(const Relation::RelationType relation_type) const
398  {
399  return relation_type == Relation::USES || relation_type == Relation::USED_BY;
400  }
401 
402  //
403  // Members needed to support Fmwk_MeshObj API
404  //
405 
406  fmwk_attributes* m_fmwk_attrs;
407 
408  // Not a supported STK_Mesh concept, but fmwk requires it. We have it
409  // here instead of in m_fmwk_attrs for performance reasons (saves a
410  // memory hop when accessing local_id).
411  unsigned m_local_id;
412 #endif
413 };
414 
415 #ifdef SIERRA_MIGRATION
416 
417 inline
418 Relation::RelationType
419 back_relation_type(const Relation::RelationType relType)
420 {
421  /* %TRACE[NONE]% */ /* %TRACE% */
422  switch(relType) {
423  case Relation::USES:
424  return Relation::USED_BY;
425  case Relation::USED_BY:
426  return Relation::USES;
427  case Relation::CHILD:
428  return Relation::PARENT;
429  case Relation::PARENT:
430  return Relation::CHILD;
431  default:
432  return relType;
433  }
434 }
435 
436 // Made publicly available so that MeshObj.C can use it
437 template <class Iterator>
438 bool
439 verify_relation_ordering(Iterator begin, Iterator end)
440 {
441  for (Iterator itr = begin; itr != end; ) {
442  Iterator prev = itr;
443  ++itr;
444  if (itr != end) {
445 
446  if (itr->entity_rank() < prev->entity_rank()) {
447  return false ;
448  }
449 
450  if (itr->entity_rank() == prev->entity_rank()) {
451 
452  if (itr->getRelationType() < prev->getRelationType()) {
453  return false ;
454  }
455 
456  if (itr->getRelationType() == prev->getRelationType()) {
457 
458  if (itr->getOrdinal() < prev->getOrdinal()) {
459  return false ;
460  }
461  }
462  }
463  }
464  }
465  return true ;
466 }
467 
468 template <class Range>
469 bool
470 verify_relation_ordering(Range range)
471 {
472  return verify_relation_ordering(boost::const_begin(range), boost::const_end(range));
473 }
474 
475 #endif
476 
478 class EntityLess {
479 public:
480  ~EntityLess() {}
481  EntityLess() {}
482  EntityLess( const EntityLess & ) {}
483  EntityLess & operator = ( const EntityLess & ) { return *this ; }
484 
486  bool operator()(const Entity& lhs, const Entity& rhs) const
487  { return lhs.key() < rhs.key(); }
488 
489  bool operator()(const Entity& lhs, const EntityKey & rhs) const
490  { return lhs.key() < rhs ; }
491 
493  bool operator()(const Entity* lhs, const Entity* rhs) const
494  {
495  const EntityKey lhs_key = lhs ? lhs->key() : EntityKey() ;
496  const EntityKey rhs_key = rhs ? rhs->key() : EntityKey() ;
497  return lhs_key < rhs_key ;
498  }
499 
500  bool operator()(const Entity* lhs, const Entity& rhs) const
501  {
502  const EntityKey lhs_key = lhs ? lhs->key() : EntityKey();
503  return lhs_key < rhs.key() ;
504  }
505 
506  bool operator()(const Entity& lhs, const Entity* rhs) const
507  {
508  const EntityKey rhs_key = rhs ? rhs->key() : EntityKey();
509  return lhs.key() < rhs_key ;
510  }
511 
512  bool operator()(const Entity* lhs, const EntityKey & rhs) const
513  {
514  const EntityKey lhs_key = lhs ? lhs->key() : EntityKey() ;
515  return lhs_key < rhs ;
516  }
517 
518  bool operator()( const EntityProc & lhs, const EntityProc & rhs) const
519  {
520  const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ;
521  const EntityKey rhs_key = rhs.first ? rhs.first->key() : EntityKey() ;
522  return lhs_key != rhs_key ? lhs_key < rhs_key : lhs.second < rhs.second ;
523  }
524 
525  bool operator()( const EntityProc & lhs, const Entity & rhs) const
526  {
527  const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ;
528  return lhs_key < rhs.key();
529  }
530 
531  bool operator()( const EntityProc & lhs, const Entity * rhs) const
532  {
533  const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ;
534  const EntityKey rhs_key = rhs ? rhs->key() : EntityKey() ;
535  return lhs_key < rhs_key ;
536  }
537 
538  bool operator()( const EntityProc & lhs, const EntityKey & rhs) const
539  {
540  const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ;
541  return lhs_key < rhs ;
542  }
543 
544 }; //class EntityLess
545 
546 class EntityEqual
547 {
548 public:
549  bool operator()(const stk_classic::mesh::Entity* lhs, const stk_classic::mesh::Entity* rhs) const
550  {
551  const stk_classic::mesh::EntityKey lhs_key = lhs ? lhs->key() : stk_classic::mesh::EntityKey();
552  const stk_classic::mesh::EntityKey rhs_key = rhs ? rhs->key() : stk_classic::mesh::EntityKey();
553  return lhs_key == rhs_key;
554  }
555 
556  bool operator()(const stk_classic::mesh::Entity& lhs, const stk_classic::mesh::Entity& rhs) const
557  {
558  const stk_classic::mesh::EntityKey lhs_key = lhs.key();
559  const stk_classic::mesh::EntityKey rhs_key = rhs.key();
560  return lhs_key == rhs_key;
561  }
562 };
563 
564 std::string print_entity_key(const Entity& entity);
565 
566 std::string print_entity_key(const Entity* entity);
567 
568 inline
569 Entity::Entity()
570  : m_entityImpl()
571 #ifdef SIERRA_MIGRATION
572  , m_fmwk_attrs(NULL)
573 #endif
574 {}
575 
576 inline
577 Entity::Entity( const EntityKey & arg_key )
578  : m_entityImpl( arg_key )
579 #ifdef SIERRA_MIGRATION
580  , m_fmwk_attrs(NULL)
581 #endif
582 {}
583 
586 } // namespace mesh
587 } // namespace stk_classic
588 
589 #endif /* stk_mesh_base_Entity_hpp */
Comparison operator for entities compares the entities&#39; keys.
Definition: Entity.hpp:478
PairIterEntityComm comm() const
Complete communicaiton list for this entity.
Definition: Entity.hpp:181
size_t synchronized_count() const
The mesh bulk data synchronized_count when this entity&#39;s part membership was most recently modified...
Definition: Entity.hpp:154
unsigned bucket_ordinal() const
The ordinal for this entity within its bucket.
Definition: Entity.hpp:145
Definition: Env.cpp:53
PairIterEntityComm sharing() const
Parallel processes which share this entity.
Definition: Entity.hpp:178
Data for ghosting mesh entities.
Definition: Ghosting.hpp:28
Bucket & bucket() const
The bucket which holds this mesh entity&#39;s field data.
Definition: Entity.hpp:141
const EntityKey & key() const
The globally unique key ( entity type + identifier ) of this entity.
Definition: Entity.hpp:138
Integer type for the entity keys, which is an encoding of the entity type and entity identifier...
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
Definition: Types.hpp:111
int parallel_rank()
function parallel_rank returns the rank of this processor in the current mpi communicator.
Definition: Env.cpp:318
EntityModificationLog log_query() const
Query the current state of the entity log.
Definition: Entity.hpp:125
bool operator()(const Entity *lhs, const Entity *rhs) const
Comparison operator.
Definition: Entity.hpp:493
PairIterRelation relations(EntityRank type) const
Entity relations for which this entity is a member, the other entity is of a given type...
Definition: Entity.hpp:166
PairIterEntityComm comm(const Ghosting &sub) const
Subset communicaiton list for this entity.
Definition: Entity.hpp:184
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Definition: Entity.hpp:161
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
Sierra Toolkit.
int parallel_size()
function parallel_size returns the number of processors in the current mpi communicator.
Definition: Env.cpp:314
EntityRank entity_rank() const
The rank of this entity.
Definition: Entity.hpp:128
EntityId identifier() const
Identifier for this entity which is globally unique for a given entity type.
Definition: Entity.hpp:133
bool operator()(const Entity &lhs, const Entity &rhs) const
Comparison operator.
Definition: Entity.hpp:486
std::vector< Relation > RelationVector
Span of a sorted relations for a given domain entity.
Definition: Types.hpp:161
A container for the field data of a homogeneous collection of entities.
Definition: Bucket.hpp:94
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
Definition: Entity.hpp:175