X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FParaMEDMEM%2FOverlapDEC.cxx;h=ff6c7e2c018960cf339603e58722981669c8639d;hb=a5a009e0d290b13f262ba4f251dd20d1c7acb20d;hp=09253d350770d8af062bb9dfcabda9d078d031f1;hpb=c9020954af7fe85dd75b34e5ea7951b0f1f4cb25;p=tools%2Fmedcoupling.git diff --git a/src/ParaMEDMEM/OverlapDEC.cxx b/src/ParaMEDMEM/OverlapDEC.cxx index 09253d350..ff6c7e2c0 100644 --- a/src/ParaMEDMEM/OverlapDEC.cxx +++ b/src/ParaMEDMEM/OverlapDEC.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,12 +20,13 @@ #include "OverlapDEC.hxx" #include "CommInterface.hxx" +#include "ParaMESH.hxx" #include "ParaFIELD.hxx" #include "MPIProcessorGroup.hxx" #include "OverlapElementLocator.hxx" #include "OverlapInterpolationMatrix.hxx" -namespace ParaMEDMEM +namespace MEDCoupling { /*! \anchor OverlapDEC-det @@ -53,8 +54,7 @@ namespace ParaMEDMEM \anchor ParaMEDMEMOverlapDECImgTest1 \image html OverlapDEC1.png "Example split of the source and target mesh among the 3 procs" - \subsection ParaMEDMEMOverlapDECAlgoStep1 Step 1 : Bounding box exchange and global interaction - between procs computation. + \subsection ParaMEDMEMOverlapDECAlgoStep1 Step 1 : Bounding box exchange and global interaction between procs computation. In order to reduce as much as possible the amount of communications between distant processors, every processor computes a bounding box for A and B. Then a AllToAll communication is performed @@ -71,7 +71,7 @@ namespace ParaMEDMEM Here the pair (0,2) does not appear because the bounding box of fieldtemplateA of proc#2 does not intersect that of fieldtemplate B on proc#0. - Stage performed by ParaMEDMEM::OverlapElementLocator::computeBoundingBoxes. + Stage performed by MEDCoupling::OverlapElementLocator::computeBoundingBoxes. \subsection ParaMEDMEMOverlapDECAlgoStep2 Step 2 : Computation of local TODO list @@ -156,7 +156,7 @@ namespace ParaMEDMEM keep track of the ids sent to proc \#m for te matrix-vector computation. This is incarnated by OverlapMapping::keepTracksOfSourceIds in proc k. - This step is performed in ParaMEDMEM::OverlapElementLocator::exchangeMeshes method. + This step is performed in MEDCoupling::OverlapElementLocator::exchangeMeshes method. \subsection ParaMEDMEMOverlapDECAlgoStep4 Step 4 : Computation of the interpolation matrix @@ -166,7 +166,7 @@ namespace ParaMEDMEM the \b local TODO list per proc is expected to be as well balanced as possible. - The interpolation is performed as the \ref ParaMEDMEM::MEDCouplingRemapper "remapper" does. + The interpolation is performed as the \ref MEDCoupling::MEDCouplingRemapper "remapper" does. This operation is performed by OverlapInterpolationMatrix::addContribution method. @@ -184,7 +184,7 @@ namespace ParaMEDMEM is equal to k. After this step, the matrix repartition is the following after a call to - ParaMEDMEM::OverlapMapping::prepare : + MEDCoupling::OverlapMapping::prepare : - proc\#0 : (0,0),(1,0),(2,0) - proc\#1 : (0,1),(2,1) @@ -194,27 +194,29 @@ namespace ParaMEDMEM "prepare". This is an example of item 0 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". Tuple (0,1) computed on proc 1 is stored in proc 1 too. This is an example of item 1 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". - In the end ParaMEDMEM::OverlapMapping::_proc_ids_to_send_vector_st will contain : + In the end MEDCoupling::OverlapMapping::_proc_ids_to_send_vector_st will contain : - Proc\#0 : 0,1 - Proc\#1 : 0,2 - Proc\#2 : 0,1,2 - In the end ParaMEDMEM::OverlapMapping::_proc_ids_to_recv_vector_st will contain : + In the end MEDCoupling::OverlapMapping::_proc_ids_to_recv_vector_st will contain : - Proc\#0 : 0,1,2 - Proc\#1 : 0,2 - Proc\#2 : 1,2 - The method in charge to perform this is : ParaMEDMEM::OverlapMapping::prepare. + The method in charge to perform this is : MEDCoupling::OverlapMapping::prepare. */ OverlapDEC::OverlapDEC(const std::set& procIds, const MPI_Comm& world_comm): - _own_group(true),_interpolation_matrix(0), + _load_balancing_algo(1), + _own_group(true),_interpolation_matrix(0), _locator(0), _source_field(0),_own_source_field(false), _target_field(0),_own_target_field(false), + _default_field_value(0.0), _comm(MPI_COMM_NULL) { - ParaMEDMEM::CommInterface comm; + MEDCoupling::CommInterface comm; int *ranks_world=new int[procIds.size()]; // ranks of sources and targets in world_comm std::copy(procIds.begin(),procIds.end(),ranks_world); MPI_Group group,world_group; @@ -244,9 +246,10 @@ namespace ParaMEDMEM if(_own_target_field) delete _target_field; delete _interpolation_matrix; + delete _locator; if (_comm != MPI_COMM_NULL) { - ParaMEDMEM::CommInterface comm; + MEDCoupling::CommInterface comm; comm.commFree(&_comm); } } @@ -261,7 +264,7 @@ namespace ParaMEDMEM void OverlapDEC::sendData() { - _interpolation_matrix->multiply(); + _interpolation_matrix->multiply(_default_field_value); } void OverlapDEC::recvData() @@ -274,24 +277,31 @@ namespace ParaMEDMEM { if(!isInGroup()) return ; + // Check number of components of field on both side (for now allowing void field/mesh on one proc is not allowed) + if (!_source_field || !_source_field->getField()) + throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void source field on a proc is not allowed!"); + if (!_target_field || !_target_field->getField()) + throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void target field on a proc is not allowed!"); + if (_target_field->getField()->getNumberOfComponents() != _source_field->getField()->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): source and target field have different number of components!"); delete _interpolation_matrix; - _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this); - OverlapElementLocator locator(_source_field,_target_field,*_group); - locator.copyOptions(*this); - locator.exchangeMeshes(*_interpolation_matrix); - std::vector< std::pair > jobs=locator.getToDoList(); - std::string srcMeth=locator.getSourceMethod(); - std::string trgMeth=locator.getTargetMethod(); + _locator = new OverlapElementLocator(_source_field,_target_field,*_group, getBoundingBoxAdjustmentAbs(), _load_balancing_algo); + _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this, *_locator); + _locator->copyOptions(*this); + _locator->exchangeMeshes(*_interpolation_matrix); + std::vector< std::pair > jobs=_locator->getToDoList(); + std::string srcMeth=_locator->getSourceMethod(); + std::string trgMeth=_locator->getTargetMethod(); for(std::vector< std::pair >::const_iterator it=jobs.begin();it!=jobs.end();it++) { - const MEDCouplingPointSet *src=locator.getSourceMesh((*it).first); - const DataArrayInt *srcIds=locator.getSourceIds((*it).first); - const MEDCouplingPointSet *trg=locator.getTargetMesh((*it).second); - const DataArrayInt *trgIds=locator.getTargetIds((*it).second); - _interpolation_matrix->addContribution(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second); + const MEDCouplingPointSet *src=_locator->getSourceMesh((*it).first); + const DataArrayInt *srcIds=_locator->getSourceIds((*it).first); + const MEDCouplingPointSet *trg=_locator->getTargetMesh((*it).second); + const DataArrayInt *trgIds=_locator->getTargetIds((*it).second); + _interpolation_matrix->computeLocalIntersection(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second); } - _interpolation_matrix->prepare(locator.getProcsInInteraction()); - _interpolation_matrix->computeDeno(); + _interpolation_matrix->prepare(_locator->getProcsToSendFieldData()); + _interpolation_matrix->computeSurfacesAndDeno(); } void OverlapDEC::attachSourceLocalField(ParaFIELD *field, bool ownPt) @@ -314,10 +324,39 @@ namespace ParaMEDMEM _own_target_field=ownPt; } + void OverlapDEC::attachSourceLocalField(MEDCouplingFieldDouble *field) + { + if(!isInGroup()) + return ; + + ParaMESH *paramesh = new ParaMESH(static_cast(const_cast(field->getMesh())), + *_group,field->getMesh()->getName()); + ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group); + tmpField->setOwnSupport(true); + attachSourceLocalField(tmpField,true); + } + + void OverlapDEC::attachTargetLocalField(MEDCouplingFieldDouble *field) + { + if(!isInGroup()) + return ; + + ParaMESH *paramesh = new ParaMESH(static_cast(const_cast(field->getMesh())), + *_group,field->getMesh()->getName()); + ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group); + tmpField->setOwnSupport(true); + attachTargetLocalField(tmpField,true); + } + bool OverlapDEC::isInGroup() const { if(!_group) return false; return _group->containsMyRank(); } + + void OverlapDEC::debugPrintWorkSharing(std::ostream & ostr) const + { + _locator->debugPrintWorkSharing(ostr); + } }