Back to index

salome-med  6.5.0
MEDSPLITTER_ParallelTopology.hxx
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 #ifndef PARALLELTOPOLOGY_HXX_
00020 #define PARALLELTOPOLOGY_HXX_
00021 
00022 #include <set>
00023 #include "InterpKernelHashMap.hxx"
00024 #include "boost/shared_ptr.hpp"
00025 
00026 #include "MEDSPLITTER_Topology.hxx"
00027 
00028 namespace INTERP_KERNEL
00029 {
00030   template<> struct hash< pair<int,int> >
00031   {
00032     size_t operator()( const pair<int,int>& x ) const
00033     {
00034       return hash< int >()( x.first*1000000+x.second );
00035     }
00036   };
00037 }
00038 
00039 namespace MEDSPLITTER {
00040 
00041   class Graph;
00042   class MESHCollection;
00043   class MEDSPLITTER_FaceModel;
00044 
00045   class ParallelTopology:public Topology
00046   {
00047 
00048   public:
00049 
00050     ParallelTopology();
00051 
00052     ParallelTopology(const std::vector<MEDMEM::MESH*>&,
00053                      const std::vector<MEDMEM::CONNECTZONE*>&,
00054                      std::vector<int*>&,
00055                      std::vector<int*>&,
00056                      std::vector<int*>&);
00057 
00058     ParallelTopology(boost::shared_ptr<Graph> graph, int nbdomain, int mesh_dimension);
00059 
00060     ~ParallelTopology();
00063     void convertGlobalNodeList(const int*, int,int*,int*);
00064     void convertGlobalNodeList(const int*, int,int*,int);
00065     void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size);
00066 
00069     void convertGlobalCellList(const int*, int , int*, int *);
00070 
00073     void convertGlobalFaceList(const int*, int , int*, int *);  
00074     void convertGlobalFaceList(const int*, int , int*, int);  
00075     void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size);
00076 
00078 
00079     void createNodeMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
00080                            std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
00081                            std::vector<int>& conn,
00082                            std::vector<int>& conn_index,
00083                            std::vector<int>& polyhedron_conn,
00084                            std::vector<int>& polyhedron_conn_index,
00085                            std::vector<int>& polyhedron_face_index,
00086                            int idomain);
00087 
00088     //  void createFaceMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
00089     //               std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
00090     //               int idomain);          
00091 
00092     void createFaceMapping(const MESHCollection &, const MESHCollection&);
00093     void createFaceMapping2ndversion(const MESHCollection &);
00094 
00096     void convertToLocal(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
00097                         std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
00098                         int idomain,
00099                         MED_EN::medEntityMesh entity);
00100     void convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain);
00101 
00102 
00103 
00105     void computeNodeNodeCorrespondencies(int nbdomain,vector<MEDMEM::MEDSKYLINEARRAY*>& ) const;
00106 
00108     void computeCellCellCorrespondencies(int nbdomain,vector<MEDMEM::MEDSKYLINEARRAY*>&, const Graph*) const;
00109 
00111     //  boost::shared_ptr<Graph> getGraph() const;
00112 
00113 
00115     inline  int convertNodeToGlobal(int ip,int icell) const
00116     {
00117       //return m_node_loc_to_glob.find(make_pair(ip,icell))->second;
00118       return icell < 1 ? icell : m_node_loc_to_glob[ip][icell-1];
00119     }
00120 
00122     inline  int convertFaceToGlobal(int ip,int iface) const
00123     {
00124       //     if (m_face_loc_to_glob.find(make_pair(ip,icell))==m_face_loc_to_glob.end())
00125       //       return -1;
00126       //     else
00127       //return m_face_loc_to_glob.find(make_pair(ip,icell))->second;
00128       return m_face_loc_to_glob[ip][iface-1];
00129     }
00130 
00131     //converting cell global numbering to local
00132     inline  int convertCellToGlobal(int ip,int icell) const
00133     {
00134       //     if (m_loc_to_glob.find(make_pair(ip,icell))==m_loc_to_glob.end())
00135       //       return -1;
00136       //     else
00137       //return m_loc_to_glob.find(make_pair(ip,icell))->second;
00138       return m_loc_to_glob[ip][icell-1];
00139     }
00140 
00141     inline  void convertNodeToGlobal(int ip, const int* local, int n, int* global)const
00142     {
00143       for (int i=0; i<n; i++)
00144         //global[i]=m_node_loc_to_glob[ip][local[i]-1];
00145         global[i]=convertNodeToGlobal(ip,local[i]);
00146       //global[i]=m_node_loc_to_glob.find(make_pair(ip,local[i]))->second;
00147     }
00148 
00149     inline  void convertCellToGlobal(int ip, const int* local, int n, int* global)const
00150     {
00151       for (int i=0; i<n; i++)
00152         global[i]=m_loc_to_glob[ip][local[i]-1];  
00153       //global[i]=m_loc_to_glob.find(make_pair(ip,local[i]))->second;
00154     }
00155 
00156     inline  void convertFaceToGlobal(int ip, const int* local, int n, int* global)const
00157     {
00158       for (int i=0; i<n; i++)
00159       {
00160         global[i]=m_face_loc_to_glob[ip][local[i]-1];
00161         //          if (m_face_loc_to_glob.find(make_pair(ip,local[i]))==m_face_loc_to_glob.end())
00162         //            {
00163         //              cout << "problem : face # "<< local[i] << " of processor "<< ip<< " was not found in mapping loc2glob"<<endl; 
00164         //              global[i]=-1;
00165         //            }
00166         //          else
00167         //            global[i]=m_face_loc_to_glob.find(make_pair(ip,local[i]))->second;
00168       }
00169     }
00170 
00171     inline  int nbDomain() const
00172     {
00173       return m_nb_domain;
00174     }
00175 
00176     int nbCells() const
00177     {
00178       return m_nb_total_cells;
00179     }
00180 
00181 
00182     inline  int nbCells( int idomain) const
00183     {
00184       return m_nb_cells[idomain];
00185     }
00186 
00187 
00188 
00189 
00191     inline  int getNodeNumber(int idomain) const
00192     {
00193       return m_nb_nodes[idomain];
00194     }
00195 
00196     inline  int getNodeNumber() const
00197     {
00198       if (m_node_glob_to_loc.empty()) return 0;
00199       set <int> keys;
00200       for (INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator iter= m_node_glob_to_loc.begin();
00201            iter!=m_node_glob_to_loc.end();
00202            iter++) {
00203         keys.insert(iter->first);
00204       }
00205       return keys.size();
00206     }
00207 
00209     inline  void getNodeList(int idomain, int* list) const
00210     {
00211       for (int i=0; i<m_nb_nodes[idomain];i++)
00212       {
00213         list[i]=m_node_loc_to_glob[idomain][i];
00214         //list[i]=(m_node_loc_to_glob.find(make_pair(idomain,i+1)))->second;
00215       }
00216     }
00217 
00219     std::vector<int> & getFusedCellNumbers(int idomain)
00220     {
00221       return m_cell_loc_to_glob_fuse[idomain];
00222     }
00223     const std::vector<int> & getFusedCellNumbers(int idomain) const
00224     {
00225       return m_cell_loc_to_glob_fuse[idomain];
00226     }
00227 
00229     std::vector<int> & getFusedFaceNumbers(int idomain)
00230     {
00231       return m_face_loc_to_glob_fuse[idomain];
00232     }
00233     const std::vector<int> & getFusedFaceNumbers(int idomain) const
00234     {
00235       return m_face_loc_to_glob_fuse[idomain];
00236     }
00237 
00238 
00240     inline  int getCellNumber(int idomain) const
00241     {
00242       return m_nb_cells[idomain];
00243     }
00244 
00245     inline  int getCellDomainNumber(int global) const
00246     {
00247       return (m_glob_to_loc.find(global)->second).first;
00248     }
00249 
00251     inline  void getCellList(int idomain, int* list) const
00252     {
00253       for (int i=0; i<m_nb_cells[idomain];i++)
00254       {
00255         list[i]=m_loc_to_glob[idomain][i];
00256         //list[i]=(m_loc_to_glob.find(make_pair(idomain,i+1)))->second;
00257       }
00258 
00259     }
00260 
00261     inline int getFaceNumber(int idomain) const
00262     {
00263       return m_nb_faces[idomain];
00264     }
00265 
00266     inline  int getFaceNumber() const
00267     {
00268       if (m_face_glob_to_loc.empty()) return 0;
00269       set <int> keys;
00270       for (INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator iter= m_face_glob_to_loc.begin();
00271            iter!=m_face_glob_to_loc.end();
00272            iter++) {
00273         keys.insert(iter->first);
00274       }
00275       return keys.size();
00276     }
00277 
00278 
00280     inline  void getFaceList(int idomain, int* list) const
00281     {
00282       for (int i=0; i<m_nb_faces[idomain];i++)
00283       {
00284         list[i]=m_face_loc_to_glob[idomain][i];
00285         //list[i]=(m_face_loc_to_glob.find(make_pair(idomain,i+1)))->second;
00286       }
00287 
00288     }
00289 
00291     inline std::pair<int,int> convertGlobalCell(int iglobal) const
00292     {
00293       return m_glob_to_loc.find(iglobal)->second;
00294     }
00295 
00296     inline int convertGlobalFace(int iglobal, int idomain)
00297     {
00298       typedef INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator MMiter;
00299       pair<MMiter,MMiter> eq = m_face_glob_to_loc.equal_range(iglobal);
00300       for (MMiter it=eq.first; it != eq.second; it++)
00301       {
00302         SCRUTE_MED (it->second.first);
00303         SCRUTE_MED (idomain);
00304         if (it->second.first == idomain) return it->second.second;
00305 
00306       }
00307       return -1;
00308     }
00309 
00310     inline int convertGlobalNode(int iglobal, int idomain)
00311     {
00312       typedef INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator MMiter;
00313       pair<MMiter,MMiter> eq = m_node_glob_to_loc.equal_range(iglobal);
00314       for (MMiter it=eq.first; it != eq.second; it++)
00315       {
00316         if (it->second.first == idomain) return it->second.second;
00317       }
00318       return -1;
00319     }
00321     inline void appendFace(int idomain, int ilocal, int iglobal)
00322     {
00323       m_face_loc_to_glob[idomain].push_back(iglobal);
00324       m_face_glob_to_loc.insert(make_pair(iglobal,make_pair(idomain,ilocal)));
00325     }
00326 
00327     //return max global face number
00328     int getMaxGlobalFace() const;
00329 
00330     boost::shared_ptr<Graph> getGraph() const
00331     {
00332       return m_graph;
00333     }
00334 
00336     void recreateFaceMapping(const TGeom2FacesByDomian& face_map);
00337 
00338     // recreating cell and node mapping after send-reveive and fusion of domain meshes
00339     virtual void recreateMappingAfterFusion(const std::vector<MEDMEM::MESH*>& );
00340 
00341 
00342 
00343   private:
00344 
00345     bool hasCellWithNodes( const MESHCollection&, int dom, const std::set<int>& nodes );
00346 
00347 
00348   private:
00350     typedef INTERP_KERNEL::HashMap<int,pair<int,int> > TGlob2DomainLoc;
00351     TGlob2DomainLoc m_glob_to_loc;
00352 
00353     //  bool is_equal_pair (pair<int,int> a, pair<int,int> b){
00354     //      return  (a.first==b.first && a.second==b.second);
00355     // }
00357     //map<pair<int,int>,int> m_loc_to_glob;
00358 
00359     //
00360     //INTERP_KERNEL::HashMap<pair<int,int>,int, INTERP_KERNEL::hash<pair<int,int> > > m_loc_to_glob;
00361     vector<vector<int> >  m_loc_to_glob;
00363     INTERP_KERNEL::HashMultiMap<int,pair<int,int> > m_node_glob_to_loc;
00364 
00366     //  map<pair<int,int>,int> m_node_loc_to_glob;
00367     //INTERP_KERNEL::HashMap<pair<int,int>,int, INTERP_KERNEL::hash<pair<int,int> > > m_node_loc_to_glob;
00368     vector<vector <int> > m_node_loc_to_glob;
00369 
00370     // global numbers in parallel mode
00371     vector<vector <int> > m_cell_loc_to_glob_fuse; // glob nums after fusing
00372     vector<vector <int> > m_face_loc_to_glob_fuse; // glob nums after fusing
00373 
00374 
00376     typedef INTERP_KERNEL::HashMultiMap<int,pair<int,int> > TGlob2LocsMap;
00377     TGlob2LocsMap m_face_glob_to_loc;
00378 
00380     //INTERP_KERNEL::HashMap<pair<int,int>,int, INTERP_KERNEL::hash<pair<int,int> > > m_face_loc_to_glob;
00381     vector<vector <int> > m_face_loc_to_glob;
00382 
00383     //map<pair<int,int>,int> m_face_loc_to_glob;
00384 
00385     vector<int> m_nb_cells;
00386 
00387     vector<int> m_nb_nodes;
00388 
00389     vector<int> m_nb_faces;
00390 
00391     int m_nb_total_cells;
00392 
00393     int m_nb_total_nodes;
00394 
00395     int m_nb_total_faces;
00396 
00397     int m_nb_domain;
00398 
00399     int m_mesh_dimension;
00400 
00401     boost::shared_ptr<Graph> m_graph;
00402   };
00403 
00404 
00405 }
00406 #endif /*PARALLELTOPOLOGY_HXX_*/