13 #include <stk_util/parallel/ParallelComm.hpp> 15 #include <stk_mesh/base/BulkModification.hpp> 17 #include <stk_mesh/base/BulkData.hpp> 18 #include <stk_mesh/base/Entity.hpp> 19 #include <stk_mesh/base/EntityComm.hpp> 25 typedef std::set<Entity *, EntityLess> EntitySet;
26 typedef std::set<EntityProc , EntityLess> EntityProcSet;
30 void construct_transitive_closure( EntitySet & closure , Entity & entry )
33 std::pair< EntitySet::const_iterator , bool >
34 result = closure.insert( & entry );
37 if ( result.second ) {
39 const unsigned erank = entry.entity_rank();
40 PairIterRelation irel = entry.relations();
42 for ( ; irel.first != irel.second ; ++irel.first ) {
44 if ( irel.first->entity_rank() < erank ) {
45 Entity * tmp = irel.first->entity();
46 construct_transitive_closure( closure , *tmp );
52 void find_local_closure ( EntitySet & closure,
const EntityVector & entities)
54 for (EntityVector::const_iterator i = entities.begin();
55 i != entities.end(); ++i)
57 construct_transitive_closure(closure, **i);
61 void construct_communication_set(
const BulkData & bulk,
const EntitySet & closure, EntityProcSet & communication_set)
63 if (bulk.parallel_size() < 2)
return;
65 for ( EntitySet::const_iterator
66 i = closure.begin(); i != closure.end(); ++i) {
68 Entity & entity = **i;
70 const bool owned = bulk.parallel_rank() == entity.
owner_rank();
75 if ( owned || ec->ghost_id == 0 ) {
77 communication_set.insert( tmp );
83 size_t count_non_used_entities(
const BulkData & bulk,
const EntityVector & entities)
85 const unsigned proc_local = bulk.parallel_rank();
86 size_t non_used_entities = 0;
88 for ( EntityVector::const_iterator
89 i = entities.begin(); i != entities.end(); ++i ) {
90 if ( ! in_owned_closure( **i , proc_local ) ) {
95 return non_used_entities;
102 void find_closure(
const BulkData & bulk,
103 const std::vector< Entity *> & entities,
104 std::vector< Entity *> & entities_closure)
107 entities_closure.clear();
110 EntityProcSet send_list;
111 EntitySet temp_entities_closure;
113 const bool bulk_not_synchronized = bulk.synchronized_state() != BulkData::SYNCHRONIZED;
114 const size_t non_used_entities = bulk_not_synchronized ? 0 : count_non_used_entities(bulk, entities);
116 const bool local_bad_input = bulk_not_synchronized || (0 < non_used_entities);
119 if ( !local_bad_input) {
121 find_local_closure(temp_entities_closure, entities);
123 construct_communication_set(bulk, temp_entities_closure, send_list);
127 CommAll all( bulk.parallel() );
130 for ( EntityProcSet::const_iterator
131 ep = send_list.begin() ; ep != send_list.end() ; ++ep ) {
132 all.send_buffer( ep->second).pack<EntityKey>(ep->first->key());
136 const bool global_bad_input = all.allocate_buffers( bulk.parallel_size() / 4 ,
false, local_bad_input );
138 if (global_bad_input) {
140 std::ostringstream msg;
142 if (bulk_not_synchronized) {
143 msg <<
"stk_classic::mesh::find_closure( const BulkData & bulk, ... ) bulk is not synchronized";
145 else if ( 0 < non_used_entities) {
146 msg <<
"stk_classic::mesh::find_closure( const BulkData & bulk, std::vector<Entity *> entities, ... ) \n" 147 <<
"entities contains " << non_used_entities <<
" non locally used entities \n";
150 throw std::runtime_error(msg.str());
155 for ( EntityProcSet::const_iterator
156 ep = send_list.begin() ; ep != send_list.end() ; ++ep ) {
157 all.send_buffer( ep->second).pack<EntityKey>(ep->first->key());
164 for (
unsigned p = 0 ; p < bulk.parallel_size() ; ++p ) {
165 CommBuffer & buf = all.recv_buffer( p );
167 while ( buf.remaining() ) {
168 buf.unpack<EntityKey>( k );
169 Entity * e = bulk.get_entity(k);
170 temp_entities_closure.insert(e);
175 entities_closure.assign(temp_entities_closure.begin(), temp_entities_closure.end());
PairIterEntityComm comm() const
Complete communicaiton list for this entity.
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
PairIter< std::vector< EntityCommInfo >::const_iterator > PairIterEntityComm
Span of ( communication-subset-ordinal , process-rank ) pairs for the communication of an entity...
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.