Sierra Toolkit  Version of the Day
Relation.cpp
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 #include <stdexcept>
10 #include <iostream>
11 #include <sstream>
12 #include <algorithm>
13 
14 #include <stk_mesh/base/MetaData.hpp>
15 #include <stk_mesh/base/BulkData.hpp>
16 #include <stk_mesh/base/Entity.hpp>
17 #include <stk_mesh/base/Bucket.hpp>
18 #include <stk_mesh/base/Relation.hpp>
19 #include <stk_mesh/base/FieldData.hpp>
20 
21 namespace stk_classic {
22 namespace mesh {
23 
24 //----------------------------------------------------------------------
25 
26 std::ostream &
27 operator << ( std::ostream & s , const Relation & rel )
28 {
29  Entity * const e = rel.entity();
30 
31  if ( e ) {
32  const MetaData & meta_data = MetaData::get(*e);
33  s << "[" << rel.identifier() << "]->" ;
34  print_entity_key( s , meta_data , e->key() );
35  }
36  else {
37  s << "[" << rel.identifier() << "]->" << rel.entity_rank();
38  }
39 
40  return s ;
41 }
42 
43 //----------------------------------------------------------------------
44 
45 Relation::Relation( Entity & entity , RelationIdentifier identifier )
46  : m_raw_relation( Relation::raw_relation_id( entity.entity_rank() , identifier ) ),
47  m_target_entity( & entity )
48 {
49 #ifdef SIERRA_MIGRATION
50  setRelationType(INVALID);
51 #endif
52 }
53 
54 bool Relation::operator < ( const Relation & rhs ) const
55 {
56  bool result = false;
57 
58 #ifdef SIERRA_MIGRATION
59  if (entity_rank() != rhs.entity_rank()) {
60  result = entity_rank() < rhs.entity_rank();
61  }
62  else if (getRelationType() != rhs.getRelationType()) {
63  result = getRelationType() < rhs.getRelationType();
64  }
65  else if (identifier() != rhs.identifier()) {
66  result = identifier() < rhs.identifier();
67  }
68 #else
69  if ( m_raw_relation.value != rhs.m_raw_relation.value ) {
70  result = m_raw_relation.value < rhs.m_raw_relation.value ;
71  }
72 #endif
73  else {
74  const EntityKey lhs_key = m_target_entity ? m_target_entity->key() : EntityKey();
75  const EntityKey rhs_key = rhs.m_target_entity ? rhs.m_target_entity->key() : EntityKey();
76  result = lhs_key < rhs_key ;
77  }
78  return result ;
79 }
80 
81 //----------------------------------------------------------------------
82 
83 #ifdef SIERRA_MIGRATION
84 
85 Relation::Relation(Entity *obj, const unsigned relation_type, const unsigned ordinal, const unsigned orient)
86  :
87  m_raw_relation( Relation::raw_relation_id( obj->entity_rank(), ordinal )),
88  m_attribute( (relation_type << fmwk_orientation_digits) | orient ),
89  m_target_entity(obj)
90 {
91  ThrowAssertMsg( orient <= fmwk_orientation_mask,
92  "orientation " << orient << " exceeds maximum allowed value");
93 }
94 
95 void Relation::setMeshObj(Entity *object)
96 {
97  if (object != NULL) {
98  m_raw_relation = Relation::raw_relation_id( object->entity_rank(), identifier() );
99  }
100  m_target_entity = object;
101 }
102 
103 #endif
104 
105 namespace {
106 
108  PairIterRelation rel ,
109  const std::vector<Entity*>::const_iterator i_beg ,
110  const std::vector<Entity*>::const_iterator i_end ,
111  std::vector<Entity*> & entities_related )
112 {
113  for ( ; rel.first != rel.second ; ++rel.first ) {
114 
115  // Do all input entities have a relation to this entity ?
116 
117  Entity * const e = rel.first->entity();
118 
119  std::vector<Entity*>::const_iterator i = i_beg ;
120 
121  for ( ; i != i_end ; ++i ) {
122  PairIterRelation r = (*i)->relations();
123  while ( r.first != r.second && e != r.first->entity() ) {
124  ++r.first ;
125  }
126  if ( r.first == r.second ) { break ; }
127  }
128 
129  if ( i == i_end ) {
130  entities_related.push_back( e );
131  }
132  }
133 }
134 
135 inline
136 void insert_part_and_supersets(OrdinalVector& induced_parts,
137  Part& part,
138  bool include_supersets)
139 {
140  insert_ordinal( induced_parts , part.mesh_meta_data_ordinal() );
141 
142  // In order to preserve superset/subset consistency we should add supersets of
143  // induced parts to the induced part lists. Unfortunately, this opens up an ambiguity
144  // where, when a relation is removed, we cannot know if an unranked superset
145  // part should be removed.
146  if (include_supersets) {
147  const PartVector & supersets = part.supersets();
148  for (PartVector::const_iterator itr = supersets.begin(), end = supersets.end(); itr != end; ++itr) {
149  insert_ordinal( induced_parts, (*itr)->mesh_meta_data_ordinal() );
150  }
151  }
152 }
153 
154 }
155 
157  const std::vector<Entity*> & entities ,
158  std::vector<Entity*> & entities_related )
159 {
160  entities_related.clear();
161 
162  if ( ! entities.empty() ) {
163  std::vector<Entity*>::const_iterator i = entities.begin();
164  const std::vector<Entity*>::const_iterator j = entities.end();
165 
166  PairIterRelation rel = (*i)->relations(); ++i ;
167 
168  get_entities_through_relations( rel , i , j , entities_related );
169  }
170 }
171 
173  const std::vector<Entity*> & entities ,
174  unsigned entities_related_rank ,
175  std::vector<Entity*> & entities_related )
176 {
177  entities_related.clear();
178 
179  if ( ! entities.empty() ) {
180  std::vector<Entity*>::const_iterator i = entities.begin();
181  const std::vector<Entity*>::const_iterator j = entities.end();
182 
183  PairIterRelation rel = (*i)->relations( entities_related_rank ); ++i ;
184 
185  get_entities_through_relations( rel , i , j , entities_related );
186  }
187 }
188 
189 //----------------------------------------------------------------------
190 
194 bool membership_is_induced( const Part & part , unsigned entity_rank )
195 {
196  const MetaData & meta = MetaData::get(part);
197 
198  const bool induced_by_type =
199  entity_rank < part.primary_entity_rank() &&
200  part.primary_entity_rank() < meta.entity_rank_count() ;
201 
202  const bool induced_by_stencil =
203  ! part.relations().empty() &&
204  part.relations().begin()->m_target == & part ;
205 
206  return induced_by_type || induced_by_stencil ;
207 }
208 
209 //----------------------------------------------------------------------
210 
212  unsigned entity_rank_from ,
213  unsigned entity_rank_to ,
214  RelationIdentifier relation_identifier ,
215  OrdinalVector & induced_parts,
216  bool include_supersets)
217 {
218  if ( entity_rank_to < entity_rank_from &&
219  part.primary_entity_rank() == entity_rank_from ) {
220 
221  // Direct relationship:
222 
223  insert_part_and_supersets( induced_parts , part, include_supersets );
224 
225  // Stencil relationship where 'part' is the root:
226  // The 'target' should not have subsets or supersets.
227 
228  const std::vector<PartRelation> & part_rel = part.relations();
229 
230  for ( std::vector<PartRelation>::const_iterator
231  j = part_rel.begin() ; j != part_rel.end() ; ++j ) {
232 
233  if ( & part == j->m_root &&
234  0 <= (* j->m_function)( entity_rank_from , entity_rank_to ,
235  relation_identifier ) ) {
236  insert_part_and_supersets( induced_parts , * j->m_target, include_supersets );
237  }
238  }
239  }
240 }
241 
242 //----------------------------------------------------------------------
243 // What are this entity's part memberships that can be deduced from
244 // this entity's relationship. Can only trust 'entity_from' to be
245 // accurate if it is owned by the local process.
246 
247 void induced_part_membership( const Entity & entity_from ,
248  const OrdinalVector & omit ,
249  unsigned entity_rank_to ,
250  RelationIdentifier relation_identifier ,
251  OrdinalVector & induced_parts,
252  bool include_supersets)
253 {
254  const Bucket & bucket_from = entity_from.bucket();
255  const BulkData & mesh = BulkData::get(bucket_from);
256  const unsigned local_proc_rank = mesh.parallel_rank();
257  const unsigned entity_rank_from = entity_from.entity_rank();
258 
259  // Only induce parts for normal (not back) relations. Can only trust
260  // 'entity_from' to be accurate if it is owned by the local process.
261  if ( entity_rank_to < entity_rank_from &&
262  local_proc_rank == entity_from.owner_rank() ) {
263  const PartVector & all_parts = mesh.mesh_meta_data().get_parts();
264 
265  const std::pair<const unsigned *, const unsigned *>
266  bucket_superset_ordinals = bucket_from.superset_part_ordinals();
267 
268  OrdinalVector::const_iterator omit_begin = omit.begin(),
269  omit_end = omit.end();
270 
271  // Contributions of the 'from' entity:
272  for ( const unsigned * i = bucket_superset_ordinals.first ;
273  i != bucket_superset_ordinals.second ; ++i ) {
274  ThrowAssertMsg( *i < all_parts.size(), "Index " << *i << " out of bounds" );
275  Part & part = * all_parts[*i] ;
276 
277  if ( part.primary_entity_rank() == entity_rank_from && ! contains_ordinal( omit_begin, omit_end , *i )) {
279  entity_rank_from ,
280  entity_rank_to ,
281  relation_identifier ,
282  induced_parts,
283  include_supersets);
284  }
285  }
286  }
287 }
288 
289 //----------------------------------------------------------------------
290 
291 void induced_part_membership( const Entity & entity ,
292  const OrdinalVector & omit ,
293  OrdinalVector & induced_parts,
294  bool include_supersets)
295 {
296  for ( PairIterRelation
297  rel = entity.relations() ; ! rel.empty() ; ++rel ) {
298 
299  induced_part_membership( * rel->entity() , omit ,
300  entity.entity_rank() ,
301  rel->identifier() ,
302  induced_parts,
303  include_supersets);
304  }
305 }
306 
307 //----------------------------------------------------------------------
308 
309 } // namespace mesh
310 } // namespace stk_classic
Entity * entity() const
The referenced entity.
Definition: Relation.hpp:86
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
bool operator<(const Relation &r) const
Ordering operator.
Definition: Relation.cpp:54
void induced_part_membership(const Entity &entity, const OrdinalVector &omit, OrdinalVector &induced_parts, bool include_supersets)
Induce an entity&#39;s part membership based upon relationships from other entities. Do not include and p...
Definition: Relation.cpp:291
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
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
unsigned primary_entity_rank() const
The primary entity type for this part.
Definition: Part.hpp:64
std::pair< const unsigned *, const unsigned * > superset_part_ordinals() const
Definition: Bucket.hpp:188
Integer type for the entity keys, which is an encoding of the entity type and entity identifier...
An application-defined subset of a problem domain.
Definition: Part.hpp:49
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Definition: Entity.hpp:161
void get_entities_through_relations(const std::vector< Entity *> &entities, unsigned entities_related_rank, std::vector< Entity *> &entities_related)
Query which mesh entities have a relation to all of the input mesh entities of the given mesh rank...
Definition: Relation.cpp:172
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
const std::vector< PartRelation > & relations() const
PartRelations for which this part is a member, root or target.
Definition: Part.hpp:84
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
const MetaData & mesh_meta_data() const
The meta data manager for this bulk data manager.
Definition: BulkData.hpp:76
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
Sierra Toolkit.
const PartVector & get_parts() const
Query all parts of the mesh ordered by the parts&#39; ordinal.
Definition: MetaData.hpp:120
unsigned entity_rank() const
The rank of the referenced entity.
Definition: Relation.hpp:261
unsigned parallel_rank() const
Rank of the parallel machine&#39;s local processor.
Definition: BulkData.hpp:85
EntityRank entity_rank() const
The rank of this entity.
Definition: Entity.hpp:128
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
A container for the field data of a homogeneous collection of entities.
Definition: Bucket.hpp:94
EntityRank entity_rank(const EntityKey &key)
Given an entity key, return an entity type (rank).
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
Definition: Entity.hpp:175