|
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 00010 #ifndef stk_mesh_Relation_hpp 00011 #define stk_mesh_Relation_hpp 00012 00013 #include <iosfwd> 00014 #include <limits> 00015 00016 #include <stk_mesh/base/EntityKey.hpp> 00017 00018 #include <boost/static_assert.hpp> 00019 00020 #ifdef SIERRA_MIGRATION 00021 00022 namespace stk_classic { 00023 namespace mesh { 00024 class Entity; 00025 } 00026 } 00027 #endif 00028 00029 namespace stk_classic { 00030 namespace mesh { 00031 00035 //---------------------------------------------------------------------- 00058 class Relation { 00059 public: 00060 typedef uint32_t raw_relation_id_type ; 00061 typedef uint32_t attribute_type; 00062 00064 Relation(); 00065 00068 Relation( Entity & entity , RelationIdentifier identifier ); 00069 00070 attribute_type attribute() const { return m_attribute; } 00071 void set_attribute(attribute_type attr) const { m_attribute = attr; } 00072 00074 static raw_relation_id_type raw_relation_id( unsigned rank , unsigned id ); 00075 00077 raw_relation_id_type raw_relation_id() const { return m_raw_relation.value ; } 00078 00080 unsigned entity_rank() const ; 00081 00083 RelationIdentifier identifier() const ; 00084 00086 Entity * entity() const { return m_target_entity ; } 00087 00089 bool operator == ( const Relation & r ) const; 00090 00092 bool operator != ( const Relation & r ) const 00093 { return !(*this == r); } 00094 00096 bool operator < ( const Relation & r ) const ; 00097 00098 private: 00099 00100 00101 enum { 00102 rank_digits = 8 , 00103 id_digits = 24 , 00104 id_mask = ~(0u) >> rank_digits 00105 #ifdef SIERRA_MIGRATION 00106 , 00107 fwmk_relation_type_digits = 8, 00108 fmwk_orientation_digits = 24, 00109 fmwk_orientation_mask = ~(0u) >> fwmk_relation_type_digits 00110 #endif 00111 }; 00112 00113 BOOST_STATIC_ASSERT(( static_cast<unsigned>(EntityKey::rank_digits) == static_cast<unsigned>(rank_digits) )); 00114 00115 union RawRelationType { 00116 public: 00117 raw_relation_id_type value ; 00118 00119 struct { 00120 raw_relation_id_type identifier : id_digits ; 00121 raw_relation_id_type entity_rank : rank_digits ; 00122 } normal_view ; 00123 00124 struct { 00125 raw_relation_id_type entity_rank : rank_digits ; 00126 raw_relation_id_type identifier : id_digits ; 00127 } reverse_view ; 00128 00129 RawRelationType( raw_relation_id_type v ) : value(v) {} 00130 RawRelationType() : value(0) {} 00131 RawRelationType( const RawRelationType & rhs ) : value( rhs.value ) {} 00132 RawRelationType & operator = ( const RawRelationType & rhs ) 00133 { value = rhs.value ; return *this ; } 00134 }; 00135 00136 RawRelationType m_raw_relation ; 00137 mutable attribute_type m_attribute ; 00138 Entity * m_target_entity ; 00139 00140 // Issue: Framework supports relation types (parent, child, etc) that STK_Mesh 00141 // does not support, so these relations will have to be managed by framework 00142 // until: 00143 // A) STK_Mesh is rewritten to support these extra relation types 00144 // B) An extra data-structure is added to manage these relation types and 00145 // this data structure works together with STK_mesh under the generic API 00146 // to manage all relation-types. 00147 // C) We transition to using a mesh that supports everything framework 00148 // supports and this problem goes away. 00149 // 00150 // The problem is that, with framework managing some relations and STK_Mesh 00151 // managing others, the type of the relation descriptor is different depending 00152 // on what type of relation you're dealing with. This can be addressed with 00153 // templates, but this makes the code very ugly. Instead... 00154 // 00155 // Solution: Have framework and STK_Mesh use the same type as its relation_descriptor. 00156 // The code below is designed to make this class compatible with the fmwk 00157 // Relation class. 00158 #ifdef SIERRA_MIGRATION 00159 public: 00163 enum RelationType { 00164 USES = 0 , 00165 USED_BY = 1 , 00166 CHILD = 2 , 00167 PARENT = 3 , 00168 EMBEDDED = 0x00ff , // 4 00169 CONTACT = 0x00ff , // 5 00170 AUXILIARY = 0x00ff , 00171 INVALID = 10 00172 }; 00173 00174 enum { 00175 POLARITY_MASK = 0x80, 00176 POLARITY_POSITIVE = 0x80, 00177 POLARITY_NEGATIVE = 0x00, 00178 POLARITY_IDENTITY = 0x80 00179 }; 00180 00181 static bool polarity(unsigned orient) { 00182 return (orient & POLARITY_MASK) == POLARITY_POSITIVE; 00183 } 00184 00185 static unsigned permutation(unsigned orient) { 00186 return orient & ~POLARITY_MASK; 00187 } 00188 00192 Relation(Entity *obj, const unsigned relation_type, const unsigned ordinal, const unsigned orient = 0); 00193 00194 Entity *getMeshObj() const { 00195 return entity(); 00196 } 00197 00198 void setMeshObj(Entity *object); 00199 00200 RelationType getRelationType() const { 00201 return static_cast<RelationType>(attribute() >> fmwk_orientation_digits); 00202 } 00203 00204 void setRelationType(RelationType relation_type) { 00205 set_attribute( (relation_type << fmwk_orientation_digits) | getOrientation() ); 00206 } 00207 00208 RelationIdentifier getOrdinal() const { 00209 return identifier(); 00210 } 00211 00212 void setOrdinal(RelationIdentifier ordinal) { 00213 m_raw_relation = Relation::raw_relation_id( entity_rank(), ordinal ); 00214 } 00215 00216 attribute_type getOrientation() const { 00217 return attribute() & fmwk_orientation_mask; 00218 } 00219 00220 void setOrientation(attribute_type orientation) { 00221 set_attribute( (getRelationType() << fmwk_orientation_digits) | orientation ); 00222 } 00223 00234 bool polarity() const { 00235 return (getOrientation() & POLARITY_MASK) == POLARITY_POSITIVE; 00236 } 00237 00238 unsigned permutation() const { 00239 return getOrientation() & ~POLARITY_MASK; 00240 } 00241 00242 private: 00243 bool has_fmwk_state() const { return getRelationType() != INVALID; } 00244 #endif // SIERRA_MIGRATION 00245 }; 00246 00247 //---------------------------------------------------------------------- 00248 00249 inline 00250 Relation::raw_relation_id_type 00251 Relation::raw_relation_id( unsigned rank , unsigned id ) 00252 { 00253 ThrowAssertMsg( id <= id_mask, 00254 "For args rank " << rank << ", id " << id << ": " << 00255 "id " << " > id_mask=" << id_mask ); 00256 00257 return ( raw_relation_id_type(rank) << id_digits ) | id ; 00258 } 00259 00260 inline 00261 unsigned Relation::entity_rank() const 00262 { return m_raw_relation.value >> id_digits; } 00263 00264 inline 00265 RelationIdentifier Relation::identifier() const 00266 { return unsigned( m_raw_relation.value & id_mask ); } 00267 00268 struct LessRelation { 00269 bool operator() ( const Relation & lhs , const Relation & rhs ) const 00270 { return lhs < rhs ; } 00271 00272 bool operator() ( const Relation & lhs , Relation::raw_relation_id_type rhs ) const 00273 { return lhs.raw_relation_id() < rhs ; } 00274 }; 00275 00276 //---------------------------------------------------------------------- 00280 void get_entities_through_relations( 00281 const std::vector<Entity*> & entities , 00282 std::vector<Entity*> & entities_related ); 00283 00288 void get_entities_through_relations( 00289 const std::vector<Entity*> & entities , 00290 EntityRank entities_related_rank , 00291 std::vector<Entity*> & entities_related ); 00292 00293 //---------------------------------------------------------------------- 00297 bool membership_is_induced( const Part & part , unsigned entity_rank ); 00298 00302 void induced_part_membership( Part & part , 00303 unsigned entity_rank_from , 00304 unsigned entity_rank_to , 00305 RelationIdentifier relation_identifier , 00306 OrdinalVector & induced_parts, 00307 bool include_supersets=true); 00308 00312 void induced_part_membership( const Entity & entity_from , 00313 const OrdinalVector & omit , 00314 unsigned entity_rank_to , 00315 RelationIdentifier relation_identifier , 00316 OrdinalVector & induced_parts, 00317 bool include_supersets=true); 00318 00322 void induced_part_membership( const Entity & entity , 00323 const OrdinalVector & omit , 00324 OrdinalVector & induced_parts, 00325 bool include_supersets=true); 00326 00327 00328 //---------------------------------------------------------------------- 00329 00330 #if 0 00331 00332 std::ostream & 00333 print_relation( std::ostream & , Relation::raw__attr_type ); 00334 00336 std::ostream & 00337 print_relation( std::ostream & , const MetaData & , 00338 Relation::raw__attr_type , EntityKey ); 00339 #endif 00340 00342 std::ostream & operator << ( std::ostream & , const Relation & ); 00343 00346 inline 00347 Relation::Relation() : 00348 m_raw_relation(), 00349 m_attribute(), 00350 m_target_entity(NULL) 00351 { 00352 #ifdef SIERRA_MIGRATION 00353 setRelationType(INVALID); 00354 #endif 00355 } 00356 00357 inline 00358 bool Relation::operator == ( const Relation & rhs ) const 00359 { 00360 return m_raw_relation.value == rhs.m_raw_relation.value && m_target_entity == rhs.m_target_entity 00361 #ifdef SIERRA_MIGRATION 00362 // compared fmwk state too 00363 && m_attribute == rhs.m_attribute 00364 #endif 00365 ; 00366 } 00367 00368 inline 00369 bool same_specification(const Relation& lhs, const Relation& rhs) 00370 { 00371 #ifdef SIERRA_MIGRATION 00372 return lhs.entity_rank() == rhs.entity_rank() && 00373 lhs.getRelationType() == rhs.getRelationType() && 00374 lhs.getOrdinal() == rhs.getOrdinal(); 00375 #else 00376 return lhs.entity_rank() == rhs.entity_rank(); 00377 #endif 00378 } 00379 00380 } // namespace mesh 00381 } // namespace stk_classic 00382 00383 //---------------------------------------------------------------------- 00384 //---------------------------------------------------------------------- 00385 00386 #endif /* stk_mesh_Relation_hpp */ 00387