]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/ParaMEDMEM/ExplicitMapping.hxx
Salome HOME
Merge from BR_V5_DEV 16Feb09
[tools/medcoupling.git] / src / ParaMEDMEM / ExplicitMapping.hxx
1 //  Copyright (C) 2007-2008  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 __EXPLICITMAPPING_HXX__
20 #define __EXPLICITMAPPING_HXX__
21
22 #include <vector>
23 #include <map>
24 #include <set>
25
26 namespace ParaMEDMEM
27 {
28   class ExplicitMapping
29   {
30   public:
31
32     ExplicitMapping():_numbers(0), _domains(0), _comm_buffer(0) { }
33
34     ~ExplicitMapping()
35     {
36       if (_domains!=0) delete[] _domains;
37       if (_numbers!=0) delete[] _numbers;
38       if (_comm_buffer!=0) delete[] _comm_buffer;
39     }
40     
41     void pushBackElem(std::pair<int,int> idistant)
42     {
43       _mapping.push_back(idistant);
44     }
45
46     void  setDistantElem(int ilocal, std::pair<int,int> idistant)
47     {
48       _mapping[ilocal]=idistant;
49     }
50
51     int nbDistantDomains()
52     {
53       if (_distant_domains.empty())
54         {
55           for (std::vector <std::pair<int,int> >::const_iterator iter= _mapping.begin();
56                iter!=_mapping.end();
57                iter++)
58             _distant_domains.insert(iter->first);
59         }
60       return _distant_domains.size();
61     }
62     
63     std::pair <int,int> getDistantNumbering(int ielem)const
64     {
65       return _mapping[ielem];
66     }
67     
68     int getDistantDomain(int i)
69     {
70       if (_domains==0)
71         computeNumbers();
72
73       return _domains[i];
74     }
75
76     int getNbDistantElems(int i)
77     {
78       if (_numbers==0)
79         computeNumbers();
80       return _numbers[i];    
81     }
82
83     int* serialize(int idproc)
84     {
85       _comm_buffer=new int[_mapping.size()*2];
86       std::vector<int> offsets(_distant_domains.size());
87       offsets[0]=0;
88       for (int i=1; i<_distant_domains.size();i++)
89         offsets[i]=offsets[i-1]+_numbers[i-1];
90       
91       for (int i=0; i< _mapping.size(); i++)
92         {
93           int offset= offsets[_mapping[i].first];
94           _comm_buffer[offset*2]=idproc;
95           _comm_buffer[offset*2+1]=_mapping[i].second;
96           offsets[_mapping[i].first]++;
97         }
98       return _comm_buffer;
99     }
100
101     void unserialize(int nbprocs, int* sizes,int nbtarget, int* targetrank, int* commbuffer)
102     {
103       int total_size=0;
104       for (int i=0; i< nbprocs; i++)
105         total_size+=sizes[i];
106       
107       _mapping.resize(total_size);
108       _buffer_index=new int[total_size];
109       int indmap=0;
110       for (int i=0; i<nbprocs; i++)
111         for (int ielem=0; ielem<sizes[i]; ielem++)
112           {
113             _mapping[indmap].first=i;
114             _mapping[indmap].second=commbuffer[indmap*2+1];
115             _buffer_index[indmap]=commbuffer[indmap*2+1];
116             indmap++;
117           }  
118       _numbers=new int [nbtarget];
119       _domains=new int [nbtarget];
120       
121       int index=0;      
122       for (int i=0; i<nbtarget; i++)
123         {
124           if (sizes[targetrank[i]]>0)
125             {
126               _numbers[index]=sizes[targetrank[i]];
127               _domains[index]=i;
128               index++;
129             }
130         }
131       _send_counts=new int[nbprocs];
132       for (int i=0; i<nbprocs; i++)
133         _send_counts[i]=sizes[i];
134     }
135
136     int* getBufferIndex() const { return _buffer_index; }
137     int* getCounts() const { return _send_counts; }
138   private:
139     std::vector <std::pair<int,int> > _mapping;
140     std::set<int> _distant_domains;
141     int* _numbers;
142     int* _domains;
143     int* _comm_buffer;
144     int* _buffer_index;
145     int* _send_counts;
146
147     void computeNumbers()
148     {
149       std::map <int,int> counts;
150       if (_numbers==0)
151         {
152           _numbers=new int[nbDistantDomains()];
153           _domains=new int[nbDistantDomains()];
154           for (int i=0; i< _mapping.size(); i++)
155             {
156               if ( counts.find(_mapping[i].first) == counts.end())
157                 counts.insert(std::make_pair(_mapping[i].first,1));
158               else
159                 (counts[_mapping[i].first])++;
160             }
161           int counter=0;
162           for (std::map<int,int>::const_iterator iter=counts.begin(); 
163                iter!=counts.end(); 
164                iter++)
165             {
166               _numbers[counter]=iter->second;
167               _domains[counter]=iter->first;
168               counter++;
169             }
170         }
171     }
172   };
173 }
174
175 #endif