1 // Copyright (C) 2007-2024 CEA, EDF
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 "ICoCoMEDDoubleField.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()
66 /** Destructor involves MPI operations: make sure this is accessible from a proper
67 * method for Python wrapping.
69 void OverlapDEC::release()
79 _source_field = nullptr;
84 _target_field = nullptr;
86 delete _interpolation_matrix;
87 _interpolation_matrix = nullptr;
90 if (_comm != MPI_COMM_NULL)
92 MEDCoupling::CommInterface comm;
93 comm.commFree(&_comm);
95 _comm = MPI_COMM_NULL;
98 void OverlapDEC::sendRecvData(bool way)
106 void OverlapDEC::sendData()
108 _interpolation_matrix->multiply(_default_field_value);
111 void OverlapDEC::recvData()
113 throw INTERP_KERNEL::Exception("Not implemented yet !!!!");
114 //_interpolation_matrix->transposeMultiply();
117 void OverlapDEC::synchronize()
121 // Check number of components of field on both side (for now allowing void field/mesh on one proc is not allowed)
122 if (!_source_field || !_source_field->getField())
123 throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void source field on a proc is not allowed!");
124 if (!_target_field || !_target_field->getField())
125 throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void target field on a proc is not allowed!");
126 if (_target_field->getField()->getNumberOfComponents() != _source_field->getField()->getNumberOfComponents())
127 throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): source and target field have different number of components!");
128 delete _interpolation_matrix;
129 _locator = new OverlapElementLocator(_source_field,_target_field,*_group, getBoundingBoxAdjustmentAbs(), _load_balancing_algo);
130 _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this, *_locator);
131 _locator->copyOptions(*this);
132 _locator->exchangeMeshes(*_interpolation_matrix);
133 std::vector< std::pair<int,int> > jobs=_locator->getToDoList();
134 std::string srcMeth=_locator->getSourceMethod();
135 std::string trgMeth=_locator->getTargetMethod();
136 for(std::vector< std::pair<int,int> >::const_iterator it=jobs.begin();it!=jobs.end();it++)
138 const MEDCouplingPointSet *src=_locator->getSourceMesh((*it).first);
139 const DataArrayIdType *srcIds=_locator->getSourceIds((*it).first);
140 const MEDCouplingPointSet *trg=_locator->getTargetMesh((*it).second);
141 const DataArrayIdType *trgIds=_locator->getTargetIds((*it).second);
142 _interpolation_matrix->computeLocalIntersection(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second);
144 _interpolation_matrix->prepare(_locator->getProcsToSendFieldData());
145 _interpolation_matrix->computeSurfacesAndDeno();
148 void OverlapDEC::attachSourceLocalField(ParaFIELD *field, bool ownPt)
152 if(_own_source_field)
153 delete _source_field;
155 _own_source_field=ownPt;
158 void OverlapDEC::attachTargetLocalField(ParaFIELD *field, bool ownPt)
162 if(_own_target_field)
163 delete _target_field;
165 _own_target_field=ownPt;
168 void OverlapDEC::attachSourceLocalField(MEDCouplingFieldDouble *field)
173 ParaMESH *paramesh = new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())),
174 *_group,field->getMesh()->getName());
175 ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group);
176 tmpField->setOwnSupport(true);
177 attachSourceLocalField(tmpField,true);
180 void OverlapDEC::attachTargetLocalField(MEDCouplingFieldDouble *field)
185 ParaMESH *paramesh = new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())),
186 *_group,field->getMesh()->getName());
187 ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group);
188 tmpField->setOwnSupport(true);
189 attachTargetLocalField(tmpField,true);
192 void OverlapDEC::attachSourceLocalField(ICoCo::MEDDoubleField *field)
194 attachSourceLocalField(field->getMCField());
197 void OverlapDEC::attachTargetLocalField(ICoCo::MEDDoubleField *field)
199 attachTargetLocalField(field->getMCField());
202 bool OverlapDEC::isInGroup() const
206 return _group->containsMyRank();
209 void OverlapDEC::debugPrintWorkSharing(std::ostream & ostr) const
211 _locator->debugPrintWorkSharing(ostr);