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