22 #include <stk_util/environment/ReportHandler.hpp> 24 #include <stk_util/parallel/ParallelComm.hpp> 25 #include <stk_util/parallel/ParallelReduce.hpp> 27 #include <stk_mesh/base/BulkData.hpp> 28 #include <stk_mesh/base/MetaData.hpp> 29 #include <stk_mesh/base/Entity.hpp> 30 #include <stk_mesh/base/EntityComm.hpp> 31 #include <stk_mesh/base/Trace.hpp> 38 bool comm_mesh_verify_parallel_consistency(
39 BulkData & M , std::ostream & error_log );
43 unsigned BulkData::determine_new_owner( Entity & entity )
const 50 EntityLogDeleted == entity.log_query() ? ~0u : m_parallel_rank ;
53 share = m_entity_comm_map.sharing(entity.key()); ! share.empty() ; ++share ) {
54 if ( share->proc < m_parallel_size &&
55 ( new_owner < share->proc || m_parallel_size <= new_owner ) ) {
56 new_owner = share->proc ;
68 Entity* find_entity(
const EntityVector& entities,
const EntityKey& key,
69 bool expect_success =
false)
71 EntityVector::const_iterator itr =
72 std::lower_bound(entities.begin(),
76 if (itr == entities.end() || (*itr)->key() != key) {
77 ThrowRequireMsg(!expect_success,
78 "Expected to be able to find entity of type: " <<
79 key.type() <<
" and rank: " << key.rank());
85 struct EntityProcState {
89 bool operator<(
const EntityProcState& rhs)
const 92 return el(entity_proc, rhs.entity_proc);
96 bool pack_entity_modification(
const BulkData & mesh ,
97 const bool pack_shared ,
102 const std::vector<Entity*> & entity_comm = mesh.entity_comm();
104 for ( std::vector<Entity*>::const_iterator
105 i = entity_comm.begin() ; i != entity_comm.end() ; ++i ) {
107 Entity & entity = **i ;
109 if ( entity.
log_query() == EntityLogModified ||
110 entity.
log_query() == EntityLogDeleted ) {
113 const bool shared = 0 == ec->ghost_id ;
114 if ( pack_shared == shared ) {
115 comm.send_buffer( ec->proc )
116 .pack<EntityKey>( entity.
key() )
117 .pack<EntityModificationLog>( entity.
log_query() );
128 void communicate_entity_modification(
const BulkData & mesh ,
130 std::vector<EntityProcState > & data )
132 CommAll comm( mesh.parallel() );
135 const bool local_mod = pack_entity_modification( mesh , shared , comm );
138 const bool global_mod =
139 comm.allocate_buffers( comm.parallel_size() / 4 , false , local_mod );
142 const std::vector<Entity*> & entity_comm = mesh.entity_comm();
145 pack_entity_modification( mesh , shared , comm );
149 for (
unsigned p = 0 ; p < comm.parallel_size() ; ++p ) {
150 CommBuffer & buf = comm.recv_buffer( p );
152 EntityProcState tmp ;
154 while ( buf.remaining() ) {
156 buf.unpack<EntityKey>( key )
157 .unpack<EntityModificationLog>( tmp.state );
161 tmp.entity_proc.first = find_entity(entity_comm, key,
true);
162 tmp.entity_proc.second = p ;
164 data.push_back( tmp );
169 std::sort( data.begin() , data.end() );
183 void BulkData::internal_update_distributed_index(
184 std::vector<Entity*> & shared_new )
186 Trace_(
"stk_classic::mesh::BulkData::internal_update_distributed_index");
188 std::vector< parallel::DistributedIndex::KeyType >
189 local_created_or_modified ,
195 for ( impl::EntityRepository::iterator
196 i = m_entity_repo.begin() ; i != m_entity_repo.end() ; ++i ) {
198 Entity & entity = * i->second ;
200 if ( EntityLogDeleted == entity.log_query() ) {
202 del_entities_keys.push_back( entity.key().raw_key() );
204 else if ( entity.log_query() != EntityLogNoChange &&
205 in_owned_closure( entity , m_parallel_rank ) ) {
207 local_created_or_modified.push_back( entity.key().raw_key() );
213 m_entities_index.update_keys( local_created_or_modified , del_entities_keys );
218 std::vector< parallel::DistributedIndex::KeyProc >
219 global_created_or_modified ;
220 m_entities_index.query_to_usage( local_created_or_modified ,
221 global_created_or_modified );
226 Entity * entity = NULL ;
231 for ( std::vector< parallel::DistributedIndex::KeyProc >::iterator
232 i = global_created_or_modified.begin() ;
233 i != global_created_or_modified.end() ; ++i ) {
235 EntityKey key( & i->first );
236 unsigned modifying_proc = i->second;
239 ThrowAssertMsg( !std::binary_search(del_entities_keys.begin(),
240 del_entities_keys.end(),
243 " was locally deleted, but somehow was included in global_created_or_modified; " <<
244 " this probably means there's problem in DistributedIndex." );
246 if ( m_parallel_rank != modifying_proc ) {
250 if ( entity == NULL || entity->key() != key ) {
254 shared_new.push_back( entity );
258 m_entity_comm_map.insert(entity->key(), EntityCommInfo( 0,
273 void destroy_dependent_ghosts( BulkData & mesh , Entity * entity )
276 PairIterRelation rel = entity->
relations();
278 if ( rel.empty() ) { break ; }
280 Entity * e = rel.back().entity();
282 if ( e->entity_rank() < entity->
entity_rank() ) { break ; }
284 ThrowRequireMsg( !in_owned_closure( *e , mesh.parallel_rank()),
285 "Entity " << print_entity_key(e) <<
" should not be in closure." );
287 destroy_dependent_ghosts( mesh , e );
290 mesh.destroy_entity( entity );
303 void resolve_shared_removed_from_owned_closure( BulkData & mesh )
305 for ( std::vector<Entity*>::const_reverse_iterator
306 i = mesh.entity_comm().rbegin() ;
307 i != mesh.entity_comm().rend() ; ++i) {
309 Entity * entity = *i ;
311 if ( ! mesh.entity_comm_sharing(entity->
key()).empty() &&
312 ! in_owned_closure( *entity , mesh.parallel_rank() ) ) {
314 destroy_dependent_ghosts( mesh , entity );
332 void BulkData::internal_resolve_shared_modify_delete()
334 Trace_(
"stk_classic::mesh::BulkData::internal_resolve_shared_modify_delete");
336 ThrowRequireMsg(
parallel_size() > 1,
"Do not call this in serial");
338 resolve_shared_removed_from_owned_closure( *
this );
340 std::vector< EntityProcState > remote_mod ;
344 const bool communicate_shared = true ;
345 communicate_entity_modification( *
this , communicate_shared , remote_mod );
349 for ( std::vector<EntityProcState>::reverse_iterator
350 i = remote_mod.rbegin(); i != remote_mod.rend() ; ) {
352 Entity *
const entity = i->entity_proc.first ;
353 const bool locally_destroyed = EntityLogDeleted == entity->log_query();
354 bool remote_owner_destroyed =
false;
357 for ( ; i != remote_mod.rend() && i->entity_proc.first == entity ; ++i ) {
359 const unsigned remote_proc = i->entity_proc.second ;
360 const bool remotely_destroyed = EntityLogDeleted == i->state ;
366 if ( ! locally_destroyed ) {
367 m_entity_repo.log_modified( *entity );
378 if ( remotely_destroyed ) {
379 m_entity_comm_map.erase(entity->key(), EntityCommInfo(0,remote_proc) );
382 if ( entity->owner_rank() == remote_proc ) {
383 remote_owner_destroyed = true ;
391 const bool exists_somewhere = ! ( remote_owner_destroyed &&
393 new_sharing.empty() );
396 if ( exists_somewhere ) {
398 const bool old_local_owner = m_parallel_rank == entity->owner_rank();
401 const bool give_ownership = locally_destroyed && old_local_owner ;
405 if ( give_ownership || remote_owner_destroyed ) {
407 const unsigned new_owner = determine_new_owner( *entity );
409 m_entity_repo.set_entity_owner_rank( *entity, new_owner );
410 m_entity_repo.set_entity_sync_count( *entity, m_sync_count );
413 if ( ! locally_destroyed ) {
417 if ( new_sharing.empty() ) {
419 remove_part.push_back(& m_mesh_meta_data.globally_shared_part());
422 const bool new_local_owner = m_parallel_rank == entity->owner_rank();
424 const bool local_claimed_ownership =
425 ( ! old_local_owner && new_local_owner );
427 if ( local_claimed_ownership ) {
429 add_part.push_back( & m_mesh_meta_data.locally_owned_part() );
432 if ( ! add_part.empty() || ! remove_part.empty() ) {
433 internal_change_entity_parts( *entity , add_part , remove_part );
440 for ( std::vector<Entity*>::const_reverse_iterator
442 Entity * entity = *i ;
444 if ( EntityLogDeleted == entity->log_query() ) {
446 m_entity_comm_map.erase(entity->key(), *m_ghosting[0] );
462 void BulkData::internal_resolve_ghosted_modify_delete()
464 Trace_(
"stk_classic::mesh::BulkData::internal_resolve_ghosted_modify_delete");
466 ThrowRequireMsg(
parallel_size() > 1,
"Do not call this in serial");
469 std::vector<EntityProcState > remote_mod ;
472 const bool communicate_shared = false ;
473 communicate_entity_modification( *
this , communicate_shared , remote_mod );
475 const size_t ghosting_count = m_ghosting.size();
477 std::vector< int > ghosting_change_flags( ghosting_count , 0 );
483 for ( std::vector<EntityProcState>::reverse_iterator
484 i = remote_mod.rbegin(); i != remote_mod.rend() ; ++i ) {
485 Entity * entity = i->entity_proc.first ;
486 const unsigned remote_proc = i->entity_proc.second ;
487 const bool local_owner = entity->owner_rank() == m_parallel_rank ;
488 const bool remotely_destroyed = EntityLogDeleted == i->state ;
489 const bool locally_destroyed = EntityLogDeleted == entity->log_query();
493 if ( remotely_destroyed ) {
497 for (
size_t j = ghosting_count ; j-- ; ) {
498 if ( m_entity_comm_map.erase( entity->key(), EntityCommInfo( j , remote_proc ) ) ) {
499 ghosting_change_flags[ j ] = true ;
511 for (
PairIterEntityComm ec = m_entity_comm_map.comm(entity->key()) ; ! ec.empty() ; ++ec ) {
512 ghosting_change_flags[ ec->ghost_id ] = true ;
517 m_entity_comm_map.comm_clear(entity->key());
519 if ( ! locally_destroyed ) {
526 if ( ! in_owned_closure( *entity , m_parallel_rank ) ) {
529 ThrowRequireMsg(destroy_entity_successful,
530 "Could not destroy ghost entity " << print_entity_key(entity));
540 for ( std::vector<Entity*>::const_reverse_iterator
543 Entity & entity = **i ;
545 const bool locally_destroyed = EntityLogDeleted == entity.log_query();
546 const bool locally_owned_and_modified =
547 EntityLogModified == entity.log_query() &&
548 m_parallel_rank == entity.owner_rank() ;
550 if ( locally_destroyed || locally_owned_and_modified ) {
554 for (
size_t j = ghosting_count ; j-- ; ) {
555 if ( m_entity_comm_map.erase( entity.key(), *m_ghosting[j] ) ) {
556 ghosting_change_flags[ j ] = true ;
562 std::vector< int > ghosting_change_flags_global( ghosting_count , 0 );
565 & ghosting_change_flags[0] ,
566 & ghosting_change_flags_global[0] ,
567 ghosting_change_flags.size() );
569 for (
unsigned ic = 0 ; ic < ghosting_change_flags_global.size() ; ++ic ) {
570 if ( ghosting_change_flags_global[ic] ) {
571 m_ghosting[ic]->m_sync_count = m_sync_count ;
582 void BulkData::internal_resolve_parallel_create()
584 Trace_(
"stk_classic::mesh::BulkData::internal_resolve_parallel_create");
586 ThrowRequireMsg(
parallel_size() > 1,
"Do not call this in serial");
588 std::vector<Entity*> shared_modified ;
592 internal_update_distributed_index( shared_modified );
598 CommAll comm_all( m_parallel_machine );
600 for (
int phase = 0; phase < 2; ++phase ) {
601 for ( std::vector<Entity*>::iterator
602 i = shared_modified.begin() ; i != shared_modified.end() ; ++i ) {
603 Entity & entity = **i ;
604 if ( entity.owner_rank() == m_parallel_rank &&
605 entity.log_query() != EntityLogCreated ) {
608 jc = m_entity_comm_map.sharing(entity.key()) ; ! jc.empty() ; ++jc ) {
609 comm_all.send_buffer( jc->proc ) .pack<EntityKey>( entity.key() );
615 comm_all.allocate_buffers( m_parallel_size / 4 );
618 comm_all.communicate();
622 for (
unsigned p = 0 ; p < m_parallel_size ; ++p ) {
623 CommBuffer & buf = comm_all.recv_buffer( p );
625 while ( buf.remaining() ) {
626 buf.unpack<EntityKey>( key );
631 m_entity_repo.set_entity_owner_rank( entity, p);
642 std::ostringstream error_msg ;
646 shared_part.push_back( & m_mesh_meta_data.globally_shared_part() );
647 owned_part.push_back( & m_mesh_meta_data.locally_owned_part() );
649 std::vector<Entity*>::const_reverse_iterator iend = shared_modified.rend();
650 for ( std::vector<Entity*>::const_reverse_iterator
651 i = shared_modified.rbegin() ; i != iend ; ++i) {
653 Entity * entity = *i ;
655 if ( entity->owner_rank() == m_parallel_rank &&
656 entity->log_query() == EntityLogCreated ) {
660 const unsigned new_owner = determine_new_owner( *entity );
662 m_entity_repo.set_entity_owner_rank( *entity, new_owner);
665 if ( entity->owner_rank() != m_parallel_rank ) {
668 m_entity_repo.set_entity_sync_count( *entity, m_sync_count);
669 internal_change_entity_parts( *entity , shared_part , owned_part );
671 else if ( ! m_entity_comm_map.sharing(entity->key()).empty() ) {
674 internal_change_entity_parts( *entity , shared_part ,
PartVector() );
679 internal_change_entity_parts( *entity ,
PartVector() , shared_part );
683 if ( ! in_owned_closure( *entity , m_parallel_rank ) ) {
684 if ( 0 == error_flag ) {
687 <<
"\nP" << m_parallel_rank <<
": " <<
" FAILED\n" 688 <<
" The following entities were declared on multiple processors,\n" 689 <<
" cannot be parallel-shared, and were declared with" 690 <<
" parallel-ghosting information. {\n";
692 error_msg <<
" " << print_entity_key(entity);
693 error_msg <<
" also declared on" ;
695 error_msg <<
" P" << ec->proc ;
702 if ( error_flag ) { error_msg <<
"}\n" ; }
703 all_reduce( m_parallel_machine , ReduceMax<1>( & error_flag ) );
704 ThrowErrorMsgIf( error_flag, error_msg.str() );
709 const size_t n_old = m_entity_comm.size();
711 m_entity_comm.insert( m_entity_comm.end() ,
712 shared_modified.begin() , shared_modified.end() );
714 std::inplace_merge( m_entity_comm.begin() ,
715 m_entity_comm.begin() + n_old ,
716 m_entity_comm.end() ,
720 std::vector<Entity*>::iterator i =
721 std::unique( m_entity_comm.begin() , m_entity_comm.end() );
723 m_entity_comm.erase( i , m_entity_comm.end() );
731 Trace_(
"stk_classic::mesh::BulkData::modification_end");
733 return internal_modification_end(
true );
742 void print_comm_list(
const BulkData & mesh ,
bool doit )
745 std::ostringstream msg ;
749 for ( std::vector<Entity*>::const_iterator
756 print_entity_key( msg , MetaData::get(mesh) , entity.
key() );
758 msg <<
" owner(" << entity.
owner_rank() <<
")" ;
760 if ( EntityLogModified == entity.
log_query() ) { msg <<
" mod" ; }
761 else if ( EntityLogDeleted == entity.
log_query() ) { msg <<
" del" ; }
762 else { msg <<
" " ; }
765 msg <<
" (" << ec->ghost_id <<
"," << ec->proc <<
")" ;
770 std::cout << msg.str();
778 bool BulkData::internal_modification_end(
bool regenerate_aura )
780 Trace_(
"stk_classic::mesh::BulkData::internal_modification_end");
782 if ( m_sync_state == SYNCHRONIZED ) {
return false ; }
787 internal_resolve_shared_modify_delete();
791 internal_resolve_ghosted_modify_delete();
798 std::vector<Entity*>::iterator i = m_entity_comm.begin();
799 bool changed = false ;
800 for ( ; i != m_entity_comm.end() ; ++i ) {
801 if ( m_entity_comm_map.comm((*i)->key()).empty() ) { *i = NULL ; changed = true ; }
805 m_entity_comm.end() , (Entity *) NULL );
806 m_entity_comm.erase( i , m_entity_comm.end() );
811 internal_resolve_parallel_create();
816 internal_resolve_shared_membership();
819 if ( regenerate_aura ) { internal_regenerate_shared_aura(); }
825 std::ostringstream msg ;
826 bool is_consistent =
true;
827 is_consistent = comm_mesh_verify_parallel_consistency( *
this , msg );
828 ThrowErrorMsgIf( !is_consistent, msg.str() );
831 std::vector<Entity*> shared_modified ;
832 internal_update_distributed_index( shared_modified );
845 if (m_optimize_buckets) m_bucket_repository.optimize_buckets();
846 else m_bucket_repository.internal_sort_bucket_entities();
850 m_sync_state = SYNCHRONIZED ;
858 enum { PART_ORD_UNIVERSAL = 0 };
859 enum { PART_ORD_OWNED = 1 };
860 enum { PART_ORD_SHARED = 2 };
864 void pack_induced_memberships( CommAll & comm ,
865 const std::vector<Entity*> & entity_comm )
867 for ( std::vector<Entity*>::const_iterator
868 i = entity_comm.begin() ; i != entity_comm.end() ; ++i ) {
870 Entity & entity = **i ;
872 if ( in_shared( entity , entity.
owner_rank() ) ) {
875 OrdinalVector empty , induced ;
879 CommBuffer & buf = comm.send_buffer( entity.
owner_rank() );
881 unsigned tmp = induced.size();
883 buf.pack<
unsigned>( tmp );
885 for ( OrdinalVector::iterator
886 j = induced.begin() ; j != induced.end() ; ++j ) {
887 buf.pack<
unsigned>( *j );
893 void generate_send_list(
const size_t sync_count ,
894 const unsigned p_rank ,
895 const std::vector<Entity*> & entity_comm ,
896 std::vector<EntityProc> & send_list )
898 for ( std::vector<Entity*>::const_iterator
899 i = entity_comm.begin() ; i != entity_comm.end() ; ++i ) {
901 Entity & entity = **i ;
908 send_list.push_back( tmp );
914 std::sort( send_list.begin() , send_list.end() , EntityLess() );
915 std::vector<EntityProc>::iterator i =
916 std::unique( send_list.begin() , send_list.end() );
917 send_list.erase( i , send_list.end() );
921 void pack_part_memberships( CommAll & comm ,
922 const std::vector<EntityProc> & send_list )
924 for ( std::vector<EntityProc>::const_iterator
925 i = send_list.begin() ; i != send_list.end() ; ++i ) {
927 Entity & entity = * i->first ;
929 std::pair<const unsigned *, const unsigned *>
939 const unsigned count_all = part_ord.second - part_ord.first ;
940 const unsigned count_skip =
941 ( 2 < count_all && part_ord.first[2] == PART_ORD_SHARED ) ? 3 : 2 ;
943 const unsigned count_send = count_all - count_skip ;
945 const unsigned *
const start_send = part_ord.first + count_skip ;
947 comm.send_buffer( i->second ).pack<EntityKey>( entity.
key() )
948 .pack<unsigned>( count_send )
949 .pack<
unsigned>( start_send , count_send );
965 void BulkData::internal_resolve_shared_membership()
967 Trace_(
"stk_classic::mesh::BulkData::internal_resolve_shared_membership");
969 ThrowRequireMsg(
parallel_size() > 1,
"Do not call this in serial");
971 const MetaData & meta = m_mesh_meta_data ;
973 const unsigned p_rank = m_parallel_rank ;
974 const unsigned p_size = m_parallel_size ;
975 const PartVector & all_parts = meta.get_parts();
977 const Part & part_universal = meta.universal_part();
978 const Part & part_owned = meta.locally_owned_part();
979 const Part & part_shared = meta.globally_shared_part();
983 ThrowRequireMsg(PART_ORD_UNIVERSAL == part_universal.mesh_meta_data_ordinal(),
984 "Universal part ordinal is wrong, expected " 985 << PART_ORD_UNIVERSAL <<
", got: " 986 << part_universal.mesh_meta_data_ordinal());
988 ThrowRequireMsg(PART_ORD_OWNED == part_owned.mesh_meta_data_ordinal(),
989 "Owned part ordinal is wrong, expected " 990 << PART_ORD_OWNED <<
", got: " 991 << part_owned.mesh_meta_data_ordinal());
993 ThrowRequireMsg(PART_ORD_SHARED == part_shared.mesh_meta_data_ordinal(),
994 "Shared part ordinal is wrong, expected " 995 << PART_ORD_SHARED <<
", got: " 996 << part_shared.mesh_meta_data_ordinal());
1002 CommAll comm( p_comm );
1004 pack_induced_memberships( comm , m_entity_comm );
1006 comm.allocate_buffers( p_size / 4 );
1008 pack_induced_memberships( comm , m_entity_comm );
1012 for ( std::vector<Entity*>::iterator
1013 i = m_entity_comm.begin() ; i != m_entity_comm.end() ; ++i ) {
1015 Entity & entity = **i ;
1017 if ( entity.owner_rank() == p_rank ) {
1020 OrdinalVector empty , induced_parts , current_parts , remove_parts ;
1025 ec = entity.sharing() ; ! ec.empty() ; ++ec ) {
1027 CommBuffer & buf = comm.recv_buffer( ec->proc );
1029 unsigned count = 0 ; buf.unpack<
unsigned>(
count );
1030 for (
unsigned j = 0 ; j <
count ; ++j ) {
1031 unsigned part_ord = 0 ; buf.unpack<
unsigned>( part_ord );
1032 insert_ordinal( induced_parts , part_ord );
1039 entity.bucket().supersets( current_parts );
1041 OrdinalVector::const_iterator induced_parts_begin = induced_parts.begin(),
1042 induced_parts_end = induced_parts.end();
1044 for ( OrdinalVector::iterator
1045 p = current_parts.begin() ; p != current_parts.end() ; ++p ) {
1047 ! contains_ordinal( induced_parts_begin, induced_parts_end , *p ) ) {
1048 remove_parts.push_back( *p );
1052 internal_change_entity_parts( entity, induced_parts, remove_parts );
1063 std::vector<EntityProc> send_list ;
1065 generate_send_list( m_sync_count, p_rank, m_entity_comm, send_list);
1067 CommAll comm( p_comm );
1069 pack_part_memberships( comm , send_list );
1071 comm.allocate_buffers( p_size / 4 );
1073 pack_part_memberships( comm , send_list );
1077 for (
unsigned p = 0 ; p < p_size ; ++p ) {
1078 CommBuffer & buf = comm.recv_buffer( p );
1079 while ( buf.remaining() ) {
1081 PartVector owner_parts , current_parts , remove_parts ;
1083 EntityKey key ; buf.unpack<EntityKey>( key );
1084 unsigned count = 0 ; buf.unpack<
unsigned>(
count );
1085 for (
unsigned j = 0 ; j <
count ; ++j ) {
1086 unsigned part_ord = 0 ; buf.unpack<
unsigned>( part_ord );
1087 insert( owner_parts , * all_parts[ part_ord ] );
1093 Entity *
const entity = find_entity(m_entity_comm, key,
true);
1095 entity->bucket().supersets( current_parts );
1097 for ( PartVector::iterator
1098 ip = current_parts.begin() ; ip != current_parts.end() ; ++ip ) {
1099 Part *
const part = *ip ;
1100 const unsigned part_ord = part->mesh_meta_data_ordinal();
1101 if ( PART_ORD_UNIVERSAL != part_ord &&
1102 PART_ORD_OWNED != part_ord &&
1103 PART_ORD_SHARED != part_ord &&
1104 !
contain( owner_parts , *part ) ) {
1105 remove_parts.push_back( part );
1109 internal_change_entity_parts( *entity , owner_parts , remove_parts );
PairIterEntityComm comm() const
Complete communicaiton list for this entity.
size_t synchronized_count() const
The mesh bulk data synchronized_count when this entity's part membership was most recently modified...
const std::vector< Entity * > & entity_comm() const
All entities with communication information.
void remove(PartVector &v, Part &part)
Remove a part from a properly ordered collection of parts.
bool membership_is_induced(const Part &part, unsigned entity_rank)
Query if a member entity of the given entity type has an induced membership.
void all_reduce_sum(ParallelMachine comm, const double *local, double *global, unsigned count)
Parallel summation to all processors.
void induced_part_membership(Part &part, unsigned entity_rank_from, unsigned entity_rank_to, RelationIdentifier relation_identifier, OrdinalVector &induced_parts, bool include_supersets)
Induce entities' part membership based upon relationships between entities. Insert the result into 'i...
Bucket & bucket() const
The bucket which holds this mesh entity's field data.
const EntityKey & key() const
The globally unique key ( entity type + identifier ) of this entity.
std::pair< const unsigned *, const unsigned * > superset_part_ordinals() const
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
EntityModificationLog log_query() const
Query the current state of the entity log.
bool contain(const PartVector &v, const Part &part)
Query containment within properly ordered PartVector.
bool modification_end()
Parallel synchronization of modifications and transition to the guaranteed parallel consistent state...
unsigned parallel_size() const
Size of the parallel machine.
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Manager for an integrated collection of entities, entity relations, and buckets of field data...
const MetaData & mesh_meta_data() const
The meta data manager for this bulk data manager.
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
unsigned parallel_rank() const
Rank of the parallel machine's local processor.
EntityRank entity_rank() const
The rank of this entity.
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
PairIter< std::vector< EntityCommInfo >::const_iterator > PairIterEntityComm
Span of ( communication-subset-ordinal , process-rank ) pairs for the communication of an entity...
bool destroy_entity(Entity *&entity)
Request the destruction an entity on the local process.
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
bool insert(PartVector &v, Part &part)
Insert a part into a properly ordered collection of parts. Returns true if this is a new insertion...
eastl::iterator_traits< InputIterator >::difference_type count(InputIterator first, InputIterator last, const T &value)