Back to index

salome-med  6.5.0
ExplicitMapping.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 
00020 #ifndef __EXPLICITMAPPING_HXX__
00021 #define __EXPLICITMAPPING_HXX__
00022 
00023 #include <vector>
00024 #include <map>
00025 #include <set>
00026 
00027 namespace ParaMEDMEM
00028 {
00029   class ExplicitMapping
00030   {
00031   public:
00032 
00033     ExplicitMapping():_numbers(0), _domains(0), _comm_buffer(0) { }
00034 
00035     ~ExplicitMapping()
00036     {
00037       if (_domains!=0) delete[] _domains;
00038       if (_numbers!=0) delete[] _numbers;
00039       if (_comm_buffer!=0) delete[] _comm_buffer;
00040     }
00041     
00042     void pushBackElem(std::pair<int,int> idistant)
00043     {
00044       _mapping.push_back(idistant);
00045     }
00046 
00047     void  setDistantElem(int ilocal, std::pair<int,int> idistant)
00048     {
00049       _mapping[ilocal]=idistant;
00050     }
00051 
00052     int nbDistantDomains()
00053     {
00054       if (_distant_domains.empty())
00055         {
00056           for (std::vector <std::pair<int,int> >::const_iterator iter= _mapping.begin();
00057                iter!=_mapping.end();
00058                iter++)
00059             _distant_domains.insert(iter->first);
00060         }
00061       return _distant_domains.size();
00062     }
00063     
00064     std::pair <int,int> getDistantNumbering(int ielem)const
00065     {
00066       return _mapping[ielem];
00067     }
00068     
00069     int getDistantDomain(int i)
00070     {
00071       if (_domains==0)
00072         computeNumbers();
00073 
00074       return _domains[i];
00075     }
00076 
00077     int getNbDistantElems(int i)
00078     {
00079       if (_numbers==0)
00080         computeNumbers();
00081       return _numbers[i];    
00082     }
00083 
00084     int* serialize(int idproc)
00085     {
00086       _comm_buffer=new int[_mapping.size()*2];
00087       std::vector<int> offsets(_distant_domains.size());
00088       offsets[0]=0;
00089       for (int i=1; i<(int)_distant_domains.size();i++)
00090         offsets[i]=offsets[i-1]+_numbers[i-1];
00091       
00092       for (int i=0; i<(int)_mapping.size(); i++)
00093         {
00094           int offset= offsets[_mapping[i].first];
00095           _comm_buffer[offset*2]=idproc;
00096           _comm_buffer[offset*2+1]=_mapping[i].second;
00097           offsets[_mapping[i].first]++;
00098         }
00099       return _comm_buffer;
00100     }
00101 
00102     void unserialize(int nbprocs, int* sizes,int nbtarget, int* targetrank, int* commbuffer)
00103     {
00104       int total_size=0;
00105       for (int i=0; i< nbprocs; i++)
00106         total_size+=sizes[i];
00107       
00108       _mapping.resize(total_size);
00109       _buffer_index=new int[total_size];
00110       int indmap=0;
00111       for (int i=0; i<nbprocs; i++)
00112         for (int ielem=0; ielem<sizes[i]; ielem++)
00113           {
00114             _mapping[indmap].first=i;
00115             _mapping[indmap].second=commbuffer[indmap*2+1];
00116             _buffer_index[indmap]=commbuffer[indmap*2+1];
00117             indmap++;
00118           }  
00119       _numbers=new int [nbtarget];
00120       _domains=new int [nbtarget];
00121       
00122       int index=0;      
00123       for (int i=0; i<nbtarget; i++)
00124         {
00125           if (sizes[targetrank[i]]>0)
00126             {
00127               _numbers[index]=sizes[targetrank[i]];
00128               _domains[index]=i;
00129               index++;
00130             }
00131         }
00132       _send_counts=new int[nbprocs];
00133       for (int i=0; i<nbprocs; i++)
00134         _send_counts[i]=sizes[i];
00135     }
00136 
00137     int* getBufferIndex() const { return _buffer_index; }
00138     int* getCounts() const { return _send_counts; }
00139   private:
00140     std::vector <std::pair<int,int> > _mapping;
00141     std::set<int> _distant_domains;
00142     int* _numbers;
00143     int* _domains;
00144     int* _comm_buffer;
00145     int* _buffer_index;
00146     int* _send_counts;
00147 
00148     void computeNumbers()
00149     {
00150       std::map <int,int> counts;
00151       if (_numbers==0)
00152         {
00153           _numbers=new int[nbDistantDomains()];
00154           _domains=new int[nbDistantDomains()];
00155           for (int i=0; i<(int)_mapping.size(); i++)
00156             {
00157               if ( counts.find(_mapping[i].first) == counts.end())
00158                 counts.insert(std::make_pair(_mapping[i].first,1));
00159               else
00160                 (counts[_mapping[i].first])++;
00161             }
00162           int counter=0;
00163           for (std::map<int,int>::const_iterator iter=counts.begin(); 
00164                iter!=counts.end(); 
00165                iter++)
00166             {
00167               _numbers[counter]=iter->second;
00168               _domains[counter]=iter->first;
00169               counter++;
00170             }
00171         }
00172     }
00173   };
00174 }
00175 
00176 #endif