Sierra Toolkit Version of the Day
Relation.hpp
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 {
00023 namespace mesh {
00024 class Entity;
00025 }
00026 }
00027 #endif
00028 
00029 namespace stk {
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
00382 
00383 //----------------------------------------------------------------------
00384 //----------------------------------------------------------------------
00385 
00386 #endif /* stk_mesh_Relation_hpp */
00387 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines