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