Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDSPLITTER / MEDSPLITTER_ParallelTopology.hxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #ifndef PARALLELTOPOLOGY_HXX_
20 #define PARALLELTOPOLOGY_HXX_
21
22 #include <set>
23 #include "InterpKernelHashMap.hxx"
24 #include "boost/shared_ptr.hpp"
25
26 #include "MEDSPLITTER_Topology.hxx"
27
28 namespace INTERP_KERNEL
29 {
30   template<> struct hash< pair<int,int> >
31   {
32     size_t operator()( const pair<int,int>& x ) const
33     {
34       return hash< int >()( x.first*1000000+x.second );
35     }
36   };
37 }
38
39 namespace MEDSPLITTER {
40
41   class Graph;
42   class MESHCollection;
43   class MEDSPLITTER_FaceModel;
44
45   class ParallelTopology:public Topology
46   {
47
48   public:
49
50     ParallelTopology();
51
52     ParallelTopology(const std::vector<MEDMEM::MESH*>&,
53                      const std::vector<MEDMEM::CONNECTZONE*>&,
54                      std::vector<int*>&,
55                      std::vector<int*>&,
56                      std::vector<int*>&);
57
58     ParallelTopology(boost::shared_ptr<Graph> graph, int nbdomain, int mesh_dimension);
59
60     ~ParallelTopology();
61     //!converts a list of global cell numbers
62     //!to a distributed array with local cell numbers
63     void convertGlobalNodeList(const int*, int,int*,int*);
64     void convertGlobalNodeList(const int*, int,int*,int);
65     void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size);
66
67     //!converts a list of global node numbers
68     //!to a distributed array with local cell numbers
69     void convertGlobalCellList(const int*, int , int*, int *);
70
71     //!converts a list of global face numbers
72     //!to a distributed array with local face numbers
73     void convertGlobalFaceList(const int*, int , int*, int *);  
74     void convertGlobalFaceList(const int*, int , int*, int);  
75     void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size);
76
77     //!creating node mapping 
78
79     void createNodeMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
80                            std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
81                            std::vector<int>& conn,
82                            std::vector<int>& conn_index,
83                            std::vector<int>& polyhedron_conn,
84                            std::vector<int>& polyhedron_conn_index,
85                            std::vector<int>& polyhedron_face_index,
86                            int idomain);
87
88     //  void createFaceMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
89     //               std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
90     //               int idomain);          
91
92     void createFaceMapping(const MESHCollection &, const MESHCollection&);
93     void createFaceMapping2ndversion(const MESHCollection &);
94
95     //!converting node global numberings to local numberings
96     void convertToLocal(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
97                         std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
98                         int idomain,
99                         MED_EN::medEntityMesh entity);
100     void convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain);
101
102
103
104     //! computing arrays with node/node correspondencies
105     void computeNodeNodeCorrespondencies(int nbdomain,vector<MEDMEM::MEDSKYLINEARRAY*>& ) const;
106
107     //! computing arrays with node/node correspondencies
108     void computeCellCellCorrespondencies(int nbdomain,vector<MEDMEM::MEDSKYLINEARRAY*>&, const Graph*) const;
109
110     //! retrieving Graph
111     //  boost::shared_ptr<Graph> getGraph() const;
112
113
114     //!converting node local numbering to global
115     inline  int convertNodeToGlobal(int ip,int icell) const
116     {
117       //return m_node_loc_to_glob.find(make_pair(ip,icell))->second;
118       return icell < 1 ? icell : m_node_loc_to_glob[ip][icell-1];
119     }
120
121     //!converting face local numbering to global
122     inline  int convertFaceToGlobal(int ip,int iface) const
123     {
124       //     if (m_face_loc_to_glob.find(make_pair(ip,icell))==m_face_loc_to_glob.end())
125       //       return -1;
126       //     else
127       //return m_face_loc_to_glob.find(make_pair(ip,icell))->second;
128       return m_face_loc_to_glob[ip][iface-1];
129     }
130
131     //converting cell global numbering to local
132     inline  int convertCellToGlobal(int ip,int icell) const
133     {
134       //     if (m_loc_to_glob.find(make_pair(ip,icell))==m_loc_to_glob.end())
135       //       return -1;
136       //     else
137       //return m_loc_to_glob.find(make_pair(ip,icell))->second;
138       return m_loc_to_glob[ip][icell-1];
139     }
140
141     inline  void convertNodeToGlobal(int ip, const int* local, int n, int* global)const
142     {
143       for (int i=0; i<n; i++)
144         //global[i]=m_node_loc_to_glob[ip][local[i]-1];
145         global[i]=convertNodeToGlobal(ip,local[i]);
146       //global[i]=m_node_loc_to_glob.find(make_pair(ip,local[i]))->second;
147     }
148
149     inline  void convertCellToGlobal(int ip, const int* local, int n, int* global)const
150     {
151       for (int i=0; i<n; i++)
152         global[i]=m_loc_to_glob[ip][local[i]-1];  
153       //global[i]=m_loc_to_glob.find(make_pair(ip,local[i]))->second;
154     }
155
156     inline  void convertFaceToGlobal(int ip, const int* local, int n, int* global)const
157     {
158       for (int i=0; i<n; i++)
159       {
160         global[i]=m_face_loc_to_glob[ip][local[i]-1];
161         //          if (m_face_loc_to_glob.find(make_pair(ip,local[i]))==m_face_loc_to_glob.end())
162         //            {
163         //              cout << "problem : face # "<< local[i] << " of processor "<< ip<< " was not found in mapping loc2glob"<<endl; 
164         //              global[i]=-1;
165         //            }
166         //          else
167         //            global[i]=m_face_loc_to_glob.find(make_pair(ip,local[i]))->second;
168       }
169     }
170
171     inline  int nbDomain() const
172     {
173       return m_nb_domain;
174     }
175
176     int nbCells() const
177     {
178       return m_nb_total_cells;
179     }
180
181
182     inline  int nbCells( int idomain) const
183     {
184       return m_nb_cells[idomain];
185     }
186
187
188
189
190     //!retrieving number of nodes
191     inline  int getNodeNumber(int idomain) const
192     {
193       return m_nb_nodes[idomain];
194     }
195
196     inline  int getNodeNumber() const
197     {
198       if (m_node_glob_to_loc.empty()) return 0;
199       set <int> keys;
200       for (INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator iter= m_node_glob_to_loc.begin();
201            iter!=m_node_glob_to_loc.end();
202            iter++) {
203         keys.insert(iter->first);
204       }
205       return keys.size();
206     }
207
208     //!retrieving list of nodes in global numbers
209     inline  void getNodeList(int idomain, int* list) const
210     {
211       for (int i=0; i<m_nb_nodes[idomain];i++)
212       {
213         list[i]=m_node_loc_to_glob[idomain][i];
214         //list[i]=(m_node_loc_to_glob.find(make_pair(idomain,i+1)))->second;
215       }
216     }
217
218     //!< retrieving cell numbers after fusing in parallel mode
219     std::vector<int> & getFusedCellNumbers(int idomain)
220     {
221       return m_cell_loc_to_glob_fuse[idomain];
222     }
223     const std::vector<int> & getFusedCellNumbers(int idomain) const
224     {
225       return m_cell_loc_to_glob_fuse[idomain];
226     }
227
228     //!< retrieving face numbers after fusing in parallel mode
229     std::vector<int> & getFusedFaceNumbers(int idomain)
230     {
231       return m_face_loc_to_glob_fuse[idomain];
232     }
233     const std::vector<int> & getFusedFaceNumbers(int idomain) const
234     {
235       return m_face_loc_to_glob_fuse[idomain];
236     }
237
238
239     //!retrieving number of nodes
240     inline  int getCellNumber(int idomain) const
241     {
242       return m_nb_cells[idomain];
243     }
244
245     inline  int getCellDomainNumber(int global) const
246     {
247       return (m_glob_to_loc.find(global)->second).first;
248     }
249
250     //!retrieving list of nodes in global numbers
251     inline  void getCellList(int idomain, int* list) const
252     {
253       for (int i=0; i<m_nb_cells[idomain];i++)
254       {
255         list[i]=m_loc_to_glob[idomain][i];
256         //list[i]=(m_loc_to_glob.find(make_pair(idomain,i+1)))->second;
257       }
258
259     }
260
261     inline int getFaceNumber(int idomain) const
262     {
263       return m_nb_faces[idomain];
264     }
265
266     inline  int getFaceNumber() const
267     {
268       if (m_face_glob_to_loc.empty()) return 0;
269       set <int> keys;
270       for (INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator iter= m_face_glob_to_loc.begin();
271            iter!=m_face_glob_to_loc.end();
272            iter++) {
273         keys.insert(iter->first);
274       }
275       return keys.size();
276     }
277
278
279     //!retrieving list of faces in global numbers
280     inline  void getFaceList(int idomain, int* list) const
281     {
282       for (int i=0; i<m_nb_faces[idomain];i++)
283       {
284         list[i]=m_face_loc_to_glob[idomain][i];
285         //list[i]=(m_face_loc_to_glob.find(make_pair(idomain,i+1)))->second;
286       }
287
288     }
289
290     //! converting a global cell number to a local representation (domain + local number)
291     inline std::pair<int,int> convertGlobalCell(int iglobal) const
292     {
293       return m_glob_to_loc.find(iglobal)->second;
294     }
295
296     inline int convertGlobalFace(int iglobal, int idomain)
297     {
298       typedef INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator MMiter;
299       pair<MMiter,MMiter> eq = m_face_glob_to_loc.equal_range(iglobal);
300       for (MMiter it=eq.first; it != eq.second; it++)
301       {
302         SCRUTE_MED (it->second.first);
303         SCRUTE_MED (idomain);
304         if (it->second.first == idomain) return it->second.second;
305
306       }
307       return -1;
308     }
309
310     inline int convertGlobalNode(int iglobal, int idomain)
311     {
312       typedef INTERP_KERNEL::HashMultiMap<int, pair<int,int> >::const_iterator MMiter;
313       pair<MMiter,MMiter> eq = m_node_glob_to_loc.equal_range(iglobal);
314       for (MMiter it=eq.first; it != eq.second; it++)
315       {
316         if (it->second.first == idomain) return it->second.second;
317       }
318       return -1;
319     }
320     //!adding a face to the topology
321     inline void appendFace(int idomain, int ilocal, int iglobal)
322     {
323       m_face_loc_to_glob[idomain].push_back(iglobal);
324       m_face_glob_to_loc.insert(make_pair(iglobal,make_pair(idomain,ilocal)));
325     }
326
327     //return max global face number
328     int getMaxGlobalFace() const;
329
330     boost::shared_ptr<Graph> getGraph() const
331     {
332       return m_graph;
333     }
334
335     //!recreating a face mapping from scratch
336     void recreateFaceMapping(const TGeom2FacesByDomian& face_map);
337
338     // recreating cell and node mapping after send-reveive and fusion of domain meshes
339     virtual void recreateMappingAfterFusion(const std::vector<MEDMEM::MESH*>& );
340
341
342
343   private:
344
345     bool hasCellWithNodes( const MESHCollection&, int dom, const std::set<int>& nodes );
346
347
348   private:
349     //!mapping global -> local
350     typedef INTERP_KERNEL::HashMap<int,pair<int,int> > TGlob2DomainLoc;
351     TGlob2DomainLoc m_glob_to_loc;
352
353     //  bool is_equal_pair (pair<int,int> a, pair<int,int> b){
354     //      return  (a.first==b.first && a.second==b.second);
355     // }
356     //!mapping local -> global
357     //map<pair<int,int>,int> m_loc_to_glob;
358
359     //
360     //INTERP_KERNEL::HashMap<pair<int,int>,int, INTERP_KERNEL::hash<pair<int,int> > > m_loc_to_glob;
361     vector<vector<int> >  m_loc_to_glob;
362     //!mapping global -> local
363     INTERP_KERNEL::HashMultiMap<int,pair<int,int> > m_node_glob_to_loc;
364
365     //!mapping local -> global
366     //  map<pair<int,int>,int> m_node_loc_to_glob;
367     //INTERP_KERNEL::HashMap<pair<int,int>,int, INTERP_KERNEL::hash<pair<int,int> > > m_node_loc_to_glob;
368     vector<vector <int> > m_node_loc_to_glob;
369
370     // global numbers in parallel mode
371     vector<vector <int> > m_cell_loc_to_glob_fuse; // glob nums after fusing
372     vector<vector <int> > m_face_loc_to_glob_fuse; // glob nums after fusing
373
374
375     //!mapping global -> local
376     typedef INTERP_KERNEL::HashMultiMap<int,pair<int,int> > TGlob2LocsMap;
377     TGlob2LocsMap m_face_glob_to_loc;
378
379     //!mapping local -> global
380     //INTERP_KERNEL::HashMap<pair<int,int>,int, INTERP_KERNEL::hash<pair<int,int> > > m_face_loc_to_glob;
381     vector<vector <int> > m_face_loc_to_glob;
382
383     //map<pair<int,int>,int> m_face_loc_to_glob;
384
385     vector<int> m_nb_cells;
386
387     vector<int> m_nb_nodes;
388
389     vector<int> m_nb_faces;
390
391     int m_nb_total_cells;
392
393     int m_nb_total_nodes;
394
395     int m_nb_total_faces;
396
397     int m_nb_domain;
398
399     int m_mesh_dimension;
400
401     boost::shared_ptr<Graph> m_graph;
402   };
403
404
405 }
406 #endif /*PARALLELTOPOLOGY_HXX_*/