|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #ifndef stk_mesh_base_Entity_hpp 00010 #define stk_mesh_base_Entity_hpp 00011 00012 #include <utility> 00013 #include <vector> 00014 #include <iosfwd> 00015 #include <string> 00016 00017 #include <stk_mesh/base/Types.hpp> 00018 00019 #include <stk_mesh/baseImpl/EntityImpl.hpp> 00020 00021 #include <boost/range.hpp> 00022 00023 #ifdef SIERRA_MIGRATION 00024 #include <stk_mesh/base/Relation.hpp> 00025 00026 namespace stk_classic { 00027 namespace mesh { 00028 typedef RelationVector::const_iterator RelationIterator; 00029 typedef boost::iterator_range<RelationIterator> RelationRange; 00030 class Entity; 00031 00032 //On a *strictly temporary* basis, we need to stick the following 00033 //fmwk stuff on an entity, just to help us through the sierra migration. 00034 //Move along folks, there's nothing to see here. 00035 struct fmwk_attributes { 00036 // Each member has an explanation of why it can't be handled by Entity. 00037 00038 // Relations of this mesh object that can't be managed by STK such as PARENT/CHILD 00039 RelationVector aux_relations; 00040 00041 // Not a supported STK_Mesh concept 00042 const void* shared_attr; 00043 00044 // Cannot just use the id embedded in the entity-key because of negative global-ids 00045 // for temporaries. 00046 int global_id; 00047 00048 // Can't use STK_Mesh's notion of this entity's owner because STK_Mesh is being used 00049 // in serial mode and therefore every process will thinks it owns everything. 00050 int owner; 00051 00052 // Not a supported STK_Mesh concept 00053 unsigned short connect_count; 00054 }; 00055 00056 } 00057 } 00058 00059 namespace sierra { 00060 namespace Fmwk { 00061 00062 class MeshObjRoster; 00063 class MeshObjSharedAttr; 00064 class MeshBulkData; 00065 00066 extern const unsigned int INVALID_LOCAL_ID; 00067 extern const stk_classic::mesh::RelationIterator INVALID_RELATION_ITR; 00068 00069 namespace detail { 00070 bool set_attributes( stk_classic::mesh::Entity & , const int , const MeshObjSharedAttr*, const int); 00071 bool set_attributes( stk_classic::mesh::Entity & , const MeshObjSharedAttr*, const int); 00072 void unset_shared_attr(stk_classic::mesh::Entity& ); 00073 } 00074 00075 namespace roster_only { 00076 void destroy_meshobj(stk_classic::mesh::Entity*); 00077 void set_shared_attr(stk_classic::mesh::Entity&, const MeshObjSharedAttr*); 00078 } 00079 00080 const MeshObjSharedAttr * get_shared_attr(const stk_classic::mesh::Entity&); 00081 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 &); 00082 bool remove_relation(stk_classic::mesh::Entity &, const stk_classic::mesh::RelationIterator, MeshBulkData &); 00083 bool verify_relations(const stk_classic::mesh::Entity &); 00084 } 00085 } 00086 #endif 00087 00088 namespace stk_classic { 00089 namespace mesh { 00090 00091 namespace impl { 00092 00093 class EntityRepository; 00094 class BucketRepository; 00095 00096 } 00097 00102 //---------------------------------------------------------------------- 00103 00104 //---------------------------------------------------------------------- 00120 class Entity { 00121 public: 00122 ~Entity() {} 00123 00125 EntityModificationLog log_query() const { return m_entityImpl.log_query(); } 00126 00128 EntityRank entity_rank() const { return m_entityImpl.entity_rank(); } 00129 00133 EntityId identifier() const { return m_entityImpl.identifier(); } 00134 00138 const EntityKey & key() const { return m_entityImpl.key(); } 00139 00141 Bucket & bucket() const { return m_entityImpl.bucket(); } 00142 Bucket * bucket_ptr() const { return m_entityImpl.bucket_ptr(); } 00143 00145 unsigned bucket_ordinal() const { return m_entityImpl.bucket_ordinal(); } 00146 00154 size_t synchronized_count() const { return m_entityImpl.synchronized_count(); } 00155 00156 //------------------------------------ 00161 PairIterRelation relations() const { return m_entityImpl.relations(); } 00162 00166 PairIterRelation relations( EntityRank type ) const { return m_entityImpl.relations(type); } 00167 PairIterRelation node_relations() const { return m_entityImpl.node_relations(); } 00168 00169 #ifdef SIERRA_MIGRATION 00170 RelationIterator node_relation(unsigned ordinal) const { return m_entityImpl.node_relation(ordinal); } 00171 #endif 00172 00173 //------------------------------------ 00175 unsigned owner_rank() const { return m_entityImpl.owner_rank(); } 00176 00178 PairIterEntityComm sharing() const { return m_entityImpl.sharing(); } 00179 00181 PairIterEntityComm comm() const { return m_entityImpl.comm(); } 00182 00184 PairIterEntityComm comm( const Ghosting & sub ) const { return m_entityImpl.comm( sub ); } 00185 00186 // RelationVector& rel_vec() { return m_entityImpl.rel_vec(); } 00187 void compress_relation_capacity(); 00188 00189 private: 00190 00191 void set_key(const EntityKey& arg_key) { m_entityImpl.set_key(arg_key); } 00192 00193 impl::EntityImpl m_entityImpl; 00194 00195 explicit Entity( const EntityKey & arg_key ); 00196 00197 Entity(); 00198 Entity & operator = ( const Entity & ); 00199 00200 #ifndef DOXYGEN_COMPILE 00201 friend class impl::EntityRepository ; 00202 friend class impl::EntityImpl ; 00203 #endif /* DOXYGEN_COMPILE */ 00204 00205 00206 00207 // Issue: We began the migration of Fmwk MeshObj with an implementation that 00208 // had a stk entity pointer underneath the MeshObj that could be used to manage 00209 // the state that stk entities can manage while leaving the rest to MeshObj. 00210 // This proved to be a performance killer since many operations required an 00211 // extra dereference (the entity pointer) compared to before, causing lots of 00212 // additional cache misses even for simple operations. 00213 // 00214 // The solution is similar to what we did with Relation; we will use the preprocessor 00215 // to add in the Fmwk pieces of the class API when the class is being compiled 00216 // with Sierra. 00217 #ifdef SIERRA_MIGRATION 00218 public: 00219 friend class sierra::Fmwk::MeshObjRoster; 00220 // These are free functions to facilitate the stk migration: 00221 friend const sierra::Fmwk::MeshObjSharedAttr * sierra::Fmwk::get_shared_attr(const Entity &); 00222 friend bool sierra::Fmwk::detail::set_attributes( Entity &, const int, const sierra::Fmwk::MeshObjSharedAttr *, const int); 00223 friend bool sierra::Fmwk::detail::set_attributes( Entity &, const sierra::Fmwk::MeshObjSharedAttr *, const int); 00224 friend void sierra::Fmwk::detail::unset_shared_attr(Entity &); 00225 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 &); 00226 friend bool sierra::Fmwk::remove_relation(Entity &, const stk_classic::mesh::RelationIterator, sierra::Fmwk::MeshBulkData &); 00227 friend bool sierra::Fmwk::verify_relations(const Entity &); 00228 friend void sierra::Fmwk::roster_only::destroy_meshobj(stk_classic::mesh::Entity*); 00229 friend void sierra::Fmwk::roster_only::set_shared_attr(stk_classic::mesh::Entity&, const sierra::Fmwk::MeshObjSharedAttr*); 00230 00231 typedef unsigned DerivedType; 00232 00236 enum ObjectTypeEnum { 00237 NODE = 0, EDGE = 1, FACE = 2, ELEMENT = 3, CONSTRAINT = 4, NUM_TYPES = 5, BASE_CLASS = 0x00ff 00238 }; 00239 static std::string TypeToString (ObjectTypeEnum type); 00240 00241 00242 00243 template <class SharedAttr> 00244 void init_fmwk( 00245 const int id, 00246 const SharedAttr* attr, 00247 const int owner, 00248 const int parallel_rank, 00249 const int parallel_size) 00250 { 00251 ThrowAssertMsg(aux_relations().capacity() == 0, "Leftover memory found in relation vector"); 00252 00253 m_fmwk_attrs->global_id = id; 00254 m_fmwk_attrs->shared_attr = attr; 00255 m_fmwk_attrs->owner = owner; 00256 m_fmwk_attrs->connect_count = 0; 00257 m_local_id = sierra::Fmwk::INVALID_LOCAL_ID; 00258 00259 if (attr->locally_owned() && owner_processor_rank() == -1) { 00260 m_fmwk_attrs->owner = parallel_rank; 00261 ThrowAssert(owner_processor_rank() < parallel_size); 00262 } 00263 00264 internal_verify_initialization_invariant(); 00265 } 00266 00270 int global_id() const { 00271 return m_fmwk_attrs->global_id; 00272 } 00273 00287 inline unsigned local_id() const { return m_local_id; } 00288 void set_local_id(unsigned int l_id) { m_local_id = l_id; } 00289 00290 int owner_processor_rank() const { return m_fmwk_attrs->owner; } 00291 void set_owner_processor_rank(int owner) { m_fmwk_attrs->owner = owner; } 00292 00299 unsigned size_connection() const { 00300 return m_fmwk_attrs->connect_count; 00301 } 00302 00306 unsigned inc_connection() { 00307 ++m_fmwk_attrs->connect_count; 00308 ThrowAssert(m_fmwk_attrs->connect_count /* Did not roll over */); 00309 return m_fmwk_attrs->connect_count; 00310 } 00311 00315 unsigned dec_connection() { 00316 ThrowAssert(m_fmwk_attrs->connect_count /* Will not roll-under */); 00317 --m_fmwk_attrs->connect_count; 00318 return m_fmwk_attrs->connect_count; 00319 } 00320 00321 RelationIterator aux_relation_begin() const { return m_fmwk_attrs->aux_relations.begin(); } 00322 RelationIterator aux_relation_end() const { return m_fmwk_attrs->aux_relations.end(); } 00323 00324 RelationVector& aux_relations() { return m_fmwk_attrs->aux_relations; } 00325 00330 RelationIterator internal_begin_relation(const Relation::RelationType relation_type) const { 00331 if (internal_is_handled_generically(relation_type)) { 00332 return relations().first; 00333 } 00334 else { 00335 return aux_relation_begin(); 00336 } 00337 } 00338 00343 RelationIterator internal_end_relation(const Relation::RelationType relation_type) const { 00344 if (internal_is_handled_generically(relation_type)) { 00345 return relations().second; 00346 } 00347 else { 00348 return aux_relation_end(); 00349 } 00350 } 00351 00352 void set_shared_attr(const void* attr) { m_fmwk_attrs->shared_attr = attr; } 00353 const void* get_shared_attr() const { return m_fmwk_attrs->shared_attr; } 00354 00355 // TODO: Refactor clients so that this method is no longer needed 00356 void set_relation_orientation(RelationIterator rel, unsigned orientation); 00357 00358 private: 00359 00367 void reserve_relation(const unsigned num); 00368 00377 bool update_relation(const RelationIterator ir, const bool back_rel_flag) const; 00378 00379 RelationIterator find_relation(const Relation& relation) const; 00380 00381 void erase_and_clear_if_empty(RelationIterator rel_itr); 00382 00383 void internal_verify_meshobj_invariant() const; 00384 00385 void internal_swap_in_real_entity(const int globalId); 00386 00387 void internal_verify_initialization_invariant() { 00388 // If this MeshObj has a proper ID (fully initialized), then the id should match 00389 // the id in the entity-key; otherwise they should not match. 00390 ThrowAssert( !(m_fmwk_attrs->global_id < 0 && key().id() == static_cast<uint64_t>(m_fmwk_attrs->global_id)) && 00391 !(m_fmwk_attrs->global_id > 0 && key().id() != static_cast<uint64_t>(m_fmwk_attrs->global_id)) ); 00392 00393 } 00394 00395 unsigned stk_entity_rank() const { return key().rank(); } 00396 00397 bool internal_is_handled_generically(const Relation::RelationType relation_type) const 00398 { 00399 return relation_type == Relation::USES || relation_type == Relation::USED_BY; 00400 } 00401 00402 // 00403 // Members needed to support Fmwk_MeshObj API 00404 // 00405 00406 fmwk_attributes* m_fmwk_attrs; 00407 00408 // Not a supported STK_Mesh concept, but fmwk requires it. We have it 00409 // here instead of in m_fmwk_attrs for performance reasons (saves a 00410 // memory hop when accessing local_id). 00411 unsigned m_local_id; 00412 #endif 00413 }; 00414 00415 #ifdef SIERRA_MIGRATION 00416 00417 inline 00418 Relation::RelationType 00419 back_relation_type(const Relation::RelationType relType) 00420 { 00421 /* %TRACE[NONE]% */ /* %TRACE% */ 00422 switch(relType) { 00423 case Relation::USES: 00424 return Relation::USED_BY; 00425 case Relation::USED_BY: 00426 return Relation::USES; 00427 case Relation::CHILD: 00428 return Relation::PARENT; 00429 case Relation::PARENT: 00430 return Relation::CHILD; 00431 default: 00432 return relType; 00433 } 00434 } 00435 00436 // Made publicly available so that MeshObj.C can use it 00437 template <class Iterator> 00438 bool 00439 verify_relation_ordering(Iterator begin, Iterator end) 00440 { 00441 for (Iterator itr = begin; itr != end; ) { 00442 Iterator prev = itr; 00443 ++itr; 00444 if (itr != end) { 00445 00446 if (itr->entity_rank() < prev->entity_rank()) { 00447 return false ; 00448 } 00449 00450 if (itr->entity_rank() == prev->entity_rank()) { 00451 00452 if (itr->getRelationType() < prev->getRelationType()) { 00453 return false ; 00454 } 00455 00456 if (itr->getRelationType() == prev->getRelationType()) { 00457 00458 if (itr->getOrdinal() < prev->getOrdinal()) { 00459 return false ; 00460 } 00461 } 00462 } 00463 } 00464 } 00465 return true ; 00466 } 00467 00468 template <class Range> 00469 bool 00470 verify_relation_ordering(Range range) 00471 { 00472 return verify_relation_ordering(boost::const_begin(range), boost::const_end(range)); 00473 } 00474 00475 #endif 00476 00478 class EntityLess { 00479 public: 00480 ~EntityLess() {} 00481 EntityLess() {} 00482 EntityLess( const EntityLess & ) {} 00483 EntityLess & operator = ( const EntityLess & ) { return *this ; } 00484 00486 bool operator()(const Entity& lhs, const Entity& rhs) const 00487 { return lhs.key() < rhs.key(); } 00488 00489 bool operator()(const Entity& lhs, const EntityKey & rhs) const 00490 { return lhs.key() < rhs ; } 00491 00493 bool operator()(const Entity* lhs, const Entity* rhs) const 00494 { 00495 const EntityKey lhs_key = lhs ? lhs->key() : EntityKey() ; 00496 const EntityKey rhs_key = rhs ? rhs->key() : EntityKey() ; 00497 return lhs_key < rhs_key ; 00498 } 00499 00500 bool operator()(const Entity* lhs, const Entity& rhs) const 00501 { 00502 const EntityKey lhs_key = lhs ? lhs->key() : EntityKey(); 00503 return lhs_key < rhs.key() ; 00504 } 00505 00506 bool operator()(const Entity& lhs, const Entity* rhs) const 00507 { 00508 const EntityKey rhs_key = rhs ? rhs->key() : EntityKey(); 00509 return lhs.key() < rhs_key ; 00510 } 00511 00512 bool operator()(const Entity* lhs, const EntityKey & rhs) const 00513 { 00514 const EntityKey lhs_key = lhs ? lhs->key() : EntityKey() ; 00515 return lhs_key < rhs ; 00516 } 00517 00518 bool operator()( const EntityProc & lhs, const EntityProc & rhs) const 00519 { 00520 const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ; 00521 const EntityKey rhs_key = rhs.first ? rhs.first->key() : EntityKey() ; 00522 return lhs_key != rhs_key ? lhs_key < rhs_key : lhs.second < rhs.second ; 00523 } 00524 00525 bool operator()( const EntityProc & lhs, const Entity & rhs) const 00526 { 00527 const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ; 00528 return lhs_key < rhs.key(); 00529 } 00530 00531 bool operator()( const EntityProc & lhs, const Entity * rhs) const 00532 { 00533 const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ; 00534 const EntityKey rhs_key = rhs ? rhs->key() : EntityKey() ; 00535 return lhs_key < rhs_key ; 00536 } 00537 00538 bool operator()( const EntityProc & lhs, const EntityKey & rhs) const 00539 { 00540 const EntityKey lhs_key = lhs.first ? lhs.first->key() : EntityKey() ; 00541 return lhs_key < rhs ; 00542 } 00543 00544 }; //class EntityLess 00545 00546 class EntityEqual 00547 { 00548 public: 00549 bool operator()(const stk_classic::mesh::Entity* lhs, const stk_classic::mesh::Entity* rhs) const 00550 { 00551 const stk_classic::mesh::EntityKey lhs_key = lhs ? lhs->key() : stk_classic::mesh::EntityKey(); 00552 const stk_classic::mesh::EntityKey rhs_key = rhs ? rhs->key() : stk_classic::mesh::EntityKey(); 00553 return lhs_key == rhs_key; 00554 } 00555 00556 bool operator()(const stk_classic::mesh::Entity& lhs, const stk_classic::mesh::Entity& rhs) const 00557 { 00558 const stk_classic::mesh::EntityKey lhs_key = lhs.key(); 00559 const stk_classic::mesh::EntityKey rhs_key = rhs.key(); 00560 return lhs_key == rhs_key; 00561 } 00562 }; 00563 00564 std::string print_entity_key(const Entity& entity); 00565 00566 std::string print_entity_key(const Entity* entity); 00567 00568 inline 00569 Entity::Entity() 00570 : m_entityImpl() 00571 #ifdef SIERRA_MIGRATION 00572 , m_fmwk_attrs(NULL) 00573 #endif 00574 {} 00575 00576 inline 00577 Entity::Entity( const EntityKey & arg_key ) 00578 : m_entityImpl( arg_key ) 00579 #ifdef SIERRA_MIGRATION 00580 , m_fmwk_attrs(NULL) 00581 #endif 00582 {} 00583 00586 } // namespace mesh 00587 } // namespace stk_classic 00588 00589 #endif /* stk_mesh_base_Entity_hpp */