std::vector<const mesh::Entity *> GeomDecomp::entity_coordinates(const mesh::Entity & entity, const VectorField & nodal_coor, std::vector<std::vector<double> > & coordinates) { coordinates.clear(); std::vector<const mesh::Entity *> mesh_nodes; const mesh::EntityRank enttype = entity.entity_rank(); if ( enttype == NODE_RANK ) { throw std::runtime_error("GeomDecomp::entity_coordinates Error: Can not be called for nodal entities."); } else { // Loop over node relations in mesh entities mesh::PairIterRelation nr = entity.relations( NODE_RANK ); for ( ; nr.first != nr.second; ++nr.first ) { const mesh::Relation &rel = *nr.first; if (rel.entity_rank() == NODE_RANK) { // %fixme: need to check for USES relation const mesh::Entity *nent = rel.entity(); const unsigned ndim(field_data_size(nodal_coor, *nent)/sizeof(double)); // TODO - is there a better way to get this info? double * coor = mesh::field_data(nodal_coor, *nent); if (!coor) { throw std::runtime_error("GeomDecomp::entity_coordinates Error: The coordinate field does not exist."); } std::vector<double> temp(ndim); for ( unsigned i = 0; i < ndim; ++i ) { temp[i] = coor[i]; } coordinates.push_back(temp); mesh_nodes.push_back(nent); } } } return mesh_nodes; }
void pack_field_values( CommBuffer & buf , Entity & entity ) { const Bucket & bucket = entity.bucket(); const BulkData & mesh = BulkData::get(bucket); const MetaData & mesh_meta_data = MetaData::get(mesh); const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields(); for ( std::vector< FieldBase * >::const_iterator i = fields.begin() ; i != fields.end() ; ++i ) { const FieldBase & f = **i ; if ( f.data_traits().is_pod ) { const unsigned size = field_data_size( f , bucket ); buf.pack<unsigned>( size ); if ( size ) { unsigned char * const ptr = reinterpret_cast<unsigned char *>( field_data( f , entity ) ); buf.pack<unsigned char>( ptr , size ); } } } }
void set_field_relations( Entity & e_from , Entity & e_to , const unsigned ident ) { const std::vector<FieldRelation> & field_rels = e_from.bucket().mesh().mesh_meta_data().get_field_relations(); for ( std::vector<FieldRelation>::const_iterator j = field_rels.begin() ; j != field_rels.end() ; ++j ) { const FieldRelation & fr = *j ; void ** const ptr = (void**) field_data( * fr.m_root , e_from ); if ( ptr ) { void * const src = field_data( * fr.m_target , e_to ); const size_t number = field_data_size(*fr.m_root,e_from) / sizeof(void*); const size_t offset = (*fr.m_function)( e_from.entity_rank() , e_to.entity_rank() , ident ); if ( offset < number ) { ptr[ offset ] = src ; } } } }
bool unpack_field_values( CommBuffer & buf , Entity & entity , std::ostream & error_msg ) { const Bucket & bucket = entity.bucket(); const BulkData & mesh = BulkData::get(bucket); const MetaData & mesh_meta_data = MetaData::get(mesh); const std::vector< FieldBase * > & fields = mesh_meta_data.get_fields(); const std::vector< FieldBase * >::const_iterator i_end = fields.end(); const std::vector< FieldBase * >::const_iterator i_beg = fields.begin(); std::vector< FieldBase * >::const_iterator i ; bool ok = true ; for ( i = i_beg ; i_end != i ; ) { const FieldBase & f = **i ; ++i ; if ( f.data_traits().is_pod ) { const unsigned size = field_data_size( f , bucket ); unsigned recv_data_size = 0 ; buf.unpack<unsigned>( recv_data_size ); if ( size != recv_data_size ) { if ( ok ) { ok = false ; print_entity_key( error_msg , mesh_meta_data , entity.key() ); } error_msg << " " << f.name(); error_msg << " " << size ; error_msg << " != " << recv_data_size ; buf.skip<unsigned char>( recv_data_size ); } else if ( size ) { // Non-zero and equal unsigned char * ptr = reinterpret_cast<unsigned char *>( field_data( f , entity ) ); buf.unpack<unsigned char>( ptr , size ); } } } return ok ; }
/** \brief Size, in bytes, of the field data for each entity */ inline unsigned field_data_size( const FieldBase & f , const Entity & e ) { return field_data_size( f , e.bucket() ); }
void communicate_field_data( const BulkData & mesh , const unsigned field_count , const FieldBase * fields[] , CommAll & sparse ) { const std::vector<Entity*> & entity_comm = mesh.entity_comm(); const unsigned parallel_size = mesh.parallel_size(); // Sizing for send and receive const unsigned zero = 0 ; std::vector<unsigned> msg_size( parallel_size , zero ); size_t j = 0; for ( j = 0 ; j < field_count ; ++j ) { const FieldBase & f = * fields[j] ; for ( std::vector<Entity*>::const_iterator i = entity_comm.begin() ; i != entity_comm.end() ; ++i ) { Entity & e = **i ; const unsigned size = field_data_size( f , e ); if ( size ) { for ( PairIterEntityComm ec = e.comm() ; ! ec.empty() && ec->ghost_id == 0 ; ++ec ) { msg_size[ ec->proc ] += size ; } } } } // Allocate send and receive buffers: { const unsigned * const s_size = & msg_size[0] ; sparse.allocate_buffers( mesh.parallel(), parallel_size / 4 , s_size, s_size); } // Pack for send: for ( j = 0 ; j < field_count ; ++j ) { const FieldBase & f = * fields[j] ; for ( std::vector<Entity*>::const_iterator i = entity_comm.begin() ; i != entity_comm.end() ; ++i ) { Entity & e = **i ; const unsigned size = field_data_size( f , e ); if ( size ) { unsigned char * ptr = reinterpret_cast<unsigned char *>(field_data( f , e )); for ( PairIterEntityComm ec = e.comm() ; ! ec.empty() && ec->ghost_id == 0 ; ++ec ) { CommBuffer & b = sparse.send_buffer( ec->proc ); b.pack<unsigned char>( ptr , size ); } } } } // Communicate: sparse.communicate(); }
void communicate_field_data( const Ghosting & ghosts , const std::vector< const FieldBase *> & fields ) { if ( fields.empty() ) { return; } const BulkData & mesh = BulkData::get(ghosts); const unsigned parallel_size = mesh.parallel_size(); const unsigned parallel_rank = mesh.parallel_rank(); const std::vector<const FieldBase *>::const_iterator fe = fields.end(); const std::vector<const FieldBase *>::const_iterator fb = fields.begin(); std::vector<const FieldBase *>::const_iterator fi ; // Sizing for send and receive const unsigned zero = 0 ; std::vector<unsigned> send_size( parallel_size , zero ); std::vector<unsigned> recv_size( parallel_size , zero ); for ( std::vector<Entity*>::const_iterator i = mesh.entity_comm().begin() ; i != mesh.entity_comm().end() ; ++i ) { Entity & e = **i ; const bool owned = e.owner_rank() == parallel_rank ; unsigned e_size = 0 ; for ( fi = fb ; fi != fe ; ++fi ) { const FieldBase & f = **fi ; e_size += field_data_size( f , e ); } for ( PairIterEntityComm ec = e.comm() ; ! ec.empty() ; ++ec ) { if ( ghosts.ordinal() == ec->ghost_id ) { if ( owned ) { send_size[ ec->proc ] += e_size ; } else { recv_size[ ec->proc ] += e_size ; } } } } // Allocate send and receive buffers: CommAll sparse ; { const unsigned * const s_size = & send_size[0] ; const unsigned * const r_size = & recv_size[0] ; sparse.allocate_buffers( mesh.parallel(), parallel_size / 4 , s_size, r_size); } // Send packing: for ( std::vector<Entity*>::const_iterator i = mesh.entity_comm().begin() ; i != mesh.entity_comm().end() ; ++i ) { Entity & e = **i ; if ( e.owner_rank() == parallel_rank ) { for ( fi = fb ; fi != fe ; ++fi ) { const FieldBase & f = **fi ; const unsigned size = field_data_size( f , e ); if ( size ) { unsigned char * ptr = reinterpret_cast<unsigned char *>(field_data( f , e )); for ( PairIterEntityComm ec = e.comm() ; ! ec.empty() ; ++ec ) { if ( ghosts.ordinal() == ec->ghost_id ) { CommBuffer & b = sparse.send_buffer( ec->proc ); b.pack<unsigned char>( ptr , size ); } } } } } } // Communicate: sparse.communicate(); // Unpack for recv: for ( std::vector<Entity*>::const_iterator i = mesh.entity_comm().begin() ; i != mesh.entity_comm().end() ; ++i ) { Entity & e = **i ; if ( e.owner_rank() != parallel_rank ) { for ( fi = fb ; fi != fe ; ++fi ) { const FieldBase & f = **fi ; const unsigned size = field_data_size( f , e ); if ( size ) { unsigned char * ptr = reinterpret_cast<unsigned char *>(field_data( f , e )); for ( PairIterEntityComm ec = e.comm() ; ! ec.empty() ; ++ec ) { if ( ghosts.ordinal() == ec->ghost_id ) { CommBuffer & b = sparse.recv_buffer( ec->proc ); b.unpack<unsigned char>( ptr , size ); } } } } } } }
void communicate_field_data( ParallelMachine machine, const std::vector<EntityProc> & domain , const std::vector<EntityProc> & range , const std::vector<const FieldBase *> & fields) { if ( fields.empty() ) { return; } const unsigned parallel_size = parallel_machine_size( machine ); const unsigned parallel_rank = parallel_machine_rank( machine ); const bool asymmetric = & domain != & range ; const std::vector<const FieldBase *>::const_iterator fe = fields.end(); const std::vector<const FieldBase *>::const_iterator fb = fields.begin(); std::vector<const FieldBase *>::const_iterator fi ; // Sizing for send and receive const unsigned zero = 0 ; std::vector<unsigned> send_size( parallel_size , zero ); std::vector<unsigned> recv_size( parallel_size , zero ); std::vector<EntityProc>::const_iterator i ; for ( i = domain.begin() ; i != domain.end() ; ++i ) { Entity & e = * i->first ; const unsigned p = i->second ; if ( asymmetric || parallel_rank == e.owner_rank() ) { unsigned e_size = 0 ; for ( fi = fb ; fi != fe ; ++fi ) { const FieldBase & f = **fi ; e_size += field_data_size( f , e ); } send_size[ p ] += e_size ; } } for ( i = range.begin() ; i != range.end() ; ++i ) { Entity & e = * i->first ; const unsigned p = i->second ; if ( asymmetric || p == e.owner_rank() ) { unsigned e_size = 0 ; for ( fi = fb ; fi != fe ; ++fi ) { const FieldBase & f = **fi ; e_size += field_data_size( f , e ); } recv_size[ p ] += e_size ; } } // Allocate send and receive buffers: CommAll sparse ; { const unsigned * const s_size = & send_size[0] ; const unsigned * const r_size = & recv_size[0] ; sparse.allocate_buffers( machine, parallel_size / 4 , s_size, r_size); } // Pack for send: for ( i = domain.begin() ; i != domain.end() ; ++i ) { Entity & e = * i->first ; const unsigned p = i->second ; if ( asymmetric || parallel_rank == e.owner_rank() ) { CommBuffer & b = sparse.send_buffer( p ); for ( fi = fb ; fi != fe ; ++fi ) { const FieldBase & f = **fi ; const unsigned size = field_data_size( f , e ); if ( size ) { unsigned char * ptr = reinterpret_cast<unsigned char *>(field_data( f , e )); b.pack<unsigned char>( ptr , size ); } } } } // Communicate: sparse.communicate(); // Unpack for recv: for ( i = range.begin() ; i != range.end() ; ++i ) { Entity & e = * i->first ; const unsigned p = i->second ; if ( asymmetric || p == e.owner_rank() ) { CommBuffer & b = sparse.recv_buffer( p ); for ( fi = fb ; fi != fe ; ++fi ) { const FieldBase & f = **fi ; const unsigned size = field_data_size( f , e ); if ( size ) { unsigned char * ptr = reinterpret_cast<unsigned char *>(field_data( f , e )); b.unpack<unsigned char>( ptr , size ); } } } } }