Back to index

salome-med  6.5.0
OverlapDEC.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 "OverlapDEC.hxx"
00021 #include "CommInterface.hxx"
00022 #include "ParaFIELD.hxx"
00023 #include "MPIProcessorGroup.hxx"
00024 #include "OverlapElementLocator.hxx"
00025 #include "OverlapInterpolationMatrix.hxx"
00154 namespace ParaMEDMEM
00155 {
00156   OverlapDEC::OverlapDEC(const std::set<int>& procIds, const MPI_Comm& world_comm):_own_group(true),_interpolation_matrix(0),
00157                                                                                    _source_field(0),_own_source_field(false),
00158                                                                                    _target_field(0),_own_target_field(false)
00159   {
00160     ParaMEDMEM::CommInterface comm;
00161     int *ranks_world=new int[procIds.size()]; // ranks of sources and targets in world_comm
00162     std::copy(procIds.begin(),procIds.end(),ranks_world);
00163     MPI_Group group,world_group;
00164     comm.commGroup(world_comm,&world_group);
00165     comm.groupIncl(world_group,procIds.size(),ranks_world,&group);
00166     delete [] ranks_world;
00167     MPI_Comm theComm;
00168     comm.commCreate(world_comm,group,&theComm);
00169     comm.groupFree(&group);
00170     if(theComm==MPI_COMM_NULL)
00171       {
00172         _group=0;
00173         return ;
00174       }
00175     std::set<int> idsUnion;
00176     for(std::size_t i=0;i<procIds.size();i++)
00177       idsUnion.insert(i);
00178     _group=new MPIProcessorGroup(comm,idsUnion,theComm);
00179   }
00180 
00181   OverlapDEC::~OverlapDEC()
00182   {
00183     if(_own_group)
00184       delete _group;
00185     if(_own_source_field)
00186       delete _source_field;
00187     if(_own_target_field)
00188       delete _target_field;
00189     delete _interpolation_matrix;
00190   }
00191 
00192   void OverlapDEC::sendRecvData(bool way)
00193   {
00194     if(way)
00195       sendData();
00196     else
00197       recvData();
00198   }
00199 
00200   void OverlapDEC::sendData()
00201   {
00202     _interpolation_matrix->multiply();
00203   }
00204 
00205   void OverlapDEC::recvData()
00206   {
00207     throw INTERP_KERNEL::Exception("Not implemented yet !!!!");
00208     //_interpolation_matrix->transposeMultiply();
00209   }
00210   
00211   void OverlapDEC::synchronize()
00212   {
00213     if(!isInGroup())
00214       return ;
00215     delete _interpolation_matrix;
00216     _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this);
00217     OverlapElementLocator locator(_source_field,_target_field,*_group);
00218     locator.copyOptions(*this);
00219     locator.exchangeMeshes(*_interpolation_matrix);
00220     std::vector< std::pair<int,int> > jobs=locator.getToDoList();
00221     std::string srcMeth=locator.getSourceMethod();
00222     std::string trgMeth=locator.getTargetMethod();
00223     for(std::vector< std::pair<int,int> >::const_iterator it=jobs.begin();it!=jobs.end();it++)
00224       {
00225         const MEDCouplingPointSet *src=locator.getSourceMesh((*it).first);
00226         const DataArrayInt *srcIds=locator.getSourceIds((*it).first);
00227         const MEDCouplingPointSet *trg=locator.getTargetMesh((*it).second);
00228         const DataArrayInt *trgIds=locator.getTargetIds((*it).second);
00229         _interpolation_matrix->addContribution(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second);
00230       }
00231     _interpolation_matrix->prepare(locator.getProcsInInteraction());
00232     _interpolation_matrix->computeDeno();
00233   }
00234 
00235   void OverlapDEC::attachSourceLocalField(ParaFIELD *field, bool ownPt)
00236   {
00237     if(!isInGroup())
00238       return ;
00239     if(_own_source_field)
00240       delete _source_field;
00241     _source_field=field;
00242     _own_source_field=ownPt;
00243   }
00244 
00245   void OverlapDEC::attachTargetLocalField(ParaFIELD *field, bool ownPt)
00246   {
00247     if(!isInGroup())
00248       return ;
00249     if(_own_target_field)
00250       delete _target_field;
00251     _target_field=field;
00252     _own_target_field=ownPt;
00253   }
00254 
00255   bool OverlapDEC::isInGroup() const
00256   {
00257     if(!_group)
00258       return false;
00259     return _group->containsMyRank();
00260   }
00261 }