Back to index

salome-med  6.5.0
MEDPARTITIONER_ParallelTopology.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "MEDPARTITIONER_MeshCollection.hxx"
00021 #include "MEDPARTITIONER_Topology.hxx"
00022 #include "MEDPARTITIONER_Graph.hxx"
00023 #include "MEDPARTITIONER_ParallelTopology.hxx"
00024 #include "MEDPARTITIONER_ConnectZone.hxx"
00025 #include "MEDPARTITIONER_Utils.hxx"
00026 
00027 #include "MEDCouplingUMesh.hxx"
00028 #include "InterpKernelHashMap.hxx"
00029 
00030 #include <set>
00031 #include <map>
00032 #include <vector>
00033 #include <iostream>
00034 
00035 #ifdef HAVE_MPI2
00036 #include <mpi.h>
00037 #endif
00038 
00039 using namespace MEDPARTITIONER;
00040 
00041 ParallelTopology::ParallelTopology():_nb_domain(0),_mesh_dimension(0)
00042 {
00043 }
00044 
00045 //constructing topology according to mesh collection without global numerotation (use setGlobalNumerotation later)
00046 ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes)
00047 {
00048   _nb_domain=meshes.size();
00049   _nb_cells.resize(_nb_domain);
00050   _nb_nodes.resize(_nb_domain);
00051   //  _nb_faces.resize(_nb_domain);
00052   
00053   if (MyGlobals::_Is0verbose>100)
00054     std::cout << "new ParallelTopology\n";
00055   _loc_to_glob.resize(0);      //precaution, need gatherNbOf() setGlobalNumerotation()
00056   _node_loc_to_glob.resize(0); //precaution, need gatherNbOf() setGlobalNumerotation()
00057   //_face_loc_to_glob.resize(_nb_domain);
00058   _mesh_dimension = -1;
00059   bool parallel_mode = false;
00060   for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++)
00061     parallel_mode = (!meshes[idomain]);
00062 
00063   if (MyGlobals::_Is0verbose>20 && !parallel_mode)
00064     std::cout << "WARNING : ParallelTopology contructor without parallel_mode" << std::endl;
00065   for (int idomain=0; idomain<_nb_domain; idomain++)
00066     {
00067       if ( !meshes[idomain] ) continue;
00068       if (_mesh_dimension==-1)
00069         {
00070           _mesh_dimension = meshes[idomain]->getMeshDimension();
00071         }
00072       else
00073         {
00074           if (_mesh_dimension!=meshes[idomain]->getMeshDimension())
00075             throw INTERP_KERNEL::Exception("meshes dimensions incompatible");
00076         }
00077       _nb_cells[idomain]=meshes[idomain]->getNumberOfCells();
00078       _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes();
00079       //note: in parallel mode _nb_cells and _nb_nodes are not complete now, needs gatherNbOf()
00080     }
00081 }
00082 
00083 //constructing _loc_to_glob etc by default, needs gatherNbOf() done
00084 void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSelector)
00085 {
00086   if (MyGlobals::_Is0verbose>100)
00087     std::cout<< "setGlobalNumerotationDefault on " << _nb_domain << " domains\n";
00088   if (_loc_to_glob.size()!=0) throw INTERP_KERNEL::Exception("a global numerotation is done yet");
00089   _loc_to_glob.resize(_nb_domain);
00090   _node_loc_to_glob.resize(_nb_domain);
00091   
00092   //warning because _nb_cells[idomain] is 0 if not my domain(s)
00093   //we set loc_to_glob etc.. only for my domain(s)
00094   if (MyGlobals::_Is0verbose>500)
00095     std::cout << "(c)idomain|ilocalCell|iglobalCell" << std::endl;
00096   for (int idomain=0; idomain<_nb_domain; idomain++)
00097     {
00098       _loc_to_glob[idomain].resize(_nb_cells[idomain]);
00099       int domainCellShift=domainSelector->getDomainCellShift(idomain);
00100       for (int i=0; i<_nb_cells[idomain]; i++)
00101         {
00102           int global=domainCellShift+i ;
00103           _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i)));
00104           _loc_to_glob[idomain][i]=global;
00105           if (MyGlobals::_Verbose>500)
00106             std::cout << "c" << idomain << "|" << i << "|" << global << " ";
00107         }
00108     }
00109 #ifdef HAVE_MPI2
00110   if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace
00111 #endif
00112   if (MyGlobals::_Is0verbose>500) std::cout << std::endl;
00113   
00114   if (MyGlobals::_Is0verbose>500) std::cout << "(n)idomain|ilocalNode|iglobalNode" << std::endl;
00115   for (int idomain=0; idomain<_nb_domain; idomain++)
00116     {
00117       _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]);
00118       int domainNodeShift=domainSelector->getDomainNodeShift(idomain);
00119       for (int i=0; i<_nb_nodes[idomain]; i++)
00120         {
00121           int global=domainNodeShift+i ;
00122           _node_glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i)));
00123           _node_loc_to_glob[idomain][i]=global;
00124           if (MyGlobals::_Verbose>500)
00125             std::cout << "n" << idomain << "|" << i << "|" << global << " ";
00126         }
00127     }
00128 #ifdef HAVE_MPI2
00129   if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace
00130 #endif
00131   if (MyGlobals::_Is0verbose>500) std::cout << std::endl;
00132   
00133   _nb_total_cells=domainSelector->getNbTotalCells();
00134   _nb_total_nodes=domainSelector->getNbTotalNodes();
00135   _nb_total_faces=domainSelector->getNbTotalFaces();
00136   if (MyGlobals::_Is0verbose>200)
00137     std::cout << "globalNumerotation default done meshDimension " << _mesh_dimension << " nbTotalCells " << _nb_total_cells << " nbTotalNodes " << _nb_total_nodes << std::endl;
00138 }
00139 
00140 //constructing topology according to mesh collection
00141 ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes, 
00142                                    const std::vector<MEDPARTITIONER::ConnectZone*>& cz,
00143                                    std::vector<int*>& cellglobal,
00144                                    std::vector<int*>& nodeglobal,
00145                                    std::vector<int*>& faceglobal)
00146 {
00147   _nb_domain=meshes.size();
00148   int index_global=0;
00149   int index_node_global=0;
00150   int index_face_global=0;
00151 
00152   _nb_cells.resize(_nb_domain);
00153   _nb_nodes.resize(_nb_domain);
00154   //  _nb_faces.resize(_nb_domain);
00155   
00156   _loc_to_glob.resize(_nb_domain);
00157   _node_loc_to_glob.resize(_nb_domain);
00158   //  _face_loc_to_glob.resize(_nb_domain);
00159 
00160   bool parallel_mode = false;
00161   for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++)
00162     parallel_mode = (!meshes[idomain]);
00163 
00164   for (int idomain=0; idomain<_nb_domain; idomain++)
00165     {
00166       if ( !meshes[idomain] ) continue;
00167       _mesh_dimension = meshes[idomain]->getMeshDimension();
00168     
00169       //creating cell maps
00170       _nb_cells[idomain]=meshes[idomain]->getNumberOfCells();
00171       //    cout << "Nb cells (domain "<<idomain<<") = "<<_nb_cells[idomain];
00172       _loc_to_glob[idomain].resize(_nb_cells[idomain]);
00173 
00174       if (cellglobal[idomain]==0 || parallel_mode)
00175         {
00176           //int cellDomainShift=_cell_shift_by_domain[idomain];
00177           //creating global numbering from scratch
00178           for (int i=0; i<_nb_cells[idomain]; i++)
00179             {
00180               int global=i ;//cellDomainShift+i;
00181               _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i)));
00182               _loc_to_glob[idomain][i]=global;
00183               index_global++;
00184             }
00185         }
00186       //using global numbering coming from a previous numbering
00187       else
00188         {
00189           for (int i=0; i<_nb_cells[idomain]; i++)
00190             {
00191               int global=cellglobal[idomain][i];
00192               _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i)));
00193               //_loc_to_glob[make_pair(idomain,i+1)]=global;
00194               _loc_to_glob[idomain][i]=global;
00195               index_global++;
00196             }
00197         }
00198 
00199       //cas sequentiel
00200       if (_nb_domain==1)
00201         {
00202           _nb_total_cells=index_global;
00203           _nb_cells[0]=index_global;
00204           _node_loc_to_glob[idomain].resize(meshes[idomain]->getNumberOfNodes());
00205           for (int i=0; i<meshes[idomain]->getNumberOfNodes(); i++)
00206             {
00207               _node_glob_to_loc.insert(std::make_pair(i,std::make_pair(0,i)));
00208               _node_loc_to_glob[0][i]=i;
00209             }
00210           _nb_total_nodes=meshes[idomain]->getNumberOfNodes();   
00211           _nb_nodes[0]=_nb_total_nodes; 
00212           return;
00213         }
00214 
00215       //creating node maps
00216       _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes();
00217       INTERP_KERNEL::HashMap <int,std::pair<int,int> > local2distant;
00218       _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]);
00219       for (std::size_t icz=0; icz<cz.size(); icz++)
00220         {
00221           if (cz[icz]->getLocalDomainNumber() == idomain && 
00222               cz[icz]->getLocalDomainNumber()>cz[icz]->getDistantDomainNumber())
00223             {
00224               int nb_node= cz[icz]->getNodeNumber();
00225               const int* node_corresp=cz[icz]->getNodeCorrespValue();
00226               int distant_ip = cz[icz]->getDistantDomainNumber();
00227               for (int i=0; i< nb_node; i++)
00228                 {
00229                   int local= node_corresp[i*2];
00230                   int distant = node_corresp[i*2+1];
00231                   local2distant.insert(std::make_pair(local, std::make_pair(distant_ip,distant)));    
00232                 }
00233             }
00234         }
00235       // setting mappings for all nodes
00236       if (nodeglobal[idomain]==0)
00237         {
00238           for (int inode=0; inode<_nb_nodes[idomain]; inode++)
00239             {
00240               if (local2distant.find(inode)==local2distant.end())
00241                 {
00242                   index_node_global++;
00243                   _node_glob_to_loc.insert(std::make_pair(index_node_global,std::make_pair(idomain,inode)));
00244                   //_node_loc_to_glob[make_pair(idomain,inode+1)]=index_node_global;
00245                   _node_loc_to_glob[idomain][inode]=index_node_global;
00246                 }   
00247               else
00248                 {
00249                   int ip = (local2distant.find(inode)->second).first;
00250                   int distant = (local2distant.find(inode)->second).second;
00251                   int global_number=_loc_to_glob[ip][distant];
00252                   _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode)));
00253                   _node_loc_to_glob[idomain][inode]=global_number;
00254                 } 
00255             }
00256         }
00257       //using former node numbering
00258       else
00259         {
00260           for (int inode=0; inode<_nb_nodes[idomain]; inode++)
00261             {
00262               int global_number=nodeglobal[idomain][inode];
00263               _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode)));
00264               _node_loc_to_glob[idomain][inode]=global_number;
00265             }
00266         }
00267     }
00268 
00269   _nb_total_cells=index_global;
00270   _nb_total_nodes=index_node_global;   
00271   _nb_total_faces=index_face_global;
00272 }
00273 
00274 
00275 //constructing ParallelTopology from an old topology and a graph
00276 ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_domain, int mesh_dimension)
00277 {
00278 
00279   _nb_domain=nb_domain;
00280   _mesh_dimension=mesh_dimension;
00281   
00282   if (MyGlobals::_Verbose>200)
00283     std::cout << "proc " << MyGlobals::_Rank << " : new topology oldNbDomain " <<
00284       oldTopology->nbDomain() << " newNbDomain " << _nb_domain << std::endl;
00285   _nb_cells.resize(_nb_domain,0);
00286   _nb_nodes.resize(_nb_domain,0);
00287   _nb_faces.resize(_nb_domain,0);
00288 
00289   _loc_to_glob.resize(_nb_domain);
00290   _node_loc_to_glob.resize(_nb_domain);
00291   _face_loc_to_glob.resize(_nb_domain);
00292   
00293   const int* part=graph->getPart(); //all cells for this proc (may be more domains)
00294   _nb_total_cells=graph->nbVertices(); //all cells for this proc (may be more domains)
00295   if (MyGlobals::_Verbose>300)
00296     std::cout << "proc " << MyGlobals::_Rank << " : topology from partition, nbTotalCells " << _nb_total_cells << std::endl;
00297   
00298   int icellProc=0; //all cells of my domains are concatenated in part
00299   for (int iold=0; iold<oldTopology->nbDomain(); iold++)
00300     {
00301       int ioldNbCell=oldTopology->getCellNumber(iold);
00302       //std::cout<<"proc "<<MyGlobals::_Rank<<" : cell number old domain "<<iold<<" : "<<ioldNbCell<<std::endl;
00303       //if not my old domains getCellNumber is 0
00304       std::vector<int> globalids(ioldNbCell);
00305       oldTopology->getCellList(iold, &globalids[0]); //unique global numerotation
00306       for (int icell=0; icell<ioldNbCell; icell++)
00307         {
00308           int idomain=part[icellProc];
00309           _nb_cells[idomain]++;
00310           icellProc++;
00311           int iGlobalCell=globalids[icell];
00312           _loc_to_glob[idomain].push_back(iGlobalCell);
00313           _glob_to_loc.insert(std::make_pair(iGlobalCell, std::make_pair(idomain, _nb_cells[idomain])));
00314         }
00315     }
00316 
00317   if (MyGlobals::_Verbose>300)
00318     for (int idomain=0; idomain<_nb_domain; idomain++)
00319       std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl; 
00320 }
00321 
00322 ParallelTopology::~ParallelTopology()
00323 {
00324 } 
00325 
00332 void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int* ip)
00333 {
00334   if (_node_glob_to_loc.empty()) 
00335     throw INTERP_KERNEL::Exception("Node mapping has not yet been built");
00336   for (int i=0; i< nbnode; i++)
00337     {
00338       std::pair<int,int> local_node = _node_glob_to_loc.find(node_list[i])->second;
00339       ip[i]=local_node.first;
00340       local[i]=local_node.second;
00341     }
00342 }
00343 
00351 void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int ip)
00352 {
00353   if (_node_glob_to_loc.empty()) 
00354     throw INTERP_KERNEL::Exception("Node mapping has not yet been built");
00355 
00356   for (int i=0; i< nbnode; i++)
00357     {
00358       typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter;
00359       std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]);
00360       for (mmiter it=range.first; it !=range.second; it++)
00361         { 
00362           int ipfound=(it->second).first;
00363           if (ipfound==ip)
00364             local[i]=(it->second).second;
00365         }
00366     }
00367 } 
00368 
00375 void ParallelTopology::convertGlobalNodeListWithTwins(const int* node_list, int nbnode, int*& local, int*& ip,int*& full_array, int& size)
00376 {
00377   if (_node_glob_to_loc.empty()) 
00378     throw INTERP_KERNEL::Exception("Node mapping has not yet been built");
00379 
00380   size=0;
00381   for (int i=0; i< nbnode; i++)
00382     {
00383       int count= _node_glob_to_loc.count(node_list[i]);
00384       size+=count;
00385     }
00386   int index=0;
00387   ip=new int[size];
00388   local=new int[size];
00389   full_array=new int[size];
00390   for (int i=0; i< nbnode; i++)
00391     {
00392       typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter;
00393       std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]);
00394       for (mmiter it=range.first; it !=range.second; it++)
00395         { 
00396           ip[index]=(it->second).first;
00397           local[index]=(it->second).second;
00398           full_array [index]=node_list[i];
00399           index++;
00400         }
00401 
00402     }
00403 }
00404 
00411 void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size)
00412 {
00413   size=0;
00414   for (int i=0; i< nbface; i++)
00415     {
00416       //int count = _face_glob_to_loc.count(face_list[i]);
00417       //if (count >1) MESSAGE_MED("face en doublon "<<face_list[i]);
00418       size+= _face_glob_to_loc.count(face_list[i]);
00419     }
00420   int index=0;
00421   ip=new int[size];
00422   local=new int[size];
00423   full_array=new int[size];
00424   for (int i=0; i< nbface; i++)
00425     {
00426       typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter;
00427       std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]);
00428       for (mmiter it=range.first; it !=range.second; it++)
00429         { 
00430           ip[index]=(it->second).first;
00431           local[index]=(it->second).second;
00432           full_array[index]=face_list[i];
00433           index++;
00434         }
00435 
00436     }
00437 }
00438 
00441 void ParallelTopology::convertGlobalCellList(const int* cell_list, int nbcell, int* local, int* ip)
00442 {
00443   for (int i=0; i<nbcell; i++)
00444     {
00445       INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _glob_to_loc.find(cell_list[i]);
00446       if (iter == _glob_to_loc.end())
00447         {
00448           std::cerr << "proc " << MyGlobals::_Rank << " : KO cell_list[" << i << "] : " << cell_list[i] << std::endl;
00449           throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalCellList : Cell not found");
00450         }
00451       else
00452         {
00453           ip[i]=(iter->second).first;     //no domain
00454           local[i]=(iter->second).second; //no local cell
00455         }
00456     }
00457 }
00458 
00462 void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int* ip)
00463 {
00464   for (int i=0; i< nbface; i++)
00465     {
00466       INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _face_glob_to_loc.find(face_list[i]);
00467       if (iter == _face_glob_to_loc.end())
00468         {
00469           throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalFaceList : Face not found");
00470         }
00471       ip[i]=(iter->second).first;
00472       local[i]=(iter->second).second;
00473     }
00474 }
00475 
00483 void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int ip)
00484 {
00485   for (int i=0; i< nbface; i++)
00486     {
00487       typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter;
00488       std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]);
00489       for (mmiter it=range.first; it !=range.second; it++)
00490         { 
00491           int ipfound=(it->second).first;
00492           if (ipfound==ip)
00493             local[i]=(it->second).second; 
00494 
00495         }
00496     }
00497 } 
00498 
00499 //replacing a table of global numbering with a table with local numberings
00500 // type_connectivity contains global connectivity for each type in input
00501 // type_connectivity contains local connectivity for each type in output
00502 void ParallelTopology::convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain)
00503 {
00504   for (int inode=0; inode<nbnodes; inode++)
00505     {
00506       //      cout <<" inode :"<<inode<< " global = "<<type_connectivity[type][inode];
00507       int global = nodes[inode];
00508       typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter;
00509       std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(global);
00510       for (mmiter it=range.first; it !=range.second; it++)
00511         {
00512           if ((it->second).first==idomain)
00513             nodes[inode]=(it->second).second;
00514         }
00515     }
00516 }
00517 
00521 int ParallelTopology::getMaxGlobalFace() const
00522 {
00523   int max = 0;
00524   TGlob2LocsMap::const_iterator g_l_l = _face_glob_to_loc.begin();
00525   for ( ; g_l_l != _face_glob_to_loc.end(); ++g_l_l )
00526     if ( g_l_l->first > max )
00527       max = g_l_l->first;
00528   return max;
00529 }
00530 
00531 int ParallelTopology::getNodeNumber() const
00532 {
00533   if (_node_glob_to_loc.empty()) return 0;
00534   std::set <int> keys;
00535   for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _node_glob_to_loc.begin(); iter!=_node_glob_to_loc.end(); iter++)
00536     {
00537       keys.insert(iter->first);
00538     }
00539   return keys.size();
00540 }
00541 
00545 void ParallelTopology::getNodeList(int idomain, int *list) const
00546 {
00547   for (int i=0; i<_nb_nodes[idomain]; i++) 
00548     list[i]=_node_loc_to_glob[idomain][i];
00549 }
00550 
00554 void ParallelTopology::getCellList(int idomain, int *list) const
00555 {
00556   for (int i=0; i<_nb_cells[idomain];i++)
00557     list[i]=_loc_to_glob[idomain][i];
00558 }
00559 
00560 int ParallelTopology::getFaceNumber() const
00561 {
00562   if (_face_glob_to_loc.empty())
00563     return 0;
00564   std::set <int> keys;
00565   for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _face_glob_to_loc.begin(); iter!=_face_glob_to_loc.end(); iter++)
00566     {
00567       keys.insert(iter->first);
00568     }
00569   return keys.size();
00570 }
00571 
00575 void ParallelTopology::getFaceList(int idomain, int *list) const
00576 {
00577   for (int i=0; i<_nb_faces[idomain];i++)   
00578     list[i]=_face_loc_to_glob[idomain][i];
00579 }
00580 
00581 int ParallelTopology::convertGlobalFace(int iglobal, int idomain)
00582 {
00583   typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter;
00584   std::pair<MMiter,MMiter> eq = _face_glob_to_loc.equal_range(iglobal);
00585   for (MMiter it=eq.first; it != eq.second; it++) 
00586     if (it->second.first == idomain)
00587       return it->second.second;   
00588   return -1;
00589 }
00590 
00591 int ParallelTopology::convertGlobalNode(int iglobal, int idomain)
00592 {
00593   typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter;
00594   std::pair<MMiter,MMiter> eq = _node_glob_to_loc.equal_range(iglobal);
00595   for (MMiter it=eq.first; it != eq.second; it++)
00596     {
00597       if (it->second.first == idomain)
00598         return it->second.second;
00599     }
00600   return -1;
00601 }
00602 
00606 void ParallelTopology::appendFace(int idomain, int ilocal, int iglobal)
00607 {
00608   _face_loc_to_glob[idomain].push_back(iglobal);
00609   _face_glob_to_loc.insert(std::make_pair(iglobal,std::make_pair(idomain,ilocal)));
00610 }