MeshKit
1.0
|
00001 #include "meshkit/ParRecvSurfMesh.hpp" 00002 #include "meshkit/ParSendPostSurfMesh.hpp" 00003 #include "moab/Types.hpp" 00004 #include "RefEntity.hpp" 00005 #include "TDParallel.hpp" 00006 00007 namespace MeshKit 00008 { 00009 // static registration of this mesh scheme 00010 moab::EntityType ParRecvSurfMesh_tps[] = {moab::MBVERTEX, moab::MBEDGE, moab::MBTRI, moab::MBTET, moab::MBMAXTYPE}; 00011 const moab::EntityType* ParRecvSurfMesh::output_types() 00012 { return ParRecvSurfMesh_tps; } 00013 00014 ParRecvSurfMesh::ParRecvSurfMesh(MKCore *mkcore, const MEntVector &me_vec) 00015 : MeshScheme(mkcore, me_vec) 00016 { 00017 // get information related to MOAB parallel communication 00018 m_mpcomm = moab::ParallelComm::get_pcomm(mk_core()->moab_instance(), 0); 00019 if (NULL == m_mpcomm) { 00020 throw Error(iBase_FAILURE, "Parallel communication should be already created."); 00021 } 00022 m_rank = m_mpcomm->proc_config().proc_rank(); 00023 } 00024 00025 ParRecvSurfMesh::~ParRecvSurfMesh() 00026 { 00027 std::vector<Range*>::iterator vit; 00028 for (vit = m_shared_entities.begin(); vit != m_shared_entities.end(); vit++) 00029 delete (*vit); 00030 m_shared_entities.clear(); 00031 } 00032 00033 void ParRecvSurfMesh::setup_this() 00034 { 00035 } 00036 00037 void ParRecvSurfMesh::execute_this() 00038 { 00039 iMesh::Error err; 00040 std::set<unsigned int> recv_procs; 00041 MEntVector recv_ents; 00042 00043 // get send procs and mesh 00044 MEntSelection::iterator mit = mentSelection.begin(); 00045 MEntSelection::iterator emit = mentSelection.end(); 00046 for (; mit != emit; mit++) { 00047 ModelEnt *me = mit->first; 00048 RefEntity* entity = reinterpret_cast<RefEntity*> (me->geom_handle()); 00049 iBase_EntitySetHandle entityset = reinterpret_cast<iBase_EntitySetHandle> (me->mesh_handle()); 00050 TDParallel *td_par = (TDParallel *) entity->get_TD(&TDParallel::is_parallel); 00051 if (td_par == NULL) ECERRCHK(MK_FAILURE, "Recv surface should have partitioned information."); 00052 00053 unsigned int charge_p = td_par->get_charge_proc(); 00054 DLIList<int>* proc_list = td_par->get_shared_proc_list(); 00055 int n_proc_list = proc_list->size(); 00056 00057 if (m_rank == charge_p) { // send proc 00058 // get all child meshes 00059 std::vector<iBase_EntityHandle> entities; 00060 err = mk_core()->imesh_instance()->getEntities(entityset, iBase_ALL_TYPES, 00061 iMesh_ALL_TOPOLOGIES, entities); 00062 IBERRCHK(err, "Couldn't get entities of surface entityset."); 00063 00064 // put processors sharing this interface vertex to buffer 00065 proc_list->reset(); 00066 for (int i = 0; i < n_proc_list; i++) { // to procs 00067 unsigned int to_proc = proc_list->get_and_step(); 00068 if (to_proc != m_rank) { 00069 int ind = get_shared_list(to_proc); 00070 int n_entity = entities.size(); 00071 for (int j = 0; j < n_entity; j++) { 00072 m_shared_entities[ind]->insert(reinterpret_cast<moab::EntityHandle> (entities[j])); 00073 } 00074 m_shared_entities[ind]->insert(reinterpret_cast<moab::EntityHandle> (entityset)); 00075 } 00076 } 00077 } 00078 else { // recv procs 00079 proc_list->reset(); 00080 proc_list->step(); 00081 for (int i = 1; i < n_proc_list; i++) { 00082 unsigned int proc = proc_list->get_and_step(); 00083 if (proc == m_rank) { // recv proc 00084 get_shared_list(charge_p); 00085 recv_procs.insert(charge_p); 00086 recv_ents.push_back(mit->first); 00087 break; 00088 } 00089 } 00090 } 00091 } 00092 00093 // get send sets 00094 std::vector<Range*> send_sets; 00095 int n_proc = m_shared_procs.size(); 00096 for (int i = 0; i < n_proc; i++) { 00097 Range set_range = m_shared_entities[i]->subset_by_type(MBENTITYSET); 00098 *m_shared_entities[i] = subtract(*m_shared_entities[i], set_range); 00099 Range* tmp_range = new Range(set_range); 00100 send_sets.push_back(tmp_range); 00101 } 00102 00103 // recv mesh 00104 int incoming1 = 0, incoming2 = 0; 00105 GraphNode* pspsm_node = get_graph()->find_node("ParSendPostSurfMesh"); 00106 if (pspsm_node != NULL) { 00107 static_cast<ParSendPostSurfMesh*> (pspsm_node)->get_incoming(incoming1, incoming2); 00108 } 00109 else ECERRCHK(MK_FAILURE, "ParSendPostSurfMesh should be inserted before."); 00110 00111 moab::ErrorCode rval = m_mpcomm->recv_entities(recv_procs, incoming1, incoming2, true); 00112 MBERRCHK(rval, mk_core()->moab_instance()); 00113 00114 // post irecv for surface meshset 00115 rval = m_mpcomm->post_irecv(m_shared_procs, recv_procs); 00116 MBERRCHK(rval, mk_core()->moab_instance()); 00117 00118 // send meshset 00119 incoming1 = recv_procs.size(); 00120 incoming2 = 0; 00121 rval = m_mpcomm->send_entities(m_shared_procs, 00122 send_sets, incoming1, 00123 incoming2, true); 00124 MBERRCHK(rval, mk_core()->moab_instance()); 00125 00126 // recv mesh 00127 rval = m_mpcomm->recv_entities(recv_procs, incoming1, incoming2, true); 00128 MBERRCHK(rval, mk_core()->moab_instance()); 00129 00130 // set the model ent mesh with received mesh 00131 int n_recv = recv_ents.size(); 00132 for (int i = 0; i < n_recv; i++) { 00133 recv_ents[i]->set_meshed_state(COMPLETE_MESH); 00134 } 00135 } 00136 00137 int ParRecvSurfMesh::get_shared_list(const int proc) 00138 { 00139 int ind = -1; 00140 std::vector<unsigned int>::iterator vit = 00141 std::find(m_shared_procs.begin(), m_shared_procs.end(), proc); 00142 if (vit == m_shared_procs.end()) { 00143 ind = m_shared_procs.size(); 00144 m_shared_procs.push_back(proc); 00145 m_shared_entities.push_back(new Range); 00146 } 00147 else ind = vit - m_shared_procs.begin(); 00148 00149 return ind; 00150 } 00151 } // namespace MeshKit