void EntityRepository::declare_relation( Entity & e_from, Entity & e_to, const RelationIdentifier local_id, unsigned sync_count ) { TraceIfWatching("stk::mesh::impl::EntityRepository::declare_relation", LOG_ENTITY, e_from.key()); bool caused_change_fwd = e_from.m_entityImpl.declare_relation( e_to, local_id, sync_count); // Relationships should always be symmetrical if ( caused_change_fwd ) { // the setup for the converse relationship works slightly differently bool is_converse = true; bool caused_change_inv = e_to.m_entityImpl.declare_relation( e_from, local_id, sync_count, is_converse ); ThrowErrorMsgIf( !caused_change_inv, " Internal error - could not create inverse relation of " << print_entity_key( e_from ) << " to " << print_entity_key( e_to )); } // It is critical that the modification be done AFTER the relations are // added so that the propagation can happen correctly. if ( caused_change_fwd ) { e_to.m_entityImpl.log_modified_and_propagate(); e_from.m_entityImpl.log_modified_and_propagate(); } }
bool EntityRepository::destroy_relation( Entity & e_from, Entity & e_to, const RelationIdentifier local_id ) { TraceIfWatching("stk::mesh::impl::EntityRepository::destroy_relation", LOG_ENTITY, e_from.key()); bool caused_change_fwd = e_from.m_entityImpl.destroy_relation(e_to, local_id); // Relationships should always be symmetrical if ( caused_change_fwd ) { bool caused_change_inv = e_to.m_entityImpl.destroy_relation(e_from, local_id); ThrowErrorMsgIf( !caused_change_inv, " Internal error - could not destroy inverse relation of " << print_entity_key( e_from ) << " to " << print_entity_key( e_to ) << " with local relation id of " << local_id); } // It is critical that the modification be done AFTER the relations are // changed so that the propagation can happen correctly. if ( caused_change_fwd ) { e_to.m_entityImpl.log_modified_and_propagate(); e_from.m_entityImpl.log_modified_and_propagate(); } return caused_change_fwd; }
std::string print_entity_key( const MetaData & meta_data , const EntityKey & key ) { std::ostringstream out; print_entity_key(out, meta_data, key); return out.str(); }
static void print_comm_list( const BulkData & mesh , bool doit ) { if ( doit ) { std::ostringstream msg ; msg << std::endl ; for ( std::vector<Entity*>::const_iterator i = mesh.entity_comm().begin() ; i != mesh.entity_comm().end() ; ++i ) { Entity & entity = **i ; msg << "P" << mesh.parallel_rank() << ": " ; print_entity_key( msg , MetaData::get(mesh) , entity.key() ); msg << " owner(" << entity.owner_rank() << ")" ; if ( EntityLogModified == entity.log_query() ) { msg << " mod" ; } else if ( EntityLogDeleted == entity.log_query() ) { msg << " del" ; } else { msg << " " ; } for ( PairIterEntityComm ec = mesh.entity_comm(entity.key()); ! ec.empty() ; ++ec ) { msg << " gid, proc (" << ec->ghost_id << "," << ec->proc << ")" ; } msg << std::endl ; } std::cout << msg.str(); } }
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 ); }
std::ostream & print_relation( std::ostream & s , relation_attr_type attr , entity_key_type key ) { print_relation( s , attr ); print_entity_key( s , key ); return s ; }
void BulkData::require_entity_owner( const Entity & entity , unsigned owner ) const { const bool error_not_owner = owner != entity.owner_rank() ; ThrowRequireMsg( !error_not_owner, "Entity " << print_entity_key(entity) << " owner is " << entity.owner_rank() << ", expected " << owner); }
std::string print_entity_key(const Entity* entity) { if (entity == NULL) { return "NULL ENTITY"; } else { return print_entity_key(*entity); } }
void BulkData::generate_new_entities(const std::vector<size_t>& requests, std::vector<Entity *>& requested_entities) { Trace_("stk_classic::mesh::BulkData::generate_new_entities"); typedef stk_classic::parallel::DistributedIndex::KeyType KeyType; std::vector< std::vector<KeyType> > requested_key_types; m_entities_index.generate_new_keys(requests, requested_key_types); //generating 'owned' entities Part * const owns = & m_mesh_meta_data.locally_owned_part(); std::vector<Part*> rem ; std::vector<Part*> add; add.push_back( owns ); requested_entities.clear(); unsigned cnt=0; for (std::vector< std::vector<KeyType> >::const_iterator itr = requested_key_types.begin(); itr != requested_key_types.end(); ++itr) { const std::vector<KeyType>& key_types = *itr; for (std::vector<KeyType>::const_iterator kitr = key_types.begin(); kitr != key_types.end(); ++kitr) { ++cnt; } } requested_entities.reserve(cnt); for (std::vector< std::vector<KeyType> >::const_iterator itr = requested_key_types.begin(); itr != requested_key_types.end(); ++itr) { const std::vector<KeyType>& key_types = *itr; for (std::vector<KeyType>::const_iterator kitr = key_types.begin(); kitr != key_types.end(); ++kitr) { EntityKey key(&(*kitr)); std::pair<Entity *, bool> result = m_entity_repo.internal_create_entity(key); //if an entity is declare with the declare_entity function in //the same modification cycle as the generate_new_entities //function, and it happens to generate a key that was declare //previously in the same cycle it is an error ThrowErrorMsgIf( ! result.second, "Generated " << print_entity_key(m_mesh_meta_data, key) << " which was already used in this modification cycle."); // A new application-created entity Entity* new_entity = result.first; m_entity_repo.set_entity_owner_rank( *new_entity, m_parallel_rank); m_entity_repo.set_entity_sync_count( *new_entity, m_sync_count); //add entity to 'owned' part change_entity_parts( *new_entity , add , rem ); requested_entities.push_back(new_entity); } } }
void EntityRepository::destroy_later( Entity & e, Bucket* nil_bucket ) { TraceIfWatching("stk::mesh::impl::EntityRepository::destroy_later", LOG_ENTITY, e.key()); ThrowErrorMsgIf( e.log_query() == EntityLogDeleted, "double deletion of entity: " << print_entity_key( e )); change_entity_bucket( *nil_bucket, e, 0); e.m_entityImpl.log_deleted(); //important that this come last }
void BulkData::require_good_rank_and_id(EntityRank ent_rank, EntityId ent_id) const { const size_t rank_count = m_mesh_meta_data.entity_rank_count(); const bool ok_id = entity_id_valid(ent_id); const bool ok_rank = ent_rank < rank_count ; ThrowRequireMsg( ok_rank, "Bad key rank: " << ent_rank << " for id " << ent_id ); ThrowRequireMsg( ok_id, "Bad key id for key: " << print_entity_key(m_mesh_meta_data, EntityKey(ent_rank, ent_id) ) ); }
void EntityRepository::internal_expunge_entity( EntityMap::iterator i ) { TraceIfWatching("stk::mesh::impl::EntityRepository::internal_expunge_entity", LOG_ENTITY, i->first); ThrowErrorMsgIf( i->second == NULL, "For key " << entity_rank(i->first) << " " << entity_id(i->first) << ", value was NULL"); ThrowErrorMsgIf( i->first != i->second->key(), "Key " << print_entity_key(MetaData::get( *i->second ), i->first) << " != " << print_entity_key(i->second)); Entity* deleted_entity = i->second; #ifdef SIERRA_MIGRATION destroy_fmwk_attr(deleted_entity->m_fmwk_attrs, m_use_pool); #endif destroy_entity(deleted_entity, m_use_pool); i->second = NULL; m_entities.erase( i ); }
std::ostream & operator << ( std::ostream & s , const Relation & con ) { Entity * const e = con.entity(); print_relation( s , con.attribute() ); if ( e ) { print_entity_key( s , e->key() ); } else { s << "?" ; } return s ; }
Relation::Relation( relation_attr_type arg_attr , Entity & arg_entity ) : m_attr( arg_attr ), m_entity( & arg_entity ) { if ( relation_entity_type( arg_attr ) != arg_entity.entity_type() ) { std::ostringstream msg ; msg << "phdmesh::Relation::Relation( " ; print_relation( msg , arg_attr ); msg << " , " ; print_entity_key( msg , arg_entity.key() ); msg << " ) INCOMPATIBLE ARGUMENTS" ; throw std::invalid_argument( msg.str() ); } }
// This code was copied from bulk data and used to remove entities // from buckets. In order to remove an entity, an appropriate entity // must be found to copy into the hole. This logic will find the // appropriate bucket which has an entity to copy into the bucket. void Transaction::remove_entity_from_bucket ( Entity &e , BucketList &buckets ) { Bucket *k = e.m_trans_bucket; unsigned i = e.m_trans_bucket_ord; Bucket * const first = k->m_key[ *k->m_key ] ? k->m_bucket : k ; Bucket * const last = first->m_bucket ; // Only move if not the last entity being removed if ( last != k || k->m_size != i + 1 ) { // Not the same bucket or not the last entity // Copy last entity in last to ik slot i Entity * const entity = last->m_entities[ last->m_size - 1 ]; k->m_entities[i] = entity ; entity->m_trans_bucket = k ; entity->m_trans_bucket_ord = i ; } --( last->m_size ); if ( last->m_size != 0 ) { last->m_entities[ last->m_size ] = NULL ; } else { // The current 'last' bucket is to be deleted. // The previous 'last' bucket becomes the // new 'last' bucket in the family: std::vector<Bucket*>::iterator ik = lower_bound(buckets, last->m_key); ThrowRequireMsg( ik != buckets.end() && last == *ik, "Internal failure during removal of entity " << print_entity_key(e) ); ik = buckets.erase( ik ); if ( first != last ) { first->m_bucket = *--ik ; } Bucket::destroy_bucket( last ); } e.m_trans_bucket = NULL; }
void BulkData::internal_verify_change_parts( const MetaData & meta , const Entity & entity , const OrdinalVector & 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 ( OrdinalVector::const_iterator i = parts.begin() ; i != parts.end() ; ++i ) { const Part * const p = meta.get_parts()[*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 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 ; }
bool element_side_polarity( const Entity & elem , const Entity & side , int local_side_id ) { // 09/14/10: TODO: tscoffe: Will this work in 1D? FEMMetaData &fem_meta = FEMMetaData::get(elem); const bool is_side = side.entity_rank() != fem_meta.edge_rank(); const CellTopologyData * const elem_top = get_cell_topology( elem ).getCellTopologyData(); const unsigned side_count = ! elem_top ? 0 : ( is_side ? elem_top->side_count : elem_top->edge_count ); ThrowErrorMsgIf( elem_top == NULL, "For Element[" << elem.identifier() << "], element has no defined topology"); ThrowErrorMsgIf( local_side_id < 0 || static_cast<int>(side_count) <= local_side_id, "For Element[" << elem.identifier() << "], " << "side: " << print_entity_key(side) << ", " << "local_side_id = " << local_side_id << " ; unsupported local_side_id"); const CellTopologyData * const side_top = is_side ? elem_top->side[ local_side_id ].topology : elem_top->edge[ local_side_id ].topology ; const unsigned * const side_map = is_side ? elem_top->side[ local_side_id ].node : elem_top->edge[ local_side_id ].node ; const PairIterRelation elem_nodes = elem.relations( FEMMetaData::NODE_RANK ); const PairIterRelation side_nodes = side.relations( FEMMetaData::NODE_RANK ); const unsigned n = side_top->node_count; bool good = false ; for ( unsigned i = 0 ; !good && i < n ; ++i ) { good = true; for ( unsigned j = 0; good && j < n ; ++j ) { good = side_nodes[(j+i)%n].entity() == elem_nodes[ side_map[j] ].entity(); } } return good ; }
std::string print_entity_key(const Entity& entity) { return print_entity_key(MetaData::get(entity), entity.key()); }