MeshKit
1.0
|
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