//This very simple test will visit all local elements and traverse the //element's node relations. It will return the number of nodes visited. //The purpose of this test is to stress the relation-traversal for a //performance test. size_t do_stk_node_rel_test(stk::mesh::BulkData& bulk) { using namespace stk::mesh; MetaData& meta = MetaData::get(bulk); Selector local = meta.locally_owned_part(); BucketVector const& buckets = bulk.get_buckets(stk::topology::ELEMENT_RANK, local); size_t nodes_visited = 0; unsigned owner_rank = 0; size_t num_elems = 0; for(size_t ib=0; ib<buckets.size(); ++ib) { const Bucket& b = *buckets[ib]; num_elems += b.size(); for(size_t i=0; i<b.size(); ++i) { Entity const *node_itr = b.begin_nodes(i); Entity const *nodes_end = b.end_nodes(i); for (; node_itr != nodes_end; ++node_itr) { Entity node = *node_itr; owner_rank += bulk.parallel_owner_rank(node); ++nodes_visited; } } } return nodes_visited; }
inline void add_nodes_to_move(stk::mesh::BulkData& bulk, stk::mesh::Entity elem, int dest_proc, std::vector<stk::mesh::EntityProc>& entities_to_move) { const stk::mesh::Entity* nodes = bulk.begin_nodes(elem); for(unsigned i = 0; i < bulk.num_nodes(elem); ++i) { if(bulk.parallel_owner_rank(nodes[i]) == bulk.parallel_rank()) { entities_to_move.push_back(stk::mesh::EntityProc(nodes[i], dest_proc)); } } }
void fixup_ghosted_to_shared_nodes(stk::mesh::BulkData & bulk) { stk::mesh::EntityVector ghosted_nodes_that_are_now_shared; find_ghosted_nodes_that_need_to_be_shared(bulk, ghosted_nodes_that_are_now_shared); stk::CommSparse comm(bulk.parallel()); for (int phase=0;phase<2;++phase) { for (size_t i = 0; i < ghosted_nodes_that_are_now_shared.size(); ++i) { stk::mesh::Entity node = ghosted_nodes_that_are_now_shared[i]; int proc = bulk.parallel_owner_rank(node); comm.send_buffer(proc).pack<stk::mesh::EntityKey>(bulk.entity_key(node)); } if (phase == 0 ) { comm.allocate_buffers(); } else { comm.communicate(); } } stk::mesh::EntityVector sharedNodes; for (int process=0;process<bulk.parallel_size();++process) { while(comm.recv_buffer(process).remaining()) { stk::mesh::EntityKey key; comm.recv_buffer(process).unpack<stk::mesh::EntityKey>(key); stk::mesh::Entity entity = bulk.get_entity(key); if ( bulk.state(entity) != stk::mesh::Deleted && bulk.is_valid(entity) ) { bulk.add_node_sharing(entity, process); sharedNodes.push_back(entity); } } } ///////////////////////// stk::CommSparse commSecondStage(bulk.parallel()); for (int phase=0;phase<2;++phase) { for (size_t i=0;i<sharedNodes.size();++i) { std::vector<int> procs; stk::mesh::EntityKey key = bulk.entity_key(sharedNodes[i]); bulk.comm_shared_procs(key, procs); for (size_t j=0;j<procs.size();++j) { if ( procs[j] != bulk.parallel_rank() ) { commSecondStage.send_buffer(procs[j]).pack<int>(bulk.parallel_rank()).pack<stk::mesh::EntityKey>(key); for (size_t k=0;k<procs.size();++k) { commSecondStage.send_buffer(procs[j]).pack<int>(procs[k]).pack<stk::mesh::EntityKey>(key); } } } } if (phase == 0 ) { commSecondStage.allocate_buffers(); } else { commSecondStage.communicate(); } } for (int proc_that_sent_message=0;proc_that_sent_message<bulk.parallel_size();++proc_that_sent_message) { if ( proc_that_sent_message == bulk.parallel_rank() ) continue; while(commSecondStage.recv_buffer(proc_that_sent_message).remaining()) { stk::mesh::EntityKey key; int sharingProc; commSecondStage.recv_buffer(proc_that_sent_message).unpack<int>(sharingProc).unpack<stk::mesh::EntityKey>(key); if ( sharingProc != bulk.parallel_rank() ) { stk::mesh::Entity entity = bulk.get_entity(key); if ( bulk.state(entity) != stk::mesh::Deleted && bulk.is_valid(entity) && !bulk.in_shared(key, sharingProc) ) { bulk.add_node_sharing(entity, sharingProc); } } } } }