Sierra Toolkit  Version of the Day
Relation.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 
10 #ifndef stk_mesh_Relation_hpp
11 #define stk_mesh_Relation_hpp
12 
13 #include <iosfwd>
14 #include <limits>
15 
16 #include <stk_mesh/base/EntityKey.hpp>
17 
18 #include <boost/static_assert.hpp>
19 
20 #ifdef SIERRA_MIGRATION
21 
22 namespace stk_classic {
23 namespace mesh {
24 class Entity;
25 }
26 }
27 #endif
28 
29 namespace stk_classic {
30 namespace mesh {
31 
35 //----------------------------------------------------------------------
58 class Relation {
59 public:
60  typedef uint32_t raw_relation_id_type ;
61  typedef uint32_t attribute_type;
62 
64  Relation();
65 
68  Relation( Entity & entity , RelationIdentifier identifier );
69 
70  attribute_type attribute() const { return m_attribute; }
71  void set_attribute(attribute_type attr) const { m_attribute = attr; }
72 
74  static raw_relation_id_type raw_relation_id( unsigned rank , unsigned id );
75 
77  raw_relation_id_type raw_relation_id() const { return m_raw_relation.value ; }
78 
80  unsigned entity_rank() const ;
81 
83  RelationIdentifier identifier() const ;
84 
86  Entity * entity() const { return m_target_entity ; }
87 
89  bool operator == ( const Relation & r ) const;
90 
92  bool operator != ( const Relation & r ) const
93  { return !(*this == r); }
94 
96  bool operator < ( const Relation & r ) const ;
97 
98 private:
99 
100 
101  enum {
102  rank_digits = 8 ,
103  id_digits = 24 ,
104  id_mask = ~(0u) >> rank_digits
105 #ifdef SIERRA_MIGRATION
106  ,
107  fwmk_relation_type_digits = 8,
108  fmwk_orientation_digits = 24,
109  fmwk_orientation_mask = ~(0u) >> fwmk_relation_type_digits
110 #endif
111  };
112 
113  BOOST_STATIC_ASSERT(( static_cast<unsigned>(EntityKey::rank_digits) == static_cast<unsigned>(rank_digits) ));
114 
115  union RawRelationType {
116  public:
117  raw_relation_id_type value ;
118 
119  struct {
120  raw_relation_id_type identifier : id_digits ;
121  raw_relation_id_type entity_rank : rank_digits ;
122  } normal_view ;
123 
124  struct {
125  raw_relation_id_type entity_rank : rank_digits ;
126  raw_relation_id_type identifier : id_digits ;
127  } reverse_view ;
128 
129  RawRelationType( raw_relation_id_type v ) : value(v) {}
130  RawRelationType() : value(0) {}
131  RawRelationType( const RawRelationType & rhs ) : value( rhs.value ) {}
132  RawRelationType & operator = ( const RawRelationType & rhs )
133  { value = rhs.value ; return *this ; }
134  };
135 
136  RawRelationType m_raw_relation ;
137  mutable attribute_type m_attribute ;
138  Entity * m_target_entity ;
139 
140 // Issue: Framework supports relation types (parent, child, etc) that STK_Mesh
141 // does not support, so these relations will have to be managed by framework
142 // until:
143 // A) STK_Mesh is rewritten to support these extra relation types
144 // B) An extra data-structure is added to manage these relation types and
145 // this data structure works together with STK_mesh under the generic API
146 // to manage all relation-types.
147 // C) We transition to using a mesh that supports everything framework
148 // supports and this problem goes away.
149 //
150 // The problem is that, with framework managing some relations and STK_Mesh
151 // managing others, the type of the relation descriptor is different depending
152 // on what type of relation you're dealing with. This can be addressed with
153 // templates, but this makes the code very ugly. Instead...
154 //
155 // Solution: Have framework and STK_Mesh use the same type as its relation_descriptor.
156 // The code below is designed to make this class compatible with the fmwk
157 // Relation class.
158 #ifdef SIERRA_MIGRATION
159  public:
163  enum RelationType {
164  USES = 0 ,
165  USED_BY = 1 ,
166  CHILD = 2 ,
167  PARENT = 3 ,
168  EMBEDDED = 0x00ff , // 4
169  CONTACT = 0x00ff , // 5
170  AUXILIARY = 0x00ff ,
171  INVALID = 10
172  };
173 
174  enum {
175  POLARITY_MASK = 0x80,
176  POLARITY_POSITIVE = 0x80,
177  POLARITY_NEGATIVE = 0x00,
178  POLARITY_IDENTITY = 0x80
179  };
180 
181  static bool polarity(unsigned orient) {
182  return (orient & POLARITY_MASK) == POLARITY_POSITIVE;
183  }
184 
185  static unsigned permutation(unsigned orient) {
186  return orient & ~POLARITY_MASK;
187  }
188 
192  Relation(Entity *obj, const unsigned relation_type, const unsigned ordinal, const unsigned orient = 0);
193 
194  Entity *getMeshObj() const {
195  return entity();
196  }
197 
198  void setMeshObj(Entity *object);
199 
200  RelationType getRelationType() const {
201  return static_cast<RelationType>(attribute() >> fmwk_orientation_digits);
202  }
203 
204  void setRelationType(RelationType relation_type) {
205  set_attribute( (relation_type << fmwk_orientation_digits) | getOrientation() );
206  }
207 
208  RelationIdentifier getOrdinal() const {
209  return identifier();
210  }
211 
212  void setOrdinal(RelationIdentifier ordinal) {
213  m_raw_relation = Relation::raw_relation_id( entity_rank(), ordinal );
214  }
215 
216  attribute_type getOrientation() const {
217  return attribute() & fmwk_orientation_mask;
218  }
219 
220  void setOrientation(attribute_type orientation) {
221  set_attribute( (getRelationType() << fmwk_orientation_digits) | orientation );
222  }
223 
234  bool polarity() const {
235  return (getOrientation() & POLARITY_MASK) == POLARITY_POSITIVE;
236  }
237 
238  unsigned permutation() const {
239  return getOrientation() & ~POLARITY_MASK;
240  }
241 
242 private:
243  bool has_fmwk_state() const { return getRelationType() != INVALID; }
244 #endif // SIERRA_MIGRATION
245 };
246 
247 //----------------------------------------------------------------------
248 
249 inline
250 Relation::raw_relation_id_type
251 Relation::raw_relation_id( unsigned rank , unsigned id )
252 {
253  ThrowAssertMsg( id <= id_mask,
254  "For args rank " << rank << ", id " << id << ": " <<
255  "id " << " > id_mask=" << id_mask );
256 
257  return ( raw_relation_id_type(rank) << id_digits ) | id ;
258 }
259 
260 inline
261 unsigned Relation::entity_rank() const
262 { return m_raw_relation.value >> id_digits; }
263 
264 inline
265 RelationIdentifier Relation::identifier() const
266 { return unsigned( m_raw_relation.value & id_mask ); }
267 
268 struct LessRelation {
269  bool operator() ( const Relation & lhs , const Relation & rhs ) const
270  { return lhs < rhs ; }
271 
272  bool operator() ( const Relation & lhs , Relation::raw_relation_id_type rhs ) const
273  { return lhs.raw_relation_id() < rhs ; }
274 };
275 
276 //----------------------------------------------------------------------
281  const std::vector<Entity*> & entities ,
282  std::vector<Entity*> & entities_related );
283 
289  const std::vector<Entity*> & entities ,
290  EntityRank entities_related_rank ,
291  std::vector<Entity*> & entities_related );
292 
293 //----------------------------------------------------------------------
297 bool membership_is_induced( const Part & part , unsigned entity_rank );
298 
302 void induced_part_membership( Part & part ,
303  unsigned entity_rank_from ,
304  unsigned entity_rank_to ,
305  RelationIdentifier relation_identifier ,
306  OrdinalVector & induced_parts,
307  bool include_supersets=true);
308 
312 void induced_part_membership( const Entity & entity_from ,
313  const OrdinalVector & omit ,
314  unsigned entity_rank_to ,
315  RelationIdentifier relation_identifier ,
316  OrdinalVector & induced_parts,
317  bool include_supersets=true);
318 
322 void induced_part_membership( const Entity & entity ,
323  const OrdinalVector & omit ,
324  OrdinalVector & induced_parts,
325  bool include_supersets=true);
326 
327 
328 //----------------------------------------------------------------------
329 
330 #if 0
331 
332 std::ostream &
333 print_relation( std::ostream & , Relation::raw__attr_type );
334 
336 std::ostream &
337 print_relation( std::ostream & , const MetaData & ,
338  Relation::raw__attr_type , EntityKey );
339 #endif
340 
342 std::ostream & operator << ( std::ostream & , const Relation & );
343 
346 inline
348  m_raw_relation(),
349  m_attribute(),
350  m_target_entity(NULL)
351 {
352 #ifdef SIERRA_MIGRATION
353  setRelationType(INVALID);
354 #endif
355 }
356 
357 inline
358 bool Relation::operator == ( const Relation & rhs ) const
359 {
360  return m_raw_relation.value == rhs.m_raw_relation.value && m_target_entity == rhs.m_target_entity
361 #ifdef SIERRA_MIGRATION
362  // compared fmwk state too
363  && m_attribute == rhs.m_attribute
364 #endif
365  ;
366 }
367 
368 inline
369 bool same_specification(const Relation& lhs, const Relation& rhs)
370 {
371 #ifdef SIERRA_MIGRATION
372  return lhs.entity_rank() == rhs.entity_rank() &&
373  lhs.getRelationType() == rhs.getRelationType() &&
374  lhs.getOrdinal() == rhs.getOrdinal();
375 #else
376  return lhs.entity_rank() == rhs.entity_rank();
377 #endif
378 }
379 
380 } // namespace mesh
381 } // namespace stk_classic
382 
383 //----------------------------------------------------------------------
384 //----------------------------------------------------------------------
385 
386 #endif /* stk_mesh_Relation_hpp */
387 
Entity * entity() const
The referenced entity.
Definition: Relation.hpp:86
bool operator<(const Relation &r) const
Ordering operator.
Definition: Relation.cpp:54
bool membership_is_induced(const Part &part, unsigned entity_rank)
Query if a member entity of the given entity type has an induced membership.
Definition: Relation.cpp:194
void induced_part_membership(Part &part, unsigned entity_rank_from, unsigned entity_rank_to, RelationIdentifier relation_identifier, OrdinalVector &induced_parts, bool include_supersets)
Induce entities&#39; part membership based upon relationships between entities. Insert the result into &#39;i...
Definition: Relation.cpp:211
bool operator!=(const Relation &r) const
Inequality operator.
Definition: Relation.hpp:92
raw_relation_id_type raw_relation_id() const
The encoded relation raw_relation_id.
Definition: Relation.hpp:77
RelationIdentifier identifier() const
The local relation identifier.
Definition: Relation.hpp:265
A relation between two mesh entities with a relation identifier and kind .
Definition: Relation.hpp:58
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
Sierra Toolkit.
void get_entities_through_relations(const std::vector< Entity *> &entities, std::vector< Entity *> &entities_related)
Query which mesh entities have a relation to all of the input mesh entities.
Definition: Relation.cpp:156
unsigned entity_rank() const
The rank of the referenced entity.
Definition: Relation.hpp:261
static raw_relation_id_type raw_relation_id(unsigned rank, unsigned id)
The encoded relation raw_relation_id.
Definition: Relation.hpp:251
EntityRank entity_rank(const EntityKey &key)
Given an entity key, return an entity type (rank).
bool operator==(const Relation &r) const
Equality operator.
Definition: Relation.hpp:358