Sierra Toolkit Version of the Day
EntityComm.cpp
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 #include <iterator>
00010 #include <stdexcept>
00011 #include <sstream>
00012 
00013 #include <stk_mesh/base/BulkData.hpp>
00014 #include <stk_mesh/base/MetaData.hpp>
00015 #include <stk_mesh/base/FieldData.hpp>
00016 #include <stk_mesh/base/EntityComm.hpp>
00017 
00018 namespace stk {
00019 namespace mesh {
00020 
00021 //----------------------------------------------------------------------------
00022 
00023 bool in_shared( const Entity & entity )
00024 {
00025   PairIterEntityComm ec = entity.comm();
00026   return ! ec.empty() && ec.front().ghost_id == 0 ;
00027 }
00028 
00029 bool in_shared( const Entity & entity , unsigned proc )
00030 {
00031   for ( PairIterEntityComm ec = entity.comm();
00032         ! ec.empty() && ec->ghost_id == 0 ; ++ec ) {
00033     if ( proc == ec->proc ) {
00034       return true ;
00035     }
00036   }
00037   return false ;
00038 }
00039 
00040 bool in_receive_ghost( const Entity & entity )
00041 {
00042   // Ghost communication with owner.
00043   PairIterEntityComm ec = entity.comm();
00044   return ! ec.empty() && ec.front().ghost_id != 0 &&
00045                          ec.front().proc == entity.owner_rank();
00046 }
00047 
00048 bool in_receive_ghost( const Ghosting & ghost , const Entity & entity )
00049 {
00050   return in_ghost( ghost , entity , entity.owner_rank() );
00051 }
00052 
00053 bool in_send_ghost( const Entity & entity )
00054 {
00055   // Ghost communication with non-owner.
00056   PairIterEntityComm ec = entity.comm();
00057   return ! ec.empty() && ec.back().ghost_id != 0 &&
00058                          ec.back().proc != entity.owner_rank();
00059 }
00060 
00061 bool in_send_ghost( const Entity & entity , unsigned proc )
00062 {
00063   for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
00064     if ( ec->ghost_id != 0 &&
00065          ec->proc   != entity.owner_rank() &&
00066          ec->proc   == proc ) {
00067       return true ;
00068     }
00069   }
00070   return false ;
00071 }
00072 
00073 bool in_ghost( const Ghosting & ghost , const Entity & entity , unsigned p )
00074 {
00075   // Ghost communication from owner.
00076   EntityCommInfo tmp( ghost.ordinal() , p );
00077 
00078   std::vector<EntityCommInfo>::const_iterator i =
00079     std::lower_bound( entity.comm().begin() , entity.comm().end() , tmp );
00080 
00081   return i != entity.comm().end() && tmp == *i ;
00082 }
00083 
00087 bool in_owned_closure( const Entity & entity , unsigned proc )
00088 {
00089   // TODO: This function has a potential performance problem if relations
00090   // are dense.
00091 
00092   // Does proc own this entity? If so, we're done
00093   bool result = entity.owner_rank() == proc ;
00094 
00095   if ( ! result ) {
00096     const unsigned erank = entity.entity_rank();
00097 
00098     // Does entity have an upward relation to an entity owned by proc
00099     for ( PairIterRelation
00100           rel = entity.relations(); ! result && ! rel.empty() ; ++rel ) {
00101       result =  erank < rel->entity_rank() &&
00102                 in_owned_closure( * rel->entity(), proc);
00103     }
00104   }
00105 
00106   return result ;
00107 }
00108 
00109 void comm_procs( const Entity & entity , std::vector<unsigned> & procs )
00110 {
00111   procs.clear();
00112   for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
00113     procs.push_back( ec->proc );
00114   }
00115   std::sort( procs.begin() , procs.end() );
00116   std::vector<unsigned>::iterator
00117     i = std::unique( procs.begin() , procs.end() );
00118   procs.erase( i , procs.end() );
00119 }
00120 
00121 void comm_procs( const Ghosting & ghost ,
00122                  const Entity & entity , std::vector<unsigned> & procs )
00123 {
00124   procs.clear();
00125   for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
00126     if ( ec->ghost_id == ghost.ordinal() ) {
00127       procs.push_back( ec->proc );
00128     }
00129   }
00130 }
00131 
00132 
00133 //----------------------------------------------------------------------------
00134 
00135 void pack_entity_info( CommBuffer & buf , const Entity & entity )
00136 {
00137   const EntityKey & key   = entity.key();
00138   const unsigned    owner = entity.owner_rank();
00139   const std::pair<const unsigned *, const unsigned *>
00140     part_ordinals = entity.bucket().superset_part_ordinals();
00141   const PairIterRelation relations = entity.relations();
00142 
00143   const unsigned nparts = part_ordinals.second - part_ordinals.first ;
00144   const unsigned nrel   = relations.size();
00145 
00146   buf.pack<EntityKey>( key );
00147   buf.pack<unsigned>( owner );
00148   buf.pack<unsigned>( nparts );
00149   buf.pack<unsigned>( part_ordinals.first , nparts );
00150   buf.pack<unsigned>( nrel );
00151 
00152   for ( unsigned i = 0 ; i < nrel ; ++i ) {
00153     buf.pack<EntityKey>( relations[i].entity()->key() );
00154     buf.pack<unsigned>( relations[i].identifier() );
00155     buf.pack<unsigned>( relations[i].attribute() );
00156   }
00157 }
00158 
00159 void unpack_entity_info(
00160   CommBuffer       & buf,
00161   const BulkData   & mesh ,
00162   EntityKey        & key ,
00163   unsigned         & owner ,
00164   PartVector       & parts ,
00165   std::vector<Relation> & relations )
00166 {
00167   unsigned nparts = 0 ;
00168   unsigned nrel = 0 ;
00169 
00170   buf.unpack<EntityKey>( key );
00171   buf.unpack<unsigned>( owner );
00172   buf.unpack<unsigned>( nparts );
00173 
00174   parts.resize( nparts );
00175 
00176   for ( unsigned i = 0 ; i < nparts ; ++i ) {
00177     unsigned part_ordinal = ~0u ;
00178     buf.unpack<unsigned>( part_ordinal );
00179     parts[i] = & MetaData::get(mesh).get_part( part_ordinal );
00180   }
00181 
00182   buf.unpack( nrel );
00183 
00184   relations.clear();
00185   relations.reserve( nrel );
00186 
00187   for ( unsigned i = 0 ; i < nrel ; ++i ) {
00188     EntityKey rel_key ;
00189     unsigned rel_id = 0 ;
00190     unsigned rel_attr = 0 ;
00191     buf.unpack<EntityKey>( rel_key );
00192     buf.unpack<unsigned>( rel_id );
00193     buf.unpack<unsigned>( rel_attr );
00194     Entity * const entity =
00195       mesh.get_entity( entity_rank(rel_key), entity_id(rel_key) );
00196     if ( entity && EntityLogDeleted != entity->log_query() ) {
00197       Relation rel( * entity, rel_id );
00198       rel.set_attribute(rel_attr);
00199       relations.push_back( rel );
00200     }
00201   }
00202 }
00203 
00204 
00205 //----------------------------------------------------------------------
00206 
00207 void pack_field_values( CommBuffer & buf , Entity & entity )
00208 {
00209   const Bucket   & bucket = entity.bucket();
00210   const BulkData & mesh   = BulkData::get(bucket);
00211   const MetaData & mesh_meta_data = MetaData::get(mesh);
00212 
00213   const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields();
00214 
00215   for ( std::vector< FieldBase * >::const_iterator
00216         i = fields.begin() ; i != fields.end() ; ++i ) {
00217 
00218     const FieldBase & f = **i ;
00219 
00220     if ( f.data_traits().is_pod ) {
00221       const unsigned size = field_data_size( f , bucket );
00222 
00223       buf.pack<unsigned>( size );
00224 
00225       if ( size ) {
00226         unsigned char * const ptr =
00227           reinterpret_cast<unsigned char *>( field_data( f , entity ) );
00228         buf.pack<unsigned char>( ptr , size );
00229       }
00230     }
00231   }
00232 }
00233 
00234 bool unpack_field_values(
00235   CommBuffer & buf , Entity & entity , std::ostream & error_msg )
00236 {
00237   const Bucket   & bucket = entity.bucket();
00238   const BulkData & mesh   = BulkData::get(bucket);
00239   const MetaData & mesh_meta_data = MetaData::get(mesh);
00240 
00241   const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields();
00242 
00243   const std::vector< FieldBase * >::const_iterator i_end = fields.end();
00244   const std::vector< FieldBase * >::const_iterator i_beg = fields.begin();
00245 
00246   std::vector< FieldBase * >::const_iterator i ;
00247 
00248   bool ok = true ;
00249 
00250   for ( i = i_beg ; i_end != i ; ) {
00251     const FieldBase & f = **i ; ++i ;
00252 
00253     if ( f.data_traits().is_pod ) {
00254 
00255       const unsigned size = field_data_size( f , bucket );
00256       unsigned recv_data_size = 0 ;
00257       buf.unpack<unsigned>( recv_data_size );
00258 
00259       if ( size != recv_data_size ) {
00260         if ( ok ) {
00261           ok = false ;
00262           print_entity_key( error_msg , mesh_meta_data , entity.key() );
00263         }
00264         error_msg << " " << f.name();
00265         error_msg << " " << size ;
00266         error_msg << " != " << recv_data_size ;
00267         buf.skip<unsigned char>( recv_data_size );
00268       }
00269       else if ( size ) { // Non-zero and equal
00270         unsigned char * ptr =
00271           reinterpret_cast<unsigned char *>( field_data( f , entity ) );
00272         buf.unpack<unsigned char>( ptr , size );
00273       }
00274     }
00275   }
00276 
00277   return ok ;
00278 }
00279 
00280 //----------------------------------------------------------------------
00281 
00282 } // namespace mesh
00283 }
00284 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines