void BulkData::internal_propagate_relocation( Entity & entity ) { PairIterRelation rel = entity.relations(); for ( ; rel ; ++rel ) { if ( rel->forward() ) { Entity & e_to = * rel->entity(); set_field_relations( entity, e_to, rel->identifier(), rel->kind() ); } else { Entity & e_from = * rel->entity(); set_field_relations( e_from, entity, rel->identifier(), rel->kind() ); } } }
void BulkData::declare_relation( Entity & e_from , Entity & e_to , const unsigned identifier , const unsigned kind ) { static const char method[] = "phdmesh::BulkData::declare_relation" ; if ( in_closure( e_to , e_from ) ) { std::ostringstream msg ; print_declare_relation( msg , method , e_from , e_to , identifier , kind ); msg << " FAILED DUE TO CIRCULAR CLOSURE." ; throw std::runtime_error( msg.str() ); } { const Relation forward( e_to , identifier , kind , false ); const std::vector<Relation>::iterator e = e_from.m_relation.end(); std::vector<Relation>::iterator i = e_from.m_relation.begin(); i = std::lower_bound( i , e , forward , LessRelation() ); if ( e == i || forward != *i ) { // Not a duplicate if ( e != i && forward.attribute() == i->attribute() ) { std::ostringstream msg ; print_declare_relation( msg, method, e_from, e_to, identifier, kind ); msg << " FAILED, ALREADY HAS THIS RELATION TO " ; print_entity_key( msg , i->entity()->key() ); throw std::runtime_error(msg.str()); } e_from.m_relation.insert( i , forward ); } } { const Relation converse( e_from , identifier , kind , true ); const std::vector<Relation>::iterator e = e_to.m_relation.end(); std::vector<Relation>::iterator i = e_to.m_relation.begin(); i = std::lower_bound( i , e , converse , LessRelation() ); if ( e == i || converse != *i ) { // Not a duplicate e_to.m_relation.insert( i , converse ); } } { PartSet add , del ; deduce_part_relations( e_from , e_to , identifier , kind , add ); internal_change_entity_parts( e_to , add , del ); } set_field_relations( e_from , e_to , identifier , kind ); }
void BulkData::declare_relation( Entity & e_from , Entity & e_to , const unsigned local_id ) { static const char method[] = "stk::mesh::BulkData::declare_relation" ; assert_ok_to_modify( method ); assert_valid_relation( method , *this , e_from , e_to ); m_entity_repo.declare_relation( e_from, e_to, local_id, m_sync_count); PartVector add , empty ; // Deduce and set new part memberships: induced_part_membership( e_from, empty, e_to.entity_rank(), local_id, add ); internal_change_entity_parts( e_to , add , empty ); set_field_relations( e_from , e_to , local_id ); }
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_propagate_part_changes( Entity & entity , const PartSet & removed ) { const EntityType etype = entity.entity_type(); Part * const owns_part = & m_mesh_meta_data.locally_owned_part(); Part * const uses_part = & m_mesh_meta_data.locally_used_part(); PairIterRelation rel = entity.relations(); for ( ; rel ; ++rel ) { const unsigned rel_ident = rel->identifier(); const unsigned rel_kind = rel->kind(); if ( rel->forward() ) { Entity & e_to = * rel->entity(); PartSet to_del ; PartSet to_add ; if ( ! removed.empty() ) { const EntityType t_to = e_to.entity_type(); // 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' deduce_part_relations( e_to , to_add ); to_del.reserve( removed.size() ); for ( PartSet::const_iterator j = removed.begin() ; j != removed.end() ; ++j ) { Part * const p = *j ; if ( p != owns_part && p != uses_part && ! contain( to_add , *p ) ) { to_del.push_back( p ); // What if removing a part with a part-relation ? const std::vector<PartRelation> & part_rel = m_mesh_meta_data.get_part_relations(); for ( std::vector<PartRelation>::const_iterator k = part_rel.begin() ; k != part_rel.end() ; ++k ) { const PartRelation & stencil = *k ; if ( p == stencil.m_root && 0 <= (*stencil.m_function)(etype,t_to,rel_ident,rel_kind) && ! contain( to_add , * stencil.m_target ) ) { } } } } } else { deduce_part_relations( entity , e_to , rel_ident , rel_kind , to_add ); } internal_change_entity_parts( e_to , to_add , to_del ); set_field_relations( entity, e_to, rel_ident , rel_kind ); } else { Entity & e_from = * rel->entity(); set_field_relations( e_from, entity, rel_ident, rel_kind ); } } }