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