void PartImpl::set_intersection_of( const PartVector & pv ) { TraceIfWatching("stk_classic::mesh::impl::PartImpl::set_intersection_of", LOG_PART, m_universe_ordinal); DiagIfWatching(LOG_PART, m_universe_ordinal, "Intersection: " << pv ); m_intersect = pv ; }
void PartImpl::add_relation( PartRelation relation ) { TraceIfWatching("stk_classic::mesh::impl::PartImpl::add_relation", LOG_PART, m_universe_ordinal); DiagIfWatching(LOG_PART, m_universe_ordinal, "New relation from: " << relation.m_root << ", to: " << relation.m_target ); m_relations.push_back(relation); }
void PartImpl::add_part_to_superset( Part & part ) { TraceIfWatching("stk_classic::mesh::impl::PartImpl::add_part_to_superset", LOG_PART, m_universe_ordinal); DiagIfWatching(LOG_PART, m_universe_ordinal, "New superset is: " << part ); insert( m_supersets, part ); }
Entity & BulkData::declare_entity( EntityRank ent_rank , EntityId ent_id , const PartVector & parts ) { require_ok_to_modify(); require_good_rank_and_id(ent_rank, ent_id); EntityKey key( ent_rank , ent_id ); TraceIfWatching("stk_classic::mesh::BulkData::declare_entity", LOG_ENTITY, key); DiagIfWatching(LOG_ENTITY, key, "declaring entity with parts " << parts); std::pair< Entity * , bool > result = m_entity_repo.internal_create_entity( key ); Entity* declared_entity = result.first; if ( result.second ) { // A new application-created entity m_entity_repo.set_entity_owner_rank( *declared_entity, m_parallel_rank); m_entity_repo.set_entity_sync_count( *declared_entity, m_sync_count); DiagIfWatching(LOG_ENTITY, key, "new entity: " << *declared_entity); } else { // An existing entity, the owner must match. require_entity_owner( *declared_entity , m_parallel_rank ); DiagIfWatching(LOG_ENTITY, key, "existing entity: " << *declared_entity); } //------------------------------ Part * const owns = & m_mesh_meta_data.locally_owned_part(); std::vector<Part*> rem ; std::vector<Part*> add( parts ); add.push_back( owns ); change_entity_parts( *declared_entity , add , rem ); // m_transaction_log.insert_entity ( *(result.first) ); return *declared_entity ; }
void EntityRepository::change_entity_bucket( Bucket & b, Entity & e, unsigned ordinal) { TraceIfWatching("stk::mesh::impl::EntityRepository::change_entity_bucket", LOG_ENTITY, e.key()); DiagIfWatching(LOG_ENTITY, e.key(), "New bucket: " << b << ", ordinal: " << ordinal); const bool modified_parts = ! e.m_entityImpl.is_bucket_valid() || ! b.equivalent( e.bucket() ); if ( modified_parts ) { e.m_entityImpl.log_modified_and_propagate(); } e.m_entityImpl.set_bucket_and_ordinal( &b, ordinal); }
bool BulkData::destroy_entity( Entity * & entity_in ) { Entity & entity = *entity_in ; TraceIfWatching("stk_classic::mesh::BulkData::destroy_entity", LOG_ENTITY, entity.key()); DiagIfWatching(LOG_ENTITY, entity.key(), "entity state: " << entity); require_ok_to_modify( ); bool has_upward_relation = false ; for ( PairIterRelation irel = entity.relations() ; ! irel.empty() && ! has_upward_relation ; ++irel ) { has_upward_relation = entity.entity_rank() <= irel->entity_rank(); } if ( has_upward_relation ) { return false ; } if ( EntityLogDeleted == entity.log_query() ) { // Cannot already be destroyed. return false ; } //------------------------------ // Immediately remove it from relations and buckets. // Postpone deletion until modification_end to be sure that // 1) No attempt is made to re-create it. // 2) Parallel index is cleaned up. // 3) Parallel sharing is cleaned up. // 4) Parallel ghosting is cleaned up. // // Must clean up the parallel lists before fully deleting the entity. // It is important that relations be destroyed in reverse order so that // the higher (back) relations are destroyed first. while ( ! entity.relations().empty() ) { destroy_relation( entity , * entity.relations().back().entity(), entity.relations().back().identifier()); } // We need to save these items and call remove_entity AFTER the call to // destroy_later because remove_entity may destroy the bucket // which would cause problems in m_entity_repo.destroy_later because it // makes references to the entity's original bucket. Bucket& orig_bucket = entity.bucket(); unsigned orig_bucket_ordinal = entity.bucket_ordinal(); // Set the bucket to 'bucket_nil' which: // 1) has no parts at all // 2) has no field data // 3) has zero capacity // // This keeps the entity-bucket methods from catastrophically failing // with a bad bucket pointer. m_entity_repo.destroy_later( entity, m_bucket_repository.get_nil_bucket() ); m_bucket_repository.remove_entity( &orig_bucket , orig_bucket_ordinal ); // Add destroyed entity to the transaction // m_transaction_log.delete_entity ( *entity_in ); // Set the calling entity-pointer to NULL; // hopefully the user-code will clean up any outstanding // references to this entity. entity_in = NULL ; return true ; }
void BulkData::internal_change_entity_parts( Entity & entity , const OrdinalVector & add_parts , const OrdinalVector & remove_parts, bool always_propagate_internal_changes ) { 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 ; } OrdinalVector 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. //(Only propagate part changes for parts which have a primary-entity-rank that matches // the entity's rank. Other parts don't get induced...) const PartVector& all_parts = m_mesh_meta_data.get_parts(); OrdinalVector rank_parts_removed; for(OrdinalVector::const_iterator pr=parts_removed.begin(), prend=parts_removed.end(); pr!=prend; ++pr) { if (all_parts[*pr]->primary_entity_rank() == entity.entity_rank()) { rank_parts_removed.push_back(*pr); } } if (always_propagate_internal_changes || !rank_parts_removed.empty() || !m_mesh_meta_data.get_field_relations().empty()) { internal_propagate_part_changes( entity , rank_parts_removed ); } #ifndef NDEBUG //ensure_part_superset_consistency( entity ); #endif }