Back to index

salome-med  6.5.0
OverlapMapping.cxx
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 #include "OverlapMapping.hxx"
00021 #include "MPIProcessorGroup.hxx"
00022 
00023 #include "MEDCouplingFieldDouble.hxx"
00024 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
00025 
00026 #include "InterpKernelAutoPtr.hxx"
00027 
00028 #include <numeric>
00029 #include <algorithm>
00030 
00031 using namespace ParaMEDMEM;
00032 
00033 OverlapMapping::OverlapMapping(const ProcessorGroup& group):_group(group)
00034 {
00035 }
00036 
00041 void OverlapMapping::keepTracksOfSourceIds(int procId, DataArrayInt *ids)
00042 {
00043   ids->incrRef();
00044   _src_ids_st2.push_back(ids);
00045   _src_proc_st2.push_back(procId);
00046 }
00047 
00052 void OverlapMapping::keepTracksOfTargetIds(int procId, DataArrayInt *ids)
00053 {
00054   ids->incrRef();
00055   _trg_ids_st2.push_back(ids);
00056   _trg_proc_st2.push_back(procId);
00057 }
00058 
00063 void OverlapMapping::addContributionST(const std::vector< std::map<int,double> >& matrixST, const DataArrayInt *srcIds, int srcProcId, const DataArrayInt *trgIds, int trgProcId)
00064 {
00065   _matrixes_st.push_back(matrixST);
00066   _source_proc_id_st.push_back(srcProcId);
00067   _target_proc_id_st.push_back(trgProcId);
00068   if(srcIds)
00069     {//item#1 of step2 algorithm in proc m. Only to know in advanced nb of recv ids [ (0,1) computed on proc1 and Matrix-Vector on proc1 ]
00070       _nb_of_src_ids_proc_st2.push_back(srcIds->getNumberOfTuples());
00071       _src_ids_proc_st2.push_back(srcProcId);
00072     }
00073   else
00074     {//item#0 of step2 algorithm in proc k
00075       std::set<int> s;
00076       for(std::vector< std::map<int,double> >::const_iterator it1=matrixST.begin();it1!=matrixST.end();it1++)
00077         for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
00078           s.insert((*it2).first);
00079       _src_ids_zip_st2.resize(_src_ids_zip_st2.size()+1);
00080       _src_ids_zip_st2.back().insert(_src_ids_zip_st2.back().end(),s.begin(),s.end());
00081       _src_ids_zip_proc_st2.push_back(trgProcId);
00082     }
00083 }
00084 
00092 void OverlapMapping::prepare(const std::vector< std::vector<int> >& procsInInteraction, int nbOfTrgElems)
00093 {
00094   CommInterface commInterface=_group.getCommInterface();
00095   const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group);
00096   const MPI_Comm *comm=group->getComm();
00097   int grpSize=_group.size();
00098   INTERP_KERNEL::AutoPtr<int> nbsend=new int[grpSize];
00099   INTERP_KERNEL::AutoPtr<int> nbsend2=new int[grpSize];
00100   INTERP_KERNEL::AutoPtr<int> nbsend3=new int[grpSize];
00101   std::fill<int *>(nbsend,nbsend+grpSize,0);
00102   int myProcId=_group.myRank();
00103   _proc_ids_to_recv_vector_st.clear();
00104   int curProc=0;
00105   for(std::vector< std::vector<int> >::const_iterator it1=procsInInteraction.begin();it1!=procsInInteraction.end();it1++,curProc++)
00106     if(std::find((*it1).begin(),(*it1).end(),myProcId)!=(*it1).end())
00107       _proc_ids_to_recv_vector_st.push_back(curProc);
00108   _proc_ids_to_send_vector_st=procsInInteraction[myProcId];
00109   for(std::size_t i=0;i<_matrixes_st.size();i++)
00110     if(_source_proc_id_st[i]==myProcId)
00111       nbsend[_target_proc_id_st[i]]=_matrixes_st[i].size();
00112   INTERP_KERNEL::AutoPtr<int> nbrecv=new int[grpSize];
00113   commInterface.allToAll(nbsend,1,MPI_INT,nbrecv,1,MPI_INT,*comm);
00114   //exchanging matrix
00115   //first exchanging offsets+ids_source
00116   INTERP_KERNEL::AutoPtr<int> nbrecv1=new int[grpSize];
00117   INTERP_KERNEL::AutoPtr<int> nbrecv2=new int[grpSize];
00118   //
00119   int *tmp=0;
00120   serializeMatrixStep0ST(nbrecv,
00121                          tmp,nbsend2,nbsend3,
00122                          nbrecv1,nbrecv2);
00123   INTERP_KERNEL::AutoPtr<int> bigArr=tmp;
00124   INTERP_KERNEL::AutoPtr<int> bigArrRecv=new int[nbrecv2[grpSize-1]+nbrecv1[grpSize-1]];
00125   commInterface.allToAllV(bigArr,nbsend2,nbsend3,MPI_INT,
00126                           bigArrRecv,nbrecv1,nbrecv2,MPI_INT,
00127                           *comm);// sending ids of sparse matrix (n+1 elems)
00128   //second phase echange target ids
00129   std::fill<int *>(nbsend2,nbsend2+grpSize,0);
00130   INTERP_KERNEL::AutoPtr<int> nbrecv3=new int[grpSize];
00131   INTERP_KERNEL::AutoPtr<int> nbrecv4=new int[grpSize];
00132   double *tmp2=0;
00133   int lgthOfArr=serializeMatrixStep1ST(nbrecv,bigArrRecv,nbrecv1,nbrecv2,
00134                                        tmp,tmp2,
00135                                        nbsend2,nbsend3,nbrecv3,nbrecv4);
00136   INTERP_KERNEL::AutoPtr<int> bigArr2=tmp;
00137   INTERP_KERNEL::AutoPtr<double> bigArrD2=tmp2;
00138   INTERP_KERNEL::AutoPtr<int> bigArrRecv2=new int[lgthOfArr];
00139   INTERP_KERNEL::AutoPtr<double> bigArrDRecv2=new double[lgthOfArr];
00140   commInterface.allToAllV(bigArr2,nbsend2,nbsend3,MPI_INT,
00141                           bigArrRecv2,nbrecv3,nbrecv4,MPI_INT,
00142                           *comm);
00143   commInterface.allToAllV(bigArrD2,nbsend2,nbsend3,MPI_DOUBLE,
00144                           bigArrDRecv2,nbrecv3,nbrecv4,MPI_DOUBLE,
00145                           *comm);
00146   //finishing
00147   unserializationST(nbOfTrgElems,nbrecv,bigArrRecv,nbrecv1,nbrecv2,
00148                     bigArrRecv2,bigArrDRecv2,nbrecv3,nbrecv4);
00149   //updating _src_ids_zip_st2 and _src_ids_zip_st2 with received matrix.
00150   updateZipSourceIdsForFuture();
00151   //finish to fill _the_matrix_st with already in place matrix in _matrixes_st
00152   finishToFillFinalMatrixST();
00153   //printTheMatrix();
00154 }
00155 
00159 void OverlapMapping::computeDenoGlobConstraint()
00160 {
00161   _the_deno_st.clear();
00162   std::size_t sz1=_the_matrix_st.size();
00163   _the_deno_st.resize(sz1);
00164   for(std::size_t i=0;i<sz1;i++)
00165     {
00166       std::size_t sz2=_the_matrix_st[i].size();
00167       _the_deno_st[i].resize(sz2);
00168       for(std::size_t j=0;j<sz2;j++)
00169         {
00170           double sum=0;
00171           std::map<int,double>& mToFill=_the_deno_st[i][j];
00172           const std::map<int,double>& m=_the_matrix_st[i][j];
00173           for(std::map<int,double>::const_iterator it=m.begin();it!=m.end();it++)
00174             sum+=(*it).second;
00175           for(std::map<int,double>::const_iterator it=m.begin();it!=m.end();it++)
00176             mToFill[(*it).first]=sum;
00177         }
00178     }
00179 }
00180 
00184 void OverlapMapping::computeDenoConservativeVolumic(int nbOfTuplesTrg)
00185 {
00186   CommInterface commInterface=_group.getCommInterface();
00187   int myProcId=_group.myRank();
00188   //
00189   _the_deno_st.clear();
00190   std::size_t sz1=_the_matrix_st.size();
00191   _the_deno_st.resize(sz1);
00192   std::vector<double> deno(nbOfTuplesTrg);
00193   for(std::size_t i=0;i<sz1;i++)
00194     {
00195       const std::vector< std::map<int,double> >& mat=_the_matrix_st[i];
00196       int curSrcId=_the_matrix_st_source_proc_id[i];
00197       std::vector<int>::iterator isItem1=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),curSrcId);
00198       int rowId=0;
00199       if(isItem1==_trg_proc_st2.end() || curSrcId==myProcId)//item1 of step2 main algo. Simple, because rowId of mat are directly target ids.
00200         {
00201           for(std::vector< std::map<int,double> >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++)
00202             for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
00203               deno[rowId]+=(*it2).second;
00204         }
00205       else
00206         {//item0 of step2 main algo. More complicated.
00207           std::vector<int>::iterator fnd=isItem1;//std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),curSrcId);
00208           int locId=std::distance(_trg_proc_st2.begin(),fnd);
00209           const DataArrayInt *trgIds=_trg_ids_st2[locId];
00210           const int *trgIds2=trgIds->getConstPointer();
00211           for(std::vector< std::map<int,double> >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++)
00212             for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
00213               deno[trgIds2[rowId]]+=(*it2).second;
00214         }
00215     }
00216   //
00217   for(std::size_t i=0;i<sz1;i++)
00218     {
00219       int rowId=0;
00220       const std::vector< std::map<int,double> >& mat=_the_matrix_st[i];
00221       int curSrcId=_the_matrix_st_source_proc_id[i];
00222       std::vector<int>::iterator isItem1=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),curSrcId);
00223       std::vector< std::map<int,double> >& denoM=_the_deno_st[i];
00224       denoM.resize(mat.size());
00225       if(isItem1==_trg_proc_st2.end() || curSrcId==myProcId)//item1 of step2 main algo. Simple, because rowId of mat are directly target ids.
00226         {
00227           int rowId=0;
00228           for(std::vector< std::map<int,double> >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++)
00229             for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
00230               denoM[rowId][(*it2).first]=deno[rowId];
00231         }
00232       else
00233         {
00234           std::vector<int>::iterator fnd=isItem1;
00235           int locId=std::distance(_trg_proc_st2.begin(),fnd);
00236           const DataArrayInt *trgIds=_trg_ids_st2[locId];
00237           const int *trgIds2=trgIds->getConstPointer();
00238           for(std::vector< std::map<int,double> >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++)
00239             for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
00240               denoM[rowId][(*it2).first]=deno[trgIds2[rowId]];
00241         }
00242     }
00243 }
00244 
00251 void OverlapMapping::serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigArr, int *count, int *offsets,
00252                                             int *countForRecv, int *offsetsForRecv) const
00253 {
00254   int grpSize=_group.size();
00255   std::fill<int *>(count,count+grpSize,0);
00256   int szz=0;
00257   int myProcId=_group.myRank();
00258   for(std::size_t i=0;i<_matrixes_st.size();i++)
00259     {
00260       if(_source_proc_id_st[i]==myProcId)// && _target_proc_id_st[i]!=myProcId
00261         {
00262           count[_target_proc_id_st[i]]=_matrixes_st[i].size()+1;
00263           szz+=_matrixes_st[i].size()+1;
00264         }
00265     }
00266   bigArr=new int[szz];
00267   offsets[0]=0;
00268   for(int i=1;i<grpSize;i++)
00269     offsets[i]=offsets[i-1]+count[i-1];
00270   for(std::size_t i=0;i<_matrixes_st.size();i++)
00271     {
00272       if(_source_proc_id_st[i]==myProcId)
00273         {
00274           int start=offsets[_target_proc_id_st[i]];
00275           int *work=bigArr+start;
00276           *work=0;
00277           const std::vector< std::map<int,double> >& mat=_matrixes_st[i];
00278           for(std::vector< std::map<int,double> >::const_iterator it=mat.begin();it!=mat.end();it++,work++)
00279             work[1]=work[0]+(*it).size();
00280         }
00281     }
00282   //
00283   offsetsForRecv[0]=0;
00284   for(int i=0;i<grpSize;i++)
00285     {
00286       if(nbOfElemsSrc[i]>0)
00287         countForRecv[i]=nbOfElemsSrc[i]+1;
00288       else
00289         countForRecv[i]=0;
00290       if(i>0)
00291         offsetsForRecv[i]=offsetsForRecv[i-1]+countForRecv[i-1];
00292     }
00293 }
00294 
00298 int OverlapMapping::serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *recvStep0, const int *countStep0, const int *offsStep0,
00299                                            int *&bigArrI, double *&bigArrD, int *count, int *offsets,
00300                                            int *countForRecv, int *offsForRecv) const
00301 {
00302   int grpSize=_group.size();
00303   int myProcId=_group.myRank();
00304   offsForRecv[0]=0;
00305   int szz=0;
00306   for(int i=0;i<grpSize;i++)
00307     {
00308       if(nbOfElemsSrc[i]!=0)
00309         countForRecv[i]=recvStep0[offsStep0[i]+nbOfElemsSrc[i]];
00310       else
00311         countForRecv[i]=0;
00312       szz+=countForRecv[i];
00313       if(i>0)
00314         offsForRecv[i]=offsForRecv[i-1]+countForRecv[i-1];
00315     }
00316   //
00317   std::fill(count,count+grpSize,0);
00318   offsets[0]=0;
00319   int fullLgth=0;
00320   for(std::size_t i=0;i<_matrixes_st.size();i++)
00321     {
00322       if(_source_proc_id_st[i]==myProcId)
00323         {
00324           const std::vector< std::map<int,double> >& mat=_matrixes_st[i];
00325           int lgthToSend=0;
00326           for(std::vector< std::map<int,double> >::const_iterator it=mat.begin();it!=mat.end();it++)
00327             lgthToSend+=(*it).size();
00328           count[_target_proc_id_st[i]]=lgthToSend;
00329           fullLgth+=lgthToSend;
00330         }
00331     }
00332   for(int i=1;i<grpSize;i++)
00333     offsets[i]=offsets[i-1]+count[i-1];
00334   //
00335   bigArrI=new int[fullLgth];
00336   bigArrD=new double[fullLgth];
00337   // feeding arrays
00338   fullLgth=0;
00339   for(std::size_t i=0;i<_matrixes_st.size();i++)
00340     {
00341       if(_source_proc_id_st[i]==myProcId)
00342         {
00343           const std::vector< std::map<int,double> >& mat=_matrixes_st[i];
00344           for(std::vector< std::map<int,double> >::const_iterator it1=mat.begin();it1!=mat.end();it1++)
00345             {
00346               int j=0;
00347               for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,j++)
00348                 {
00349                   bigArrI[fullLgth+j]=(*it2).first;
00350                   bigArrD[fullLgth+j]=(*it2).second;
00351                 }
00352               fullLgth+=(*it1).size();
00353             }
00354         }
00355     }
00356   return szz;
00357 }
00358 
00366 void OverlapMapping::unserializationST(int nbOfTrgElems,
00367                                        const int *nbOfElemsSrcPerProc,//first all2all
00368                                        const int *bigArrRecv, const int *bigArrRecvCounts, const int *bigArrRecvOffs,//2nd all2all
00369                                        const int *bigArrRecv2, const double *bigArrDRecv2, const int *bigArrRecv2Count, const int *bigArrRecv2Offs)//3rd and 4th all2alls
00370 {
00371   _the_matrix_st.clear();
00372   _the_matrix_st_source_proc_id.clear();
00373   //
00374   int grpSize=_group.size();
00375   for(int i=0;i<grpSize;i++)
00376     if(nbOfElemsSrcPerProc[i]!=0)
00377       _the_matrix_st_source_proc_id.push_back(i);
00378   int nbOfPseudoProcs=_the_matrix_st_source_proc_id.size();//_the_matrix_st_target_proc_id.size() contains number of matrix fetched remotely whose sourceProcId==myProcId
00379   _the_matrix_st.resize(nbOfPseudoProcs);
00380   //
00381   int j=0;
00382   for(int i=0;i<grpSize;i++)
00383     if(nbOfElemsSrcPerProc[i]!=0)
00384       {
00385         _the_matrix_st[j].resize(nbOfElemsSrcPerProc[i]);
00386         for(int k=0;k<nbOfElemsSrcPerProc[i];k++)
00387           {
00388             int offs=bigArrRecv[bigArrRecvOffs[i]+k];
00389             int lgthOfMap=bigArrRecv[bigArrRecvOffs[i]+k+1]-offs;
00390             for(int l=0;l<lgthOfMap;l++)
00391               _the_matrix_st[j][k][bigArrRecv2[bigArrRecv2Offs[i]+offs+l]]=bigArrDRecv2[bigArrRecv2Offs[i]+offs+l];
00392           }
00393         j++;
00394       }
00395 }
00396 
00402 void OverlapMapping::finishToFillFinalMatrixST()
00403 {
00404   int myProcId=_group.myRank();
00405   int sz=_matrixes_st.size();
00406   int nbOfEntryToAdd=0;
00407   for(int i=0;i<sz;i++)
00408     if(_source_proc_id_st[i]!=myProcId)
00409       nbOfEntryToAdd++;
00410   if(nbOfEntryToAdd==0)
00411     return ;
00412   int oldNbOfEntry=_the_matrix_st.size();
00413   int newNbOfEntry=oldNbOfEntry+nbOfEntryToAdd;
00414   _the_matrix_st.resize(newNbOfEntry);
00415   int j=oldNbOfEntry;
00416   for(int i=0;i<sz;i++)
00417     if(_source_proc_id_st[i]!=myProcId)
00418       {
00419         const std::vector<std::map<int,double> >& mat=_matrixes_st[i];
00420         _the_matrix_st[j]=mat;
00421         _the_matrix_st_source_proc_id.push_back(_source_proc_id_st[i]);
00422         j++;
00423       }
00424   _matrixes_st.clear();
00425 }
00426 
00430 void OverlapMapping::prepareIdsToSendST()
00431 {
00432   CommInterface commInterface=_group.getCommInterface();
00433   const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group);
00434   const MPI_Comm *comm=group->getComm();
00435   int grpSize=_group.size();
00436   _source_ids_to_send_st.clear();
00437   _source_ids_to_send_st.resize(grpSize);
00438   INTERP_KERNEL::AutoPtr<int> nbsend=new int[grpSize];
00439   std::fill<int *>(nbsend,nbsend+grpSize,0);
00440   for(std::size_t i=0;i<_the_matrix_st_source_proc_id.size();i++)
00441     nbsend[_the_matrix_st_source_proc_id[i]]=_the_matrix_st_source_ids[i].size();
00442   INTERP_KERNEL::AutoPtr<int> nbrecv=new int[grpSize];
00443   commInterface.allToAll(nbsend,1,MPI_INT,nbrecv,1,MPI_INT,*comm);
00444   //
00445   INTERP_KERNEL::AutoPtr<int> nbsend2=new int[grpSize];
00446   std::copy((int *)nbsend,((int *)nbsend)+grpSize,(int *)nbsend2);
00447   INTERP_KERNEL::AutoPtr<int> nbsend3=new int[grpSize];
00448   nbsend3[0]=0;
00449   for(int i=1;i<grpSize;i++)
00450     nbsend3[i]=nbsend3[i-1]+nbsend2[i-1];
00451   int sendSz=nbsend3[grpSize-1]+nbsend2[grpSize-1];
00452   INTERP_KERNEL::AutoPtr<int> bigDataSend=new int[sendSz];
00453   for(std::size_t i=0;i<_the_matrix_st_source_proc_id.size();i++)
00454     {
00455       int offset=nbsend3[_the_matrix_st_source_proc_id[i]];
00456       std::copy(_the_matrix_st_source_ids[i].begin(),_the_matrix_st_source_ids[i].end(),((int *)nbsend3)+offset);
00457     }
00458   INTERP_KERNEL::AutoPtr<int> nbrecv2=new int[grpSize];
00459   INTERP_KERNEL::AutoPtr<int> nbrecv3=new int[grpSize];
00460   std::copy((int *)nbrecv,((int *)nbrecv)+grpSize,(int *)nbrecv2);
00461   nbrecv3[0]=0;
00462   for(int i=1;i<grpSize;i++)
00463     nbrecv3[i]=nbrecv3[i-1]+nbrecv2[i-1];
00464   int recvSz=nbrecv3[grpSize-1]+nbrecv2[grpSize-1];
00465   INTERP_KERNEL::AutoPtr<int> bigDataRecv=new int[recvSz];
00466   //
00467   commInterface.allToAllV(bigDataSend,nbsend2,nbsend3,MPI_INT,
00468                           bigDataRecv,nbrecv2,nbrecv3,MPI_INT,
00469                           *comm);
00470   for(int i=0;i<grpSize;i++)
00471     {
00472       if(nbrecv2[i]>0)
00473         {
00474           _source_ids_to_send_st[i].insert(_source_ids_to_send_st[i].end(),((int *)bigDataRecv)+nbrecv3[i],((int *)bigDataRecv)+nbrecv3[i]+nbrecv2[i]);
00475         }
00476     }
00477 }
00478 
00483 void OverlapMapping::multiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput) const
00484 {
00485   int nbOfCompo=fieldInput->getNumberOfComponents();//to improve same number of components to test
00486   CommInterface commInterface=_group.getCommInterface();
00487   const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group);
00488   const MPI_Comm *comm=group->getComm();
00489   int grpSize=_group.size();
00490   int myProcId=_group.myRank();
00491   //
00492   INTERP_KERNEL::AutoPtr<int> nbsend=new int[grpSize];
00493   INTERP_KERNEL::AutoPtr<int> nbsend2=new int[grpSize];
00494   INTERP_KERNEL::AutoPtr<int> nbrecv=new int[grpSize];
00495   INTERP_KERNEL::AutoPtr<int> nbrecv2=new int[grpSize];
00496   std::fill<int *>(nbsend,nbsend+grpSize,0);
00497   std::fill<int *>(nbrecv,nbrecv+grpSize,0);
00498   nbsend2[0]=0;
00499   nbrecv2[0]=0;
00500   std::vector<double> valsToSend;
00501   for(int i=0;i<grpSize;i++)
00502     {
00503       if(std::find(_proc_ids_to_send_vector_st.begin(),_proc_ids_to_send_vector_st.end(),i)!=_proc_ids_to_send_vector_st.end())
00504         {
00505           std::vector<int>::const_iterator isItem1=std::find(_src_proc_st2.begin(),_src_proc_st2.end(),i);
00506           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> vals;
00507           if(isItem1!=_src_proc_st2.end())//item1 of step2 main algo
00508             {
00509               int id=std::distance(_src_proc_st2.begin(),isItem1);
00510               vals=fieldInput->getArray()->selectByTupleId(_src_ids_st2[id]->getConstPointer(),_src_ids_st2[id]->getConstPointer()+_src_ids_st2[id]->getNumberOfTuples());
00511             }
00512           else
00513             {//item0 of step2 main algo
00514               int id=std::distance(_src_ids_zip_proc_st2.begin(),std::find(_src_ids_zip_proc_st2.begin(),_src_ids_zip_proc_st2.end(),i));
00515               vals=fieldInput->getArray()->selectByTupleId(&(_src_ids_zip_st2[id])[0],&(_src_ids_zip_st2[id])[0]+_src_ids_zip_st2[id].size());
00516             }
00517           nbsend[i]=vals->getNbOfElems();
00518           valsToSend.insert(valsToSend.end(),vals->getConstPointer(),vals->getConstPointer()+nbsend[i]);
00519         }
00520       if(std::find(_proc_ids_to_recv_vector_st.begin(),_proc_ids_to_recv_vector_st.end(),i)!=_proc_ids_to_recv_vector_st.end())
00521         {
00522           std::vector<int>::const_iterator isItem0=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),i);
00523           if(isItem0==_trg_proc_st2.end())//item1 of step2 main algo [ (0,1) computed on proc1 and Matrix-Vector on proc1 ]
00524             {
00525               std::vector<int>::const_iterator it1=std::find(_src_ids_proc_st2.begin(),_src_ids_proc_st2.end(),i);
00526               if(it1!=_src_ids_proc_st2.end())
00527                 {
00528                   int id=std::distance(_src_ids_proc_st2.begin(),it1);
00529                   nbrecv[i]=_nb_of_src_ids_proc_st2[id]*nbOfCompo;
00530                 }
00531               else if(i==myProcId)
00532                 {
00533                   nbrecv[i]=fieldInput->getNumberOfTuplesExpected()*nbOfCompo;
00534                 }
00535               else
00536                 throw INTERP_KERNEL::Exception("Plouff ! send email to anthony.geay@cea.fr ! ");
00537             }
00538           else
00539             {//item0 of step2 main algo [ (2,1) computed on proc2 but Matrix-Vector on proc1 ] [(1,0) computed on proc1 but Matrix-Vector on proc0]
00540               int id=std::distance(_src_ids_zip_proc_st2.begin(),std::find(_src_ids_zip_proc_st2.begin(),_src_ids_zip_proc_st2.end(),i));
00541               nbrecv[i]=_src_ids_zip_st2[id].size()*nbOfCompo;
00542             }
00543         }
00544     }
00545   for(int i=1;i<grpSize;i++)
00546     {
00547       nbsend2[i]=nbsend2[i-1]+nbsend[i-1];
00548       nbrecv2[i]=nbrecv2[i-1]+nbrecv[i-1];
00549     }
00550   INTERP_KERNEL::AutoPtr<double> bigArr=new double[nbrecv2[grpSize-1]+nbrecv[grpSize-1]];
00551   commInterface.allToAllV(&valsToSend[0],nbsend,nbsend2,MPI_DOUBLE,
00552                           bigArr,nbrecv,nbrecv2,MPI_DOUBLE,*comm);
00553   fieldOutput->getArray()->fillWithZero();
00554   INTERP_KERNEL::AutoPtr<double> tmp=new double[nbOfCompo];
00555   for(int i=0;i<grpSize;i++)
00556     {
00557       if(nbrecv[i]>0)
00558         {
00559           double *pt=fieldOutput->getArray()->getPointer();
00560           std::vector<int>::const_iterator it=std::find(_the_matrix_st_source_proc_id.begin(),_the_matrix_st_source_proc_id.end(),i);
00561           if(it==_the_matrix_st_source_proc_id.end())
00562             throw INTERP_KERNEL::Exception("Big problem !");
00563           int id=std::distance(_the_matrix_st_source_proc_id.begin(),it);
00564           const std::vector< std::map<int,double> >& mat=_the_matrix_st[id];
00565           const std::vector< std::map<int,double> >& deno=_the_deno_st[id];
00566           std::vector<int>::const_iterator isItem0=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),i);
00567           if(isItem0==_trg_proc_st2.end())//item1 of step2 main algo [ (0,1) computed on proc1 and Matrix-Vector on proc1 ]
00568             {
00569               int nbOfTrgTuples=mat.size();
00570               for(int j=0;j<nbOfTrgTuples;j++,pt+=nbOfCompo)
00571                 {
00572                   const std::map<int,double>& mat1=mat[j];
00573                   const std::map<int,double>& deno1=deno[j];
00574                   std::map<int,double>::const_iterator it4=deno1.begin();
00575                   for(std::map<int,double>::const_iterator it3=mat1.begin();it3!=mat1.end();it3++,it4++)
00576                     {
00577                       std::transform(bigArr+nbrecv2[i]+((*it3).first)*nbOfCompo,bigArr+nbrecv2[i]+((*it3).first+1)*(nbOfCompo),(double *)tmp,std::bind2nd(std::multiplies<double>(),(*it3).second/(*it4).second));
00578                       std::transform((double *)tmp,(double *)tmp+nbOfCompo,pt,pt,std::plus<double>());
00579                     }
00580                 }
00581             }
00582           else
00583             {//item0 of step2 main algo [ (2,1) computed on proc2 but Matrix-Vector on proc1 ]
00584               double *pt=fieldOutput->getArray()->getPointer();
00585               std::map<int,int> zipCor;
00586               int id=std::distance(_src_ids_zip_proc_st2.begin(),std::find(_src_ids_zip_proc_st2.begin(),_src_ids_zip_proc_st2.end(),i));
00587               const std::vector<int> zipIds=_src_ids_zip_st2[id];
00588               int newId=0;
00589               for(std::vector<int>::const_iterator it=zipIds.begin();it!=zipIds.end();it++,newId++)
00590                 zipCor[*it]=newId;
00591               int id2=std::distance(_trg_proc_st2.begin(),std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),i));
00592               const DataArrayInt *tgrIds=_trg_ids_st2[id2];
00593               const int *tgrIds2=tgrIds->getConstPointer();
00594               int nbOfTrgTuples=mat.size();
00595               for(int j=0;j<nbOfTrgTuples;j++)
00596                 {
00597                   const std::map<int,double>& mat1=mat[j];
00598                   const std::map<int,double>& deno1=deno[j];
00599                   std::map<int,double>::const_iterator it5=deno1.begin();
00600                   for(std::map<int,double>::const_iterator it3=mat1.begin();it3!=mat1.end();it3++,it5++)
00601                     {
00602                       std::map<int,int>::const_iterator it4=zipCor.find((*it3).first);
00603                       if(it4==zipCor.end())
00604                         throw INTERP_KERNEL::Exception("Hmmmmm send e mail to anthony.geay@cea.fr !");
00605                       std::transform(bigArr+nbrecv2[i]+((*it4).second)*nbOfCompo,bigArr+nbrecv2[i]+((*it4).second+1)*(nbOfCompo),(double *)tmp,std::bind2nd(std::multiplies<double>(),(*it3).second/(*it5).second));
00606                       std::transform((double *)tmp,(double *)tmp+nbOfCompo,pt+tgrIds2[j]*nbOfCompo,pt+tgrIds2[j]*nbOfCompo,std::plus<double>());
00607                     }
00608                 }
00609             }
00610         }
00611     }
00612 }
00613 
00618 void OverlapMapping::transposeMultiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput)
00619 {
00620 }
00621 
00626 void OverlapMapping::updateZipSourceIdsForFuture()
00627 {
00628   CommInterface commInterface=_group.getCommInterface();
00629   int myProcId=_group.myRank();
00630   int nbOfMatrixRecveived=_the_matrix_st_source_proc_id.size();
00631   for(int i=0;i<nbOfMatrixRecveived;i++)
00632     {
00633       int curSrcProcId=_the_matrix_st_source_proc_id[i];
00634       if(curSrcProcId!=myProcId)
00635         {
00636           const std::vector< std::map<int,double> >& mat=_the_matrix_st[i];
00637           _src_ids_zip_proc_st2.push_back(curSrcProcId);
00638           _src_ids_zip_st2.resize(_src_ids_zip_st2.size()+1);
00639           std::set<int> s;
00640           for(std::vector< std::map<int,double> >::const_iterator it1=mat.begin();it1!=mat.end();it1++)
00641             for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
00642               s.insert((*it2).first);
00643           _src_ids_zip_st2.back().insert(_src_ids_zip_st2.back().end(),s.begin(),s.end());
00644         }
00645     }
00646 }
00647 
00648 // #include <iostream>
00649 
00650 // void OverlapMapping::printTheMatrix() const
00651 // {
00652 //   CommInterface commInterface=_group.getCommInterface();
00653 //   const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group);
00654 //   const MPI_Comm *comm=group->getComm();
00655 //   int grpSize=_group.size();
00656 //   int myProcId=_group.myRank();
00657 //   std::cerr << "I am proc #" << myProcId << std::endl;
00658 //   int nbOfMat=_the_matrix_st.size();
00659 //   std::cerr << "I do manage " << nbOfMat << "matrix : "<< std::endl;
00660 //   for(int i=0;i<nbOfMat;i++)
00661 //     {
00662 //       std::cerr << "   - Matrix #" << i << " on source proc #" << _the_matrix_st_source_proc_id[i];
00663 //       const std::vector< std::map<int,double> >& locMat=_the_matrix_st[i];
00664 //       for(std::vector< std::map<int,double> >::const_iterator it1=locMat.begin();it1!=locMat.end();it1++)
00665 //         {
00666 //           for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
00667 //             std::cerr << "(" << (*it2).first << "," << (*it2).second << "), ";
00668 //           std::cerr << std::endl;
00669 //         }
00670 //     }
00671 //   std::cerr << "*********" << std::endl;
00672 // }