1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "OverlapDEC.hxx"
22 #include "CommInterface.hxx"
23 #include "ParaMESH.hxx"
24 #include "ParaFIELD.hxx"
25 #include "MPIProcessorGroup.hxx"
26 #include "OverlapElementLocator.hxx"
27 #include "OverlapInterpolationMatrix.hxx"
28 #include "ICoCoMEDField.hxx"
32 OverlapDEC::OverlapDEC(const std::set<int>& procIds, const MPI_Comm& world_comm):
33 _load_balancing_algo(1),
34 _own_group(true),_interpolation_matrix(0), _locator(0),
35 _default_field_value(0.0),
36 _source_field(0),_own_source_field(false),
37 _target_field(0),_own_target_field(false),
40 MEDCoupling::CommInterface comm;
41 int *ranks_world=new int[procIds.size()]; // ranks of sources and targets in world_comm
42 std::copy(procIds.begin(),procIds.end(),ranks_world);
43 MPI_Group group,world_group;
44 comm.commGroup(world_comm,&world_group);
45 comm.groupIncl(world_group,(int)procIds.size(),ranks_world,&group);
46 delete [] ranks_world;
47 comm.commCreate(world_comm,group,&_comm);
48 comm.groupFree(&group);
49 comm.groupFree(&world_group);
50 if(_comm==MPI_COMM_NULL)
55 std::set<int> idsUnion;
56 for(unsigned int i=0;i<procIds.size();i++)
58 _group=new MPIProcessorGroup(comm,idsUnion,_comm);
61 OverlapDEC::~OverlapDEC()
69 delete _interpolation_matrix;
71 if (_comm != MPI_COMM_NULL)
73 MEDCoupling::CommInterface comm;
74 comm.commFree(&_comm);
78 void OverlapDEC::sendRecvData(bool way)
86 void OverlapDEC::sendData()
88 _interpolation_matrix->multiply(_default_field_value);
91 void OverlapDEC::recvData()
93 throw INTERP_KERNEL::Exception("Not implemented yet !!!!");
94 //_interpolation_matrix->transposeMultiply();
97 void OverlapDEC::synchronize()
101 // Check number of components of field on both side (for now allowing void field/mesh on one proc is not allowed)
102 if (!_source_field || !_source_field->getField())
103 throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void source field on a proc is not allowed!");
104 if (!_target_field || !_target_field->getField())
105 throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void target field on a proc is not allowed!");
106 if (_target_field->getField()->getNumberOfComponents() != _source_field->getField()->getNumberOfComponents())
107 throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): source and target field have different number of components!");
108 delete _interpolation_matrix;
109 _locator = new OverlapElementLocator(_source_field,_target_field,*_group, getBoundingBoxAdjustmentAbs(), _load_balancing_algo);
110 _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this, *_locator);
111 _locator->copyOptions(*this);
112 _locator->exchangeMeshes(*_interpolation_matrix);
113 std::vector< std::pair<int,int> > jobs=_locator->getToDoList();
114 std::string srcMeth=_locator->getSourceMethod();
115 std::string trgMeth=_locator->getTargetMethod();
116 for(std::vector< std::pair<int,int> >::const_iterator it=jobs.begin();it!=jobs.end();it++)
118 const MEDCouplingPointSet *src=_locator->getSourceMesh((*it).first);
119 const DataArrayIdType *srcIds=_locator->getSourceIds((*it).first);
120 const MEDCouplingPointSet *trg=_locator->getTargetMesh((*it).second);
121 const DataArrayIdType *trgIds=_locator->getTargetIds((*it).second);
122 _interpolation_matrix->computeLocalIntersection(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second);
124 _interpolation_matrix->prepare(_locator->getProcsToSendFieldData());
125 _interpolation_matrix->computeSurfacesAndDeno();
128 void OverlapDEC::attachSourceLocalField(ParaFIELD *field, bool ownPt)
132 if(_own_source_field)
133 delete _source_field;
135 _own_source_field=ownPt;
138 void OverlapDEC::attachTargetLocalField(ParaFIELD *field, bool ownPt)
142 if(_own_target_field)
143 delete _target_field;
145 _own_target_field=ownPt;
148 void OverlapDEC::attachSourceLocalField(MEDCouplingFieldDouble *field)
153 ParaMESH *paramesh = new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())),
154 *_group,field->getMesh()->getName());
155 ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group);
156 tmpField->setOwnSupport(true);
157 attachSourceLocalField(tmpField,true);
160 void OverlapDEC::attachTargetLocalField(MEDCouplingFieldDouble *field)
165 ParaMESH *paramesh = new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())),
166 *_group,field->getMesh()->getName());
167 ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group);
168 tmpField->setOwnSupport(true);
169 attachTargetLocalField(tmpField,true);
172 void OverlapDEC::attachSourceLocalField(ICoCo::MEDField *field)
174 attachSourceLocalField(field->getField());
177 void OverlapDEC::attachTargetLocalField(ICoCo::MEDField *field)
179 attachTargetLocalField(field->getField());
182 bool OverlapDEC::isInGroup() const
186 return _group->containsMyRank();
189 void OverlapDEC::debugPrintWorkSharing(std::ostream & ostr) const
191 _locator->debugPrintWorkSharing(ostr);