MeshKit  1.0
ParExchangeMesh.cpp
Go to the documentation of this file.
00001 #include "meshkit/ParExchangeMesh.hpp"
00002 #include "moab/Range.hpp"
00003 #include "moab/Types.hpp"
00004 #include "RefEntity.hpp"
00005 #include "TDParallel.hpp"
00006 
00007 const bool debug_par_exchange_mesh = false;
00008 
00009 namespace MeshKit 
00010 {
00011 // static registration of this mesh scheme
00012   moab::EntityType ParExchangeMesh_tps[] = {moab::MBVERTEX, moab::MBEDGE, moab::MBTRI, moab::MBTET, moab::MBMAXTYPE};
00013 const moab::EntityType* ParExchangeMesh::output_types()
00014 { return ParExchangeMesh_tps; }
00015   
00016 ParExchangeMesh::ParExchangeMesh(MKCore *mkcore, const MEntVector &me_vec)
00017   : MeshScheme(mkcore, me_vec)
00018 {
00019   // get information related to MOAB parallel communication
00020   m_mpcomm = moab::ParallelComm::get_pcomm(mk_core()->moab_instance(), 0);
00021   if (NULL == m_mpcomm) {
00022     throw Error(iBase_FAILURE, "Parallel communication should be already created.");
00023   }
00024   m_rank = m_mpcomm->proc_config().proc_rank();
00025   m_proc_size = m_mpcomm->proc_config().proc_size();
00026 
00027   // create tag
00028   iMesh::Error err = mk_core()->imesh_instance()->createTag("PARALLEL_UNIQUE_ID", 1, iBase_INTEGER, m_mPuniqueIDTag);
00029   if (err != iBase_TAG_ALREADY_EXISTS) {
00030     IBERRCHK(err, "Trouble create a parallel unique id tag handle.");
00031   }
00032 }
00033 
00034 ParExchangeMesh::~ParExchangeMesh()
00035 {
00036   std::vector<Range*>::iterator vit;
00037   for (vit = m_shared_entities.begin(); vit != m_shared_entities.end(); vit++)
00038     delete (*vit);
00039   m_shared_entities.clear();
00040 }
00041 
00042 void ParExchangeMesh::setup_this()
00043 {
00044 }
00045 
00046 void ParExchangeMesh::execute_this()
00047 {
00048   iMesh::Error err;
00049   MEntVector meshed_mes;
00050 
00051   for (MEntSelection::iterator mit = mentSelection.begin(); mit != mentSelection.end(); mit++) {
00052     ModelEnt *me = mit->first;
00053     RefEntity* entity = reinterpret_cast<RefEntity*> (me->geom_handle());
00054     iBase_EntitySetHandle entityset = reinterpret_cast<iBase_EntitySetHandle> (me->mesh_handle());
00055     TDParallel *td_par = (TDParallel *) entity->get_TD(&TDParallel::is_parallel);
00056     if (td_par == NULL) ECERRCHK(MK_FAILURE, "Exchange entity should have partitioned information.");
00057     unsigned int charge_p = td_par->get_charge_proc();
00058 
00059     if (m_rank == charge_p) { // send proc
00060       // get all child meshes
00061       std::vector<iBase_EntityHandle> entities;
00062       err = mk_core()->imesh_instance()->getEntities(entityset, iBase_ALL_TYPES,
00063                                                      iMesh_ALL_TOPOLOGIES, entities);
00064       IBERRCHK(err, "Couldn't get entities of surface entityset.");
00065       
00066       // put processors sharing this interface vertex to buffer
00067       DLIList<int>* proc_list = td_par->get_shared_proc_list();
00068       int n_proc_list = proc_list->size();
00069       proc_list->reset();
00070       
00071       for (int i = 0; i < n_proc_list; i++) {
00072         unsigned int proc = proc_list->get_and_step();
00073         if (proc != m_rank) {
00074           int ind = get_shared_list(proc);
00075           int n_entity = entities.size(); 
00076           for (int j = 0; j < n_entity; j++) {
00077             m_shared_entities[ind]->insert(reinterpret_cast<moab::EntityHandle> (entities[j]));
00078           }
00079           m_shared_entities[ind]->insert(reinterpret_cast<moab::EntityHandle> (entityset));
00080         }
00081       }
00082     }
00083     else {
00084       get_shared_list(charge_p); // receive proc: just create shared entity/proc list
00085       meshed_mes.push_back(me);
00086     }
00087   }
00088 
00089   // exchange shared entities
00090   if (debug_par_exchange_mesh) {
00091     std::cout << "m_shared_procs_size=" << m_shared_procs.size() << std::endl;
00092     for (unsigned int i = 0; i < m_shared_procs.size(); i++) {
00093       std::cout << "m_shared_procs[" << i << "]=" << m_shared_procs[i] << std::endl;
00094     }
00095     std::cout << "m_shared_entities_size=" << m_shared_entities.size() << std::endl;
00096     for (unsigned int i = 0; i < m_shared_entities.size(); i++) {
00097       std::cout << "m_shared_entities_range[" << i << "]_size=" << m_shared_entities[i]->size() << std::endl;
00098     }
00099   }
00100 
00101   int dim = mentSelection.begin()->first->dimension();
00102   moab::ErrorCode rval = m_mpcomm->exchange_owned_meshs(m_shared_procs,
00103                                                         m_shared_entities,
00104                                                         m_recv_reqs,
00105                                                         m_recv_remoteh_reqs,
00106                                                         true, false, false, dim);
00107   MBERRCHK(rval, mk_core()->moab_instance());
00108   
00109   // set the model ent mesh with received mesh
00110   int n_meshed = meshed_mes.size();
00111   for (int i = 0; i < n_meshed; i++) {
00112     meshed_mes[i]->set_meshed_state(COMPLETE_MESH);
00113   }
00114 }
00115 
00116 int ParExchangeMesh::get_shared_list(const int proc)
00117 {
00118   int ind = -1;
00119   std::vector<unsigned int>::iterator vit = 
00120     std::find(m_shared_procs.begin(), m_shared_procs.end(), proc);
00121   if (vit == m_shared_procs.end()) {
00122     ind = m_shared_procs.size();
00123     m_shared_procs.push_back(proc);
00124     m_shared_entities.push_back(new Range);
00125   }
00126   else ind = vit - m_shared_procs.begin();
00127 
00128   return ind;
00129 }
00130 
00131 void ParExchangeMesh::print_mesh()
00132 {
00133   // test
00134   int tmp_procs[MAX_SHARING_PROCS];
00135   moab::EntityHandle tmp_hs[MAX_SHARING_PROCS];
00136   unsigned char pstat;
00137   int num_ps;
00138   moab::Range entities;
00139   moab::ErrorCode rval;
00140 
00141   for (moab::EntityType type = MBVERTEX; type != MBMAXTYPE; type++) {
00142     entities.clear();
00143     rval = mk_core()->moab_instance()->get_entities_by_type(0, type, entities);
00144     MBERRCHK(rval, mk_core()->moab_instance());
00145 
00146     for (moab::Range::iterator rit = entities.begin(); rit != entities.end(); rit++) {
00147       rval = m_mpcomm->get_sharing_data(*rit, tmp_procs, tmp_hs, pstat, num_ps);
00148       MBERRCHK(rval, mk_core()->moab_instance());
00149 
00150       //std::cout << "ParExchangeMesh::entity=" << *rit << ", type=" << type;
00151       if (type == MBVERTEX) {
00152         double coord[3];
00153         rval = mk_core()->moab_instance()->get_coords(&(*rit), 1, coord);
00154         MBERRCHK(rval, mk_core()->moab_instance());
00155         //std::cout << ", coords=" << coord[0] << " " << coord[1] << " " << coord[2];
00156       }
00157       else if (type != MBENTITYSET) {
00158         std::vector<moab::EntityHandle> connect;
00159         rval = mk_core()->moab_instance()->get_connectivity(&(*rit), 1, connect);
00160         MBERRCHK(rval, mk_core()->moab_instance());
00161         //        int n_conn = connect.size();
00162         //std::cout << ", connect=";
00163         //for (int j = 0; j < n_conn; j++) {
00164         //std::cout << connect[j] << " ";
00165         //}
00166       }
00167       /*
00168       std::cout << ", shared_info=";
00169       for (int ii = 0; ii < num_ps; ii++) {
00170         std::cout << tmp_procs[ii] << ":" << tmp_hs[ii] << ", ";
00171       }
00172       std::cout << std::endl;
00173       */
00174     }
00175   }    
00176 }
00177 } // namespace MeshKit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines