void sort_and_unique( PartVector & partVector ) { PartVector::iterator begin = partVector.begin(); PartVector::iterator end = partVector.end(); std::sort( begin , end , PartLess() ); PartVector::iterator new_end = std::unique( begin , end ); partVector.erase( new_end , end ); }
void remove( PartVector & v , Part & part ) { const PartVector::iterator e = v.end(); PartVector::iterator i = v.begin(); i = std::lower_bound( i , e , part , PartLess() ); if ( i != e && *i == & part ) { v.erase( i ); } }
bool contain( const PartVector & v , const Part & part ) { const PartVector::const_iterator e = v.end(); PartVector::const_iterator i = v.begin(); i = std::lower_bound( i , e , part , PartLess() ); return i != e && *i == & part ; }
void Transaction::add_parts_to_partset ( Entity &e , PartSet &pl ) { PartVector parts; e.bucket().supersets ( parts ); for ( PartVector::iterator part_iter = parts.begin(); part_iter != parts.end() ; ++part_iter ) pl.insert ( *part_iter ); }
Selector selectIntersection( const PartVector& intersection_part_vector ) { Selector selector; if (intersection_part_vector.size() > 0) { selector = *intersection_part_vector[0]; for (unsigned i = 1 ; i < intersection_part_vector.size() ; ++i) { selector &= *intersection_part_vector[i]; } } return selector; }
void BulkData::destroy_relation( Entity & e_from , Entity & e_to ) { static const char method[]= "stk::mesh::BulkData::destroy_relation" ; assert_ok_to_modify( method ); assert_valid_relation( method , *this , e_from , e_to ); //------------------------------ // When removing a relationship may need to // remove part membership and set field relation pointer to NULL PartVector del , keep ; for ( PairIterRelation i = e_to.relations() ; i.first != i.second ; ++(i.first) ) { if ( !( i.first->entity() == & e_from ) && ( e_to.entity_rank() < i.first->entity_rank() ) ) { induced_part_membership( * i.first->entity(), del, e_to.entity_rank(), i.first->identifier(), keep ); } } for ( PairIterRelation i = e_from.relations() ; i.first != i.second ; ++(i.first) ) { if ( i.first->entity() == & e_to ) { induced_part_membership( e_from, keep, e_to.entity_rank(), i.first->identifier(), del ); clear_field_relations( e_from , e_to.entity_rank() , i.first->identifier() ); } } //------------------------------ // 'keep' contains the parts deduced from kept relations // 'del' contains the parts deduced from deleted relations // that are not in 'keep' // Only remove these part memberships the entity is not shared. // If the entity is shared then wait until modificaton_end_synchronize. //------------------------------ if ( ! del.empty() && (parallel_size() < 2 || e_to.sharing().empty()) ) { PartVector add ; internal_change_entity_parts( e_to , add , del ); } //delete relations from the entities m_entity_repo.destroy_relation( e_from, e_to); }
bool insert( PartVector & v , Part & part ) { const PartVector::iterator e = v.end(); PartVector::iterator i = v.begin(); i = std::lower_bound( i , e , part , PartLess() ); const bool new_member = i == e || *i != & part ; if ( new_member ) { v.insert( i , &part ); } return new_member ; }
std::ostream & operator << ( std::ostream & s , const Bucket & k ) { const MetaData & mesh_meta_data = k.mesh().mesh_meta_data(); const std::string & entity_name = mesh_meta_data.entity_rank_names()[ k.entity_rank() ]; PartVector parts ; k.supersets( parts ); s << "Bucket( " << entity_name << " : " ; for ( PartVector::iterator i = parts.begin() ; i != parts.end() ; ++i ) { s << (*i)->name() << " " ; } s << ")" ; return s ; }
void BulkData::internal_verify_change_parts( const MetaData & meta , const Entity & entity , const PartVector & parts ) const { const std::vector<std::string> & rank_names = meta.entity_rank_names(); const EntityRank undef_rank = InvalidEntityRank; const EntityRank entity_rank = entity.entity_rank(); bool ok = true ; std::ostringstream msg ; for ( PartVector::const_iterator i = parts.begin() ; i != parts.end() ; ++i ) { const Part * const p = *i ; const unsigned part_rank = p->primary_entity_rank(); bool intersection_ok, rel_target_ok, rank_ok; internal_basic_part_check(p, entity_rank, undef_rank, intersection_ok, rel_target_ok, rank_ok); if ( !intersection_ok || !rel_target_ok || !rank_ok ) { if ( ok ) { ok = false ; msg << "change parts for entity " << print_entity_key( entity ); msg << " , { " ; } else { msg << " , " ; } msg << p->name() << "[" ; if ( part_rank < rank_names.size() ) { msg << rank_names[ part_rank ]; } else { msg << part_rank ; } msg << "] " ; if ( !intersection_ok ) { msg << "is_intersection " ; } if ( !rel_target_ok ) { msg << "is_relation_target " ; } if ( !rank_ok ) { msg << "is_bad_rank " ; } } } ThrowErrorMsgIf( !ok, msg.str() << "}" ); }
bool Bucket::member_any( const PartVector & parts ) const { const unsigned * const i_beg = key() + 1 ; const unsigned * const i_end = key() + key()[0] ; const PartVector::const_iterator ip_end = parts.end(); PartVector::const_iterator ip = parts.begin() ; bool result_none = true ; for ( ; result_none && ip_end != ip ; ++ip ) { const unsigned ord = (*ip)->mesh_meta_data_ordinal(); const unsigned * const i = std::lower_bound( i_beg , i_end , ord ); result_none = i_end == i || ord != *i ; } return ! result_none ; }
void Transaction::translate_partset_to_partvector ( const PartSet &in , PartVector &out ) const { out.resize ( in.size() ); unsigned i = 0; for ( PartSet::const_iterator cur_in = in.begin() ; cur_in != in.end() ; cur_in++ ) { out[i] = *cur_in; ++i; } }
bool has_superset( const Bucket & bucket , const PartVector & ps ) { const std::pair<const unsigned *, const unsigned *> part_ord = bucket.superset_part_ordinals(); bool result = ! ps.empty(); for ( PartVector::const_iterator i = ps.begin() ; result && i != ps.end() ; ++i ) { const unsigned ordinal = (*i)->mesh_meta_data_ordinal(); const unsigned * iter = std::lower_bound( part_ord.first , part_ord.second , ordinal ); result = iter < part_ord.second && ordinal == *iter ; } return result ; }
void get_involved_parts( const PartVector & union_parts, const Bucket & candidate, PartVector & involved_parts ) { involved_parts.clear(); if (union_parts.size() == 0) { return; } // Used to convert part ordinals to part pointers: MetaData & meta_data = MetaData::get( * union_parts[0]); const PartVector & all_parts = meta_data.get_parts(); const std::pair<const unsigned *,const unsigned *> bucket_part_begin_end_iterators = candidate.superset_part_ordinals(); // sorted and unique std::vector<unsigned> union_parts_ids; copy_ids( union_parts_ids , union_parts ); // sorted and unique std::vector<unsigned>::const_iterator union_part_id_it = union_parts_ids.begin(); const unsigned * bucket_part_id_it = bucket_part_begin_end_iterators.first ; while ( union_part_id_it != union_parts_ids.end() && bucket_part_id_it != bucket_part_begin_end_iterators.second ) { if ( *union_part_id_it < *bucket_part_id_it ) { ++union_part_id_it ; } else if ( *bucket_part_id_it < *union_part_id_it ) { ++bucket_part_id_it ; } else { // Find every match: Part * const part = all_parts[ *union_part_id_it ]; involved_parts.push_back( part ); ++union_part_id_it; ++bucket_part_id_it; } } }
size_t intersect( const PartVector & v , const PartVector & p ) { // Both lists must be sorted, assume v.size() > p.size() const PartVector::const_iterator ev = v.end(); PartVector::const_iterator iv = v.begin(); const PartVector::const_iterator ep = p.end(); PartVector::const_iterator ip = p.begin(); size_t count = 0 ; for ( ; ip != ep && iv != ev ; ++ip ) { Part * const q = *ip ; iv = std::lower_bound( iv , ev , q , PartLess() ); if ( iv != ev && *iv == q ) { ++count ; } } return count ; }
void Bucket::supersets( PartVector & ps ) const { const MetaData & mesh_meta_data = mesh().mesh_meta_data(); std::pair<const unsigned *, const unsigned *> part_ord = superset_part_ordinals(); ps.resize( part_ord.second - part_ord.first ); for ( unsigned i = 0 ; part_ord.first < part_ord.second ; ++(part_ord.first) , ++i ) { ps[i] = & mesh_meta_data.get_part( * part_ord.first ); } }
void copy_ids( std::vector<unsigned> & v , const PartVector & p ) { { const size_t n = p.size(); v.resize( n ); for ( size_t k = 0 ; k < n ; ++k ) { v[k] = p[k]->mesh_meta_data_ordinal(); } } { std::vector<unsigned>::iterator i = v.begin() , j = v.end(); std::sort( i , j ); i = std::unique( i , j ); v.erase( i , j ); } }
void unpack_entity_info( CommBuffer & buf, const BulkData & mesh , EntityKey & key , unsigned & owner , PartVector & parts , std::vector<Relation> & relations ) { unsigned nparts = 0 ; unsigned nrel = 0 ; buf.unpack<EntityKey>( key ); buf.unpack<unsigned>( owner ); buf.unpack<unsigned>( nparts ); parts.resize( nparts ); for ( unsigned i = 0 ; i < nparts ; ++i ) { unsigned part_ordinal = ~0u ; buf.unpack<unsigned>( part_ordinal ); parts[i] = & MetaData::get(mesh).get_part( part_ordinal ); } buf.unpack( nrel ); relations.clear(); relations.reserve( nrel ); for ( unsigned i = 0 ; i < nrel ; ++i ) { EntityKey rel_key ; unsigned rel_id = 0 ; unsigned rel_attr = 0 ; buf.unpack<EntityKey>( rel_key ); buf.unpack<unsigned>( rel_id ); buf.unpack<unsigned>( rel_attr ); Entity * const entity = mesh.get_entity( entity_rank(rel_key), entity_id(rel_key) ); if ( entity && EntityLogDeleted != entity->log_query() ) { Relation rel( * entity, rel_id ); rel.set_attribute(rel_attr); relations.push_back( rel ); } } }
bool contain( const PartVector & super , const PartVector & sub ) { bool result = ( ! sub.empty() ) && ( sub.size() <= super.size() ); if ( result ) { PartLess comp ; const PartVector::const_iterator ev = super.end(); PartVector::const_iterator iv = super.begin(); const PartVector::const_iterator ep = sub.end(); PartVector::const_iterator ip = sub.begin(); while ( result && ip != ep ) { Part * const q = *ip ; ++ip ; iv = std::lower_bound( iv , ev , q , comp ); result = iv != ev && *iv == q ; } } return result ; }
void BulkData::internal_propagate_part_changes( Entity & entity , const PartVector & removed ) { const unsigned etype = entity.entity_rank(); PairIterRelation rel = entity.relations(); for ( ; ! rel.empty() ; ++rel ) { const unsigned rel_type = rel->entity_rank(); const unsigned rel_ident = rel->identifier(); if ( rel_type < etype ) { // a 'to' entity Entity & e_to = * rel->entity(); PartVector to_del , to_add , empty ; // Induce part membership from this relationship to // pick up any additions. induced_part_membership( entity, empty, rel_type, rel_ident, to_add ); if ( ! removed.empty() ) { // Something was removed from the 'from' entity, // deduce what may have to be removed from the 'to' entity. // Deduce parts for 'e_to' from all upward relations. // Any non-parallel part that I removed that is not deduced for // 'e_to' must be removed from 'e_to' for ( PairIterRelation to_rel = e_to.relations(); ! to_rel.empty() ; ++to_rel ) { if ( e_to.entity_rank() < to_rel->entity_rank() && & entity != to_rel->entity() /* Already did this entity */ ) { // Relation from to_rel->entity() to e_to induced_part_membership( * to_rel->entity(), empty, e_to.entity_rank(), to_rel->identifier(), to_add ); } } for ( PartVector::const_iterator j = removed.begin() ; j != removed.end() ; ++j ) { if ( ! contain( to_add , **j ) ) { induced_part_membership( **j, etype, rel_type, rel_ident, to_del ); } } } if ( parallel_size() < 2 || e_to.sharing().empty() ) { // Entirely local, ok to remove memberships now internal_change_entity_parts( e_to , to_add , to_del ); } else { // Shared, do not remove memberships now. // Wait until modification_end. internal_change_entity_parts( e_to , to_add , empty ); } set_field_relations( entity, e_to, rel_ident ); } else if ( etype < rel_type ) { // a 'from' entity Entity & e_from = * rel->entity(); set_field_relations( e_from, entity, rel_ident ); } } }
void BulkData::internal_change_entity_parts( Entity & entity , const PartVector & add_parts , const PartVector & remove_parts ) { TraceIfWatching("stk_classic::mesh::BulkData::internal_change_entity_parts", LOG_ENTITY, entity.key()); DiagIfWatching(LOG_ENTITY, entity.key(), "entity state: " << entity); DiagIfWatching(LOG_ENTITY, entity.key(), "add_parts: " << add_parts); DiagIfWatching(LOG_ENTITY, entity.key(), "remove_parts: " << remove_parts); Bucket * const k_old = m_entity_repo.get_entity_bucket( entity ); const unsigned i_old = entity.bucket_ordinal() ; if ( k_old && k_old->member_all( add_parts ) && ! k_old->member_any( remove_parts ) ) { // Is already a member of all add_parts, // is not a member of any remove_parts, // thus nothing to do. return ; } PartVector parts_removed ; OrdinalVector parts_total ; // The final part list //-------------------------------- if ( k_old ) { // Keep any of the existing bucket's parts // that are not a remove part. // This will include the 'intersection' parts. // // These parts are properly ordered and unique. const std::pair<const unsigned *, const unsigned*> bucket_parts = k_old->superset_part_ordinals(); const unsigned * parts_begin = bucket_parts.first; const unsigned * parts_end = bucket_parts.second; const unsigned num_bucket_parts = parts_end - parts_begin; parts_total.reserve( num_bucket_parts + add_parts.size() ); parts_total.insert( parts_total.begin(), parts_begin , parts_end); if ( !remove_parts.empty() ) { parts_removed.reserve(remove_parts.size()); filter_out( parts_total , remove_parts , parts_removed ); } } else { parts_total.reserve(add_parts.size()); } if ( !add_parts.empty() ) { merge_in( parts_total , add_parts ); } if ( parts_total.empty() ) { // Always a member of the universal part. const unsigned univ_ord = m_mesh_meta_data.universal_part().mesh_meta_data_ordinal(); parts_total.push_back( univ_ord ); } //-------------------------------- // Move the entity to the new bucket. Bucket * k_new = m_bucket_repository.declare_bucket( entity.entity_rank(), parts_total.size(), & parts_total[0] , m_mesh_meta_data.get_fields() ); // If changing buckets then copy its field values from old to new bucket if ( k_old ) { m_bucket_repository.copy_fields( *k_new , k_new->size() , *k_old , i_old ); } else { m_bucket_repository.initialize_fields( *k_new , k_new->size() ); } // Set the new bucket m_entity_repo.change_entity_bucket( *k_new, entity, k_new->size() ); m_bucket_repository.add_entity_to_bucket( entity, *k_new ); // If changing buckets then remove the entity from the bucket, if ( k_old && k_old->capacity() > 0) { m_bucket_repository.remove_entity( k_old , i_old ); } // Update the change counter to the current cycle. m_entity_repo.set_entity_sync_count( entity, m_sync_count ); // Propagate part changes through the entity's relations. internal_propagate_part_changes( entity , parts_removed ); #ifndef NDEBUG //ensure_part_superset_consistency( entity ); #endif }
void add_node_parts(Iterator itr, size_t num) { ThrowRequire(!m_meta.is_commit()); m_node_parts.insert(m_node_parts.end(), itr, itr + num); }
Entity declare_element_to_entity(BulkData & mesh, Entity elem, Entity entity, const unsigned relationOrdinal, const PartVector& parts, stk::topology entity_top) { stk::topology elem_top = mesh.bucket(elem).topology(); std::vector<unsigned> entity_node_ordinals(entity_top.num_nodes()); elem_top.sub_topology_node_ordinals(mesh.entity_rank(entity), relationOrdinal, entity_node_ordinals.begin()); const stk::mesh::Entity *elem_nodes = mesh.begin_nodes(elem); EntityVector entity_top_nodes(entity_top.num_nodes()); elem_top.sub_topology_nodes(elem_nodes, mesh.entity_rank(entity), relationOrdinal, entity_top_nodes.begin()); Permutation perm = mesh.find_permutation(elem_top, elem_nodes, entity_top, &entity_top_nodes[0], relationOrdinal); OrdinalVector ordinal_scratch; ordinal_scratch.reserve(64); PartVector part_scratch; part_scratch.reserve(64); if(!parts.empty()) { mesh.change_entity_parts(entity, parts); } const stk::mesh::ConnectivityOrdinal *side_ordinals = mesh.begin_ordinals(elem, mesh.entity_rank(entity)); unsigned num_sides = mesh.count_valid_connectivity(elem, mesh.entity_rank(entity)); bool elem_to_side_exists = false; for(unsigned i = 0; i < num_sides; ++i) { if(side_ordinals[i] == relationOrdinal) { elem_to_side_exists = true; break; } } if(!elem_to_side_exists) { mesh.declare_relation(elem, entity, relationOrdinal, perm, ordinal_scratch, part_scratch); } const unsigned num_side_nodes = mesh.count_valid_connectivity(entity, stk::topology::NODE_RANK); if(0 == num_side_nodes) { Permutation node_perm = stk::mesh::Permutation::INVALID_PERMUTATION; Entity const *elem_nodes_local = mesh.begin_nodes(elem); for(unsigned i = 0; i < entity_top.num_nodes(); ++i) { Entity node = elem_nodes_local[entity_node_ordinals[i]]; mesh.declare_relation(entity, node, i, node_perm, ordinal_scratch, part_scratch); } } else { ThrowAssertMsg(num_side_nodes == entity_top.num_nodes(), "declare_element_to_entity: " << mesh.entity_key(entity) << " already exists with different number of nodes."); } return entity; }