From: ageay Date: Tue, 25 Aug 2009 13:33:12 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: V5_1_main_FINAL~357 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=920b18abe8135d2368c327911366fa42e678d08f;p=tools%2Fmedcoupling.git *** empty log message *** --- diff --git a/src/ParaMEDMEM/BASICS_JR b/src/ParaMEDMEM/BASICS_JR index af82fda16..61a724d45 100644 --- a/src/ParaMEDMEM/BASICS_JR +++ b/src/ParaMEDMEM/BASICS_JR @@ -296,7 +296,7 @@ Presentation-ParaMEDMEM : mode de fonctionnement reste naturellement disponible. . Cela repose sur trois nouvelles options creees avec registerOption - dans le constructeur de IntersectionDEC : + dans le constructeur de InterpKernelDEC : + Asynchronous : true ou false (par defaut) + TimeInterpolation : WithoutTimeInterp (par defaut) ou LinearTimeInterp typedef enum{WithoutTimeInterp,LinearTimeInterp} TimeInterpolationMethod; @@ -306,7 +306,7 @@ Presentation-ParaMEDMEM : dans MxN_Mapping.hxx . Le choix des options se fait avec le Data Exchange Channel : - + ParaMEDMEM::IntersectionDEC dec (*source_group,*target_group); + + ParaMEDMEM::InterpKernelDEC dec (*source_group,*target_group); + dec.setOption("Asynchronous",true); + dec.setOption("TimeInterpolation",LinearTimeInterp); + dec.setOption("AllToAllMethod",PointToPoint); @@ -321,17 +321,17 @@ Presentation-ParaMEDMEM : et TimeInterpolation : methodes Asynchronous et SetTimeInterpolator de MPI_AccessDEC. -. ParaMEDMEM::IntersectionDEC comporte maintenant une surcharge des +. ParaMEDMEM::InterpKernelDEC comporte maintenant une surcharge des methodes recvData() et sendData() : - + void IntersectionDEC::recvData( double time ) qui appelle + + void InterpKernelDEC::recvData( double time ) qui appelle SetTime(time) de MPI_AccessDEC et recvData() - + void IntersectionDEC::sendData( double time , double deltatime ) + + void InterpKernelDEC::sendData( double time , double deltatime ) qui appelle SetTime(time,deltatime) de MPI_AccessDEC et sendData() -. recvData() et sendData() de ParaMEDMEM::IntersectionDEC +. recvData() et sendData() de ParaMEDMEM::InterpKernelDEC appellent multiply et transposeMultiply de l'InterpolationMatrix qui appellent sendRecv et reverseSendRecv de MxN_Mapping qui appellent comm_interface.allToAllV en mode "Native" diff --git a/src/ParaMEDMEM/DEC.cxx b/src/ParaMEDMEM/DEC.cxx index c488d6b8d..c564438bb 100644 --- a/src/ParaMEDMEM/DEC.cxx +++ b/src/ParaMEDMEM/DEC.cxx @@ -55,7 +55,7 @@ The following code excerpt shows how to set options for an object that inherits from DEC : \code - IntersectionDEC dec(source_group,target_group); + InterpKernelDEC dec(source_group,target_group); dec.setOptions("ForcedRenormalization",true); dec.attachLocalField(field); dec.synchronize(); diff --git a/src/ParaMEDMEM/InterpKernelDEC.cxx b/src/ParaMEDMEM/InterpKernelDEC.cxx new file mode 100644 index 000000000..6badf5117 --- /dev/null +++ b/src/ParaMEDMEM/InterpKernelDEC.cxx @@ -0,0 +1,274 @@ +// Copyright (C) 2007-2008 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include +#include "CommInterface.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" +#include "ParaFIELD.hxx" +#include "MPIProcessorGroup.hxx" +#include "ParaMESH.hxx" +#include "DEC.hxx" +#include "InterpolationMatrix.hxx" +#include "InterpKernelDEC.hxx" +#include "ElementLocator.hxx" + +namespace ParaMEDMEM +{ + + /*! + \defgroup interpkerneldec InterpKernelDEC + + \section overview Overview + + The InterpKernelDEC enables the \ref conservativeremapping of fields between two parallel codes. This remapping is based on the computation of intersection volumes between elements from code A and elements from code B. The computation is possible for 3D meshes, 2D meshes, and 3D-surface meshes. Dimensions must be similar for code A and code B (for instance, though it could be desirable, it is not yet possible to couple 3D surfaces with 2D surfaces). + + In the present version, only fields lying on elements are considered. + + \image html NonCoincident_small.png "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on quadrangles are weighted by their intersection area and summed." + + \image latex NonCoincident_small.eps "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on quadrangles are weighted by their intersection area and summed." + + A typical use of InterpKernelDEC encompasses two distinct phases : + - A setup phase during which the intersection volumes are computed and the communication structures are setup. This corresponds to calling the InterpKernelDEC::synchronize() method. + - A use phase during which the remappings are actually performed. This corresponds to the calls to sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous in the current version of the library so that recvData() and sendData() calls must be synchronized on code A and code B processor groups. + + The following code excerpt illutrates a typical use of the InterpKernelDEC class. + + \code + ... + InterpKernelDEC dec(groupA, groupB); + dec.attachLocalField(field); + dec.synchronize(); + if (groupA.containsMyRank()) + dec.recvData(); + else if (groupB.containsMyRank()) + dec.sendData(); + ... + \endcode + A \ref conservativeremapping of the field from the source mesh to the target mesh is performed by the function synchronise(), which computes the \ref remappingmatrix. + + Computing the field on the receiving side can be expressed in terms of a matrix-vector product : \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t \f$ the field on the target side and \f$ \phi_s \f$ the field on the source side. + When remapping a 3D surface to another 3D surface, a projection phase is necessary to match elements from both sides. Care must be taken when defining this projection to obtain a \ref conservative remapping. + + In the P0-P0 case, this matrix is a plain rectangular matrix with coefficients equal to the intersection areas between triangle and quadrangles. For instance, in the above figure, the matrix is : + + \f[ + \begin{tabular}{|cccc|} + 0.72 & 0 & 0.2 & 0 \\ + 0.46 & 0 & 0.51 & 0.03\\ + 0.42 & 0.53 & 0 & 0.05\\ + 0 & 0 & 0.92 & 0.05 \\ + \end{tabular} + \f] + + + + \section interpkerneldec_options Options + On top of \ref dec_options, options supported by %InterpKernelDEC objects are + related to the underlying Intersector class. + All the options available in the intersector objects are + available for the %InterpKernelDEC object. The various options available for * intersectors can be reviewed in \ref InterpKerIntersectors. + + For instance : + \verbatim + InterpKernelDEC dec(source_group, target_group); + dec.attachLocalField(field); + dec.setOptions("DoRotate",false); + dec.setOptions("Precision",1e-12); + dec.synchronize(); + \endverbatim + + \warning{ Options must be set before calling the synchronize method. } + */ + + /*! + \addtogroup interpkerneldec + @{ + */ + + InterpKernelDEC::InterpKernelDEC() + { + } + + /*! + This constructor creates an InterpKernelDEC which has \a source_group as a working side + and \a target_group as an idle side. All the processors will actually participate, but intersection computations will be performed on the working side during the \a synchronize() phase. + The constructor must be called synchronously on all processors of both processor groups. + + \param source_group working side ProcessorGroup + \param target_group lazy side ProcessorGroup + + */ + InterpKernelDEC::InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group): + DEC(source_group, target_group),_interpolation_matrix(0) + { + + } + + InterpKernelDEC::~InterpKernelDEC() + { + if (_interpolation_matrix !=0) + delete _interpolation_matrix; + } + + /*! + \brief Synchronization process for exchanging topologies. + + This method prepares all the structures necessary for sending data from a processor group to the other. It uses the mesh underlying the fields that have been set with attachLocalField method. + It works in four steps : + -# Bounding boxes are computed for each subdomain, + -# The lazy side mesh parts that are likely to intersect the working side local processor are sent to the working side, + -# The working side calls the interpolation kernel to compute the intersection between local and imported mesh. + -# The lazy side is updated so that it knows the structure of the data that will be sent by + the working side during a \a sendData() call. + + */ + void InterpKernelDEC::synchronize() + { + delete _interpolation_matrix; + _interpolation_matrix = new InterpolationMatrix (_local_field, *_source_group,*_target_group,*this,*this); + + //setting up the communication DEC on both sides + if (_source_group->containsMyRank()) + { + //locate the distant meshes + ElementLocator locator(*_local_field, *_target_group, *_source_group); + + //transfering option from InterpKernelDEC to ElementLocator + locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); + + MEDCouplingPointSet* distant_mesh=0; + int* distant_ids=0; + std::string distantMeth; + for (int i=0; i<_target_group->size(); i++) + { + // int idistant_proc = (i+_source_group->myRank())%_target_group->size(); + int idistant_proc=i; + + //gathers pieces of the target meshes that can intersect the local mesh + locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); + if (distant_mesh !=0) + { + locator.exchangeMethod(_method,idistant_proc,distantMeth); + //adds the contribution of the distant mesh on the local one + int idistant_proc_in_union=_union_group->translateRank(_target_group,idistant_proc); + std::cout <<"add contribution from proc "<myRank()<addContribution(*distant_mesh,idistant_proc_in_union,distant_ids,_method,distantMeth); + distant_mesh->decrRef(); + delete[] distant_ids; + distant_mesh=0; + distant_ids=0; + } + } + _interpolation_matrix->finishContributionW(locator); + } + + if (_target_group->containsMyRank()) + { + ElementLocator locator(*_local_field, *_source_group, *_target_group); + //transfering option from InterpKernelDEC to ElementLocator + locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); + + MEDCouplingPointSet* distant_mesh=0; + int* distant_ids=0; + for (int i=0; i<_source_group->size(); i++) + { + // int idistant_proc = (i+_target_group->myRank())%_source_group->size(); + int idistant_proc=i; + //gathers pieces of the target meshes that can intersect the local mesh + locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); + std::cout << " Data sent from "<<_union_group->myRank()<<" to source proc "<< idistant_proc<decrRef(); + delete[] distant_ids; + distant_mesh=0; + distant_ids=0; + } + } + _interpolation_matrix->finishContributionL(locator); + } + _interpolation_matrix->prepare(); + } + + + /*! + Receives the data whether the processor is on the working side or on the lazy side. It must match a \a sendData() call on the other side. + */ + void InterpKernelDEC::recvData() + { + if (_source_group->containsMyRank()) + _interpolation_matrix->transposeMultiply(*_local_field->getField()); + else if (_target_group->containsMyRank()) + { + _interpolation_matrix->multiply(*_local_field->getField()); + if (getForcedRenormalization()) + renormalizeTargetField(); + } + } + + + /*! + Receives the data at time \a time in asynchronous mode. The value of the field + will be time-interpolated from the field values received. + \param time time at which the value is desired + */ + void InterpKernelDEC::recvData( double time ) + { + _interpolation_matrix->getAccessDEC()->setTime(time); + recvData() ; + } + + /*! + Sends the data whether the processor is on the working side or on the lazy side. + It must match a recvData() call on the other side. + */ + void InterpKernelDEC::sendData() + { + if (_source_group->containsMyRank()) + { + + _interpolation_matrix->multiply(*_local_field->getField()); + if (getForcedRenormalization()) + renormalizeTargetField(); + + } + else if (_target_group->containsMyRank()) + _interpolation_matrix->transposeMultiply(*_local_field->getField()); + } + + /*! + Sends the data available at time \a time in asynchronous mode. + \param time time at which the value is available + \param deltatime time interval between the value presently sent and the next one. + */ + void InterpKernelDEC::sendData( double time , double deltatime ) + { + _interpolation_matrix->getAccessDEC()->setTime(time,deltatime); + sendData() ; + } + + /*! + @} + */ + +} diff --git a/src/ParaMEDMEM/InterpKernelDEC.hxx b/src/ParaMEDMEM/InterpKernelDEC.hxx new file mode 100644 index 000000000..e33b031d4 --- /dev/null +++ b/src/ParaMEDMEM/InterpKernelDEC.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2008 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef __INTERPKERNELDEC_HXX__ +#define __INTERPKERNELDEC_HXX__ + +#include "DEC.hxx" +#include "MxN_Mapping.hxx" +#include "InterpolationOptions.hxx" + +namespace ParaMEDMEM +{ + class InterpolationMatrix; + + class InterpKernelDEC : public DEC, public INTERP_KERNEL::InterpolationOptions + { + public: + InterpKernelDEC(); + InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group); + virtual ~InterpKernelDEC(); + void synchronize(); + void recvData(); + void recvData(double time); + void sendData(); + void sendData(double time , double deltatime); + void prepareSourceDE() { } + void prepareTargetDE() { } + private : + //Number of distant points to be located locally + int _nb_distant_points; + //coordinates of distant points + const double* _distant_coords; + //local element number containing the distant points + const int* _distant_locations; + InterpolationMatrix* _interpolation_matrix; + }; +} + +#endif diff --git a/src/ParaMEDMEM/IntersectionDEC.cxx b/src/ParaMEDMEM/IntersectionDEC.cxx deleted file mode 100644 index b080ab51f..000000000 --- a/src/ParaMEDMEM/IntersectionDEC.cxx +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (C) 2007-2008 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 -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#include -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ParaFIELD.hxx" -#include "MPIProcessorGroup.hxx" -#include "ParaMESH.hxx" -#include "DEC.hxx" -#include "InterpolationMatrix.hxx" -#include "IntersectionDEC.hxx" -#include "ElementLocator.hxx" - -namespace ParaMEDMEM -{ - - /*! - \defgroup intersectiondec IntersectionDEC - - \section overview Overview - - The IntersectionDEC enables the \ref conservativeremapping of fields between two parallel codes. This remapping is based on the computation of intersection volumes between elements from code A and elements from code B. The computation is possible for 3D meshes, 2D meshes, and 3D-surface meshes. Dimensions must be similar for code A and code B (for instance, though it could be desirable, it is not yet possible to couple 3D surfaces with 2D surfaces). - - In the present version, only fields lying on elements are considered. - - \image html NonCoincident_small.png "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on quadrangles are weighted by their intersection area and summed." - - \image latex NonCoincident_small.eps "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on quadrangles are weighted by their intersection area and summed." - - A typical use of IntersectionDEC encompasses two distinct phases : - - A setup phase during which the intersection volumes are computed and the communication structures are setup. This corresponds to calling the IntersectionDEC::synchronize() method. - - A use phase during which the remappings are actually performed. This corresponds to the calls to sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous in the current version of the library so that recvData() and sendData() calls must be synchronized on code A and code B processor groups. - - The following code excerpt illutrates a typical use of the IntersectionDEC class. - - \code - ... - IntersectionDEC dec(groupA, groupB); - dec.attachLocalField(field); - dec.synchronize(); - if (groupA.containsMyRank()) - dec.recvData(); - else if (groupB.containsMyRank()) - dec.sendData(); - ... - \endcode - A \ref conservativeremapping of the field from the source mesh to the target mesh is performed by the function synchronise(), which computes the \ref remappingmatrix. - - Computing the field on the receiving side can be expressed in terms of a matrix-vector product : \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t \f$ the field on the target side and \f$ \phi_s \f$ the field on the source side. - When remapping a 3D surface to another 3D surface, a projection phase is necessary to match elements from both sides. Care must be taken when defining this projection to obtain a \ref conservative remapping. - - In the P0-P0 case, this matrix is a plain rectangular matrix with coefficients equal to the intersection areas between triangle and quadrangles. For instance, in the above figure, the matrix is : - - \f[ - \begin{tabular}{|cccc|} - 0.72 & 0 & 0.2 & 0 \\ - 0.46 & 0 & 0.51 & 0.03\\ - 0.42 & 0.53 & 0 & 0.05\\ - 0 & 0 & 0.92 & 0.05 \\ - \end{tabular} - \f] - - - - \section intersectiondec_options Options - On top of \ref dec_options, options supported by %IntersectionDEC objects are - related to the underlying Intersector class. - All the options available in the intersector objects are - available for the %IntersectionDEC object. The various options available for * intersectors can be reviewed in \ref InterpKerIntersectors. - - For instance : - \verbatim - IntersectionDEC dec(source_group, target_group); - dec.attachLocalField(field); - dec.setOptions("DoRotate",false); - dec.setOptions("Precision",1e-12); - dec.synchronize(); - \endverbatim - - \warning{ Options must be set before calling the synchronize method. } - */ - - /*! - \addtogroup intersectiondec - @{ - */ - - IntersectionDEC::IntersectionDEC() - { - } - - /*! - This constructor creates an IntersectionDEC which has \a source_group as a working side - and \a target_group as an idle side. All the processors will actually participate, but intersection computations will be performed on the working side during the \a synchronize() phase. - The constructor must be called synchronously on all processors of both processor groups. - - \param source_group working side ProcessorGroup - \param target_group lazy side ProcessorGroup - - */ - IntersectionDEC::IntersectionDEC(ProcessorGroup& source_group, ProcessorGroup& target_group): - DEC(source_group, target_group),_interpolation_matrix(0) - { - - } - - IntersectionDEC::~IntersectionDEC() - { - if (_interpolation_matrix !=0) - delete _interpolation_matrix; - } - - /*! - \brief Synchronization process for exchanging topologies. - - This method prepares all the structures necessary for sending data from a processor group to the other. It uses the mesh underlying the fields that have been set with attachLocalField method. - It works in four steps : - -# Bounding boxes are computed for each subdomain, - -# The lazy side mesh parts that are likely to intersect the working side local processor are sent to the working side, - -# The working side calls the interpolation kernel to compute the intersection between local and imported mesh. - -# The lazy side is updated so that it knows the structure of the data that will be sent by - the working side during a \a sendData() call. - - */ - void IntersectionDEC::synchronize() - { - delete _interpolation_matrix; - _interpolation_matrix = new InterpolationMatrix (_local_field, *_source_group,*_target_group,*this,*this); - - //setting up the communication DEC on both sides - if (_source_group->containsMyRank()) - { - //locate the distant meshes - ElementLocator locator(*_local_field, *_target_group, *_source_group); - - //transfering option from IntersectionDEC to ElementLocator - locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); - - MEDCouplingPointSet* distant_mesh=0; - int* distant_ids=0; - std::string distantMeth; - for (int i=0; i<_target_group->size(); i++) - { - // int idistant_proc = (i+_source_group->myRank())%_target_group->size(); - int idistant_proc=i; - - //gathers pieces of the target meshes that can intersect the local mesh - locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); - if (distant_mesh !=0) - { - locator.exchangeMethod(_method,idistant_proc,distantMeth); - //adds the contribution of the distant mesh on the local one - int idistant_proc_in_union=_union_group->translateRank(_target_group,idistant_proc); - std::cout <<"add contribution from proc "<myRank()<addContribution(*distant_mesh,idistant_proc_in_union,distant_ids,_method,distantMeth); - distant_mesh->decrRef(); - delete[] distant_ids; - distant_mesh=0; - distant_ids=0; - } - } - _interpolation_matrix->finishContributionW(locator); - } - - if (_target_group->containsMyRank()) - { - ElementLocator locator(*_local_field, *_source_group, *_target_group); - //transfering option from IntersectionDEC to ElementLocator - locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); - - MEDCouplingPointSet* distant_mesh=0; - int* distant_ids=0; - for (int i=0; i<_source_group->size(); i++) - { - // int idistant_proc = (i+_target_group->myRank())%_source_group->size(); - int idistant_proc=i; - //gathers pieces of the target meshes that can intersect the local mesh - locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); - std::cout << " Data sent from "<<_union_group->myRank()<<" to source proc "<< idistant_proc<decrRef(); - delete[] distant_ids; - distant_mesh=0; - distant_ids=0; - } - } - _interpolation_matrix->finishContributionL(locator); - } - _interpolation_matrix->prepare(); - } - - - /*! - Receives the data whether the processor is on the working side or on the lazy side. It must match a \a sendData() call on the other side. - */ - void IntersectionDEC::recvData() - { - if (_source_group->containsMyRank()) - _interpolation_matrix->transposeMultiply(*_local_field->getField()); - else if (_target_group->containsMyRank()) - { - _interpolation_matrix->multiply(*_local_field->getField()); - if (getForcedRenormalization()) - renormalizeTargetField(); - } - } - - - /*! - Receives the data at time \a time in asynchronous mode. The value of the field - will be time-interpolated from the field values received. - \param time time at which the value is desired - */ - void IntersectionDEC::recvData( double time ) - { - _interpolation_matrix->getAccessDEC()->setTime(time); - recvData() ; - } - - /*! - Sends the data whether the processor is on the working side or on the lazy side. - It must match a recvData() call on the other side. - */ - void IntersectionDEC::sendData() - { - if (_source_group->containsMyRank()) - { - - _interpolation_matrix->multiply(*_local_field->getField()); - if (getForcedRenormalization()) - renormalizeTargetField(); - - } - else if (_target_group->containsMyRank()) - _interpolation_matrix->transposeMultiply(*_local_field->getField()); - } - - /*! - Sends the data available at time \a time in asynchronous mode. - \param time time at which the value is available - \param deltatime time interval between the value presently sent and the next one. - */ - void IntersectionDEC::sendData( double time , double deltatime ) - { - _interpolation_matrix->getAccessDEC()->setTime(time,deltatime); - sendData() ; - } - - /*! - @} - */ - -} diff --git a/src/ParaMEDMEM/IntersectionDEC.hxx b/src/ParaMEDMEM/IntersectionDEC.hxx deleted file mode 100644 index 6659155c8..000000000 --- a/src/ParaMEDMEM/IntersectionDEC.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2007-2008 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 -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __INTERSECTIONDEC_HXX__ -#define __INTERSECTIONDEC_HXX__ - -#include "DEC.hxx" -#include "MxN_Mapping.hxx" -#include "InterpolationOptions.hxx" - -namespace ParaMEDMEM -{ - class InterpolationMatrix; - - class IntersectionDEC : public DEC, public INTERP_KERNEL::InterpolationOptions - { - public: - IntersectionDEC(); - IntersectionDEC(ProcessorGroup& source_group, ProcessorGroup& target_group); - virtual ~IntersectionDEC(); - void synchronize(); - void recvData(); - void recvData(double time); - void sendData(); - void sendData(double time , double deltatime); - void prepareSourceDE() { } - void prepareTargetDE() { } - private : - //Number of distant points to be located locally - int _nb_distant_points; - //coordinates of distant points - const double* _distant_coords; - //local element number containing the distant points - const int* _distant_locations; - InterpolationMatrix* _interpolation_matrix; - }; -} - -#endif diff --git a/src/ParaMEDMEM/Makefile.am b/src/ParaMEDMEM/Makefile.am index b2d0e0bd5..ba0f42214 100644 --- a/src/ParaMEDMEM/Makefile.am +++ b/src/ParaMEDMEM/Makefile.am @@ -51,7 +51,7 @@ DECOptions.hxx\ MxN_Mapping.hxx\ StructuredCoincidentDEC.hxx\ InterpolationMatrix.hxx\ -IntersectionDEC.hxx\ +InterpKernelDEC.hxx\ ExplicitCoincidentDEC.hxx\ ElementLocator.hxx\ ExplicitMapping.hxx\ @@ -72,7 +72,7 @@ MPIAccess.cxx \ InterpolationMatrix.cxx\ StructuredCoincidentDEC.cxx\ ExplicitCoincidentDEC.cxx\ -IntersectionDEC.cxx\ +InterpKernelDEC.cxx\ ElementLocator.cxx\ MPIAccessDEC.cxx \ TimeInterpolator.cxx \ diff --git a/src/ParaMEDMEM/NonCoincidentDEC.cxx b/src/ParaMEDMEM/NonCoincidentDEC.cxx index 6ca700a0b..c1f5725de 100644 --- a/src/ParaMEDMEM/NonCoincidentDEC.cxx +++ b/src/ParaMEDMEM/NonCoincidentDEC.cxx @@ -47,9 +47,9 @@ namespace ParaMEDMEM It is not available for 3D surfaces. The computation enables fast parallel localization, based on the FVM library. The computation is based on a point in element search, followed by a field evaluation at the point location. Thus, it is typically - faster than the \ref intersectiondec which gives a \ref conservativeremapping. + faster than the \ref interpkerneldec which gives a \ref conservativeremapping. It is particularly true for the initialisation phase (synchronize) - which is very computationnaly intensive in \ref intersectiondec. + which is very computationnaly intensive in \ref interpkerneldec. In the present version, only fields lying on elements are considered. The value is estimated by locating the barycenter of the target diff --git a/src/ParaMEDMEM/README_JR b/src/ParaMEDMEM/README_JR index 3039608eb..865af2b1d 100644 --- a/src/ParaMEDMEM/README_JR +++ b/src/ParaMEDMEM/README_JR @@ -333,13 +333,13 @@ mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH gcov TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ ParaMEDMEMTest_MPIProcessorGroup.cxx \ ParaMEDMEMTest_BlockTopology.cxx \ - ParaMEDMEMTest_IntersectionDEC.cxx \ + ParaMEDMEMTest_InterpKernelDEC.cxx \ ../BlockTopology.cxx \ ../ComponentTopology.cxx \ ../DEC.cxx \ ../ElementLocator.cxx \ ../InterpolationMatrix.cxx \ - ../IntersectionDEC.cxx \ + ../InterpKernelDEC.cxx \ ../MPIProcessorGroup.cxx \ ../MxN_Mapping.cxx \ ../ParaFIELD.cxx \ @@ -354,13 +354,13 @@ gcov TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ gcov -o ../ TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ ParaMEDMEMTest_MPIProcessorGroup.cxx \ ParaMEDMEMTest_BlockTopology.cxx \ - ParaMEDMEMTest_IntersectionDEC.cxx \ + ParaMEDMEMTest_InterpKernelDEC.cxx \ ../BlockTopology.cxx \ ../ComponentTopology.cxx \ ../DEC.cxx \ ../ElementLocator.cxx \ ../InterpolationMatrix.cxx \ - ../IntersectionDEC.cxx \ + ../InterpKernelDEC.cxx \ ../MPIProcessorGroup.cxx \ ../MxN_Mapping.cxx \ ../ParaFIELD.cxx \ diff --git a/src/ParaMEDMEM/StructuredCoincidentDEC.cxx b/src/ParaMEDMEM/StructuredCoincidentDEC.cxx index e62add48c..2f0f03b1f 100644 --- a/src/ParaMEDMEM/StructuredCoincidentDEC.cxx +++ b/src/ParaMEDMEM/StructuredCoincidentDEC.cxx @@ -47,7 +47,7 @@ namespace ParaMEDMEM The remapping between the two supports is based on identity of global ids, instead of geometrical considerations as it is the case for - NonCoincidentDEC and IntersectionDEC. Therefore, this DEC must not be used + NonCoincidentDEC and InterpKernelDEC. Therefore, this DEC must not be used for coincident meshes that do not have the same numbering. As all the other DECs, its use is made of two phases : diff --git a/src/ParaMEDMEM/Test/Makefile.am b/src/ParaMEDMEM/Test/Makefile.am index ba5d75adc..83fed05c1 100644 --- a/src/ParaMEDMEM/Test/Makefile.am +++ b/src/ParaMEDMEM/Test/Makefile.am @@ -33,7 +33,7 @@ dist_libParaMEDMEMTest_la_SOURCES = \ ParaMEDMEMTest.cxx \ ParaMEDMEMTest_MPIProcessorGroup.cxx \ ParaMEDMEMTest_BlockTopology.cxx \ - ParaMEDMEMTest_IntersectionDEC.cxx \ + ParaMEDMEMTest_InterpKernelDEC.cxx \ ParaMEDMEMTest_StructuredCoincidentDEC.cxx \ ParaMEDMEMTest_MEDLoader.cxx \ ParaMEDMEMTest_ICocoTrio.cxx \ diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx index 9e33a62b6..3187eb1db 100644 --- a/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx @@ -35,24 +35,24 @@ class ParaMEDMEMTest : public CppUnit::TestFixture CPPUNIT_TEST(testMPIProcessorGroup_rank); CPPUNIT_TEST(testBlockTopology_constructor); CPPUNIT_TEST(testBlockTopology_serialize); - CPPUNIT_TEST(testIntersectionDEC_2D); - CPPUNIT_TEST(testIntersectionDEC_2DP0P1); - CPPUNIT_TEST(testIntersectionDEC_3D); - CPPUNIT_TEST(testIntersectionDECNonOverlapp_2D_P0P0); - CPPUNIT_TEST(testIntersectionDECNonOverlapp_2D_P0P1P1P0); + CPPUNIT_TEST(testInterpKernelDEC_2D); + CPPUNIT_TEST(testInterpKernelDEC_2DP0P1); + CPPUNIT_TEST(testInterpKernelDEC_3D); + CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P0); + CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P1P1P0); - CPPUNIT_TEST(testSynchronousEqualIntersectionWithoutInterpNativeDEC_2D); - CPPUNIT_TEST(testSynchronousEqualIntersectionWithoutInterpDEC_2D); - CPPUNIT_TEST(testSynchronousEqualIntersectionDEC_2D); - CPPUNIT_TEST(testSynchronousFasterSourceIntersectionDEC_2D); - CPPUNIT_TEST(testSynchronousSlowerSourceIntersectionDEC_2D); - CPPUNIT_TEST(testSynchronousSlowSourceIntersectionDEC_2D); - CPPUNIT_TEST(testSynchronousFastSourceIntersectionDEC_2D); - CPPUNIT_TEST(testAsynchronousEqualIntersectionDEC_2D); - CPPUNIT_TEST(testAsynchronousFasterSourceIntersectionDEC_2D); - CPPUNIT_TEST(testAsynchronousSlowerSourceIntersectionDEC_2D); - CPPUNIT_TEST(testAsynchronousSlowSourceIntersectionDEC_2D); - CPPUNIT_TEST(testAsynchronousFastSourceIntersectionDEC_2D); + CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D); + CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D); + CPPUNIT_TEST(testSynchronousEqualInterpKernelDEC_2D); + CPPUNIT_TEST(testSynchronousFasterSourceInterpKernelDEC_2D); + CPPUNIT_TEST(testSynchronousSlowerSourceInterpKernelDEC_2D); + CPPUNIT_TEST(testSynchronousSlowSourceInterpKernelDEC_2D); + CPPUNIT_TEST(testSynchronousFastSourceInterpKernelDEC_2D); + CPPUNIT_TEST(testAsynchronousEqualInterpKernelDEC_2D); + CPPUNIT_TEST(testAsynchronousFasterSourceInterpKernelDEC_2D); + CPPUNIT_TEST(testAsynchronousSlowerSourceInterpKernelDEC_2D); + CPPUNIT_TEST(testAsynchronousSlowSourceInterpKernelDEC_2D); + CPPUNIT_TEST(testAsynchronousFastSourceInterpKernelDEC_2D); #ifdef MED_ENABLE_FVM //can be added again after FVM correction for 2D // CPPUNIT_TEST(testNonCoincidentDEC_2D); @@ -81,29 +81,29 @@ public: void testMPIProcessorGroup_rank(); void testBlockTopology_constructor(); void testBlockTopology_serialize(); - void testIntersectionDEC_2D(); - void testIntersectionDEC_2DP0P1(); - void testIntersectionDEC_3D(); - void testIntersectionDECNonOverlapp_2D_P0P0(); - void testIntersectionDECNonOverlapp_2D_P0P1P1P0(); + void testInterpKernelDEC_2D(); + void testInterpKernelDEC_2DP0P1(); + void testInterpKernelDEC_3D(); + void testInterpKernelDECNonOverlapp_2D_P0P0(); + void testInterpKernelDECNonOverlapp_2D_P0P1P1P0(); #ifdef MED_ENABLE_FVM void testNonCoincidentDEC_2D(); void testNonCoincidentDEC_3D(); #endif void testStructuredCoincidentDEC(); - void testSynchronousEqualIntersectionWithoutInterpNativeDEC_2D(); - void testSynchronousEqualIntersectionWithoutInterpDEC_2D(); - void testSynchronousEqualIntersectionDEC_2D(); - void testSynchronousFasterSourceIntersectionDEC_2D(); - void testSynchronousSlowerSourceIntersectionDEC_2D(); - void testSynchronousSlowSourceIntersectionDEC_2D(); - void testSynchronousFastSourceIntersectionDEC_2D(); + void testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D(); + void testSynchronousEqualInterpKernelWithoutInterpDEC_2D(); + void testSynchronousEqualInterpKernelDEC_2D(); + void testSynchronousFasterSourceInterpKernelDEC_2D(); + void testSynchronousSlowerSourceInterpKernelDEC_2D(); + void testSynchronousSlowSourceInterpKernelDEC_2D(); + void testSynchronousFastSourceInterpKernelDEC_2D(); - void testAsynchronousEqualIntersectionDEC_2D(); - void testAsynchronousFasterSourceIntersectionDEC_2D(); - void testAsynchronousSlowerSourceIntersectionDEC_2D(); - void testAsynchronousSlowSourceIntersectionDEC_2D(); - void testAsynchronousFastSourceIntersectionDEC_2D(); + void testAsynchronousEqualInterpKernelDEC_2D(); + void testAsynchronousFasterSourceInterpKernelDEC_2D(); + void testAsynchronousSlowerSourceInterpKernelDEC_2D(); + void testAsynchronousSlowSourceInterpKernelDEC_2D(); + void testAsynchronousFastSourceInterpKernelDEC_2D(); // void testICocoTrio1(); void testGauthier1(); @@ -124,11 +124,11 @@ private: const std::string& filename2, const std::string& meshname2, int nbprocsource, double epsilon); - void testAsynchronousIntersectionDEC_2D(double dtA, double tmaxA, + void testAsynchronousInterpKernelDEC_2D(double dtA, double tmaxA, double dtB, double tmaxB, bool WithPointToPoint, bool Asynchronous, bool WithInterp, const char *srcMeth, const char *targetMeth); - void testIntersectionDEC_2D_(const char *srcMeth, const char *targetMeth); - void testIntersectionDEC_3D_(const char *srcMeth, const char *targetMeth); + void testInterpKernelDEC_2D_(const char *srcMeth, const char *targetMeth); + void testInterpKernelDEC_3D_(const char *srcMeth, const char *targetMeth); }; // to automatically remove temporary files from disk diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_Gauthier1.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_Gauthier1.cxx index b104583af..c20eb5904 100644 --- a/src/ParaMEDMEM/Test/ParaMEDMEMTest_Gauthier1.cxx +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_Gauthier1.cxx @@ -6,7 +6,7 @@ #include "ProcessorGroup.hxx" #include "MPIProcessorGroup.hxx" #include "DEC.hxx" -#include "IntersectionDEC.hxx" +#include "InterpKernelDEC.hxx" #include #include #include "ICoCoTrioField.hxx" @@ -208,7 +208,7 @@ void ParaMEDMEMTest::testGauthier1() for (int send=0;send<2;send++) for (int rec=0;rec<2;rec++) { - IntersectionDEC dec_emetteur(emetteur_group, recepteur_group); + InterpKernelDEC dec_emetteur(emetteur_group, recepteur_group); dec_emetteur.setOrientation(2); TrioField champ_emetteur, champ_recepteur; diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_ICocoTrio.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_ICocoTrio.cxx index 70174206b..25f7a3da7 100644 --- a/src/ParaMEDMEM/Test/ParaMEDMEMTest_ICocoTrio.cxx +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_ICocoTrio.cxx @@ -4,7 +4,7 @@ #include "ProcessorGroup.hxx" #include "MPIProcessorGroup.hxx" #include "DEC.hxx" -#include "IntersectionDEC.hxx" +#include "InterpKernelDEC.hxx" #include #include #include "ICoCoTrioField.hxx" @@ -173,7 +173,7 @@ void ParaMEDMEMTest::testICocoTrio1() else cas="emetteur"; - IntersectionDEC dec_emetteur(emetteur_group, recepteur_group); + InterpKernelDEC dec_emetteur(emetteur_group, recepteur_group); TrioField champ_emetteur, champ_recepteur; diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_InterpKernelDEC.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_InterpKernelDEC.cxx new file mode 100644 index 000000000..cfaef00ff --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_InterpKernelDEC.cxx @@ -0,0 +1,1215 @@ +// Copyright (C) 2007-2008 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "ParaMEDMEMTest.hxx" +#include + +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "Topology.hxx" +#include "DEC.hxx" +#include "MxN_Mapping.hxx" +#include "InterpKernelDEC.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "ComponentTopology.hxx" +#include "ICoCoMEDField.hxx" +#include "MEDLoader.hxx" + +#include +#include + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + + +using namespace std; +using namespace ParaMEDMEM; + +void ParaMEDMEMTest::testInterpKernelDEC_2D() +{ + testInterpKernelDEC_2D_("P0","P0"); +} + +void ParaMEDMEMTest::testInterpKernelDEC_3D() +{ + testInterpKernelDEC_3D_("P0","P0"); +} + +void ParaMEDMEMTest::testInterpKernelDEC_2DP0P1() +{ + //testInterpKernelDEC_2D_("P0","P1"); +} + +/* + * Check methods defined in InterpKernelDEC.hxx + * + InterpKernelDEC(); + InterpKernelDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); + virtual ~InterpKernelDEC(); + void synchronize(); + void recvData(); + void sendData(); +*/ + +void ParaMEDMEMTest::testInterpKernelDEC_2D_(const char *srcMeth, const char *targetMeth) +{ + std::string srcM(srcMeth); + std::string targetM(targetMeth); + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + + //the test is meant to run on five processors + if (size !=5) return ; + + int nproc_source = 3; + set self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + string master = filename_xml1; + + ostringstream strstream; + strstream <getField()->setNature(ConservativeVolumic); + } + else + parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + int nb_local; + if(srcM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielemcontainsMyRank()) + { + string master= filename_xml2; + ostringstream strstream; + strstream << master<<(rank-nproc_source+1)<<".med"; + ostringstream meshname ; + meshname<< "Mesh_3_"<getField()->setNature(ConservativeVolumic); + } + else + parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + int nb_local; + if(targetM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielemcontainsMyRank()) + { + field_before_int = parafield->getVolumeIntegral(0); + dec.synchronize(); + cout<<"DEC usage"<myRank()==0) + aRemover.Register("./sourcesquareb"); + ostringstream filename; + filename<<"./sourcesquareb_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + MEDLoader::writeParaField("./sourcesquareb","boundary",parafield); + + dec.recvData(); + cout <<"writing"<myRank()==0) + aRemover.Register("./sourcesquare"); + MEDLoader::writeParaField("./sourcesquare","boundary",parafield); + + + filename<<"./sourcesquare_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + field_after_int = parafield->getVolumeIntegral(0); + + + // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); + + } + + //attaching a DEC to the target group + if (target_group->containsMyRank()) + { + dec.synchronize(); + dec.setForcedRenormalization(false); + + dec.recvData(); + MEDLoader::writeParaMesh("./targetsquareb",paramesh); + MEDLoader::writeParaField("./targetsquareb", "boundary",parafield); + if (target_group->myRank()==0) + aRemover.Register("./targetsquareb"); + ostringstream filename; + filename<<"./targetsquareb_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + dec.sendData(); + MEDLoader::writeParaMesh("./targetsquare",paramesh); + MEDLoader::writeParaField("./targetsquare", "boundary",parafield); + + if (target_group->myRank()==0) + aRemover.Register("./targetsquareb"); + + filename<<"./targetsquareb_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + // double field_before_int, field_after_int; + // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + + // CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); + + } + + delete source_group; + delete target_group; + delete self_group; + delete parafield; + delete paramesh; + mesh->decrRef(); + + delete icocofield; + + MPI_Barrier(MPI_COMM_WORLD); + cout << "end of InterpKernelDEC_2D test"< self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + string master = filename_xml1; + + ostringstream strstream; + strstream <getField()->setNature(ConservativeVolumic); + } + else + parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + int nb_local; + if(srcM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielemcontainsMyRank()) + { + string master= filename_xml2; + ostringstream strstream; + strstream << master << ".med"; + ostringstream meshname ; + meshname<< "Mesh_6"; + mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); + + paramesh=new ParaMESH (mesh,*target_group,"target mesh"); + // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group); + ParaMEDMEM::ComponentTopology comptopo; + if(targetM=="P0") + { + parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafield->getField()->setNature(ConservativeVolumic); + } + else + parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + int nb_local; + if(targetM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielemcontainsMyRank()) + { + field_before_int = parafield->getVolumeIntegral(0); + dec.synchronize(); + cout<<"DEC usage"<myRank()==0) + aRemover.Register("./sourcesquareb"); + ostringstream filename; + filename<<"./sourcesquareb_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + MEDLoader::writeParaField("./sourcesquareb","boundary",parafield); + + dec.recvData(); + cout <<"writing"<myRank()==0) + aRemover.Register("./sourcesquare"); + MEDLoader::writeParaField("./sourcesquare","boundary",parafield); + + + filename<<"./sourcesquare_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + field_after_int = parafield->getVolumeIntegral(0); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); + + } + + //attaching a DEC to the target group + if (target_group->containsMyRank()) + { + dec.synchronize(); + dec.setForcedRenormalization(false); + + dec.recvData(); + MEDLoader::writeParaMesh("./targetsquareb",paramesh); + MEDLoader::writeParaField("./targetsquareb", "boundary",parafield); + if (target_group->myRank()==0) + aRemover.Register("./targetsquareb"); + ostringstream filename; + filename<<"./targetsquareb_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + dec.sendData(); + MEDLoader::writeParaMesh("./targetsquare",paramesh); + MEDLoader::writeParaField("./targetsquare", "boundary",parafield); + + if (target_group->myRank()==0) + aRemover.Register("./targetsquareb"); + + filename<<"./targetsquareb_"<myRank()+1; + aRemover.Register(filename.str().c_str()); + } + delete source_group; + delete target_group; + delete self_group; + delete parafield; + delete paramesh; + mesh->decrRef(); + + delete icocofield; + + MPI_Barrier(MPI_COMM_WORLD); + cout << "end of InterpKernelDEC_3D test"< self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + std::ostringstream stream; stream << "sourcemesh2D proc " << rank; + mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + const double *sourceCoords=sourceCoordsAll[rank]; + std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*source_group,"source mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + double *value=parafield->getField()->getArray()->getPointer(); + value[0]=34+13*((double)rank); + } + else + { + std::ostringstream stream; stream << "targetmesh2D proc " << rank-nproc_source; + mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All+4); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(8,2); + const double *targetCoords=targetCoordsAll[rank-nproc_source]; + std::copy(targetCoords,targetCoords+16,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH (mesh,*target_group,"target mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + } + //test 1 - Conservative volumic + ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); + parafield->getField()->setNature(ConservativeVolumic); + if (source_group->containsMyRank()) + { + dec.setMethod("P0"); + dec.attachLocalField(parafield); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.sendData(); + } + else + { + dec.setMethod("P0"); + dec.attachLocalField(parafield); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.recvData(); + const double *res=parafield->getField()->getArray()->getConstPointer(); + const double *expected=targetResults[rank-nproc_source]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); + } + //test 2 - Integral + ParaMEDMEM::InterpKernelDEC dec2(*source_group,*target_group); + parafield->getField()->setNature(Integral); + if (source_group->containsMyRank()) + { + dec2.setMethod("P0"); + dec2.attachLocalField(parafield); + dec2.synchronize(); + dec2.setForcedRenormalization(false); + dec2.sendData(); + } + else + { + dec2.setMethod("P0"); + dec2.attachLocalField(parafield); + dec2.synchronize(); + dec2.setForcedRenormalization(false); + dec2.recvData(); + const double *res=parafield->getField()->getArray()->getConstPointer(); + const double *expected=targetResults2[rank-nproc_source]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); + } + //test 3 - Integral with global constraint + ParaMEDMEM::InterpKernelDEC dec3(*source_group,*target_group); + parafield->getField()->setNature(IntegralGlobConstraint); + if (source_group->containsMyRank()) + { + dec3.setMethod("P0"); + dec3.attachLocalField(parafield); + dec3.synchronize(); + dec3.setForcedRenormalization(false); + dec3.sendData(); + } + else + { + dec3.setMethod("P0"); + dec3.attachLocalField(parafield); + dec3.synchronize(); + dec3.setForcedRenormalization(false); + dec3.recvData(); + const double *res=parafield->getField()->getArray()->getConstPointer(); + const double *expected=targetResults3[rank-nproc_source]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); + } + //test 4 - Conservative volumic reversed + ParaMEDMEM::InterpKernelDEC dec4(*source_group,*target_group); + parafield->getField()->setNature(ConservativeVolumic); + if (source_group->containsMyRank()) + { + dec4.setMethod("P0"); + dec4.attachLocalField(parafield); + dec4.synchronize(); + dec4.setForcedRenormalization(false); + dec4.recvData(); + const double *res=parafield->getField()->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); + const double expected[]={37.8518518518519,43.5333333333333}; + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); + } + else + { + dec4.setMethod("P0"); + dec4.attachLocalField(parafield); + dec4.synchronize(); + dec4.setForcedRenormalization(false); + double *res=parafield->getField()->getArray()->getPointer(); + const double *toSet=targetResults[rank-nproc_source]; + res[0]=toSet[0]; + res[1]=toSet[1]; + dec4.sendData(); + } + //test 5 - Integral reversed + ParaMEDMEM::InterpKernelDEC dec5(*source_group,*target_group); + parafield->getField()->setNature(Integral); + if (source_group->containsMyRank()) + { + dec5.setMethod("P0"); + dec5.attachLocalField(parafield); + dec5.synchronize(); + dec5.setForcedRenormalization(false); + dec5.recvData(); + const double *res=parafield->getField()->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); + const double expected[]={0.794600591715977,1.35631163708087}; + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); + } + else + { + dec5.setMethod("P0"); + dec5.attachLocalField(parafield); + dec5.synchronize(); + dec5.setForcedRenormalization(false); + double *res=parafield->getField()->getArray()->getPointer(); + const double *toSet=targetResults2[rank-nproc_source]; + res[0]=toSet[0]; + res[1]=toSet[1]; + dec5.sendData(); + } + //test 6 - Integral with global constraint reversed + ParaMEDMEM::InterpKernelDEC dec6(*source_group,*target_group); + parafield->getField()->setNature(IntegralGlobConstraint); + if (source_group->containsMyRank()) + { + dec6.setMethod("P0"); + dec6.attachLocalField(parafield); + dec6.synchronize(); + dec6.setForcedRenormalization(false); + dec6.recvData(); + const double *res=parafield->getField()->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); + const double expected[]={36.4592592592593,44.5407407407407}; + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); + } + else + { + dec6.setMethod("P0"); + dec6.attachLocalField(parafield); + dec6.synchronize(); + dec6.setForcedRenormalization(false); + double *res=parafield->getField()->getArray()->getPointer(); + const double *toSet=targetResults3[rank-nproc_source]; + res[0]=toSet[0]; + res[1]=toSet[1]; + dec6.sendData(); + } + // + delete parafield; + mesh->decrRef(); + delete paramesh; + delete self_group; + delete target_group; + delete source_group; + // + MPI_Barrier(MPI_COMM_WORLD); +} + +void ParaMEDMEMTest::testInterpKernelDECNonOverlapp_2D_P0P1P1P0() +{ + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + // + if(size!=5) + return ; + int nproc_source = 2; + set self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + if(rank==0) + { + double coords[6]={-0.3,-0.3, 0.7,0.7, 0.7,-0.3}; + int conn[3]={0,1,2}; + int globalNode[3]={1,2,0}; + mesh=MEDCouplingUMesh::New("Source mesh Proc0",2); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,2); + std::copy(coords,coords+6,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + if(rank==1) + { + double coords[6]={-0.3,-0.3, -0.3,0.7, 0.7,0.7}; + int conn[3]={0,1,2}; + int globalNode[3]={1,3,2}; + mesh=MEDCouplingUMesh::New("Source mesh Proc1",2); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,2); + std::copy(coords,coords+6,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + paramesh=new ParaMESH(mesh,*source_group,"source mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafieldP1 = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + double *valueP1=parafieldP1->getField()->getArray()->getPointer(); + parafieldP0->getField()->setNature(ConservativeVolumic); + parafieldP1->getField()->setNature(ConservativeVolumic); + if(rank==0) + { + valueP0[0]=31.; + valueP1[0]=34.; valueP1[1]=77.; valueP1[2]=53.; + } + if(rank==1) + { + valueP0[0]=47.; + valueP1[0]=34.; valueP1[1]=57.; valueP1[2]=77.; + } + } + else + { + const char targetMeshName[]="target mesh"; + if(rank==2) + { + double coords[10]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; + int conn[7]={0,3,4,1, 1,4,2}; + int globalNode[5]={4,3,0,2,1}; + mesh=MEDCouplingUMesh::New("Target mesh Proc2",2); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+4); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,2); + std::copy(coords,coords+10,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + DataArrayInt *da=DataArrayInt::New(); + const int globalNumberingP2[5]={0,1,2,3,4}; + da->useArray(globalNumberingP2,false,CPP_DEALLOC,5,1); + paramesh->setNodeGlobal(da); + da->decrRef(); + } + if(rank==3) + { + double coords[6]={0.2,0.2, 0.7,-0.3, 0.7,0.2}; + int conn[3]={0,2,1}; + int globalNode[3]={1,0,5}; + mesh=MEDCouplingUMesh::New("Target mesh Proc3",2); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,2); + std::copy(coords,coords+6,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + DataArrayInt *da=DataArrayInt::New(); + const int globalNumberingP3[3]={4,2,5}; + da->useArray(globalNumberingP3,false,CPP_DEALLOC,3,1); + paramesh->setNodeGlobal(da); + da->decrRef(); + } + if(rank==4) + { + double coords[12]={-0.3,0.2, -0.3,0.7, 0.2,0.7, 0.2,0.2, 0.7,0.7, 0.7,0.2}; + int conn[8]={0,1,2,3, 3,2,4,5}; + int globalNode[6]={2,6,7,1,8,5}; + mesh=MEDCouplingUMesh::New("Target mesh Proc4",2); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(6,2); + std::copy(coords,coords+12,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + DataArrayInt *da=DataArrayInt::New(); + const int globalNumberingP4[6]={3,6,7,4,8,5}; + da->useArray(globalNumberingP4,false,CPP_DEALLOC,6,1); + paramesh->setNodeGlobal(da); + da->decrRef(); + } + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafieldP1 = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + parafieldP0->getField()->setNature(ConservativeVolumic); + parafieldP1->getField()->setNature(ConservativeVolumic); + } + // test 1 - P0 P1 + ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); + if (source_group->containsMyRank()) + { + dec.setMethod("P0"); + dec.attachLocalField(parafieldP0); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.sendData(); + dec.recvData(); + const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + if(rank==0) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(34.42857143,valueP0[0],1e-7); + } + if(rank==1) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(44.,valueP0[0],1e-7); + } + } + else + { + dec.setMethod("P1"); + dec.attachLocalField(parafieldP1); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.recvData(); + const double *res=parafieldP1->getField()->getArray()->getConstPointer(); + if(rank==2) + { + const double expectP2[5]={39.0, 31.0, 31.0, 47.0, 39.0}; + CPPUNIT_ASSERT_EQUAL(5,parafieldP1->getField()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); + for(int kk=0;kk<5;kk++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP2[kk],res[kk],1e-12); + } + if(rank==3) + { + const double expectP3[3]={39.0, 31.0, 31.0}; + CPPUNIT_ASSERT_EQUAL(3,parafieldP1->getField()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); + for(int kk=0;kk<3;kk++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP3[kk],res[kk],1e-12); + } + if(rank==4) + { + const double expectP4[6]={47.0, 47.0, 47.0, 39.0, 39.0, 31.0}; + CPPUNIT_ASSERT_EQUAL(6,parafieldP1->getField()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); + for(int kk=0;kk<6;kk++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP4[kk],res[kk],1e-12); + } + dec.sendData(); + } + // + delete parafieldP0; + delete parafieldP1; + mesh->decrRef(); + delete paramesh; + delete self_group; + delete target_group; + delete source_group; + // + MPI_Barrier(MPI_COMM_WORLD); +} + +/*! + * Tests an asynchronous exchange between two codes + * one sends data with dtA as an interval, the max time being tmaxA + * the other one receives with dtB as an interval, the max time being tmaxB + */ +void ParaMEDMEMTest::testAsynchronousInterpKernelDEC_2D(double dtA, double tmaxA, + double dtB, double tmaxB, bool WithPointToPoint, bool Asynchronous, + bool WithInterp, const char *srcMeth, const char *targetMeth) +{ + std::string srcM(srcMeth); + std::string targetM(targetMeth); + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + + //the test is meant to run on five processors + if (size !=5) return ; + + int nproc_source = 3; + set self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + string master = filename_xml1; + + ostringstream strstream; + strstream <getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic); + } + else + parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + + int nb_local; + if(srcM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielemcontainsMyRank()) + { + string master= filename_xml2; + ostringstream strstream; + strstream << master<<(rank-nproc_source+1)<<".med"; + ostringstream meshname ; + meshname<< "Mesh_3_"<getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic); + } + else + parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); + + int nb_local; + if(targetM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielemcontainsMyRank()) + { + cout<<"DEC usage"<getField()->getArray()->getPointer(); + int nb_local=parafield->getField()->getMesh()->getNumberOfCells(); + for (int i=0; icontainsMyRank()) + { + cout<<"DEC usage"< times; + for (double time=0; timegetVolumeIntegral(0); + cout << "testAsynchronousInterpKernelDEC_2D" << rank << " time " << time + << " VolumeIntegral " << vi + << " time*10000 " << time*10000 << endl ; + + CPPUNIT_ASSERT_DOUBLES_EQUAL(vi,time*10000,0.001); + } + + } + + delete source_group; + delete target_group; + delete self_group; + delete parafield ; + delete paramesh ; + mesh->decrRef() ; + delete icocofield ; + + cout << "testAsynchronousInterpKernelDEC_2D" << rank << " MPI_Barrier " << endl ; + + if (Asynchronous) MPI_Barrier(MPI_COMM_WORLD); + cout << "end of InterpKernelDEC_2D test"< - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "DEC.hxx" -#include "MxN_Mapping.hxx" -#include "IntersectionDEC.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ComponentTopology.hxx" -#include "ICoCoMEDField.hxx" -#include "MEDLoader.hxx" - -#include -#include - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - - -using namespace std; -using namespace ParaMEDMEM; - -void ParaMEDMEMTest::testIntersectionDEC_2D() -{ - testIntersectionDEC_2D_("P0","P0"); -} - -void ParaMEDMEMTest::testIntersectionDEC_3D() -{ - testIntersectionDEC_3D_("P0","P0"); -} - -void ParaMEDMEMTest::testIntersectionDEC_2DP0P1() -{ - //testIntersectionDEC_2D_("P0","P1"); -} - -/* - * Check methods defined in IntersectionDEC.hxx - * - IntersectionDEC(); - IntersectionDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); - virtual ~IntersectionDEC(); - void synchronize(); - void recvData(); - void sendData(); -*/ - -void ParaMEDMEMTest::testIntersectionDEC_2D_(const char *srcMeth, const char *targetMeth) -{ - std::string srcM(srcMeth); - std::string targetM(targetMeth); - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - //the test is meant to run on five processors - if (size !=5) return ; - - int nproc_source = 3; - set self_procs; - set procs_source; - set procs_target; - - for (int i=0; icontainsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(srcM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielemcontainsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master<<(rank-nproc_source+1)<<".med"; - ostringstream meshname ; - meshname<< "Mesh_3_"<getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(targetM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielemcontainsMyRank()) - { - field_before_int = parafield->getVolumeIntegral(0); - dec.synchronize(); - cout<<"DEC usage"<myRank()==0) - aRemover.Register("./sourcesquareb"); - ostringstream filename; - filename<<"./sourcesquareb_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - MEDLoader::writeParaField("./sourcesquareb","boundary",parafield); - - dec.recvData(); - cout <<"writing"<myRank()==0) - aRemover.Register("./sourcesquare"); - MEDLoader::writeParaField("./sourcesquare","boundary",parafield); - - - filename<<"./sourcesquare_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - field_after_int = parafield->getVolumeIntegral(0); - - - // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); - - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()) - { - dec.synchronize(); - dec.setForcedRenormalization(false); - - dec.recvData(); - MEDLoader::writeParaMesh("./targetsquareb",paramesh); - MEDLoader::writeParaField("./targetsquareb", "boundary",parafield); - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - ostringstream filename; - filename<<"./targetsquareb_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - dec.sendData(); - MEDLoader::writeParaMesh("./targetsquare",paramesh); - MEDLoader::writeParaField("./targetsquare", "boundary",parafield); - - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - - filename<<"./targetsquareb_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - // double field_before_int, field_after_int; - // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - - // CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); - - } - - delete source_group; - delete target_group; - delete self_group; - delete parafield; - delete paramesh; - mesh->decrRef(); - - delete icocofield; - - MPI_Barrier(MPI_COMM_WORLD); - cout << "end of IntersectionDEC_2D test"< self_procs; - set procs_source; - set procs_target; - - for (int i=0; icontainsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(srcM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielemcontainsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master << ".med"; - ostringstream meshname ; - meshname<< "Mesh_6"; - mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group); - ParaMEDMEM::ComponentTopology comptopo; - if(targetM=="P0") - { - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(targetM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielemcontainsMyRank()) - { - field_before_int = parafield->getVolumeIntegral(0); - dec.synchronize(); - cout<<"DEC usage"<myRank()==0) - aRemover.Register("./sourcesquareb"); - ostringstream filename; - filename<<"./sourcesquareb_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - MEDLoader::writeParaField("./sourcesquareb","boundary",parafield); - - dec.recvData(); - cout <<"writing"<myRank()==0) - aRemover.Register("./sourcesquare"); - MEDLoader::writeParaField("./sourcesquare","boundary",parafield); - - - filename<<"./sourcesquare_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - field_after_int = parafield->getVolumeIntegral(0); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); - - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()) - { - dec.synchronize(); - dec.setForcedRenormalization(false); - - dec.recvData(); - MEDLoader::writeParaMesh("./targetsquareb",paramesh); - MEDLoader::writeParaField("./targetsquareb", "boundary",parafield); - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - ostringstream filename; - filename<<"./targetsquareb_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - dec.sendData(); - MEDLoader::writeParaMesh("./targetsquare",paramesh); - MEDLoader::writeParaField("./targetsquare", "boundary",parafield); - - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - - filename<<"./targetsquareb_"<myRank()+1; - aRemover.Register(filename.str().c_str()); - } - delete source_group; - delete target_group; - delete self_group; - delete parafield; - delete paramesh; - mesh->decrRef(); - - delete icocofield; - - MPI_Barrier(MPI_COMM_WORLD); - cout << "end of IntersectionDEC_3D test"< self_procs; - set procs_source; - set procs_target; - - for (int i=0; icontainsMyRank()) - { - std::ostringstream stream; stream << "sourcemesh2D proc " << rank; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - const double *sourceCoords=sourceCoordsAll[rank]; - std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - double *value=parafield->getField()->getArray()->getPointer(); - value[0]=34+13*((double)rank); - } - else - { - std::ostringstream stream; stream << "targetmesh2D proc " << rank-nproc_source; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(8,2); - const double *targetCoords=targetCoordsAll[rank-nproc_source]; - std::copy(targetCoords,targetCoords+16,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - } - //test 1 - Conservative volumic - ParaMEDMEM::IntersectionDEC dec(*source_group,*target_group); - parafield->getField()->setNature(ConservativeVolumic); - if (source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - } - else - { - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults[rank-nproc_source]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - } - //test 2 - Integral - ParaMEDMEM::IntersectionDEC dec2(*source_group,*target_group); - parafield->getField()->setNature(Integral); - if (source_group->containsMyRank()) - { - dec2.setMethod("P0"); - dec2.attachLocalField(parafield); - dec2.synchronize(); - dec2.setForcedRenormalization(false); - dec2.sendData(); - } - else - { - dec2.setMethod("P0"); - dec2.attachLocalField(parafield); - dec2.synchronize(); - dec2.setForcedRenormalization(false); - dec2.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults2[rank-nproc_source]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - } - //test 3 - Integral with global constraint - ParaMEDMEM::IntersectionDEC dec3(*source_group,*target_group); - parafield->getField()->setNature(IntegralGlobConstraint); - if (source_group->containsMyRank()) - { - dec3.setMethod("P0"); - dec3.attachLocalField(parafield); - dec3.synchronize(); - dec3.setForcedRenormalization(false); - dec3.sendData(); - } - else - { - dec3.setMethod("P0"); - dec3.attachLocalField(parafield); - dec3.synchronize(); - dec3.setForcedRenormalization(false); - dec3.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults3[rank-nproc_source]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - } - //test 4 - Conservative volumic reversed - ParaMEDMEM::IntersectionDEC dec4(*source_group,*target_group); - parafield->getField()->setNature(ConservativeVolumic); - if (source_group->containsMyRank()) - { - dec4.setMethod("P0"); - dec4.attachLocalField(parafield); - dec4.synchronize(); - dec4.setForcedRenormalization(false); - dec4.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); - const double expected[]={37.8518518518519,43.5333333333333}; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); - } - else - { - dec4.setMethod("P0"); - dec4.attachLocalField(parafield); - dec4.synchronize(); - dec4.setForcedRenormalization(false); - double *res=parafield->getField()->getArray()->getPointer(); - const double *toSet=targetResults[rank-nproc_source]; - res[0]=toSet[0]; - res[1]=toSet[1]; - dec4.sendData(); - } - //test 5 - Integral reversed - ParaMEDMEM::IntersectionDEC dec5(*source_group,*target_group); - parafield->getField()->setNature(Integral); - if (source_group->containsMyRank()) - { - dec5.setMethod("P0"); - dec5.attachLocalField(parafield); - dec5.synchronize(); - dec5.setForcedRenormalization(false); - dec5.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); - const double expected[]={0.794600591715977,1.35631163708087}; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); - } - else - { - dec5.setMethod("P0"); - dec5.attachLocalField(parafield); - dec5.synchronize(); - dec5.setForcedRenormalization(false); - double *res=parafield->getField()->getArray()->getPointer(); - const double *toSet=targetResults2[rank-nproc_source]; - res[0]=toSet[0]; - res[1]=toSet[1]; - dec5.sendData(); - } - //test 6 - Integral with global constraint reversed - ParaMEDMEM::IntersectionDEC dec6(*source_group,*target_group); - parafield->getField()->setNature(IntegralGlobConstraint); - if (source_group->containsMyRank()) - { - dec6.setMethod("P0"); - dec6.attachLocalField(parafield); - dec6.synchronize(); - dec6.setForcedRenormalization(false); - dec6.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); - const double expected[]={36.4592592592593,44.5407407407407}; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); - } - else - { - dec6.setMethod("P0"); - dec6.attachLocalField(parafield); - dec6.synchronize(); - dec6.setForcedRenormalization(false); - double *res=parafield->getField()->getArray()->getPointer(); - const double *toSet=targetResults3[rank-nproc_source]; - res[0]=toSet[0]; - res[1]=toSet[1]; - dec6.sendData(); - } - // - delete parafield; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - -void ParaMEDMEMTest::testIntersectionDECNonOverlapp_2D_P0P1P1P0() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=5) - return ; - int nproc_source = 2; - set self_procs; - set procs_source; - set procs_target; - - for (int i=0; icontainsMyRank()) - { - if(rank==0) - { - double coords[6]={-0.3,-0.3, 0.7,0.7, 0.7,-0.3}; - int conn[3]={0,1,2}; - int globalNode[3]={1,2,0}; - mesh=MEDCouplingUMesh::New("Source mesh Proc0",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - if(rank==1) - { - double coords[6]={-0.3,-0.3, -0.3,0.7, 0.7,0.7}; - int conn[3]={0,1,2}; - int globalNode[3]={1,3,2}; - mesh=MEDCouplingUMesh::New("Source mesh Proc1",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafieldP1 = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - double *valueP1=parafieldP1->getField()->getArray()->getPointer(); - parafieldP0->getField()->setNature(ConservativeVolumic); - parafieldP1->getField()->setNature(ConservativeVolumic); - if(rank==0) - { - valueP0[0]=31.; - valueP1[0]=34.; valueP1[1]=77.; valueP1[2]=53.; - } - if(rank==1) - { - valueP0[0]=47.; - valueP1[0]=34.; valueP1[1]=57.; valueP1[2]=77.; - } - } - else - { - const char targetMeshName[]="target mesh"; - if(rank==2) - { - double coords[10]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; - int conn[7]={0,3,4,1, 1,4,2}; - int globalNode[5]={4,3,0,2,1}; - mesh=MEDCouplingUMesh::New("Target mesh Proc2",2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coords,coords+10,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - DataArrayInt *da=DataArrayInt::New(); - const int globalNumberingP2[5]={0,1,2,3,4}; - da->useArray(globalNumberingP2,false,CPP_DEALLOC,5,1); - paramesh->setNodeGlobal(da); - da->decrRef(); - } - if(rank==3) - { - double coords[6]={0.2,0.2, 0.7,-0.3, 0.7,0.2}; - int conn[3]={0,2,1}; - int globalNode[3]={1,0,5}; - mesh=MEDCouplingUMesh::New("Target mesh Proc3",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - DataArrayInt *da=DataArrayInt::New(); - const int globalNumberingP3[3]={4,2,5}; - da->useArray(globalNumberingP3,false,CPP_DEALLOC,3,1); - paramesh->setNodeGlobal(da); - da->decrRef(); - } - if(rank==4) - { - double coords[12]={-0.3,0.2, -0.3,0.7, 0.2,0.7, 0.2,0.2, 0.7,0.7, 0.7,0.2}; - int conn[8]={0,1,2,3, 3,2,4,5}; - int globalNode[6]={2,6,7,1,8,5}; - mesh=MEDCouplingUMesh::New("Target mesh Proc4",2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(6,2); - std::copy(coords,coords+12,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - DataArrayInt *da=DataArrayInt::New(); - const int globalNumberingP4[6]={3,6,7,4,8,5}; - da->useArray(globalNumberingP4,false,CPP_DEALLOC,6,1); - paramesh->setNodeGlobal(da); - da->decrRef(); - } - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafieldP1 = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - parafieldP0->getField()->setNature(ConservativeVolumic); - parafieldP1->getField()->setNature(ConservativeVolumic); - } - // test 1 - P0 P1 - ParaMEDMEM::IntersectionDEC dec(*source_group,*target_group); - if (source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - dec.recvData(); - const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(34.42857143,valueP0[0],1e-7); - } - if(rank==1) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(44.,valueP0[0],1e-7); - } - } - else - { - dec.setMethod("P1"); - dec.attachLocalField(parafieldP1); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafieldP1->getField()->getArray()->getConstPointer(); - if(rank==2) - { - const double expectP2[5]={39.0, 31.0, 31.0, 47.0, 39.0}; - CPPUNIT_ASSERT_EQUAL(5,parafieldP1->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); - for(int kk=0;kk<5;kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP2[kk],res[kk],1e-12); - } - if(rank==3) - { - const double expectP3[3]={39.0, 31.0, 31.0}; - CPPUNIT_ASSERT_EQUAL(3,parafieldP1->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); - for(int kk=0;kk<3;kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP3[kk],res[kk],1e-12); - } - if(rank==4) - { - const double expectP4[6]={47.0, 47.0, 47.0, 39.0, 39.0, 31.0}; - CPPUNIT_ASSERT_EQUAL(6,parafieldP1->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); - for(int kk=0;kk<6;kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP4[kk],res[kk],1e-12); - } - dec.sendData(); - } - // - delete parafieldP0; - delete parafieldP1; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - -/*! - * Tests an asynchronous exchange between two codes - * one sends data with dtA as an interval, the max time being tmaxA - * the other one receives with dtB as an interval, the max time being tmaxB - */ -void ParaMEDMEMTest::testAsynchronousIntersectionDEC_2D(double dtA, double tmaxA, - double dtB, double tmaxB, bool WithPointToPoint, bool Asynchronous, - bool WithInterp, const char *srcMeth, const char *targetMeth) -{ - std::string srcM(srcMeth); - std::string targetM(targetMeth); - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - //the test is meant to run on five processors - if (size !=5) return ; - - int nproc_source = 3; - set self_procs; - set procs_source; - set procs_target; - - for (int i=0; icontainsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - - int nb_local; - if(srcM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielemcontainsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master<<(rank-nproc_source+1)<<".med"; - ostringstream meshname ; - meshname<< "Mesh_3_"<getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - - int nb_local; - if(targetM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielemcontainsMyRank()) - { - cout<<"DEC usage"<getField()->getArray()->getPointer(); - int nb_local=parafield->getField()->getMesh()->getNumberOfCells(); - for (int i=0; icontainsMyRank()) - { - cout<<"DEC usage"< times; - for (double time=0; timegetVolumeIntegral(0); - cout << "testAsynchronousIntersectionDEC_2D" << rank << " time " << time - << " VolumeIntegral " << vi - << " time*10000 " << time*10000 << endl ; - - CPPUNIT_ASSERT_DOUBLES_EQUAL(vi,time*10000,0.001); - } - - } - - delete source_group; - delete target_group; - delete self_group; - delete parafield ; - delete paramesh ; - mesh->decrRef() ; - delete icocofield ; - - cout << "testAsynchronousIntersectionDEC_2D" << rank << " MPI_Barrier " << endl ; - - if (Asynchronous) MPI_Barrier(MPI_COMM_WORLD); - cout << "end of IntersectionDEC_2D test"<