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   bool result = entity.owner_rank() == proc ;
00090   
00091   if ( ! result ) {
00092     const unsigned erank = entity.entity_rank();
00093 
00094     for ( PairIterRelation
00095           rel = entity.relations(); ! result && ! rel.empty() ; ++rel ) {
00096       result =  erank < rel->entity_rank() &&
00097                 proc == rel->entity()->owner_rank();
00098     }
00099   }
00100 
00101   return result ;
00102 }
00103 
00104 void comm_procs( const Entity & entity , std::vector<unsigned> & procs )
00105 {
00106   procs.clear();
00107   for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
00108     procs.push_back( ec->proc );
00109   }
00110   std::sort( procs.begin() , procs.end() );
00111   std::vector<unsigned>::iterator
00112     i = std::unique( procs.begin() , procs.end() );
00113   procs.erase( i , procs.end() );
00114 }
00115 
00116 void comm_procs( const Ghosting & ghost ,
00117                  const Entity & entity , std::vector<unsigned> & procs )
00118 {
00119   procs.clear();
00120   for ( PairIterEntityComm ec = entity.comm(); ! ec.empty() ; ++ec ) {
00121     if ( ec->ghost_id == ghost.ordinal() ) {
00122       procs.push_back( ec->proc );
00123     }
00124   }
00125 }
00126 
00127 
00128 //----------------------------------------------------------------------------
00129 
00130 void pack_entity_info( CommBuffer & buf , const Entity & entity )
00131 {
00132   const EntityKey & key   = entity.key();
00133   const unsigned    owner = entity.owner_rank();
00134   const std::pair<const unsigned *, const unsigned *>
00135     part_ordinals = entity.bucket().superset_part_ordinals();
00136   const PairIterRelation relations = entity.relations();
00137 
00138   const unsigned nparts = part_ordinals.second - part_ordinals.first ;
00139   const unsigned nrel   = relations.size();
00140 
00141   buf.pack<EntityKey>( key );
00142   buf.pack<unsigned>( owner );
00143   buf.pack<unsigned>( nparts );
00144   buf.pack<unsigned>( part_ordinals.first , nparts );
00145   buf.pack<unsigned>( nrel );
00146 
00147   for ( unsigned i = 0 ; i < nrel ; ++i ) {
00148     buf.pack<EntityKey>( relations[i].entity()->key() );
00149     buf.pack<Relation::raw_attr_type>( relations[i].attribute() );
00150   }
00151 }
00152 
00153 void unpack_entity_info(
00154   CommBuffer       & buf,
00155   const BulkData   & mesh ,
00156   EntityKey        & key ,
00157   unsigned         & owner ,
00158   PartVector       & parts ,
00159   std::vector<Relation> & relations )
00160 {
00161   unsigned nparts = 0 ;
00162   unsigned nrel = 0 ;
00163 
00164   buf.unpack<EntityKey>( key );
00165   buf.unpack<unsigned>( owner );
00166   buf.unpack<unsigned>( nparts );
00167 
00168   parts.resize( nparts );
00169 
00170   for ( unsigned i = 0 ; i < nparts ; ++i ) {
00171     unsigned part_ordinal = ~0u ;
00172     buf.unpack<unsigned>( part_ordinal );
00173     parts[i] = & mesh.mesh_meta_data().get_part( part_ordinal );
00174   }
00175 
00176   buf.unpack( nrel );
00177 
00178   relations.clear();
00179   relations.reserve( nrel );
00180 
00181   for ( unsigned i = 0 ; i < nrel ; ++i ) {
00182     EntityKey rel_key ;
00183     Relation::raw_attr_type rel_attr = 0 ;
00184     buf.unpack<EntityKey>( rel_key );
00185     buf.unpack<Relation::raw_attr_type>( rel_attr );
00186     Entity * const entity =
00187       mesh.get_entity( entity_rank(rel_key), entity_id(rel_key) );
00188     if ( entity && EntityLogDeleted != entity->log_query() ) {
00189       Relation rel( rel_attr , * entity );
00190       relations.push_back( rel );
00191     }
00192   }
00193 }
00194 
00195 
00196 //----------------------------------------------------------------------
00197 
00198 void pack_field_values( CommBuffer & buf , Entity & entity )
00199 {
00200   const Bucket   & bucket = entity.bucket();
00201   const BulkData & mesh   = bucket.mesh();
00202   const MetaData & mesh_meta_data = mesh.mesh_meta_data();
00203 
00204   const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields();
00205 
00206   for ( std::vector< FieldBase * >::const_iterator
00207         i = fields.begin() ; i != fields.end() ; ++i ) {
00208 
00209     const FieldBase & f = **i ;
00210 
00211     if ( f.data_traits().is_pod ) {
00212       const unsigned size = field_data_size( f , bucket );
00213 
00214       buf.pack<unsigned>( size );
00215 
00216       if ( size ) {
00217         unsigned char * const ptr =
00218           reinterpret_cast<unsigned char *>( field_data( f , entity ) );
00219         buf.pack<unsigned char>( ptr , size );
00220       }
00221     }
00222   }
00223 }
00224 
00225 bool unpack_field_values(
00226   CommBuffer & buf , Entity & entity , std::ostream & error_msg )
00227 {
00228   const Bucket   & bucket = entity.bucket();
00229   const BulkData & mesh   = bucket.mesh();
00230   const MetaData & mesh_meta_data = mesh.mesh_meta_data();
00231 
00232   const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields();
00233 
00234   const std::vector< FieldBase * >::const_iterator i_end = fields.end();
00235   const std::vector< FieldBase * >::const_iterator i_beg = fields.begin();
00236 
00237   std::vector< FieldBase * >::const_iterator i ;
00238 
00239   bool ok = true ;
00240 
00241   for ( i = i_beg ; i_end != i ; ) {
00242     const FieldBase & f = **i ; ++i ;
00243 
00244     if ( f.data_traits().is_pod ) {
00245 
00246       const unsigned size = field_data_size( f , bucket );
00247       unsigned recv_data_size = 0 ;
00248       buf.unpack<unsigned>( recv_data_size );
00249 
00250       if ( size != recv_data_size ) {
00251         if ( ok ) {
00252           ok = false ;
00253           print_entity_key( error_msg , mesh_meta_data , entity.key() );
00254         }
00255         error_msg << " " << f.name();
00256         error_msg << " " << size ;
00257         error_msg << " != " << recv_data_size ;
00258         buf.skip<unsigned char>( recv_data_size );
00259       }
00260       else if ( size ) { // Non-zero and equal
00261         unsigned char * ptr =
00262           reinterpret_cast<unsigned char *>( field_data( f , entity ) );
00263         buf.unpack<unsigned char>( ptr , size );
00264       }
00265     }
00266   }
00267 
00268   return ok ;
00269 }
00270 
00271 //----------------------------------------------------------------------
00272 
00273 } // namespace mesh
00274 }
00275 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends