Sierra Toolkit  Version of the Day
EntityComm.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 <iterator>
10 #include <stdexcept>
11 #include <sstream>
12 
13 #include <stk_mesh/base/BulkData.hpp>
14 #include <stk_mesh/base/MetaData.hpp>
15 #include <stk_mesh/base/FieldData.hpp>
16 #include <stk_mesh/base/EntityComm.hpp>
17 
18 namespace stk_classic {
19 namespace mesh {
20 
21 //----------------------------------------------------------------------------
22 
23 bool in_shared( const Entity & entity )
24 {
25  PairIterEntityComm ec = entity.comm();
26  return ! ec.empty() && ec.front().ghost_id == 0 ;
27 }
28 
29 bool in_shared( const Entity & entity , unsigned proc )
30 {
31  for ( PairIterEntityComm ec = entity.comm();
32  ! ec.empty() && ec->ghost_id == 0 ; ++ec ) {
33  if ( proc == ec->proc ) {
34  return true ;
35  }
36  }
37  return false ;
38 }
39 
40 bool in_receive_ghost( const Entity & entity )
41 {
42  // Ghost communication with owner.
43  PairIterEntityComm ec = entity.comm();
44  return ! ec.empty() && ec.front().ghost_id != 0 &&
45  ec.front().proc == entity.owner_rank();
46 }
47 
48 bool in_receive_ghost( const Ghosting & ghost , const Entity & entity )
49 {
50  return in_ghost( ghost , entity , entity.owner_rank() );
51 }
52 
53 bool in_send_ghost( const Entity & entity )
54 {
55  // Ghost communication with non-owner.
56  PairIterEntityComm ec = entity.comm();
57  return ! ec.empty() && ec.back().ghost_id != 0 &&
58  ec.back().proc != entity.owner_rank();
59 }
60 
61 bool in_send_ghost( const Entity & entity , unsigned proc )
62 {
63  for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
64  if ( ec->ghost_id != 0 &&
65  ec->proc != entity.owner_rank() &&
66  ec->proc == proc ) {
67  return true ;
68  }
69  }
70  return false ;
71 }
72 
73 bool in_ghost( const Ghosting & ghost , const Entity & entity , unsigned p )
74 {
75  // Ghost communication from owner.
76  EntityCommInfo tmp( ghost.ordinal() , p );
77 
78  std::vector<EntityCommInfo>::const_iterator i =
79  std::lower_bound( entity.comm().begin() , entity.comm().end() , tmp );
80 
81  return i != entity.comm().end() && tmp == *i ;
82 }
83 
87 bool in_owned_closure( const Entity & entity , unsigned proc )
88 {
89  // TODO: This function has a potential performance problem if relations
90  // are dense.
91 
92  // Does proc own this entity? If so, we're done
93  bool result = entity.owner_rank() == proc ;
94 
95  if ( ! result ) {
96  const unsigned erank = entity.entity_rank();
97 
98  // Does entity have an upward relation to an entity owned by proc
99  for ( PairIterRelation
100  rel = entity.relations(); ! result && ! rel.empty() ; ++rel ) {
101  result = erank < rel->entity_rank() &&
102  in_owned_closure( * rel->entity(), proc);
103  }
104  }
105 
106  return result ;
107 }
108 
109 void comm_procs( const Entity & entity , std::vector<unsigned> & procs )
110 {
111  procs.clear();
112  for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
113  procs.push_back( ec->proc );
114  }
115  std::sort( procs.begin() , procs.end() );
116  std::vector<unsigned>::iterator
117  i = std::unique( procs.begin() , procs.end() );
118  procs.erase( i , procs.end() );
119 }
120 
121 void comm_procs( const Ghosting & ghost ,
122  const Entity & entity , std::vector<unsigned> & procs )
123 {
124  procs.clear();
125  for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
126  if ( ec->ghost_id == ghost.ordinal() ) {
127  procs.push_back( ec->proc );
128  }
129  }
130 }
131 
132 
133 //----------------------------------------------------------------------------
134 
135 void pack_entity_info( CommBuffer & buf , const Entity & entity )
136 {
137  const EntityKey & key = entity.key();
138  const unsigned owner = entity.owner_rank();
139  const std::pair<const unsigned *, const unsigned *>
140  part_ordinals = entity.bucket().superset_part_ordinals();
141  const PairIterRelation relations = entity.relations();
142 
143  const unsigned nparts = part_ordinals.second - part_ordinals.first ;
144  const unsigned nrel = relations.size();
145 
146  buf.pack<EntityKey>( key );
147  buf.pack<unsigned>( owner );
148  buf.pack<unsigned>( nparts );
149  buf.pack<unsigned>( part_ordinals.first , nparts );
150  buf.pack<unsigned>( nrel );
151 
152  for ( unsigned i = 0 ; i < nrel ; ++i ) {
153  buf.pack<EntityKey>( relations[i].entity()->key() );
154  buf.pack<unsigned>( relations[i].identifier() );
155  buf.pack<unsigned>( relations[i].attribute() );
156  }
157 }
158 
159 void unpack_entity_info(
160  CommBuffer & buf,
161  const BulkData & mesh ,
162  EntityKey & key ,
163  unsigned & owner ,
164  PartVector & parts ,
165  std::vector<Relation> & relations )
166 {
167  unsigned nparts = 0 ;
168  unsigned nrel = 0 ;
169 
170  buf.unpack<EntityKey>( key );
171  buf.unpack<unsigned>( owner );
172  buf.unpack<unsigned>( nparts );
173 
174  parts.resize( nparts );
175 
176  for ( unsigned i = 0 ; i < nparts ; ++i ) {
177  unsigned part_ordinal = ~0u ;
178  buf.unpack<unsigned>( part_ordinal );
179  parts[i] = & MetaData::get(mesh).get_part( part_ordinal );
180  }
181 
182  buf.unpack( nrel );
183 
184  relations.clear();
185  relations.reserve( nrel );
186 
187  for ( unsigned i = 0 ; i < nrel ; ++i ) {
188  EntityKey rel_key ;
189  unsigned rel_id = 0 ;
190  unsigned rel_attr = 0 ;
191  buf.unpack<EntityKey>( rel_key );
192  buf.unpack<unsigned>( rel_id );
193  buf.unpack<unsigned>( rel_attr );
194  Entity * const entity =
195  mesh.get_entity( entity_rank(rel_key), entity_id(rel_key) );
196  if ( entity && EntityLogDeleted != entity->log_query() ) {
197  Relation rel( * entity, rel_id );
198  rel.set_attribute(rel_attr);
199  relations.push_back( rel );
200  }
201  }
202 }
203 
204 
205 //----------------------------------------------------------------------
206 
207 void pack_field_values( CommBuffer & buf , Entity & entity )
208 {
209  const Bucket & bucket = entity.bucket();
210  const BulkData & mesh = BulkData::get(bucket);
211  const MetaData & mesh_meta_data = MetaData::get(mesh);
212 
213  const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields();
214 
215  for ( std::vector< FieldBase * >::const_iterator
216  i = fields.begin() ; i != fields.end() ; ++i ) {
217 
218  const FieldBase & f = **i ;
219 
220  if ( f.data_traits().is_pod ) {
221  const unsigned size = field_data_size( f , bucket );
222 
223  buf.pack<unsigned>( size );
224 
225  if ( size ) {
226  unsigned char * const ptr =
227  reinterpret_cast<unsigned char *>( field_data( f , entity ) );
228  buf.pack<unsigned char>( ptr , size );
229  }
230  }
231  }
232 }
233 
234 bool unpack_field_values(
235  CommBuffer & buf , Entity & entity , std::ostream & error_msg )
236 {
237  const Bucket & bucket = entity.bucket();
238  const BulkData & mesh = BulkData::get(bucket);
239  const MetaData & mesh_meta_data = MetaData::get(mesh);
240 
241  const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields();
242 
243  const std::vector< FieldBase * >::const_iterator i_end = fields.end();
244  const std::vector< FieldBase * >::const_iterator i_beg = fields.begin();
245 
246  std::vector< FieldBase * >::const_iterator i ;
247 
248  bool ok = true ;
249 
250  for ( i = i_beg ; i_end != i ; ) {
251  const FieldBase & f = **i ; ++i ;
252 
253  if ( f.data_traits().is_pod ) {
254 
255  const unsigned size = field_data_size( f , bucket );
256  unsigned recv_data_size = 0 ;
257  buf.unpack<unsigned>( recv_data_size );
258 
259  if ( size != recv_data_size ) {
260  if ( ok ) {
261  ok = false ;
262  print_entity_key( error_msg , mesh_meta_data , entity.key() );
263  }
264  error_msg << " " << f.name();
265  error_msg << " " << size ;
266  error_msg << " != " << recv_data_size ;
267  buf.skip<unsigned char>( recv_data_size );
268  }
269  else if ( size ) { // Non-zero and equal
270  unsigned char * ptr =
271  reinterpret_cast<unsigned char *>( field_data( f , entity ) );
272  buf.unpack<unsigned char>( ptr , size );
273  }
274  }
275  }
276 
277  return ok ;
278 }
279 
280 //----------------------------------------------------------------------
281 
282 } // namespace mesh
283 }
284 
PairIterEntityComm comm() const
Complete communicaiton list for this entity.
Definition: Entity.hpp:181
unsigned field_data_size(const FieldBase &f, const Bucket &k)
Size, in bytes, of the field data for each entity.
Definition: FieldData.hpp:99
FieldTraits< field_type >::data_type * field_data(const field_type &f, const Bucket::iterator i)
Pointer to the field data array.
Definition: FieldData.hpp:116
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
std::pair< const unsigned *, const unsigned * > superset_part_ordinals() const
Definition: Bucket.hpp:188
EntityModificationLog log_query() const
Query the current state of the entity log.
Definition: Entity.hpp:125
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Definition: Entity.hpp:161
EntityId entity_id(const EntityKey &key)
Given an entity key, return the identifier for the entity.
Sierra Toolkit.
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
PairIter< std::vector< EntityCommInfo >::const_iterator > PairIterEntityComm
Span of ( communication-subset-ordinal , process-rank ) pairs for the communication of an entity...
Definition: Types.hpp:128
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