MeshKit  1.0
ParRecvSurfMesh.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines