|
Sierra Toolkit
Version of the Day
|
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_classic { 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