void printNode(std::ostringstream& msg, Entity *node)
{
  printEntity(msg, node);
  PairIterRelation rels = node->relations();
  for (unsigned i = 0; i < rels.size(); i++)
    {
      Entity *entity = rels[i].entity();
      if (entity->entity_rank() > node->entity_rank())
        printEntity(msg, entity);
    }
}
Esempio n. 2
0
bool in_closure( const Entity & e_from , const Entity & e )
{
  PairIterRelation rel = e_from.relations();

  bool not_in_closure = & e_from != & e ;

  for ( ; not_in_closure && rel ; ++rel ) {
    if ( rel->forward() ) {
      not_in_closure = ! in_closure( * rel->entity() , e );
    }
  }

  return ! not_in_closure ;
}
Esempio n. 3
0
void closure( const Entity & e_from , std::vector<Entity*> & eset )
{
  PairIterRelation rel = e_from.relations();
  for ( ; rel ; ++rel ) {
    if ( rel->forward() ) {
      Entity * const e = rel->entity();
      std::vector<Entity*>::iterator i = eset.begin();
      std::vector<Entity*>::iterator j = eset.end();
      i = std::lower_bound( i , j , e , LessEntityPointer() );
      if ( i == j || e != *i ) {
        eset.push_back( e );
        closure( *e , eset );
      }
    }
  }
}
Esempio n. 4
0
/** \brief  Is in owned closure of the given process,
 *          typically the local process.
 */
bool in_owned_closure( const Entity & entity , unsigned proc )
{
  // TODO: This function has a potential performance problem if relations
  // are dense.

  // Does proc own this entity? If so, we're done
  bool result = entity.owner_rank() == proc ;

  if ( ! result ) {
    const unsigned erank = entity.entity_rank();

    // Does entity have an upward relation to an entity owned by proc
    for ( PairIterRelation
          rel = entity.relations(); ! result && ! rel.empty() ; ++rel ) {
      result =  erank < rel->entity_rank() &&
                in_owned_closure( * rel->entity(), proc);
    }
  }

  return result ;
}
Esempio n. 5
0
bool gather_field_data( const field_type & field ,
                        const Entity     & entity ,
                        typename FieldTraits< field_type >::data_type * dst )
{
  typedef typename FieldTraits< field_type >::data_type T ;

  PairIterRelation rel = entity.relations( EType );

  bool result = NRel == (unsigned) rel.size();

  if ( result ) {
    T * const dst_end = dst + NType * NRel ;
    for ( const T * src ;
          ( dst < dst_end ) &&
          ( src = field_data( field , * rel->entity() ) ) ;
          ++rel , dst += NType ) {
      Copy<NType>( dst , src );
    }
    result = dst == dst_end ;
  }
  return result ;
}
Esempio n. 6
0
void pack_entity_info( CommBuffer & buf , const Entity & entity )
{
  const EntityKey & key   = entity.key();
  const unsigned    owner = entity.owner_rank();
  const std::pair<const unsigned *, const unsigned *>
    part_ordinals = entity.bucket().superset_part_ordinals();
  const PairIterRelation relations = entity.relations();

  const unsigned nparts = part_ordinals.second - part_ordinals.first ;
  const unsigned nrel   = relations.size();

  buf.pack<EntityKey>( key );
  buf.pack<unsigned>( owner );
  buf.pack<unsigned>( nparts );
  buf.pack<unsigned>( part_ordinals.first , nparts );
  buf.pack<unsigned>( nrel );

  for ( unsigned i = 0 ; i < nrel ; ++i ) {
    buf.pack<EntityKey>( relations[i].entity()->key() );
    buf.pack<unsigned>( relations[i].identifier() );
    buf.pack<unsigned>( relations[i].attribute() );
  }
}
Esempio n. 7
0
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() );
    }
  }
}
Esempio n. 8
0
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 );
    }
  }
}
Esempio n. 9
0
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 );
    }
  }
}
Esempio n. 10
0
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 ;
}