13 #include <stk_mesh/baseImpl/BucketRepository.hpp> 14 #include <stk_mesh/baseImpl/EntityRepository.hpp> 15 #include <stk_mesh/base/BulkData.hpp> 16 #include <stk_mesh/base/Bucket.hpp> 17 #include <stk_mesh/base/Trace.hpp> 26 BucketRepository::BucketRepository(
28 unsigned bucket_capacity,
29 unsigned entity_rank_count,
30 EntityRepository & entity_repo
33 m_bucket_capacity(bucket_capacity),
34 m_buckets(entity_rank_count),
36 m_entity_repo(entity_repo)
41 BucketRepository::~BucketRepository()
46 for ( std::vector< std::vector<Bucket*> >::iterator
47 i = m_buckets.end() ; i != m_buckets.begin() ; ) {
49 std::vector<Bucket*> & kset = *--i ;
51 while ( ! kset.empty() ) {
52 try { destroy_bucket( kset.back() ); }
catch(...) {}
61 try {
if ( m_nil_bucket ) destroy_bucket( m_nil_bucket ); }
catch(...) {}
69 void BucketRepository::destroy_bucket(
const unsigned &
entity_rank , Bucket * bucket_to_be_deleted )
71 TraceIfWatching(
"stk_classic::mesh::impl::BucketRepository::destroy_bucket", LOG_BUCKET, bucket_to_be_deleted);
73 ThrowRequireMsg(MetaData::get(m_mesh).check_rank(
entity_rank),
76 std::vector<Bucket *> & bucket_set = m_buckets[
entity_rank];
79 Bucket *
const first = bucket_to_be_deleted->m_bucketImpl.first_bucket_in_family();
81 ThrowRequireMsg( bucket_to_be_deleted->equivalent(*first),
"Logic error - bucket_to_be_deleted is not in same family as first_bucket_in_family");
82 ThrowRequireMsg( first->equivalent(*bucket_to_be_deleted),
"Logic error - first_bucket_in_family is not in same family as bucket_to_be_deleted");
84 ThrowRequireMsg( bucket_to_be_deleted->size() == 0,
85 "Destroying non-empty bucket " << *(bucket_to_be_deleted->key()) );
87 ThrowRequireMsg( bucket_to_be_deleted == first->m_bucketImpl.get_bucket_family_pointer(),
88 "Destroying bucket family") ;
90 std::vector<Bucket*>::iterator ik = lower_bound(bucket_set, bucket_to_be_deleted->key());
91 ThrowRequireMsg( ik != bucket_set.end() && bucket_to_be_deleted == *ik,
92 "Bucket not found in bucket set for entity rank " <<
entity_rank );
94 ik = bucket_set.erase( ik );
96 if ( first != bucket_to_be_deleted ) {
98 ThrowRequireMsg( ik != bucket_set.begin(),
99 "Where did first bucket go?" );
101 first->m_bucketImpl.set_last_bucket_in_family( *--ik );
103 ThrowRequireMsg ( first->m_bucketImpl.get_bucket_family_pointer()->size() != 0,
107 destroy_bucket( bucket_to_be_deleted );
111 void BucketRepository::destroy_bucket( Bucket * bucket )
113 TraceIfWatching(
"stk_classic::mesh::impl::BucketRepository::destroy_bucket", LOG_BUCKET, bucket);
122 BucketRepository::declare_nil_bucket()
124 TraceIf(
"stk_classic::mesh::impl::BucketRepository::declare_nil_bucket", LOG_BUCKET);
126 if (m_nil_bucket == NULL) {
130 std::vector<unsigned> new_key(2);
135 new Bucket(m_mesh, InvalidEntityRank, new_key, 0);
137 bucket->m_bucketImpl.set_bucket_family_pointer( bucket );
141 m_nil_bucket = bucket;
171 BucketRepository::declare_bucket(
172 const unsigned arg_entity_rank ,
173 const unsigned part_count ,
174 const unsigned part_ord[] ,
175 const std::vector< FieldBase * > & field_set
178 enum { KEY_TMP_BUFFER_SIZE = 64 };
180 TraceIf(
"stk_classic::mesh::impl::BucketRepository::declare_bucket", LOG_BUCKET);
182 const unsigned max =
static_cast<unsigned>(-1);
184 ThrowRequireMsg(MetaData::get(m_mesh).check_rank(arg_entity_rank),
185 "Entity rank " << arg_entity_rank <<
" is invalid");
187 ThrowRequireMsg( !m_buckets.empty(),
188 "m_buckets is empty! Did you forget to initialize MetaData before creating BulkData?");
189 std::vector<Bucket *> & bucket_set = m_buckets[ arg_entity_rank ];
192 std::vector<unsigned> key(2+part_count) ;
201 key[0] = part_count+1;
202 key[ key[0] ] = max ;
205 for (
unsigned i = 0 ; i < part_count ; ++i ) { key[i+1] = part_ord[i] ; }
212 const std::vector<Bucket*>::iterator ik = lower_bound( bucket_set , &key[0] );
217 const bool bucket_family_exists =
218 ik != bucket_set.begin() && bucket_part_equal( ik[-1]->key() , &key[0] );
220 Bucket *
const last_bucket = bucket_family_exists ? ik[-1] : NULL ;
222 Bucket * bucket = NULL ;
224 if ( last_bucket == NULL ) {
229 ThrowRequireMsg( last_bucket->size() != 0,
230 "Last bucket should not be empty.");
234 const unsigned last_count = last_bucket->key()[ key[0] ];
236 const unsigned cap = last_bucket->capacity();
238 if ( last_bucket->size() < cap ) {
239 bucket = last_bucket ;
241 else if ( last_count < max ) {
242 key[ key[0] ] = 1 + last_count ;
246 ThrowRequireMsg(
false,
"Insanely large number of buckets" );
254 if ( NULL == bucket )
256 bucket =
new Bucket( m_mesh, arg_entity_rank, key, m_bucket_capacity);
258 Bucket * first_bucket = last_bucket ? last_bucket->m_bucketImpl.first_bucket_in_family() : bucket ;
260 bucket->m_bucketImpl.set_first_bucket_in_family(first_bucket);
262 first_bucket->m_bucketImpl.set_last_bucket_in_family(bucket);
264 bucket_set.insert( ik , bucket );
269 ThrowRequireMsg( bucket->equivalent(*bucket->m_bucketImpl.first_bucket_in_family()),
"Logic error - new bucket is not in same family as first_bucket_in_family");
270 ThrowRequireMsg( bucket->m_bucketImpl.first_bucket_in_family()->equivalent(*bucket),
"Logic error - first_bucket_in_family is not in same family as new bucket");
277 void BucketRepository::initialize_fields( Bucket & k_dst ,
unsigned i_dst )
279 TraceIfWatching(
"stk_classic::mesh::impl::BucketRepository::initialize_fields", LOG_BUCKET, &k_dst);
280 k_dst.m_bucketImpl.initialize_fields(i_dst);
285 void BucketRepository::update_field_data_states()
const 287 TraceIf(
"stk_classic::mesh::impl::BucketRepository::update_field_data_states", LOG_BUCKET);
289 for ( std::vector< std::vector<Bucket*> >::const_iterator
290 i = m_buckets.begin() ; i != m_buckets.end() ; ++i ) {
292 const std::vector<Bucket*> & kset = *i ;
294 for ( std::vector<Bucket*>::const_iterator
295 ik = kset.begin() ; ik != kset.end() ; ++ik ) {
296 (*ik)->m_bucketImpl.update_state();
305 void BucketRepository::internal_sort_bucket_entities()
307 TraceIf(
"stk_classic::mesh::impl::BucketRepository::internal_sort_bucket_entities", LOG_BUCKET);
312 std::vector<Bucket*> & buckets = m_buckets[
entity_rank ];
317 for ( ; bk < buckets.size() ; bk = ek ) {
318 Bucket * b_scratch = NULL ;
319 Bucket * ik_vacant = buckets[bk]->m_bucketImpl.last_bucket_in_family();
320 unsigned ie_vacant = ik_vacant->size();
322 if ( ik_vacant->capacity() <= ie_vacant ) {
324 const unsigned *
const bucket_key = buckets[bk]->key() ;
325 const unsigned part_count = bucket_key[0] - 1 ;
326 const unsigned *
const part_ord = bucket_key + 1 ;
329 part_count , part_ord ,
330 MetaData::get(m_mesh).get_fields() );
332 ik_vacant = b_scratch ;
336 ik_vacant->m_bucketImpl.replace_entity( ie_vacant , NULL ) ;
339 while ( ek < buckets.size() && ik_vacant != buckets[ek] ) { ++ek ; }
340 if (ek < buckets.size()) ++ek ;
343 for (
size_t ik = bk ; ik != ek ; ++ik ) {
344 count += buckets[ik]->size();
347 std::vector<Entity*> entities( count );
349 std::vector<Entity*>::iterator j = entities.begin();
351 for (
size_t ik = bk ; ik != ek ; ++ik ) {
352 Bucket & b = * buckets[ik];
353 const unsigned n = b.size();
354 for (
unsigned i = 0 ; i < n ; ++i , ++j ) {
359 std::sort( entities.begin() , entities.end() , EntityLess() );
361 j = entities.begin();
363 bool change_this_family = false ;
365 for (
size_t ik = bk ; ik != ek ; ++ik ) {
366 Bucket & b = * buckets[ik];
367 const unsigned n = b.size();
368 for (
unsigned i = 0 ; i < n ; ++i , ++j ) {
369 Entity *
const current = & b[i] ;
371 if ( current != *j ) {
375 copy_fields( *ik_vacant , ie_vacant , b, i );
376 m_entity_repo.change_entity_bucket(*ik_vacant, *current, ie_vacant);
377 ik_vacant->m_bucketImpl.replace_entity( ie_vacant , current ) ;
381 ik_vacant = & ((*j)->bucket()) ;
382 ie_vacant = (*j)->bucket_ordinal() ;
383 ik_vacant->m_bucketImpl.replace_entity( ie_vacant , NULL ) ;
386 copy_fields( b, i, *ik_vacant , ie_vacant );
387 m_entity_repo.change_entity_bucket( b, **j, i);
388 b.m_bucketImpl.replace_entity( i, *j );
390 change_this_family = true ;
398 if ( change_this_family ) { internal_propagate_relocation( **j ); }
411 void BucketRepository::optimize_buckets()
413 TraceIf(
"stk_classic::mesh::impl::BucketRepository::optimize_buckets", LOG_BUCKET);
419 std::vector<Bucket*> & buckets = m_buckets[
entity_rank ];
421 std::vector<Bucket*> tmp_buckets;
423 size_t begin_family = 0 ;
424 size_t end_family = 0 ;
427 for ( ; begin_family < buckets.size() ; begin_family = end_family ) {
428 Bucket * last_bucket_in_family = buckets[begin_family]->m_bucketImpl.last_bucket_in_family();
431 while ( end_family < buckets.size() && last_bucket_in_family != buckets[end_family] ) { ++end_family ; }
432 if (end_family < buckets.size()) ++end_family ;
435 const bool is_compressed = (end_family-begin_family == 1)
436 && (buckets[begin_family]->size() == buckets[begin_family]->capacity());
438 const Bucket & b = *buckets[begin_family];
439 bool is_sorted =
true;
440 for (
size_t i=0, end=b.size()-1; i<end && is_sorted; ++i)
442 if(b[i].key() >= b[i+1].key()) is_sorted =
false;
445 tmp_buckets.push_back(buckets[begin_family]);
450 std::vector<unsigned> new_key = buckets[begin_family]->m_bucketImpl.key_vector();
452 new_key[ new_key[0] ] = 0;
454 unsigned new_capacity = 0 ;
455 for (
size_t i = begin_family ; i != end_family ; ++i ) {
456 new_capacity += buckets[i]->m_bucketImpl.size();
459 std::vector<Entity*> entities;
460 entities.reserve(new_capacity);
462 for (
size_t i = begin_family ; i != end_family ; ++i ) {
463 Bucket& b = *buckets[i];
464 for(
size_t j=0; j<b.size(); ++j) {
465 entities.push_back(&b[j]);
469 std::sort( entities.begin(), entities.end(), EntityLess() );
471 Bucket * new_bucket =
new Bucket( m_mesh,
477 new_bucket->m_bucketImpl.set_first_bucket_in_family(new_bucket);
478 new_bucket->m_bucketImpl.set_last_bucket_in_family(new_bucket);
480 tmp_buckets.push_back(new_bucket);
482 for(
size_t new_ordinal=0; new_ordinal<entities.size(); ++new_ordinal) {
484 new_bucket->m_bucketImpl.increment_size();
486 Entity & entity = *entities[new_ordinal];
487 Bucket& old_bucket = entity.
bucket();
491 copy_fields( *new_bucket, new_ordinal, old_bucket, old_ordinal);
492 m_entity_repo.change_entity_bucket( *new_bucket, entity, new_ordinal);
493 new_bucket->m_bucketImpl.replace_entity( new_ordinal , &entity ) ;
494 internal_propagate_relocation(entity);
497 for (
size_t ik = begin_family; ik != end_family; ++ik) {
503 buckets.swap(tmp_buckets);
508 void BucketRepository::remove_entity( Bucket * k ,
unsigned i )
510 TraceIfWatching(
"stk_classic::mesh::impl::BucketRepository::remove_entity", LOG_BUCKET, k);
512 ThrowRequireMsg( k != m_nil_bucket,
"Cannot remove entity from nil_bucket" );
519 Bucket *
const last = k->m_bucketImpl.last_bucket_in_family();
521 ThrowRequireMsg( last->equivalent(*k),
"Logic error - last bucket in family not equivalent to bucket");
522 ThrowRequireMsg( k->equivalent(*last),
"Logic error - bucket not equivalent to last bucket in family");
526 if ( last != k || k->size() != i + 1 ) {
530 Entity & entity = (*last)[ last->size() - 1 ];
532 copy_fields( *k , i , *last , last->size() - 1 );
534 k->m_bucketImpl.replace_entity(i, & entity ) ;
535 m_entity_repo.change_entity_bucket( *k, entity, i);
539 internal_propagate_relocation( entity );
542 last->m_bucketImpl.decrement_size();
544 last->m_bucketImpl.replace_entity( last->size() , NULL ) ;
546 if ( 0 == last->size() ) {
553 void BucketRepository::internal_propagate_relocation( Entity & entity )
555 TraceIf(
"stk_classic::mesh::impl::BucketRepository::internal_propagate_relocation", LOG_BUCKET);
558 PairIterRelation rel = entity.
relations();
560 for ( ; ! rel.empty() ; ++rel ) {
561 const EntityRank rel_rank = rel->entity_rank();
562 if ( rel_rank < erank ) {
563 Entity & e_to = * rel->entity();
565 set_field_relations( entity, e_to, rel->identifier() );
567 else if ( erank < rel_rank ) {
568 Entity & e_from = * rel->entity();
570 set_field_relations( e_from, entity, rel->identifier() );
unsigned bucket_ordinal() const
The ordinal for this entity within its bucket.
Bucket & bucket() const
The bucket which holds this mesh entity's field data.
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
EntityRank entity_rank() const
The rank of this entity.
EntityRank entity_rank(const EntityKey &key)
Given an entity key, return an entity type (rank).
eastl::iterator_traits< InputIterator >::difference_type count(InputIterator first, InputIterator last, const T &value)