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