]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
*** empty log message ***
authorageay <ageay>
Tue, 19 May 2009 10:23:50 +0000 (10:23 +0000)
committerageay <ageay>
Tue, 19 May 2009 10:23:50 +0000 (10:23 +0000)
50 files changed:
src/INTERP_KERNEL/ConvexIntersector.hxx
src/INTERP_KERNEL/ConvexIntersector.txx
src/INTERP_KERNEL/Geometric2DIntersector.hxx
src/INTERP_KERNEL/Geometric2DIntersector.txx
src/INTERP_KERNEL/Interpolation3DSurf.hxx
src/INTERP_KERNEL/Interpolation3DSurf.txx
src/INTERP_KERNEL/InterpolationOptions.cxx [new file with mode: 0644]
src/INTERP_KERNEL/InterpolationOptions.hxx
src/INTERP_KERNEL/InterpolationPlanar.txx
src/INTERP_KERNEL/Makefile.am
src/INTERP_KERNEL/PlanarIntersector.hxx
src/INTERP_KERNEL/PlanarIntersector.txx
src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx
src/INTERP_KERNEL/PlanarIntersectorP0P0.txx
src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx
src/INTERP_KERNEL/PlanarIntersectorP0P1.txx
src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx
src/INTERP_KERNEL/PlanarIntersectorP1P0.txx
src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx
src/INTERP_KERNEL/PlanarIntersectorP1P1.txx
src/INTERP_KERNEL/TriangulationIntersector.hxx
src/INTERP_KERNEL/TriangulationIntersector.txx
src/MEDCoupling/MEDCouplingField.cxx
src/MEDCoupling/MEDCouplingField.hxx
src/MEDCoupling/MEDCouplingFieldDiscretization.cxx
src/MEDCoupling/MEDCouplingFieldDiscretization.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMeshDesc.cxx
src/MEDCoupling/MEDCouplingUMeshDesc.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx
src/ParaMEDMEM/DEC.cxx
src/ParaMEDMEM/DEC.hxx
src/ParaMEDMEM/ElementLocator.cxx
src/ParaMEDMEM/ElementLocator.hxx
src/ParaMEDMEM/GlobalizerMesh.cxx [new file with mode: 0644]
src/ParaMEDMEM/GlobalizerMesh.hxx [new file with mode: 0644]
src/ParaMEDMEM/ICoCoMEDField.cxx
src/ParaMEDMEM/InterpolationMatrix.cxx
src/ParaMEDMEM/InterpolationMatrix.hxx
src/ParaMEDMEM/IntersectionDEC.cxx
src/ParaMEDMEM/Makefile.am
src/ParaMEDMEM/MxN_Mapping.hxx
src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx
src/ParaMEDMEM/Test/ParaMEDMEMTest_ICocoTrio.cxx
src/ParaMEDMEM/Test/ParaMEDMEMTest_IntersectionDEC.cxx
src/ParaMEDMEM_Swig/test_IntersectionDEC.py

index 7e1300f96aab76111c24ef45ee751f0f3a239bc6..094b4c76faf78b1a45650ec0219b9a152fd88077 100644 (file)
@@ -36,7 +36,7 @@ namespace INTERP_KERNEL
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   public:
     ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, 
-                      double dimCaracteristic, double precision, double medianPlane,
+                      double dimCaracteristic, double precision, double md3DSurf, double medianPlane,
                       bool doRotate, int orientation, int printLevel);
     double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS);
     double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad);
index c61a7ba7579f60c9be4cea7696309d7a91972e99..70576f39f3463767a4ff684aa83f34ac0f9e5fb2 100644 (file)
@@ -33,9 +33,9 @@ namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType>
   ConvexIntersector<MyMeshType,MyMatrix,InterpType>::ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, 
-                                                                double dimCaracteristic, double precision,
-                                                                double medianPlane, bool doRotate , int oriantation, int printLevel)
-    :InterpType<MyMeshType,MyMatrix,ConvexIntersector<MyMeshType,MyMatrix,InterpType> >(meshT,meshS,dimCaracteristic, precision, medianPlane, doRotate, oriantation, printLevel),
+                                                                       double dimCaracteristic, double precision, double md3DSurf,
+                                                                       double medianPlane, bool doRotate , int oriantation, int printLevel)
+    :InterpType<MyMeshType,MyMatrix,ConvexIntersector<MyMeshType,MyMatrix,InterpType> >(meshT,meshS,dimCaracteristic, precision, md3DSurf, medianPlane, doRotate, oriantation, printLevel),
      _epsilon(precision*dimCaracteristic)
   {
     if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 1)
index 6055bad227ff707186fb0fb7dfc7c948772c0825..257d6516bda9465c0d70699dc7a4ac9848c40049 100644 (file)
@@ -38,7 +38,7 @@ namespace INTERP_KERNEL
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   public:
     Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS,
-                           double dimCaracteristic, double medianPlane, double precision, int orientation);
+                           double dimCaracteristic, double md3DSurf, double medianPlane, double precision, int orientation);
     double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS);
     double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad);
     double intersectGeometryGeneral(const std::vector<double>& targetCoords, const std::vector<double>& sourceCoords);
index 6763d8a22b44554b550dea13d38cb8635c82b48d..3592c35b276de49528d98d7e02c0f3c6a5917076 100644 (file)
@@ -35,8 +35,8 @@ namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType>
   Geometric2DIntersector<MyMeshType,MyMatrix,InterpType>::Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS,
-                                                                          double dimCaracteristic, double medianPlane, double precision, int orientation):
-    InterpType<MyMeshType,MyMatrix,Geometric2DIntersector<MyMeshType,MyMatrix,InterpType> >(meshT,meshS,dimCaracteristic, precision, medianPlane, true, orientation, 0)
+                                                                          double dimCaracteristic, double md3DSurf, double medianPlane, double precision, int orientation):
+    InterpType<MyMeshType,MyMatrix,Geometric2DIntersector<MyMeshType,MyMatrix,InterpType> >(meshT,meshS,dimCaracteristic, precision, md3DSurf, medianPlane, true, orientation, 0)
   {
     QUADRATIC_PLANAR::_precision=dimCaracteristic*precision;
   }
index 4fff636cf800bcf32bb6e239e6c008848679747b..7aed59254166b5c71ef3009400e4082c49f70c51 100644 (file)
@@ -31,21 +31,10 @@ namespace INTERP_KERNEL
     Interpolation3DSurf(const InterpolationOptions& io);
     void setOptions(double precision, int printLevel, double medianPlane, 
                     IntersectionType intersectionType, bool doRotate, int orientation=0);
-
   public:
-    bool doRotate() const { return _do_rotate; }
-    double medianPlane() const { return _median_plane; }
-    double surf3DAdjustmentEps() const { return _surf_3D_adjustment_eps; }
-    void setSurf3DAdjustmentEps(double val) { _surf_3D_adjustment_eps=val; }
     template<class MyMeshType, class MyMatrixRow>
-      void performAdjustmentOfBB(PlanarIntersector<MyMeshType,MyMatrixRow>* intersector, std::vector<double>& bbox) const
-    { intersector->adjustBoundingBoxes(bbox,_surf_3D_adjustment_eps); }
-  protected:
-    bool _do_rotate;
-    double _median_plane;
-    double _surf_3D_adjustment_eps;
-    static const double DFT_MEDIAN_PLANE;
-    static const double DFT_SURF3D_ADJ_EPS;
+    void performAdjustmentOfBB(PlanarIntersector<MyMeshType,MyMatrixRow>* intersector, std::vector<double>& bbox) const
+    { intersector->adjustBoundingBoxes(bbox,InterpolationPlanar<Interpolation3DSurf>::getBoundingBoxAdjustment(),InterpolationPlanar<Interpolation3DSurf>::getBoundingBoxAdjustmentAbs()); }
   };
 }
 
index 8688ec85b4e45bc27fd9276702a8e51b089af43e..34306738289c97d99d337794031e39ed9e65eb15 100644 (file)
 
 namespace INTERP_KERNEL
 {
-  const double Interpolation3DSurf::DFT_MEDIAN_PLANE=0.5;
-  const double Interpolation3DSurf::DFT_SURF3D_ADJ_EPS=1e-4;
-  
-  Interpolation3DSurf::Interpolation3DSurf():_do_rotate(true)
-                                            ,_median_plane(DFT_MEDIAN_PLANE)
-                                            ,_surf_3D_adjustment_eps(DFT_SURF3D_ADJ_EPS)
+  Interpolation3DSurf::Interpolation3DSurf()
   {
   }
 
   Interpolation3DSurf::Interpolation3DSurf(const InterpolationOptions& io):InterpolationPlanar<Interpolation3DSurf>(io)
-                                                                         ,_median_plane(io.getMedianPlane())
-                                                                         ,_surf_3D_adjustment_eps(io.getBoundingBoxAdjustment())
   {
   }
 
@@ -63,8 +56,8 @@ namespace INTERP_KERNEL
                                        IntersectionType intersectionType, bool doRotate, int orientation)
   {
     InterpolationPlanar<Interpolation3DSurf>::setOptions(precision,printLevel,intersectionType, orientation);
-    _do_rotate=doRotate;
-    _median_plane=medianPlane;
+    InterpolationPlanar<Interpolation3DSurf>::setDoRotate(doRotate);
+    InterpolationPlanar<Interpolation3DSurf>::setMedianPlane(medianPlane);
   }
 }
 
diff --git a/src/INTERP_KERNEL/InterpolationOptions.cxx b/src/INTERP_KERNEL/InterpolationOptions.cxx
new file mode 100644 (file)
index 0000000..a234225
--- /dev/null
@@ -0,0 +1,25 @@
+//  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 "InterpolationOptions.hxx"
+
+const double INTERP_KERNEL::InterpolationOptions::DFT_MEDIAN_PLANE=0.5;
+
+const double INTERP_KERNEL::InterpolationOptions::DFT_SURF3D_ADJ_EPS=1.e-4;
+
+const double INTERP_KERNEL::InterpolationOptions::DFT_MAX_DIST_3DSURF_INTERSECT=-1.;
index 34a7d042d472526d876513788cbd5e897f11a54f..a18f76d44b4aa56567ef7fee6931034e4a127187 100644 (file)
 #ifndef __INTERPOLATIONOPTIONS_HXX__
 #define __INTERPOLATIONOPTIONS_HXX__
 
-
-namespace INTERP_KERNEL {
+namespace INTERP_KERNEL
+{
   typedef enum { Triangulation, Convex, Geometric2D } IntersectionType;
   /// Type describing the different ways in which the hexahedron can be split into tetrahedra.
   /// The PLANAR_* policies persume that each face is to be considered planar, while the general
   /// policies make no such hypothesis. The integer at the end gives the number of tetrahedra
   /// that result from the split.
   typedef enum  { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy;
-
   
-  class InterpolationOptions{
+  class InterpolationOptions
+  {
   private :
     int _print_level ;
     IntersectionType _intersection_type;
     double _precision;
     double _median_plane ;
     bool _do_rotate ;
+    //! this measure is relative to the caracteristic dimension
     double _bounding_box_adjustment ;
+    //! this measure is absolute \b not relative to the cell size
+    double _bounding_box_adjustment_abs ;
+    double _max_distance_for_3Dsurf_intersect;
     int _orientation ;
     SplittingPolicy _splitting_policy ;
 
@@ -45,23 +49,29 @@ namespace INTERP_KERNEL {
     int getPrintLevel() const { return _print_level; }
     void setPrintLevel(int pl) { _print_level=pl; }
 
-    IntersectionType getIntersectionType() const { return InterpolationOptions::_intersection_type; }
-    void setIntersectionType(IntersectionType it) { InterpolationOptions::_intersection_type=it; }
+    IntersectionType getIntersectionType() const { return _intersection_type; }
+    void setIntersectionType(IntersectionType it) { _intersection_type=it; }
 
-    double getPrecision() const { return InterpolationOptions::_precision; }
-    void setPrecision(double p) { InterpolationOptions::_precision=p; }
+    double getPrecision() const { return _precision; }
+    void setPrecision(double p) { _precision=p; }
 
-    double getMedianPlane() const { return InterpolationOptions::_median_plane; }
-    void setMedianPlane(double mp) { InterpolationOptions::_median_plane=mp; }
+    double getMedianPlane() const { return _median_plane; }
+    void setMedianPlane(double mp) { _median_plane=mp; }
     
-    bool getDoRotate() const { return InterpolationOptions::_do_rotate; }
-    void setDoRotate( bool dr) { InterpolationOptions::_do_rotate = dr; }
+    bool getDoRotate() const { return _do_rotate; }
+    void setDoRotate( bool dr) { _do_rotate = dr; }
     
-    double getBoundingBoxAdjustment() const { return InterpolationOptions::_bounding_box_adjustment; }
-    void setBoundingBoxAdjustment(double bba) { InterpolationOptions::_bounding_box_adjustment=bba; }
+    double getBoundingBoxAdjustment() const { return _bounding_box_adjustment; }
+    void setBoundingBoxAdjustment(double bba) { _bounding_box_adjustment=bba; }
+
+    double getBoundingBoxAdjustmentAbs() const { return _bounding_box_adjustment_abs; }
+    void setBoundingBoxAdjustmentAbs(double bba) { _bounding_box_adjustment_abs=bba; }
     
-    int getOrientation() const { return InterpolationOptions::_orientation; }
-    void setOrientation(int o) { InterpolationOptions::_orientation=o; }
+    double getMaxDistance3DSurfIntersect() const { return _max_distance_for_3Dsurf_intersect; }
+    void setMaxDistance3DSurfIntersect(double bba) { _max_distance_for_3Dsurf_intersect=bba; }
+
+    int getOrientation() const { return _orientation; }
+    void setOrientation(int o) { _orientation=o; }
     
     SplittingPolicy getSplittingPolicy() const { return _splitting_policy; }
     void setSplittingPolicy(SplittingPolicy sp) { _splitting_policy=sp; }
@@ -70,12 +80,18 @@ namespace INTERP_KERNEL {
       _print_level=0;
       _intersection_type=Triangulation;
       _precision=1e-12;
-      _median_plane=0.5;
+      _median_plane=DFT_MEDIAN_PLANE;
       _do_rotate=true;
-      _bounding_box_adjustment=1e-4;
+      _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS;
+      _bounding_box_adjustment_abs=0.;
+      _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT;
       _orientation=0;
       _splitting_policy=GENERAL_48;
     }
+  private:
+    static const double DFT_MEDIAN_PLANE;
+    static const double DFT_SURF3D_ADJ_EPS;
+    static const double DFT_MAX_DIST_3DSURF_INTERSECT;
   };
 
 }
index d48246b495334563c67b7d43fc8768339ece3ac4..1e720fd25fdf2b451e9badb0c37ecdd7ae24264b 100644 (file)
@@ -148,6 +148,7 @@ namespace INTERP_KERNEL
           case Triangulation:
             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                                   InterpolationOptions::getPrecision(),
+                                                                                                  InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                   InterpolationOptions::getMedianPlane(),
                                                                                                   InterpolationOptions::getOrientation(),
                                                                                                   InterpolationOptions::getPrintLevel());
@@ -155,6 +156,7 @@ namespace INTERP_KERNEL
           case Convex:
             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                            InterpolationOptions::getPrecision(),
+                                                                                           InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                            InterpolationOptions::getDoRotate(),
                                                                                            InterpolationOptions::getMedianPlane(),
                                                                                            InterpolationOptions::getOrientation(),
@@ -162,6 +164,7 @@ namespace INTERP_KERNEL
             break;
           case Geometric2D:
             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT, myMeshS, _dim_caracteristic,
+                                                                                                InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                 InterpolationOptions::getMedianPlane(),
                                                                                                 InterpolationOptions::getPrecision(),
                                                                                                 InterpolationOptions::getOrientation());
@@ -175,6 +178,7 @@ namespace INTERP_KERNEL
           case Triangulation:
             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                                   InterpolationOptions::getPrecision(),
+                                                                                                  InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                   InterpolationOptions::getMedianPlane(),
                                                                                                   InterpolationOptions::getOrientation(),
                                                                                                   InterpolationOptions::getPrintLevel());
@@ -182,6 +186,7 @@ namespace INTERP_KERNEL
           case Convex:
             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                            InterpolationOptions::getPrecision(),
+                                                                                           InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                            InterpolationOptions::getDoRotate(),
                                                                                            InterpolationOptions::getMedianPlane(),
                                                                                            InterpolationOptions::getOrientation(),
@@ -189,6 +194,7 @@ namespace INTERP_KERNEL
             break;
           case Geometric2D:
             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT, myMeshS, _dim_caracteristic,
+                                                                                                InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                 InterpolationOptions::getMedianPlane(),
                                                                                                 InterpolationOptions::getPrecision(),
                                                                                                 InterpolationOptions::getOrientation());
@@ -202,6 +208,7 @@ namespace INTERP_KERNEL
           case Triangulation:
             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                                   InterpolationOptions::getPrecision(),
+                                                                                                  InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                   InterpolationOptions::getMedianPlane(),
                                                                                                   InterpolationOptions::getOrientation(),
                                                                                                   InterpolationOptions::getPrintLevel());
@@ -209,6 +216,7 @@ namespace INTERP_KERNEL
           case Convex:
             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                            InterpolationOptions::getPrecision(),
+                                                                                           InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                            InterpolationOptions::getDoRotate(),
                                                                                            InterpolationOptions::getMedianPlane(),
                                                                                            InterpolationOptions::getOrientation(),
@@ -216,6 +224,7 @@ namespace INTERP_KERNEL
             break;
           case Geometric2D:
             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT, myMeshS, _dim_caracteristic,
+                                                                                                InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                 InterpolationOptions::getMedianPlane(),
                                                                                                 InterpolationOptions::getPrecision(),
                                                                                                 InterpolationOptions::getOrientation());
@@ -229,6 +238,7 @@ namespace INTERP_KERNEL
           case Triangulation:
             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                                   InterpolationOptions::getPrecision(),
+                                                                                                  InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                   InterpolationOptions::getMedianPlane(),
                                                                                                   InterpolationOptions::getOrientation(),
                                                                                                   InterpolationOptions::getPrintLevel());
@@ -236,6 +246,7 @@ namespace INTERP_KERNEL
           case Convex:
             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT,myMeshS,_dim_caracteristic,
                                                                                            InterpolationOptions::getPrecision(),
+                                                                                           InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                            InterpolationOptions::getDoRotate(),
                                                                                            InterpolationOptions::getMedianPlane(),
                                                                                            InterpolationOptions::getOrientation(),
@@ -243,6 +254,7 @@ namespace INTERP_KERNEL
             break;
           case Geometric2D:
             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT, myMeshS, _dim_caracteristic,
+                                                                                                InterpolationOptions::getMaxDistance3DSurfIntersect(),
                                                                                                 InterpolationOptions::getMedianPlane(),
                                                                                                 InterpolationOptions::getPrecision(),
                                                                                                 InterpolationOptions::getOrientation());
index 45ed3229efbb9d0c3d39aba9ce38d62b16ab585e..7a348f54646abc772adc1a275e21ab5ee968acd2 100644 (file)
@@ -115,7 +115,8 @@ dist_libinterpkernel_la_SOURCES = \
        BoundingBox.cxx \
        TetraAffineTransform.cxx\
        CellModel.cxx\
-       UnitTetraIntersectionBary.cxx
+       UnitTetraIntersectionBary.cxx \
+       InterpolationOptions.cxx
 
 libinterpkernel_la_CPPFLAGS=-I$(srcdir)/Geometric2D -I$(srcdir)/Bases
 
index 3cce25cdcb873f92c240375c0b007e0b2a1cf543..d78414b661ce280a309c260f98c9977cf4fad224 100644 (file)
@@ -36,11 +36,11 @@ namespace INTERP_KERNEL
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   public:
     //! \addtogroup InterpKerGrpIntPlan @{
-    PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel);
+    PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel);
     //! @}
     virtual ~PlanarIntersector();
     void createBoundingBoxes(const MyMeshType& mesh, std::vector<double>& bbox);
-    void adjustBoundingBoxes(std::vector<double>& bbox, double Surf3DAdjustmentEps);
+    void adjustBoundingBoxes(std::vector<double>& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs);
     inline void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes);
   protected :
     int projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB);
@@ -49,8 +49,9 @@ namespace INTERP_KERNEL
     void getRealTargetCoordinatesPermute(ConnType icellT, int offset, std::vector<double>& coordsT);
     void getRealSourceCoordinatesPermute(ConnType icellS, int offset, std::vector<double>& coordsS);
     void getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector<double>& coordsT, std::vector<double>& coordsS, int& orientation);
-    static int projection(double *Coords_A, double *Coords_B, 
-                           int nb_NodesA, int nb_NodesB, double epsilon, double median_plane, bool do_rotate);
+    double getValueRegardingOption(double val) const;
+    static int projection(double *Coords_A, double *Coords_B,
+                          int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double median_plane, bool do_rotate);
     static void rotate3DTriangle( double* PP1, double*PP2, double*PP3,
                                   TranslationRotationMatrix& rotation_matrix);
   protected:
@@ -63,6 +64,7 @@ namespace INTERP_KERNEL
     const MyMeshType& _meshT;
     const MyMeshType& _meshS;
     double _dim_caracteristic;
+    double _max_distance_3Dsurf_intersect;
     double _precision;
     double _median_plane;
     bool _do_rotate;
index 4493aeb1438445d5d1adb5129d4596d207ce1e1c..2a0234587e2ac2d047a38db11e36d888ef784c3f 100644 (file)
@@ -29,9 +29,9 @@
 namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix>
-  PlanarIntersector<MyMeshType,MyMatrix>::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel):
+  PlanarIntersector<MyMeshType,MyMatrix>::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel):
     _meshT(meshT),_meshS(meshS),
-    _dim_caracteristic(dimCaracteristic),_precision(precision),_median_plane(medianPlane),
+    _dim_caracteristic(dimCaracteristic),_max_distance_3Dsurf_intersect(md3DSurf),_precision(precision),_median_plane(medianPlane),
     _do_rotate(doRotate),_orientation(orientation),_print_level(printLevel)
   {
     _connectT=meshT.getConnectivityPtr();
@@ -127,7 +127,7 @@ namespace INTERP_KERNEL
     \param bbox vector containing the bounding boxes
   */
   template<class MyMeshType, class MyMatrix>
-  void PlanarIntersector<MyMeshType,MyMatrix>::adjustBoundingBoxes(std::vector<double>& bbox, double Surf3DAdjustmentEps)
+  void PlanarIntersector<MyMeshType,MyMatrix>::adjustBoundingBoxes(std::vector<double>& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs)
   {
     /* We build the segment tree for locating possible matching intersections*/
   
@@ -142,8 +142,8 @@ namespace INTERP_KERNEL
           }
         for(int idim=0; idim<SPACEDIM; idim++)
           {            
-            bbox[i*2*SPACEDIM+2*idim  ] -= Surf3DAdjustmentEps*max;
-            bbox[i*2*SPACEDIM+2*idim+1] += Surf3DAdjustmentEps*max;
+            bbox[i*2*SPACEDIM+2*idim  ] -= surf3DAdjustmentEps*max+surf3DAdjustmentEpsAbs;
+            bbox[i*2*SPACEDIM+2*idim+1] += surf3DAdjustmentEps*max+surf3DAdjustmentEpsAbs;
           }
       }
   }
@@ -224,58 +224,6 @@ namespace INTERP_KERNEL
   template<class MyMeshType, class MyMatrix>
   void PlanarIntersector<MyMeshType,MyMatrix>::getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector<double>& coordsT, std::vector<double>& coordsS, int& orientation)
   {
-    /*double epsilon=_precision*_dim_caracteristic;
-      coordsT.resize(SPACEDIM*nbNodesT);
-      coordsS.resize(SPACEDIM*nbNodesS);
-      int nb_dist_NodesT=nbNodesT;
-      int nb_dist_NodesS=nbNodesS;
-      int i_last = nbNodesT - 1;
-      const double * Pi_last=_coordsT +_connectT[OTT<ConnType,numPol>::conn2C(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]+i_last)];
-
-      for (int iT=0; iT<nbNodesT; iT++)
-      {
-      const double * PiT = _coordsT + SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectT[OTT<ConnType,numPol>::conn2C(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]+iT)]);
-      if(distance2<SPACEDIM>(Pi_last, PiT)>epsilon)
-      {
-      for (int idim=0; idim<SPACEDIM; idim++)
-      coordsT[SPACEDIM*iT+idim]=PiT[idim];
-      i_last=iT; Pi_last = PiT;
-      }
-      else 
-      nb_dist_NodesT--;
-      }
-      coordsT.resize(nb_dist_NodesT*SPACEDIM);
-      i_last = nbNodesS - 1;
-      Pi_last=_coordsS + SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectS[OTT<ConnType,numPol>::conn2C(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]+i_last)]);
-      for (int iS=0; iS<nbNodesS; iS++)
-      {
-      const double * PiS=_coordsS+SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectS[OTT<ConnType,numPol>::conn2C(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]+iS)]);
-      if(distance2<SPACEDIM>(Pi_last, PiS)>epsilon)
-      {
-      for (int idim=0; idim<SPACEDIM; idim++)
-      coordsS[SPACEDIM*iS+idim]=PiS[idim];
-      i_last=iS; Pi_last = PiS;
-      }
-      else
-      nb_dist_NodesS--;
-      }
-      coordsS.resize(nb_dist_NodesS*SPACEDIM);
-      //project cells T and S on the median plane
-      // and rotate the median plane
-      if(SPACEDIM==3) 
-      orientation = projectionThis(&coordsT[0], &coordsS[0], nb_dist_NodesT, nb_dist_NodesS);
-
-      //DEBUG PRINTS
-      if(_print_level >= 3) 
-      {
-      std::cout << std::endl << "Cell coordinates (possibly after projection)" << std::endl;
-      std::cout << std::endl << "icellT= " << icellT << ", nb nodes T= " <<  nbNodesT << std::endl;
-      for(int iT =0; iT< nbNodesT; iT++)
-      {for (int idim=0; idim<SPACEDIM; idim++) std::cout << coordsT[SPACEDIM*iT+idim] << " "; std::cout << std::endl;}
-      std::cout << std::endl << "icellS= " << icellS << ", nb nodes S= " <<  nbNodesS << std::endl;
-      for(int iS =0; iS< nbNodesS; iS++)
-      {for (int idim=0; idim<SPACEDIM; idim++) std::cout << coordsS[SPACEDIM*iS+idim]<< " "; std::cout << std::endl; }
-      }*/
     coordsT.resize(SPACEDIM*nbNodesT);
     coordsS.resize(SPACEDIM*nbNodesS);
     for (int idim=0; idim<SPACEDIM; idim++)
@@ -302,16 +250,36 @@ namespace INTERP_KERNEL
           {for (int idim=0; idim<SPACEDIM; idim++) std::cout << coordsS[SPACEDIM*iS+idim]<< " "; std::cout << std::endl; }
       }
   }
+  
+  /*!
+   * Filtering out zero surfaces and badly oriented surfaces
+   * _orientation = -1,0,1,2
+   * -1 : the intersection is taken into account if target and cells have different orientation
+   * 0 : the intersection is always taken into account
+   * 1 : the intersection is taken into account if target and cells have the same orientation
+   * 2 : the absolute value of intersection is always taken into account 
+   */
+  template<class MyMeshType, class MyMatrix>
+  double PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(double val) const
+  {
+    if(_orientation==0)
+      return val;
+    if(_orientation==2)
+      return fabs(val);
+    if (( val > 0.0 && _orientation==1) || ( val < 0.0 && _orientation==-1 ))
+      return val;
+    return 0.;
+  }
 
   template<class MyMeshType, class MyMatrix>
   int PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB)
   {
-    return projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_median_plane,_do_rotate);
+    return projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_max_distance_3Dsurf_intersect,_median_plane,_do_rotate);
   }
 
   template<class MyMeshType, class MyMatrix>
   int PlanarIntersector<MyMeshType,MyMatrix>::projection(double *Coords_A, double *Coords_B, 
-                                                         int nb_NodesA, int nb_NodesB, double epsilon, double median_plane, bool do_rotate)
+                                                         int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double median_plane, bool do_rotate)
   {
     double normal_A[3]={0,0,0};
     double normal_B[3]={0,0,0};
@@ -344,6 +312,32 @@ namespace INTERP_KERNEL
         normB = sqrt(dotprod<SPACEDIM>(normal_B,normal_B));
       }
 
+    //fabien option
+    if(md3DSurf>0.)
+      {
+        double coords_GA[3];
+        for (int i=0;i<3;i++)
+          {
+            coords_GA[i]=0.;
+            for (int j=0;j<nb_NodesA;j++)
+              coords_GA[i]+=Coords_A[3*j+i];
+            coords_GA[i]/=nb_NodesA;
+          }
+        double G1[3],G2[3],G3[3];
+      for (int i=0;i<3;i++)
+        {
+          G1[i]=Coords_B[i]-coords_GA[i];
+          G2[i]=Coords_B[i+3]-coords_GA[i];
+          G3[i]=Coords_B[i+6]-coords_GA[i];
+        }
+      double prodvect[3];
+      prodvect[0]=G1[1]*G2[2]-G1[2]*G2[1];
+      prodvect[1]=G1[2]*G2[0]-G1[0]*G2[2];
+      prodvect[2]=G1[0]*G2[1]-G1[1]*G2[0];
+      double prodscal=prodvect[0]*G3[0]+prodvect[1]*G3[1]+prodvect[2]*G3[2];
+      if(fabs(prodscal)>md3DSurf)
+        return 0;
+      }
     if(i_A2<nb_NodesA && i_B2<nb_NodesB)
       {
         //Build the normal of the median plane
index ba7be6a43495f0b013087211f0e776c7200c1dfc..bbd3f943427b136f98818ae130dbcc05e6bff8fd 100644 (file)
@@ -32,7 +32,7 @@ namespace INTERP_KERNEL
     typedef typename MyMeshType::MyConnType ConnType;
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   protected:
-    PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel);
+    PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel);
   public:
     int getNumberOfRowsOfResMatrix() const;
     int getNumberOfColsOfResMatrix() const;
index aa51627a077edbf0e6e17f9d2e3f2aabaeb2ac7e..a3dadda581c1af8d82e15defc62b8e5e83634262 100644 (file)
@@ -24,9 +24,9 @@ namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector>
   PlanarIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS,
-                                                                                            double dimCaracteristic, double precision, double medianPlane,
+                                                                                            double dimCaracteristic, double precision, double md3DSurf, double medianPlane,
                                                                                             bool doRotate, int orientation, int printLevel):
-    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,medianPlane,doRotate,orientation,printLevel)
+    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel)
   {
   }
 
@@ -52,12 +52,8 @@ namespace INTERP_KERNEL
         int iS=*iter;
         int nbNodesS=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS];
         double surf=intersectGeometry(OTT<ConnType,numPol>::indFC(icellT),OTT<ConnType,numPol>::indFC(iS),nbNodesT,nbNodesS);
-        //filtering out zero surfaces and badly oriented surfaces
-        // _orientation = -1,0,1
-        // -1 : the intersection is taken into account if target and cells have different orientation
-        // 0 : the intersection is always taken into account
-        // 1 : the intersection is taken into account if target and cells have the same orientation
-        if (( surf > 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation >=0 ) || ( surf < 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation <=0 ))
+        surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf);
+        if(surf!=0.)
           resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),surf));
       }
   }
index 964133cecb94a1c3e0637be0cb42d21cb81bf1f0..a5a53021624a29d076d9cb30382860100b8387b6 100644 (file)
@@ -32,7 +32,7 @@ namespace INTERP_KERNEL
     typedef typename MyMeshType::MyConnType ConnType;
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   protected:
-    PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel);
+    PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel);
   public:
     void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res);
     int getNumberOfRowsOfResMatrix() const;
index ac1969fce0f44815d7d8e21f1a12e96e073507a6..f0f3a5a36a78f1c02198ee9141f794e935c17800 100644 (file)
@@ -26,9 +26,9 @@ namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector>
   PlanarIntersectorP0P1<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS,
-                                                                                              double dimCaracteristic, double precision, double medianPlane,
-                                                                                              bool doRotate, int orientation, int printLevel):
-    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,medianPlane,doRotate,orientation,printLevel)
+                                                                                            double dimCaracteristic, double precision, double md3DSurf, double medianPlane,
+                                                                                            bool doRotate, int orientation, int printLevel):
+    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel)
   {
   }
 
@@ -80,12 +80,8 @@ namespace INTERP_KERNEL
                   orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&sourceCellCoordsTmp[0],quadrangle,sourceCellCoords.size()/SPACEDIM,4);
                 NormalizedCellType tS=PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getTypeOfElement(iS);
                 double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,sourceCellCoordsTmp,CellModel::getCellModel(tS).isQuadratic());
-                //filtering out zero surfaces and badly oriented surfaces
-                // _orientation = -1,0,1
-                // -1 : the intersection is taken into account if target and cells have different orientation
-                // 0 : the intersection is always taken into account
-                // 1 : the intersection is taken into account if target and cells have the same orientation
-                if (( surf > 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation >=0 ) || ( surf < 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation <=0 ))
+                surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf);
+                if(surf!=0.)
                   {
                     typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(iS));
                     if(iterRes==resRow.end())
index 5c2f0934cdd25edbe8a9cdb3d5fa4e2ebb1b86e3..c7b5aaf2364b47cac7af33dcecf169db1d60876a 100644 (file)
@@ -32,7 +32,7 @@ namespace INTERP_KERNEL
     typedef typename MyMeshType::MyConnType ConnType;
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   protected:
-    PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel);
+    PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel);
   public:
     void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res);
     int getNumberOfRowsOfResMatrix() const;
index 209ca229c7e85ce06d81497c49fc2c331b29cf42..577cb16939d635f61b26504eafa524dc9a189941 100644 (file)
@@ -25,9 +25,9 @@ namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector>
   PlanarIntersectorP1P0<MyMeshType,MyMatrix,ConcreteP1P0Intersector>::PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS,
-                                                                                              double dimCaracteristic, double precision, double medianPlane,
-                                                                                              bool doRotate, int orientation, int printLevel):
-    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,medianPlane,doRotate,orientation,printLevel)
+                                                                                            double dimCaracteristic, double precision, double md3DSurf, double medianPlane,
+                                                                                            bool doRotate, int orientation, int printLevel):
+    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel)
   {
   }
 
@@ -80,7 +80,8 @@ namespace INTERP_KERNEL
                 if(SPACEDIM==3)
                   orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&targetCellCoordsTmp[0],quadrangle,targetCellCoords.size()/SPACEDIM,4);
                 double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad);
-                if (( surf > 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation >=0 ) || ( surf < 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation <=0 ))
+                surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf);
+                if(surf!=0.)
                   {
                     typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode));
                     if(iterRes==resRow.end())
index a4012879fb05870dc6e90e6d03931cd4c032dd3e..44854c8ef7bd846d7b79d9f71959baf36f0d0dd9 100644 (file)
@@ -32,7 +32,7 @@ namespace INTERP_KERNEL
     typedef typename MyMeshType::MyConnType ConnType;
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   protected:
-    PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel);
+    PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel);
   public:
     void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res);
     int getNumberOfRowsOfResMatrix() const;
index e00ec61af1a6bcd814bd502198ae9e35406b1d53..66ab5e59dabb250cf924489ca4ccd52a8a32a6f1 100644 (file)
@@ -26,9 +26,9 @@ namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix, class ConcreteP1P1Intersector>
   PlanarIntersectorP1P1<MyMeshType,MyMatrix,ConcreteP1P1Intersector>::PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS,
-                                                                                              double dimCaracteristic, double precision, double medianPlane,
-                                                                                              bool doRotate, int orientation, int printLevel):
-    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,medianPlane,doRotate,orientation,printLevel)
+                                                                                            double dimCaracteristic, double precision, double md3DSurf, double medianPlane,
+                                                                                            bool doRotate, int orientation, int printLevel):
+    PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel)
   {
   }
 
@@ -78,12 +78,8 @@ namespace INTERP_KERNEL
                 if(SPACEDIM==3)
                   orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&polygDualS[0],&polygDualTTmp[0],polygDualS.size()/SPACEDIM,polygDualT.size()/SPACEDIM);
                 double surf=orientation*intersectGeometryGeneral(polygDualTTmp,polygDualS);
-                //filtering out zero surfaces and badly oriented surfaces
-                // _orientation = -1,0,1
-                // -1 : the intersection is taken into account if target and cells have different orientation
-                // 0 : the intersection is always taken into account
-                // 1 : the intersection is taken into account if target and cells have the same orientation
-                if (( surf > 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation >=0 ) || ( surf < 0.0 && PlanarIntersector<MyMeshType,MyMatrix>::_orientation <=0 ))
+                surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf);
+                if(surf!=0.)
                   {
                     typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode));
                     if(iterRes==resRow.end())
index e22c430f7a82b741d8c967e186c2ee22b699eb77..2f93f9c4047629b9df6f8e574d239a7d59d06cb6 100644 (file)
@@ -36,7 +36,7 @@ namespace INTERP_KERNEL
     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   public:
     TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS,
-                             double dimCaracteristic, double precision, double medianPlane, int orientation, int printLevel);
+                             double dimCaracteristic, double precision, double md3DSurf, double medianPlane, int orientation, int printLevel);
     double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS);
     double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad);
     double intersectGeometryGeneral(const std::vector<double>& targetCoords, const std::vector<double>& sourceCoords);
index dfdf9bc2fe0c1304c7985fe0cb2e6aa017220aad..ad7e91efb4d8dfd77e9b2b350b19ad07faf2849e 100644 (file)
@@ -33,9 +33,9 @@ namespace INTERP_KERNEL
 {
   template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType>
   TriangulationIntersector<MyMeshType,MyMatrix,InterpType>::TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, 
-                                                                              double DimCaracteristic, double Precision,
+                                                                              double DimCaracteristic, double Precision, double md3DSurf,
                                                                               double MedianPlane, int orientation, int PrintLevel)
-    :InterpType<MyMeshType,MyMatrix,TriangulationIntersector<MyMeshType,MyMatrix,InterpType> >(meshT,meshS,DimCaracteristic, Precision, MedianPlane, true, orientation, PrintLevel)
+    :InterpType<MyMeshType,MyMatrix,TriangulationIntersector<MyMeshType,MyMatrix,InterpType> >(meshT,meshS,DimCaracteristic, Precision, md3DSurf, MedianPlane, true, orientation, PrintLevel)
   {
     if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 1)
       {
index c5b53a5f820d4474c9bcc5ddc469f25933ba1c94..1443a82a8f40514e96b87f1903e0a04291007b83 100644 (file)
@@ -85,3 +85,9 @@ MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):_name(other._n
       _mesh->incrRef();
     }
 }
+
+
+MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const
+{
+  return _type->buildSubMeshData(start,end,_mesh,di);
+}
index 5f59bccfe07555be9f078197d8d0e689eefcf4c7..40a1b3857d87bd9e4f30585c56fe28dc0ccc7b2a 100644 (file)
@@ -28,6 +28,7 @@
 
 namespace ParaMEDMEM
 {
+  class DataArrayInt;
   class MEDCouplingMesh;
   class MEDCouplingFieldDiscretization;
 
@@ -43,6 +44,7 @@ namespace ParaMEDMEM
     void setDescription(const char *desc) { _desc=desc; }
     const char *getName() const { return _name.c_str(); }
     TypeOfField getEntity() const;
+    MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const;
   protected:
     void updateTime();
   protected:
index 844f67eee486e78f5161dba251c73051ff86f5a5..6987c1bff31c6477270713204f0476b3158cac4f 100644 (file)
@@ -20,6 +20,8 @@
 #include "MEDCouplingMesh.hxx"
 #include "MEDCouplingFieldDouble.hxx"
 
+#include "MEDCouplingPointSet.hxx"
+
 using namespace ParaMEDMEM;
 
 const char MEDCouplingFieldDiscretizationP0::REPR[]="P0";
@@ -89,6 +91,21 @@ MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getWeightingField(cons
   return mesh->getMeasureField();
 }
 
+/*!
+ * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end).
+ * @ param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh.
+ * Example : The first cell id of returned mesh has the (*di)[0] id in 'mesh'
+ */
+MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const
+{
+  MEDCouplingPointSet* ret=((const MEDCouplingPointSet *) mesh)->buildPartOfMySelf(start,end,false);
+  di=DataArrayInt::New();
+  di->alloc(end-start,1);
+  int *pt=di->getPointer();
+  std::copy(start,end,pt);
+  return ret;
+}
+
 TypeOfField MEDCouplingFieldDiscretizationP1::getEnum() const
 {
   return TYPE;
@@ -138,3 +155,28 @@ MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getWeightingField(cons
   //Dual mesh to build
   return 0;
 }
+
+/*!
+ * This method invert array 'di' that is a conversion map from Old to New node numbering to New to Old node numbering.
+ */
+DataArrayInt *MEDCouplingFieldDiscretizationP1::invertArrayO2N2N2O(const MEDCouplingMesh *mesh, const DataArrayInt *di)
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(mesh->getNumberOfNodes(),1);
+  int nbOfOldNodes=di->getNumberOfTuples();
+  const int *old2New=di->getConstPointer();
+  int *pt=ret->getPointer();
+  for(int i=0;i!=nbOfOldNodes;i++)
+    if(old2New[i]!=-1)
+      pt[old2New[i]]=i;
+  return ret;
+}
+
+MEDCouplingMesh *MEDCouplingFieldDiscretizationP1::buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const
+{
+  MEDCouplingPointSet* ret=((const MEDCouplingPointSet *) mesh)->buildPartOfMySelf(start,end,true);
+  DataArrayInt *diInv=ret->zipCoordsTraducer();
+  di=invertArrayO2N2N2O(ret,diInv);
+  diInv->decrRef();
+  return ret;
+}
index 35b83f809832843f2d0b054925bb66a74c7262f4..6061bf20f883e2af6a0193416935cf9d10eb73ff 100644 (file)
@@ -26,6 +26,7 @@
 
 namespace ParaMEDMEM
 {
+  class DataArrayInt;
   class MEDCouplingMesh;
   class DataArrayDouble;
   class MEDCouplingFieldDouble;
@@ -42,6 +43,7 @@ namespace ParaMEDMEM
     virtual void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) = 0;
     virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) = 0;
     virtual MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh) const = 0;
+    virtual MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const = 0;
   };
 
   class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationP0 : public MEDCouplingFieldDiscretization
@@ -55,6 +57,7 @@ namespace ParaMEDMEM
     void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception);
     void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh) const;
+    MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const;
   public:
     static const char REPR[];
     static const TypeOfField TYPE;
@@ -71,6 +74,8 @@ namespace ParaMEDMEM
     void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception);
     void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh) const;
+    MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const;
+    static DataArrayInt *invertArrayO2N2N2O(const MEDCouplingMesh *mesh, const DataArrayInt *di);
   public:
     static const char REPR[];
     static const TypeOfField TYPE;
index abbc4cfd04b882831ea022452897f13629c630db..d4b975eab2bbf0f7577b19ba7d77b4d27e7cbf23 100644 (file)
 #include "MEDCouplingUMeshDesc.hxx"
 #include "MEDCouplingMemArray.hxx"
 
+#include <cmath>
+#include <limits>
+#include <numeric>
+
 using namespace ParaMEDMEM;
 
 MEDCouplingPointSet::MEDCouplingPointSet():_coords(0)
@@ -118,6 +122,38 @@ void MEDCouplingPointSet::getBoundingBox(double *bbox) const
     }
 }
 
+void MEDCouplingPointSet::zipCoords()
+{
+  checkFullyDefined();
+  DataArrayInt *traducer=zipCoordsTraducer();
+  traducer->decrRef();
+}
+
+void MEDCouplingPointSet::rotate(const double *center, const double *vector, double angle)
+{
+  int spaceDim=getSpaceDimension();
+  if(spaceDim==3)
+    rotate3D(center,vector,angle);
+  else if(spaceDim==2)
+    rotate2D(center,angle);
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::rotate : invalid space dim for rotation must be 2 or 3");
+  _coords->declareAsNew();
+  updateTime();
+}
+
+void MEDCouplingPointSet::translate(const double *vector)
+{
+  double *coords=_coords->getPointer();
+  int nbNodes=getNumberOfNodes();
+  int dim=getSpaceDimension();
+  for(int i=0; i<nbNodes; i++)
+    for(int idim=0; idim<dim;idim++)
+      coords[i*dim+idim]+=vector[idim];
+  _coords->declareAsNew();
+  updateTime();
+}
+
 MEDCouplingPointSet *MEDCouplingPointSet::buildInstanceFromMeshType(MEDCouplingMeshType type)
 {
   switch(type)
@@ -219,8 +255,65 @@ bool MEDCouplingPointSet::intersectsBoundingBox(const double* bb1, const double*
     {
       bool intersects = (bbtemp[idim*2]<bb2[idim*2+1])
         && (bb2[idim*2]<bbtemp[idim*2+1]) ;
-      if (!intersects) return false; 
+      if (!intersects)
+        return false; 
     }
   return true;
 }
 
+/*!
+ * 'This' is expected to be of spaceDim==3. Idem for 'center' and 'vect'
+ */
+void MEDCouplingPointSet::rotate3D(const double *center, const double *vect, double angle)
+{
+  double sina=sin(angle);
+  double cosa=cos(angle);
+  double vectorNorm[3];
+  double matrix[9];
+  double matrixTmp[9];
+  double norm=sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]);
+  std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
+  //rotation matrix computation
+  matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa;
+  matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
+  matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
+  matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
+  std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
+  std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
+  matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
+  matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
+  matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
+  std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
+  std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
+  //rotation matrix computed.
+  double *coords=_coords->getPointer();
+  int nbNodes=getNumberOfNodes();
+  double tmp[3];
+  for(int i=0; i<nbNodes; i++)
+    {
+      std::transform(coords+i*3,coords+(i+1)*3,center,tmp,std::minus<double>());
+      coords[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
+      coords[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
+      coords[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
+    }
+}
+
+/*!
+ * 'This' is expected to be of spaceDim==2. Idem for 'center' and 'vect'
+ */
+void MEDCouplingPointSet::rotate2D(const double *center, double angle)
+{
+  double cosa=cos(angle);
+  double sina=sin(angle);
+  double matrix[4];
+  matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
+  double *coords=_coords->getPointer();
+  int nbNodes=getNumberOfNodes();
+  double tmp[2];
+  for(int i=0; i<nbNodes; i++)
+    {
+      std::transform(coords+i*2,coords+(i+1)*2,center,tmp,std::minus<double>());
+      coords[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
+      coords[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
+    }
+}
index 26694f4131f5cdb251def551a017d9e9f8149782..e79f7b20bbde4db0ac9ebdb71ba80be30bcf1c6b 100644 (file)
@@ -44,8 +44,13 @@ namespace ParaMEDMEM
     DataArrayDouble *getCoords() const { return _coords; }
     bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const;
     void getBoundingBox(double *bbox) const;
+    void zipCoords();
+    void rotate(const double *center, const double *vector, double angle);
+    void translate(const double *vector);
     static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type);
     virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const = 0;
+    virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
+    virtual void renumberConnectivity(const int *newNodeNumbers) = 0;
     //! size of returned tinyInfo must be always the same.
     virtual void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
     virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings);
@@ -53,8 +58,12 @@ namespace ParaMEDMEM
     virtual void unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2,
                                  const std::vector<std::string>& littleStrings);
     virtual void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) = 0;
+    virtual DataArrayInt *zipCoordsTraducer() = 0;
   protected:
+    virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception) = 0;
     static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps);
+    void rotate2D(const double *center, double angle);
+    void rotate3D(const double *center, const double *vect, double angle);
   protected:
     DataArrayDouble *_coords;
   };
index 552a96d02bdfd86a1c9640cf210025a9970b5a11..29a27c0ab73dd0d0e03eebd49b874b746619b914 100644 (file)
@@ -22,6 +22,7 @@
 #include "VolSurfFormulae.hxx"
 
 #include <sstream>
+#include <limits>
 
 using namespace ParaMEDMEM;
 
@@ -198,13 +199,6 @@ void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataA
     }
 }
 
-void MEDCouplingUMesh::zipCoords()
-{
-  checkFullyDefined();
-  DataArrayInt *traducer=zipCoordsTraducer();
-  traducer->decrRef();
-}
-
 struct MEDCouplingAccVisit
 {
   MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
@@ -262,6 +256,49 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *start, const
   return ret;
 }
 
+/*!
+ * Keeps from 'this' only cells which constituing point id is in the ids specified by 'start' and 'end'.
+ * The return newly allocated mesh will share the same coordinates as 'this'.
+ * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not.
+ * If 'fullyIn' is true only cells whose ids are \b fully contained in ['start','end') tab will be kept.
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
+{
+  std::set<int> fastFinder(start,end);
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<int> cellIdsKept;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      std::set<int> connOfCell(conn+connIndex[i]+1,conn+connIndex[i+1]);
+      connOfCell.erase(-1);//polyhedron separator
+      int refLgth=std::min(connOfCell.size(),fastFinder.size());
+      std::set<int> locMerge;
+      std::insert_iterator< std::set<int> > it(locMerge,locMerge.begin());
+      std::set_intersection(connOfCell.begin(),connOfCell.end(),fastFinder.begin(),fastFinder.end(),it);
+      if(locMerge.size()==refLgth && fullyIn || locMerge.size()!=0 && !fullyIn)
+        cellIdsKept.push_back(i);
+    }
+  return buildPartOfMySelf(&cellIdsKept[0],&cellIdsKept[cellIdsKept.size()],true);
+}
+
+void MEDCouplingUMesh::renumberConnectivity(const int *newNodeNumbers)
+{
+  int *conn=getNodalConnectivity()->getPointer();
+  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
+      {
+        int& node=conn[iconn];
+        if(node>=0)//avoid polyhedron separator
+          {
+            node=newNodeNumbers[node];
+          }
+      }
+}
+
 /*!
  * Given a boundary box 'bbox' returns elements 'elems' contained in this 'bbox'.
  * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be
@@ -286,16 +323,18 @@ void MEDCouplingUMesh::giveElemsInBoundingBox(const double *bbox, double eps, st
       for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type.
         {
           int node= conn[inode];
-     
-          for (int idim=0; idim<dim; idim++)
+          if(node>=0)//avoid polyhedron separator
             {
-              if ( coords[node*dim+idim] < elem_bb[idim*2] )
-                {
-                  elem_bb[idim*2] = coords[node*dim+idim] ;
-                }
-              if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
+              for (int idim=0; idim<dim; idim++)
                 {
-                  elem_bb[idim*2+1] = coords[node*dim+idim] ;
+                  if ( coords[node*dim+idim] < elem_bb[idim*2] )
+                    {
+                      elem_bb[idim*2] = coords[node*dim+idim] ;
+                    }
+                  if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
+                    {
+                      elem_bb[idim*2+1] = coords[node*dim+idim] ;
+                    }
                 }
             }
         }
@@ -532,10 +571,10 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField() const
                 int N2 = connec[ipt+2];
                 int N3 = connec[ipt+3];
 
-                area_vol[iel]=INTERP_KERNEL::calculateAreaForTria(coords+(dim_space*N1),
-                                                                  coords+(dim_space*N2),
-                                                                  coords+(dim_space*N3),
-                                                                  dim_space);
+                area_vol[iel]=fabs(INTERP_KERNEL::calculateAreaForTria(coords+(dim_space*N1),
+                                                                       coords+(dim_space*N2),
+                                                                       coords+(dim_space*N3),
+                                                                       dim_space));
               }
               break ;
 
@@ -547,11 +586,11 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField() const
                 int N3 = connec[ipt+3];
                 int N4 = connec[ipt+4];
 
-                area_vol[iel]=INTERP_KERNEL::calculateAreaForQuad(coords+dim_space*N1,
-                                                                  coords+dim_space*N2,
-                                                                  coords+dim_space*N3,
-                                                                  coords+dim_space*N4,
-                                                                  dim_space) ;
+                area_vol[iel]=fabs(INTERP_KERNEL::calculateAreaForQuad(coords+dim_space*N1,
+                                                                       coords+dim_space*N2,
+                                                                       coords+dim_space*N3,
+                                                                       coords+dim_space*N4,
+                                                                       dim_space));
               }
               break ;
 
index 1c065e2d1b17784e5e864d89af118d984824f087..f45a780a8a62183904bf7a9e3977b4a230a84e4b 100644 (file)
@@ -57,10 +57,11 @@ namespace ParaMEDMEM
     void unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2,
                          const std::vector<std::string>& littleStrings);
     //tools
-    void zipCoords();
     DataArrayInt *zipCoordsTraducer();
     void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
     MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
+    MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
+    void renumberConnectivity(const int *newNodeNumbers);
     void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCouplingFieldDouble *getMeasureField() const;
   private:
index 995e3f77b16b7480bcb8762e000de48b12422b55..16b07423dc76983645a74de3122add7b2d8fdf23 100644 (file)
@@ -20,6 +20,8 @@
 #include "CellModel.hxx"
 #include "MEDCouplingMemArray.hxx"
 
+#include <limits>
+
 using namespace ParaMEDMEM;
 
 MEDCouplingUMeshDesc::MEDCouplingUMeshDesc():_mesh_dim(-1),_desc_connec(0),_desc_connec_index(0),
@@ -219,12 +221,28 @@ MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, c
   return 0;
 }
 
+MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
+{
+  //not implemented yet
+  return 0;
+}
+
+void MEDCouplingUMeshDesc::renumberConnectivity(const int *newNodeNumbers)
+{
+}
+
 MEDCouplingFieldDouble *MEDCouplingUMeshDesc::getMeasureField() const
 {
   //not implemented yet.
   return 0;
 }
 
+DataArrayInt *MEDCouplingUMeshDesc::zipCoordsTraducer()
+{
+  //not implemented yet.
+  return 0;
+}
+
 void MEDCouplingUMeshDesc::computeTypes()
 {
   if(_desc_connec && _desc_connec_index)
@@ -237,3 +255,9 @@ void MEDCouplingUMeshDesc::computeTypes()
         _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
     }
 }
+
+void MEDCouplingUMeshDesc::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
+{
+  if(!_desc_connec || !_desc_connec_index || !_nodal_connec_face || !_nodal_connec_face_index || !_coords)
+    throw INTERP_KERNEL::Exception("full connectivity and coordinates not set in unstructured mesh.");
+}
index 79641fe6749095fd48cb66af1aa1156ec8a0a2b2..ceced564008d4bae1fef45e9161a4c393547c889 100644 (file)
@@ -49,11 +49,15 @@ namespace ParaMEDMEM
                          const std::vector<std::string>& littleStrings);
     void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
+    MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
+    void renumberConnectivity(const int *newNodeNumbers);
     MEDCouplingFieldDouble *getMeasureField() const;
+    DataArrayInt *zipCoordsTraducer();
   private:
     MEDCouplingUMeshDesc();
     ~MEDCouplingUMeshDesc();
     void computeTypes();
+    void checkFullyDefined() const throw(INTERP_KERNEL::Exception);
   private:
     unsigned _mesh_dim;
     DataArrayInt *_desc_connec;
index 031acfd26cc7864f8749a52691b15f6b5b214837..a3ef044857bc69316bee746ee594e7b1722cd886 100644 (file)
@@ -352,6 +352,54 @@ void MEDCouplingBasicsTest::testBuildPartOfMySelf()
   mesh->decrRef();
 }
 
+void MEDCouplingBasicsTest::testBuildPartOfMySelfNode()
+{
+  MEDCouplingUMesh *mesh=build2DTargetMesh_1();
+  const int tab1[2]={5,7};
+  MEDCouplingPointSet *subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+2,true);
+  MEDCouplingUMesh *subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple);
+  CPPUNIT_ASSERT(subMesh);
+  CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllTypes().size());
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllTypes().begin());
+  CPPUNIT_ASSERT_EQUAL(1,subMesh->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(5,subMesh->getNodalConnectivity()->getNbOfElems());
+  CPPUNIT_ASSERT_EQUAL(2,subMesh->getNodalConnectivityIndex()->getNbOfElems());
+  const int subConn[5]={4,7,8,5,4};
+  const int subConnIndex[3]={0,5};
+  CPPUNIT_ASSERT(std::equal(subConn,subConn+5,subMesh->getNodalConnectivity()->getPointer()));
+  CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+2,subMesh->getNodalConnectivityIndex()->getPointer()));
+  CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords());
+  subMeshSimple->decrRef();
+  //
+  subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+2,false);
+  subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple);
+  CPPUNIT_ASSERT(subMesh);
+  CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllTypes().size());
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllTypes().begin());
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllTypes().begin()));
+  CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(14,subMesh->getNodalConnectivity()->getNbOfElems());
+  CPPUNIT_ASSERT_EQUAL(4,subMesh->getNodalConnectivityIndex()->getNbOfElems());
+  const int subConn2[14]={3,4,5,2,4,6,7,4,3,4,7,8,5,4};
+  const int subConnIndex2[4]={0,4,9,14};
+  CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer()));
+  CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer()));
+  CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords());
+  subMeshSimple->decrRef();
+  //testing the case where length of tab2 is greater than max number of node per cell.
+  const int tab2[7]={0,3,2,1,4,5,6};
+  subMeshSimple=mesh->buildPartOfMySelfNode(tab2,tab2+7,true);
+  subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple);
+  CPPUNIT_ASSERT(subMesh);
+  CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllTypes().size());
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllTypes().begin());
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllTypes().begin()));
+  CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells());
+  subMeshSimple->decrRef();
+  //
+  mesh->decrRef();
+}
+
 void MEDCouplingBasicsTest::testZipCoords()
 {
   MEDCouplingUMesh *mesh=build2DTargetMesh_1();
@@ -808,6 +856,203 @@ void MEDCouplingBasicsTest::test3DSurfInterpP1P0_1()
   targetMesh->decrRef();
 }
 
+void MEDCouplingBasicsTest::test3DSurfInterpP1P1_1()
+{
+  MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1();
+  MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_2();
+  //
+  MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh);
+  INTERP_KERNEL::Interpolation3DSurf myInterpolator;
+  vector<map<int,double> > res;
+  INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D};
+  for(int i=0;i<2;i++)
+    {
+      myInterpolator.setPrecision(1e-12);
+      myInterpolator.setIntersectionType(types[i]);
+      myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1");
+      CPPUNIT_ASSERT_EQUAL(9,(int)res.size());
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[0][0],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[1][0],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[1][1],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[2][1],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[3][0],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666668*sqrt(2.),res[3][2],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1416666666666666*sqrt(2.),res[4][0],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][1],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][2],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09999999999999999*sqrt(2.),res[4][3],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[5][1],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333333*sqrt(2.),res[5][3],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333333*sqrt(2.),res[6][2],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666667*sqrt(2.),res[7][2],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333331*sqrt(2.),res[7][3],1.e-12);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04166666666666668*sqrt(2.),res[8][3],1.e-12);
+      res.clear();
+    }
+  //
+  sourceMesh->decrRef();
+  targetMesh->decrRef();
+}
+
+void MEDCouplingBasicsTest::test3DSurfInterpP0P0_2()
+{
+  MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1();
+  MEDCouplingUMesh *targetMesh=build3DSurfTargetMeshPerm_1();
+  //
+  MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh);
+  INTERP_KERNEL::Interpolation3DSurf myInterpolator;
+  vector<map<int,double> > res;
+  myInterpolator.setPrecision(1e-12);
+  myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation);
+  {
+    myInterpolator.setOrientation(2);
+    myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0");
+    CPPUNIT_ASSERT_EQUAL(5,(int)res.size());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12);
+    res.clear();
+  }
+  {
+    myInterpolator.setOrientation(0);
+    myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0");
+    CPPUNIT_ASSERT_EQUAL(5,(int)res.size());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125*sqrt(2.),res[2][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75*sqrt(2.),sumAll(res),1e-12);
+    res.clear();
+  }
+  {
+    myInterpolator.setOrientation(1);
+    myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0");
+    CPPUNIT_ASSERT_EQUAL(5,(int)res.size());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.875*sqrt(2.),sumAll(res),1e-12);
+    res.clear();
+  }
+  {
+    myInterpolator.setOrientation(-1);
+    myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0");
+    CPPUNIT_ASSERT_EQUAL(5,(int)res.size());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125*sqrt(2.),res[2][0],1e-12);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125*sqrt(2.),sumAll(res),1e-12);
+    res.clear();
+  }
+  //clean up
+  sourceMesh->decrRef();
+  targetMesh->decrRef();
+}
+
+/*!
+ * Test of precision option implemented by Fabien that represents distance of "barycenter" to the other cell.
+ */
+void MEDCouplingBasicsTest::test3DSurfInterpP0P0_3()
+{
+  INTERP_KERNEL::Interpolation3DSurf myInterpolator;
+  vector<map<int,double> > res;
+  double vecTrans[3]={0.,0.,1.e-10};
+  double vec[3]={0.,-1.,0.};
+  double pt[3]={-0.3,-0.3,5.e-11};
+  const int N=32;
+  const double deltaA=M_PI/N;
+  myInterpolator.setPrecision(1e-12);
+  myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation);
+  myInterpolator.setMaxDistance3DSurfIntersect(1e-9);
+  for(int i=0;i<N;i++)
+    {
+      res.clear();
+      MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2();
+      sourceMesh->rotate(pt,vec,i*deltaA);
+      MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2();
+      targetMesh->translate(vecTrans);
+      targetMesh->rotate(pt,vec,i*deltaA);
+      MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh);
+      MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh);
+      myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0");
+      CPPUNIT_ASSERT_EQUAL(2,(int)res.size());
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12);
+      sourceMesh->decrRef();
+      targetMesh->decrRef();
+    }
+  //
+  myInterpolator.setMaxDistance3DSurfIntersect(1e-11);
+  for(int i=0;i<N;i++)
+    {
+      res.clear();
+      MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2();
+      sourceMesh->rotate(pt,vec,i*deltaA);
+      MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2();
+      targetMesh->translate(vecTrans);
+      targetMesh->rotate(pt,vec,i*deltaA);
+      MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh);
+      MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh);
+      myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0");
+      CPPUNIT_ASSERT_EQUAL(2,(int)res.size());
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12);
+      sourceMesh->decrRef();
+      targetMesh->decrRef();
+    }
+  //
+  res.clear();
+  myInterpolator.setMaxDistance3DSurfIntersect(-1.);//unactivate fabien lookup
+  MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2();
+  MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2();
+  targetMesh->translate(vecTrans);
+  myInterpolator.setBoundingBoxAdjustment(1e-11);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper0(sourceMesh);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper0(targetMesh);
+  myInterpolator.interpolateMeshes(sourceWrapper0,targetWrapper0,res,"P0P0");
+  CPPUNIT_ASSERT_EQUAL(2,(int)res.size());
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12);
+  sourceMesh->decrRef();
+  targetMesh->decrRef();
+  //
+  res.clear();
+  sourceMesh=build3DSurfSourceMesh_2();
+  targetMesh=build3DSurfSourceMesh_2();
+  targetMesh->translate(vecTrans);
+  myInterpolator.setBoundingBoxAdjustment(1e-9);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper1(sourceMesh);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper1(targetMesh);
+  myInterpolator.interpolateMeshes(sourceWrapper1,targetWrapper1,res,"P0P0");
+  CPPUNIT_ASSERT_EQUAL(2,(int)res.size());
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12);
+  sourceMesh->decrRef();
+  targetMesh->decrRef();
+  //keeping the same bbox adj == 1.e-11 but trying rotation
+  res.clear();
+  sourceMesh=build3DSurfSourceMesh_2();
+  sourceMesh->rotate(pt,vec,M_PI/4.);
+  targetMesh=build3DSurfSourceMesh_2();
+  targetMesh->translate(vecTrans);
+  targetMesh->rotate(pt,vec,M_PI/4.);
+  myInterpolator.setBoundingBoxAdjustment(1e-11);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper2(sourceMesh);
+  MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper2(targetMesh);
+  myInterpolator.interpolateMeshes(sourceWrapper2,targetWrapper2,res,"P0P0");
+  CPPUNIT_ASSERT_EQUAL(2,(int)res.size());
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12);
+  sourceMesh->decrRef();
+  targetMesh->decrRef();
+}
+
 void MEDCouplingBasicsTest::test3DInterpP0P0_1()
 {
   MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1();
@@ -1049,6 +1294,24 @@ MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_1()
   return sourceMesh;
 }
 
+MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_2()
+{
+  double sourceCoords[12]={-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.};
+  int sourceConn[6]={0,3,1,0,2,3};
+  MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New();
+  sourceMesh->setMeshDimension(2);
+  sourceMesh->allocateCells(2);
+  sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn);
+  sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3);
+  sourceMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(4,3);
+  std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer());
+  sourceMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return sourceMesh;
+}
+
 MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_1()
 {
   double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5};
@@ -1070,6 +1333,30 @@ MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_1()
   return targetMesh;
 }
 
+/*!
+ * Idem build3DSurfTargetMesh_1 except that cell id 2 is not correctly numbered.
+ */
+MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMeshPerm_1()
+{
+  double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5};
+  int targetConn[18]={0,3,4,1, 1,4,2, 4,2,5, 6,7,4,3, 7,8,5,4};
+  MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
+  targetMesh->setMeshDimension(2);
+  targetMesh->allocateCells(5);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14);
+  targetMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(9,3);
+  std::copy(targetCoords,targetCoords+27,myCoords->getPointer());
+  targetMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return targetMesh;
+}
+
 MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_2()
 {
   double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5};
index 167e64e22026a387161bb1bebe27e473b7f1bea5..e3f38c6ec4ef907bec76ed7b829a175d251428d0 100644 (file)
@@ -38,6 +38,7 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testDeepCopy );
     CPPUNIT_TEST( testRevNodal );
     CPPUNIT_TEST( testBuildPartOfMySelf );
+    CPPUNIT_TEST( testBuildPartOfMySelfNode );
     CPPUNIT_TEST( testZipCoords );
     CPPUNIT_TEST( testEqualMesh );
     CPPUNIT_TEST( testEqualFieldDouble );
@@ -49,6 +50,9 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( test3DSurfInterpP0P0_1 );
     CPPUNIT_TEST( test3DSurfInterpP0P1_1 );
     CPPUNIT_TEST( test3DSurfInterpP1P0_1 );
+    CPPUNIT_TEST( test3DSurfInterpP1P1_1 );
+    CPPUNIT_TEST( test3DSurfInterpP0P0_2 );
+    CPPUNIT_TEST( test3DSurfInterpP0P0_3 );
     CPPUNIT_TEST( test3DInterpP0P0_1 );
     CPPUNIT_TEST( test3DInterpP0P1_1 );
     CPPUNIT_TEST( test3DInterpP1P0_1 );
@@ -61,6 +65,7 @@ namespace ParaMEDMEM
     void testDeepCopy();
     void testRevNodal();
     void testBuildPartOfMySelf();
+    void testBuildPartOfMySelfNode();
     void testZipCoords();
     void testEqualMesh();
     void testEqualFieldDouble();
@@ -72,6 +77,9 @@ namespace ParaMEDMEM
     void test3DSurfInterpP0P0_1();
     void test3DSurfInterpP0P1_1();
     void test3DSurfInterpP1P0_1();
+    void test3DSurfInterpP1P1_1();
+    void test3DSurfInterpP0P0_2();
+    void test3DSurfInterpP0P0_3();
     void test3DInterpP0P0_1();
     void test3DInterpP0P1_1();
     void test3DInterpP1P0_1();
@@ -80,7 +88,9 @@ namespace ParaMEDMEM
     MEDCouplingUMesh *build2DTargetMesh_1();
     MEDCouplingUMesh *build2DTargetMesh_2();
     MEDCouplingUMesh *build3DSurfSourceMesh_1();
+    MEDCouplingUMesh *build3DSurfSourceMesh_2();
     MEDCouplingUMesh *build3DSurfTargetMesh_1();
+    MEDCouplingUMesh *build3DSurfTargetMeshPerm_1();
     MEDCouplingUMesh *build3DSurfTargetMesh_2();
     MEDCouplingUMesh *build3DSourceMesh_1();
     MEDCouplingUMesh *build3DTargetMesh_1();
index 27b9aa79dc0e5c337795d62eeec7e119215196e0..b17616c6da8b31cb76b0c321b87c0b3d33bd8047 100644 (file)
@@ -89,7 +89,14 @@ namespace ParaMEDMEM
       delete _local_field;
     delete _icoco_field;
     delete _union_group;
-  }  
+  }
+
+  void DEC::setNature(NatureOfField nature)
+  {
+    if(_local_field)
+      _local_field->getField()->setNature(nature);
+  }
+
   /*! Attaches a local field to a DEC.
     If the processor is on the receiving end of the DEC, the field
     will be updated by a recvData() call.
@@ -154,7 +161,7 @@ namespace ParaMEDMEM
           localgroup=_source_group;
         else
           localgroup=_target_group;
-       //delete _icoco_field;
+        //delete _icoco_field;
         _icoco_field=new ICoCo::MEDField(*const_cast<ICoCo::TrioField* >(triofield), *localgroup);
         attachLocalField(_icoco_field);
         return;
index 50b8dd1c22c484b2cab6b7192ad105d8c06c5435..0f4c545bbe5066d78c83704d02f5804111565853 100644 (file)
@@ -37,7 +37,8 @@ namespace ParaMEDMEM
   {
   public:
     DEC():_local_field(0) { }
-    DEC(ProcessorGroup& source_group, ProcessorGroup& target_group); 
+    DEC(ProcessorGroup& source_group, ProcessorGroup& target_group);
+    void setNature(NatureOfField nature);
     void attachLocalField( MEDCouplingFieldDouble* field);
     void attachLocalField(const ParaFIELD* field);
     void attachLocalField(const ICoCo::Field* field);
index 2d243a4c23a3859bab540db38f26c5e3ba692f37..773aa508690c2dff3bed995cf39da8039bf34ada 100644 (file)
 #include "ElementLocator.hxx"
 #include "Topology.hxx"
 #include "BlockTopology.hxx"
+#include "ParaFIELD.hxx"
 #include "ParaMESH.hxx"
 #include "ProcessorGroup.hxx"
 #include "MPIProcessorGroup.hxx"
+#include "MEDCouplingFieldDouble.hxx"
 
 #include <map>
 #include <set>
@@ -33,12 +35,12 @@ using namespace std;
 
 namespace ParaMEDMEM 
 { 
-  ElementLocator::ElementLocator(const ParaMESH& sourceMesh,
+  ElementLocator::ElementLocator(const ParaFIELD& sourceField,
                                  const ProcessorGroup& distant_group)
-    : _local_para_mesh(sourceMesh),
-      _local_cell_mesh(sourceMesh.getCellMesh()),
-      _local_face_mesh(sourceMesh.getFaceMesh()),
-      _local_group(*sourceMesh.getBlockTopology()->getProcGroup()),
+    : _local_para_field(sourceField),
+      _local_cell_mesh(sourceField.getSupport()->getCellMesh()),
+      _local_face_mesh(sourceField.getSupport()->getFaceMesh()),
+      _local_group(*sourceField.getSupport()->getBlockTopology()->getProcGroup()),
       _distant_group(distant_group)
   { 
     _union_group = _local_group.fuse(distant_group);
@@ -51,6 +53,12 @@ namespace ParaMEDMEM
     delete [] _domain_bounding_boxes;
   }
 
+  const MPI_Comm *ElementLocator::getCommunicator() const
+  {
+    MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group);
+    return group->getComm();
+  }
+
   // ==========================================================================
   // Procedure for exchanging mesh between a distant proc and a local processor
   // param idistantrank  proc id on distant group
@@ -74,6 +82,16 @@ namespace ParaMEDMEM
     vector<int> elems;
     double* distant_bb =  _domain_bounding_boxes+rank*2*dim;
     _local_cell_mesh->giveElemsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems);
+    
+    DataArrayInt *distant_ids_send;
+    MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(&elems[0],&elems[elems.size()],distant_ids_send);
+    _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids);
+    distant_ids_send->decrRef();
+    
+    if(send_mesh)
+      send_mesh->decrRef();
+#if 0
+    int* distant_ids_send=0;
     //send_mesh contains null pointer if elems is empty
     MEDCouplingPointSet* send_mesh = _local_cell_mesh->buildPartOfMySelf(&elems[0],&elems[elems.size()],false);
     // Constituting an array containing the ids of the elements that are 
@@ -81,21 +99,16 @@ namespace ParaMEDMEM
     // This array  enables the correct redistribution of the data when the
     // interpolated field is transmitted to the target array
 
-    int* distant_ids_send=0;
     if (elems.size()>0)
       {
         distant_ids_send = new int[elems.size()];
-        int index=0;
-        for (std::vector<int>::const_iterator iter = elems.begin(); iter!= elems.end(); iter++)
-          {
-            distant_ids_send[index]=*iter;
-            index++;
-          }
+        std::copy(elems.begin(),elems.end(),distant_ids_send);
       }
     _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids);
     delete[] distant_ids_send;
     if(send_mesh)
       send_mesh->decrRef();
+#endif
   }
 
   void ElementLocator::exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth)
@@ -173,7 +186,7 @@ namespace ParaMEDMEM
   void ElementLocator::_exchangeMesh( MEDCouplingPointSet* local_mesh,
                                       MEDCouplingPointSet*& distant_mesh,
                                       int iproc_distant,
-                                      const int* distant_ids_send,
+                                      const DataArrayInt* distant_ids_send,
                                       int*& distant_ids_recv)
   {
     CommInterface comm_interface=_union_group->getCommInterface();
@@ -185,7 +198,7 @@ namespace ParaMEDMEM
     //Getting tiny info of local mesh to allow the distant proc to initialize and allocate
     //the transmitted mesh.
     local_mesh->getTinySerializationInformation(tinyInfoLocal,tinyInfoLocalS);
-    tinyInfoLocal.push_back(local_mesh->getNumberOfCells());
+    tinyInfoLocal.push_back(distant_ids_send->getNumberOfTuples());
     tinyInfoDistant.resize(tinyInfoLocal.size());
     std::fill(tinyInfoDistant.begin(),tinyInfoDistant.end(),0);
     MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group);
@@ -229,7 +242,7 @@ namespace ParaMEDMEM
     else
       distant_mesh_tmp->decrRef();
     distant_ids_recv=new int[tinyInfoDistant.back()];
-    comm_interface.sendRecv((void *)distant_ids_send,tinyInfoLocal.back(), MPI_INT,
+    comm_interface.sendRecv((void *)distant_ids_send->getConstPointer(),tinyInfoLocal.back(), MPI_INT,
                             iprocdistant_in_union, 1113,
                             distant_ids_recv,tinyInfoDistant.back(), MPI_INT,
                             iprocdistant_in_union,1113,
index 82d84c2341658a6d28b5e09c44a628b100391417..38a49bd0cdd1b04b9eb64d43b95893efebd32363 100644 (file)
 
 #include "InterpolationOptions.hxx"
 
+#include <mpi.h>
 #include <vector>
 #include <set>
 
 namespace ParaMEDMEM
 {
-  class ParaMESH;
+  class ParaFIELD;
   class ProcessorGroup;
   class ParaSUPPORT;
   class InterpolationMatrix;
   class MEDCouplingPointSet;
+  class DataArrayInt;
 
   class ElementLocator : public INTERP_KERNEL::InterpolationOptions
   {
   public:
-    ElementLocator(const ParaMESH& sourceMesh, const ProcessorGroup& distant_group);
+    ElementLocator(const ParaFIELD& sourceField, const ProcessorGroup& distant_group);
 
     virtual ~ElementLocator();
     void exchangeMesh(int idistantrank,
                       MEDCouplingPointSet*& target_mesh,
                       int*& distant_ids);
     void exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth);
+    const std::vector<int>& getDistantProcIds() const { return _distant_proc_ids; }
+    const MPI_Comm *getCommunicator() const;
   private:
-    const ParaMESH&  _local_para_mesh ;
+    void _computeBoundingBoxes();
+    bool _intersectsBoundingBox(int irank);
+    void _exchangeMesh(MEDCouplingPointSet* local_mesh, MEDCouplingPointSet*& distant_mesh,
+                       int iproc_distant, const DataArrayInt* distant_ids_send,
+                       int*& distant_ids_recv);
+  private:
+    const ParaFIELD&  _local_para_field ;
     MEDCouplingPointSet* _local_cell_mesh;
     MEDCouplingPointSet* _local_face_mesh;
     std::vector<MEDCouplingPointSet*> _distant_cell_meshes;
@@ -53,12 +63,6 @@ namespace ParaMEDMEM
     const ProcessorGroup& _local_group;
     ProcessorGroup* _union_group;
     std::vector<int> _distant_proc_ids;
-  
-    void _computeBoundingBoxes();
-    bool _intersectsBoundingBox(int irank);
-    void _exchangeMesh(MEDCouplingPointSet* local_mesh, MEDCouplingPointSet*& distant_mesh,
-                       int iproc_distant, const int* distant_ids_send,
-                       int*& distant_ids_recv);
   };
 
 }
diff --git a/src/ParaMEDMEM/GlobalizerMesh.cxx b/src/ParaMEDMEM/GlobalizerMesh.cxx
new file mode 100644 (file)
index 0000000..9092158
--- /dev/null
@@ -0,0 +1,143 @@
+//  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 "GlobalizerMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "CommInterface.hxx"
+
+using namespace std;
+
+namespace ParaMEDMEM
+{
+  GlobalizerMesh::GlobalizerMesh(const MPI_Comm *comm, MEDCouplingFieldDouble *localField):_comm(comm),_local_field(localField)
+  {
+    if(_local_field)
+      _local_field->incrRef();
+  }
+  
+  GlobalizerMesh::~GlobalizerMesh()
+  {
+    if(_local_field)
+      _local_field->decrRef();
+  }
+
+  NatureOfField GlobalizerMesh::getLocalNature() const
+  {
+    return _local_field->getNature();
+  }
+
+  GlobalizerMeshWorkingSide::GlobalizerMeshWorkingSide(const MPI_Comm *comm, MEDCouplingFieldDouble *localField,
+                                                       const std::string& distantMeth, const std::vector<int>& lazyProcs):GlobalizerMesh(comm,localField),_distant_method(distantMeth),_lazy_procs(lazyProcs)
+  {
+  }
+
+  GlobalizerMeshWorkingSide::~GlobalizerMeshWorkingSide()
+  {
+  }
+
+  const std::vector<int>& GlobalizerMeshWorkingSide::getProcIdsInInteraction() const
+  {
+    return _lazy_procs;
+  }
+
+  /*!
+   * connected with GlobalizerMeshLazySide::recvFromWorkingSide
+   */
+  void GlobalizerMeshWorkingSide::sendSumToLazySide(const std::vector< std::vector<int> >& distantLocEltIds, const std::vector< std::vector<double> >& partialSumRelToDistantIds)
+  {
+    int procId=0;
+    CommInterface comm;
+    for(vector<int>::const_iterator iter=_lazy_procs.begin();iter!=_lazy_procs.end();iter++,procId++)
+      {
+        const vector<int>& eltIds=distantLocEltIds[procId];
+        const vector<double>& valued=partialSumRelToDistantIds[procId];
+        int lgth=eltIds.size();
+        comm.send(&lgth,1,MPI_INT,*iter,1114,*_comm);
+        comm.send((void *)&eltIds[0],lgth,MPI_INT,*iter,1115,*_comm);
+        comm.send((void *)&valued[0],lgth,MPI_DOUBLE,*iter,1116,*_comm);
+      }
+  }
+
+  /*!
+   * connected with GlobalizerMeshLazySide::sendToWorkingSide
+   */
+  void GlobalizerMeshWorkingSide::recvSumFromLazySide(std::vector< std::vector<double> >& globalSumRelToDistantIds)
+  {
+    int procId=0;
+    CommInterface comm;
+    MPI_Status status;
+    for(vector<int>::const_iterator iter=_lazy_procs.begin();iter!=_lazy_procs.end();iter++,procId++)
+      {
+        std::vector<double>& vec=globalSumRelToDistantIds[procId];
+        comm.recv(&vec[0],vec.size(),MPI_DOUBLE,*iter,1117,*_comm,&status);
+      }
+  }
+
+  GlobalizerMeshLazySide::GlobalizerMeshLazySide(const MPI_Comm *comm, MEDCouplingFieldDouble *localField, const std::vector<int>& computeProcs):GlobalizerMesh(comm,localField),_compute_procs(computeProcs)
+  {
+  }
+
+  GlobalizerMeshLazySide::~GlobalizerMeshLazySide()
+  {
+  }
+
+  /*!
+   * connected with GlobalizerMeshWorkingSide::sendSumToLazySide
+   */
+  void GlobalizerMeshLazySide::recvFromWorkingSide()
+  {
+    _values_added.resize(_local_field->getNumberOfTuples());
+    int procId=0;
+    CommInterface comm;
+    _ids_per_working_proc.resize(_compute_procs.size());
+    MPI_Status status;
+    for(vector<int>::const_iterator iter=_compute_procs.begin();iter!=_compute_procs.end();iter++,procId++)
+      {
+        int lgth;
+        comm.recv(&lgth,1,MPI_INT,*iter,1114,*_comm,&status);
+        vector<int>& ids=_ids_per_working_proc[procId];
+        ids.resize(lgth);
+        vector<double> values(lgth);
+        comm.recv(&ids[0],lgth,MPI_INT,*iter,1115,*_comm,&status);
+        comm.recv(&values[0],lgth,MPI_DOUBLE,*iter,1116,*_comm,&status);
+        for(int i=0;i<lgth;i++)
+          _values_added[ids[i]]+=values[i];
+      }
+  }
+
+  /*!
+   * connected with GlobalizerMeshWorkingSide::recvSumFromLazySide
+   */
+  void GlobalizerMeshLazySide::sendToWorkingSide()
+  {
+    int procId=0;
+    CommInterface comm;
+    for(vector<int>::const_iterator iter=_compute_procs.begin();iter!=_compute_procs.end();iter++,procId++)
+      {
+        vector<int>& ids=_ids_per_working_proc[procId];
+        vector<double> valsToSend(ids.size());
+        vector<double>::iterator iter3=valsToSend.begin();
+        for(vector<int>::const_iterator iter2=ids.begin();iter2!=ids.end();iter2++,iter3++)
+          *iter3=_values_added[*iter2];
+        comm.send(&valsToSend[0],ids.size(),MPI_DOUBLE,*iter,1117,*_comm);
+        ids.clear();
+      }
+    _ids_per_working_proc.clear();
+  }
+}
+
diff --git a/src/ParaMEDMEM/GlobalizerMesh.hxx b/src/ParaMEDMEM/GlobalizerMesh.hxx
new file mode 100644 (file)
index 0000000..3436545
--- /dev/null
@@ -0,0 +1,72 @@
+//  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 __GLOBALIZERMESH_HXX__
+#define __GLOBALIZERMESH_HXX__
+
+#include "MEDCouplingNatureOfField.hxx"
+
+#include <mpi.h>
+#include <string>
+#include <vector>
+
+namespace ParaMEDMEM
+{
+  class MEDCouplingFieldDouble;
+
+  class GlobalizerMesh
+  {
+  protected:
+    GlobalizerMesh(const MPI_Comm *comm, MEDCouplingFieldDouble *localField);
+  public:
+    NatureOfField getLocalNature() const;
+    virtual ~GlobalizerMesh();
+  protected:
+    const MPI_Comm *_comm;
+    MEDCouplingFieldDouble *_local_field;
+  };
+
+  class GlobalizerMeshWorkingSide : public GlobalizerMesh
+  {
+  public:
+    GlobalizerMeshWorkingSide(const MPI_Comm *comm, MEDCouplingFieldDouble *localField, const std::string& distantMeth, const std::vector<int>& lazyProcs);
+    ~GlobalizerMeshWorkingSide();
+    //
+    const std::vector<int>& getProcIdsInInteraction() const;
+    void sendSumToLazySide(const std::vector< std::vector<int> >& distantLocEltIds, const std::vector< std::vector<double> >& partialSumRelToDistantIds);
+    void recvSumFromLazySide(std::vector< std::vector<double> >& globalSumRelToDistantIds);
+  private:
+    std::string _distant_method;
+    std::vector<int> _lazy_procs;
+  };
+
+  class GlobalizerMeshLazySide : public GlobalizerMesh
+  {
+  public:
+    GlobalizerMeshLazySide(const MPI_Comm *comm, MEDCouplingFieldDouble *localField, const std::vector<int>& computeProcs);
+    ~GlobalizerMeshLazySide();
+    void recvFromWorkingSide();
+    void sendToWorkingSide();
+  private:
+    std::vector<int> _compute_procs;
+    std::vector<double> _values_added;
+    std::vector< std::vector<int> > _ids_per_working_proc;
+  };
+}
+
+#endif
index 9ba7ed5eb76f7013734c951efee569949d0bf1f4..f2e68709113af24102cb174a594b55fdd686dcea 100644 (file)
@@ -94,7 +94,7 @@ namespace ICoCo
       for(int j=0;j<triofield._nodes_per_elem;j++)
         {
           conn[j]=(triofield._connectivity)[i*triofield._nodes_per_elem+j];
-       }
+        }
       _local_mesh->insertNextCell(elemtype,triofield._nodes_per_elem,conn);
     }
     delete[] conn;
index 80e44c9cb3a1d20c1d7c08bd8e95aa97f0d2133b..d75d5428ce502c691c0894714793e673fa5d5438 100644 (file)
@@ -17,6 +17,7 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 #include "ParaMESH.hxx"
+#include "ParaFIELD.hxx"
 #include "ProcessorGroup.hxx"
 #include "MxN_Mapping.hxx"
 #include "InterpolationMatrix.hxx"
@@ -29,6 +30,7 @@
 #include "MEDCouplingNormalizedUnstructuredMesh.txx"
 #include "InterpolationOptions.hxx"
 #include "NormalizedUnstructuredMesh.hxx"
+#include "GlobalizerMesh.hxx"
 
 // class InterpolationMatrix
 // This class enables the storage of an interpolation matrix Wij mapping 
@@ -51,28 +53,23 @@ namespace ParaMEDMEM
   //   param method interpolation method
   //   ====================================================================
 
-  InterpolationMatrix::InterpolationMatrix(ParaMEDMEM::ParaMESH *source_support
+  InterpolationMatrix::InterpolationMatrix(const ParaMEDMEM::ParaFIELD *source_field
                                            const ProcessorGroup& source_group,
                                            const ProcessorGroup& target_group,
                                            const DECOptions& dec_options,
                                            const INTERP_KERNEL::InterpolationOptions& interp_options):
-    _source_support(source_support->getCellMesh()),
+    _source_field(source_field),
+    _source_support(source_field->getSupport()->getCellMesh()),
     _mapping(source_group, target_group, dec_options),
     _source_group(source_group),
     _target_group(target_group),
-    _source_volume(0),
     DECOptions(dec_options),
     INTERP_KERNEL::InterpolationOptions(interp_options)
   {
-    int nbelems = _source_support->getNumberOfCells();
-
+    int nbelems = source_field->getField()->getNumberOfTuples();
     _row_offsets.resize(nbelems+1);
-    for (int i=0; i<nbelems+1; i++)
-      {
-        _row_offsets[i]=0;
-      }
-
     _coeffs.resize(nbelems);
+    _target_volume.resize(nbelems);
   }
 
   InterpolationMatrix::~InterpolationMatrix()
@@ -106,8 +103,8 @@ namespace ParaMEDMEM
       {
         throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions");
       }
-    std::string interpMethod(srcMeth);
-    interpMethod+=targetMeth;
+    std::string interpMethod(targetMeth);
+    interpMethod+=srcMeth;
     //creating the interpolator structure
     vector<map<int,double> > surfaces;
     int colSize=0;
@@ -137,7 +134,7 @@ namespace ParaMEDMEM
         source_wrapper.ReleaseTempArrays();
       }
     else if ( distant_support.getMeshDimension() == 3
-              && distant_support.getSpaceDimension() ==3 )
+              && distant_support.getSpaceDimension() == 3 )
       {
         MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(distant_supportC);
         MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(source_supportC);
@@ -153,22 +150,15 @@ namespace ParaMEDMEM
       }
   
     int source_size=surfaces.size();
+    bool needTargetSurf=isSurfaceComputationNeeded(targetMeth);
 
-    MEDCouplingFieldDouble *target_triangle_surf = distant_support.getMeasureField();
-    MEDCouplingFieldDouble *source_triangle_surf = _source_support->getMeasureField();
-
-    // Storing the source volumes
-    _source_volume.resize(source_size);
-    for (int i=0; i<source_size; i++)
-      {
-        _source_volume[i] = source_triangle_surf->getIJ(i,0);
-      }
-
-    source_triangle_surf->decrRef();
+    MEDCouplingFieldDouble *target_triangle_surf;
+    if(needTargetSurf)
+      target_triangle_surf = distant_support.getMeasureField();
 
     //loop over the elements to build the interpolation
     //matrix structures
-    for (int ielem=0; ielem < surfaces.size(); ielem++) 
+    for (int ielem=0; ielem < source_size; ielem++) 
       {
         _row_offsets[ielem+1] += surfaces[ielem].size();
         //_source_indices.push_back(make_pair(iproc_distant, ielem));
@@ -178,7 +168,9 @@ namespace ParaMEDMEM
              iter++)
           {
             //surface of the target triangle
-            double surf = target_triangle_surf->getIJ(iter->first,0);
+            double surf;
+            if(needTargetSurf)
+              surf = target_triangle_surf->getIJ(iter->first,0);
 
             //locating the (iproc, itriangle) pair in the list of columns
             map<pair<int,int>,int >::iterator iter2 = _col_offsets.find(make_pair(iproc_distant,iter->first));
@@ -189,11 +181,11 @@ namespace ParaMEDMEM
                 //(iproc, itriangle) is not registered in the list
                 //of distant elements
 
-                col_id =_col_offsets.size()+1;
+                col_id =_col_offsets.size();
                 _col_offsets.insert(make_pair(make_pair(iproc_distant,iter->first),col_id));
                 _mapping.addElementFromSource(iproc_distant,
                                               distant_elems[iter->first]);
-                _target_volume.push_back(surf);
+                //target_volume.push_back(surf);
               }
             else 
               {
@@ -204,13 +196,208 @@ namespace ParaMEDMEM
             //ielem is the row,
             //col_id is the number of the column
             //iter->second is the value of the coefficient
-
+            if(needTargetSurf)
+              _target_volume[ielem].push_back(surf);
             _coeffs[ielem].push_back(make_pair(col_id,iter->second));
           }
       }
-    target_triangle_surf->decrRef();
+    if(needTargetSurf)
+      target_triangle_surf->decrRef();
+  }
+
+  void InterpolationMatrix::finishContributionW(GlobalizerMeshWorkingSide& globalizer)
+  {
+    NatureOfField nature=globalizer.getLocalNature();
+    switch(nature)
+      {
+      case ConservativeVolumic:
+        computeConservVolDenoW(globalizer);
+        break;
+      case Integral:
+        computeIntegralDenoW(globalizer);
+        break;
+      case IntegralGlobConstraint:
+        computeGlobConstraintDenoW(globalizer);
+        break;
+      default:
+        throw INTERP_KERNEL::Exception("Not recognized nature of field. Change nature of Field.");
+        break;
+      }
+    /*for(map<pair<int,int>,int>::iterator iter=_col_offsets.begin();iter!=_col_offsets.end();iter++)
+          if((*iter).second==9)
+            cout << (*iter).first.first << " ** " << (*iter).first.second << endl;
+    cout << "--> " << _col_offsets[make_pair(4,74)] << endl;
+    for(vector<vector<pair<int,double> > >::iterator iter3=_coeffs.begin();iter3!=_coeffs.end();iter3++)
+      for(vector<pair<int,double> >::iterator iter4=(*iter3).begin();iter4!=(*iter3).end();iter4++)
+        if((*iter4).first==569)
+          cout << " __ " << iter3-_coeffs.begin() << "___" << (*iter4).second << endl; 
+    ostringstream st; st << "deno_" << _deno_multiply[0][0];
+    ofstream fs(st.str().c_str());
+    for(vector<vector<double> >::iterator iter1=_deno_multiply.begin();iter1!=_deno_multiply.end();iter1++)
+      {
+        for(vector<double>::iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
+          fs << *iter2 << " ";
+        fs << endl;
+        }*/
+  }
+
+  void InterpolationMatrix::finishContributionL(GlobalizerMeshLazySide& globalizer)
+  {
+    NatureOfField nature=globalizer.getLocalNature();
+    switch(nature)
+      {
+      case ConservativeVolumic:
+        computeConservVolDenoL(globalizer);
+        break;
+      case Integral:
+        computeIntegralDenoL(globalizer);
+        break;
+      case IntegralGlobConstraint:
+        computeGlobConstraintDenoL(globalizer);
+        break;
+      default:
+        throw INTERP_KERNEL::Exception("Not recognized nature of field. Change nature of Field.");
+        break;
+      }
+  }
+  
+  void InterpolationMatrix::computeConservVolDenoW(GlobalizerMeshWorkingSide& globalizer)
+  {
+    computeGlobalRowSum(globalizer,_deno_multiply);
+    computeGlobalColSum(_deno_reverse_multiply);
   }
   
+  void InterpolationMatrix::computeConservVolDenoL(GlobalizerMeshLazySide& globalizer)
+  {
+    globalizer.recvFromWorkingSide();
+    globalizer.sendToWorkingSide();
+  }
+
+  void InterpolationMatrix::computeIntegralDenoW(GlobalizerMeshWorkingSide& globalizer)
+  {
+    MEDCouplingFieldDouble *source_triangle_surf = _source_support->getMeasureField();
+    _deno_multiply.resize(_coeffs.size());
+    vector<vector<double> >::iterator iter6=_deno_multiply.begin();
+    const double *values=source_triangle_surf->getArray()->getConstPointer();
+    for(vector<vector<pair<int,double> > >::const_iterator iter4=_coeffs.begin();iter4!=_coeffs.end();iter4++,iter6++,values++)
+      {
+        (*iter6).resize((*iter4).size());
+        std::fill((*iter6).begin(),(*iter6).end(),*values);
+      }
+    source_triangle_surf->decrRef();
+    _deno_reverse_multiply=_target_volume;
+  }
+  
+  /*!
+   * Nothing to do because surface computation is on working side.
+   */
+  void InterpolationMatrix::computeIntegralDenoL(GlobalizerMeshLazySide& globalizer)
+  {
+  }
+
+  void InterpolationMatrix::computeGlobConstraintDenoW(GlobalizerMeshWorkingSide& globalizer)
+  {
+    computeGlobalColSum(_deno_multiply);
+    computeGlobalRowSum(globalizer,_deno_reverse_multiply);
+  }
+
+  void InterpolationMatrix::computeGlobConstraintDenoL(GlobalizerMeshLazySide& globalizer)
+  {
+    globalizer.recvFromWorkingSide();
+    globalizer.sendToWorkingSide();
+  }
+
+  void InterpolationMatrix::computeGlobalRowSum(GlobalizerMeshWorkingSide& globalizer, std::vector<std::vector<double> >& denoStrorage)
+  {
+    //stores id in distant procs sorted by lazy procs connected with
+    vector< vector<int> > rowsPartialSumI;
+    //stores the corresponding values.
+    vector< vector<double> > rowsPartialSumD;
+    computeLocalRowSum(globalizer.getProcIdsInInteraction(),rowsPartialSumI,rowsPartialSumD);
+    globalizer.sendSumToLazySide(rowsPartialSumI,rowsPartialSumD);
+    globalizer.recvSumFromLazySide(rowsPartialSumD);
+    divideByGlobalRowSum(globalizer.getProcIdsInInteraction(),rowsPartialSumI,rowsPartialSumD,denoStrorage);
+  }
+
+  /*!
+   * @param distantProcs in parameter that indicates which lazy procs are concerned.
+   * @param resPerProcI out parameter that must be cleared before calling this method. The size of 1st dimension is equal to the size of 'distantProcs'.
+   *                    It contains the element ids (2nd dimension) of the corresponding lazy proc.
+   * @param  resPerProcD out parameter with the same format than 'resPerProcI'. It contains corresponding sum values.
+   */
+  void InterpolationMatrix::computeLocalRowSum(const std::vector<int>& distantProcs, std::vector<std::vector<int> >& resPerProcI,
+                                               std::vector<std::vector<double> >& resPerProcD) const
+  {
+    resPerProcI.resize(distantProcs.size());
+    resPerProcD.resize(distantProcs.size());
+    std::vector<double> res(_col_offsets.size());
+    for(vector<vector<pair<int,double> > >::const_iterator iter=_coeffs.begin();iter!=_coeffs.end();iter++)
+      for(vector<pair<int,double> >::const_iterator iter3=(*iter).begin();iter3!=(*iter).end();iter3++)
+        res[(*iter3).first]+=(*iter3).second;
+    set<int> procsSet;
+    int id;
+    const vector<std::pair<int,int> >& mapping=_mapping.getSendingIds();
+    for(vector<std::pair<int,int> >::const_iterator iter2=mapping.begin();iter2!=mapping.end();iter2++)
+      {
+        std::pair<set<int>::iterator,bool> isIns=procsSet.insert((*iter2).first);
+        if(isIns.second)
+          id=std::find(distantProcs.begin(),distantProcs.end(),(*iter2).first)-distantProcs.begin();
+        resPerProcI[id].push_back((*iter2).second);
+        resPerProcD[id].push_back(res[iter2-mapping.begin()]);
+      }
+    /*
+    for(map<pair<int,int>, int >::const_iterator iter2=_col_offsets.begin();iter2!=_col_offsets.end();iter2++)
+      {
+        std::pair<set<int>::iterator,bool> isIns=procsSet.insert((*iter2).first.first);
+        if(isIns.second)
+          id=std::find(distantProcs.begin(),distantProcs.end(),(*iter2).first.first)-distantProcs.begin();
+        resPerProcI[id].push_back((*iter2).first.second);
+        resPerProcD[id].push_back(res[(*iter2).second]);
+        }*/
+  }
+
+  void InterpolationMatrix::divideByGlobalRowSum(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& resPerProcI,
+                                                 const std::vector<std::vector<double> >& resPerProcD, std::vector<std::vector<double> >& deno)
+  {
+    map<int,double> fastSums;
+    int procId=0;
+    const vector<std::pair<int,int> >& mapping=_mapping.getSendingIds();
+    map< int, map<int,int> > distIdToLocId;
+    for(map< pair<int,int>,int >::iterator iter8=_col_offsets.begin();iter8!=_col_offsets.end();iter8++)
+          distIdToLocId[(*iter8).first.first][mapping[(*iter8).second].second]=(*iter8).first.second;
+
+    for(vector<int>::const_iterator iter1=distantProcs.begin();iter1!=distantProcs.end();iter1++,procId++)
+      {
+        const std::vector<int>& currentProcI=resPerProcI[procId];
+        const std::vector<double>& currentProcD=resPerProcD[procId];
+        vector<double>::const_iterator iter3=currentProcD.begin();
+        for(vector<int>::const_iterator iter2=currentProcI.begin();iter2!=currentProcI.end();iter2++,iter3++)
+          fastSums[_col_offsets[std::make_pair(*iter1,distIdToLocId[*iter1][*iter2])]]=*iter3;
+      }
+    deno.resize(_coeffs.size());
+    vector<vector<double> >::iterator iter6=deno.begin();
+    for(vector<vector<pair<int,double> > >::const_iterator iter4=_coeffs.begin();iter4!=_coeffs.end();iter4++,iter6++)
+      {
+        (*iter6).resize((*iter4).size());
+        vector<double>::iterator iter7=(*iter6).begin();
+        for(vector<pair<int,double> >::const_iterator iter5=(*iter4).begin();iter5!=(*iter4).end();iter5++,iter7++)
+          *iter7=fastSums[(*iter5).first];
+      }
+  }
+
+  void InterpolationMatrix::computeGlobalColSum(std::vector<std::vector<double> >& denoStrorage)
+  {
+    denoStrorage.resize(_coeffs.size());
+    vector<vector<double> >::iterator iter2=denoStrorage.begin();
+    for(vector<vector<pair<int,double> > >::const_iterator iter1=_coeffs.begin();iter1!=_coeffs.end();iter1++,iter2++)
+      {
+        (*iter2).resize((*iter1).size());
+        double sumOfCurrentRow=0.;
+        for(vector<pair<int,double> >::const_iterator iter3=(*iter1).begin();iter3!=(*iter1).end();iter3++)
+          sumOfCurrentRow+=(*iter3).second;
+        std::fill((*iter2).begin(),(*iter2).end(),sumOfCurrentRow);
+      }
+  }
 
   // ==================================================================
   // The call to this method updates the arrays on the target side
@@ -222,11 +409,11 @@ namespace ParaMEDMEM
 
   void InterpolationMatrix::prepare()
   {
-    int nbelems = _source_support->getNumberOfCells();
+    int nbelems = _source_field->getField()->getNumberOfTuples();
     for (int ielem=0; ielem < nbelems; ielem++)
       {
         _row_offsets[ielem+1]+=_row_offsets[ielem];
-      }  
+      }
     _mapping.prepareSendRecv();
   }
 
@@ -251,7 +438,7 @@ namespace ParaMEDMEM
     //computing the matrix multiply on source side
     if (_source_group.containsMyRank())
       {
-        int nbrows = _source_support->getNumberOfCells();
+        int nbrows = _coeffs.size();
 
         // performing W.S
         // W is the intersection matrix
@@ -266,23 +453,11 @@ namespace ParaMEDMEM
                   {
                     int colid= _coeffs[irow][icol-_row_offsets[irow]].first;
                     double value = _coeffs[irow][icol-_row_offsets[irow]].second;
-                    target_value[(colid-1)*nbcomp+icomp]+=value*coeff_row;
+                    double deno = _deno_multiply[irow][icol-_row_offsets[irow]];
+                    target_value[colid*nbcomp+icomp]+=value*coeff_row/deno;
                   }
               }
           }
-
-        // performing VT^(-1).(W.S)
-        // where VT^(-1) is the inverse of the diagonal matrix containing 
-        // the volumes of target cells
-
-        for (int i=0; i<_col_offsets.size();i++)
-          {
-            for (int icomp=0; icomp<nbcomp; icomp++)
-              {
-                target_value[i*nbcomp+icomp] /= _target_volume[i];
-              }
-          }
-
       }
 
     if (_target_group.containsMyRank())
@@ -317,7 +492,6 @@ namespace ParaMEDMEM
 
   void InterpolationMatrix::transposeMultiply(MEDCouplingFieldDouble& field) const
   {
-    //  int nbcomp = field.getNumberOfComponents();
     int nbcomp = field.getArray()->getNumberOfComponents();
     vector<double> source_value(_col_offsets.size()* nbcomp,0.0);
     _mapping.reverseSendRecv(&source_value[0],field);
@@ -325,7 +499,7 @@ namespace ParaMEDMEM
     //treatment of the transpose matrix multiply on the source side
     if (_source_group.containsMyRank())
       {
-        int nbrows    = _source_support->getNumberOfCells();
+        int nbrows    = _coeffs.size();
         double *array = field.getArray()->getPointer() ;
 
         // Initialization
@@ -340,27 +514,19 @@ namespace ParaMEDMEM
               {
                 int colid    = _coeffs[irow][icol-_row_offsets[irow]].first;
                 double value = _coeffs[irow][icol-_row_offsets[irow]].second;
-          
+                double deno = _deno_reverse_multiply[irow][icol-_row_offsets[irow]];
                 for (int icomp=0; icomp<nbcomp; icomp++)
                   {
-                    double coeff_row = source_value[(colid-1)*nbcomp+icomp];
-                    array[irow*nbcomp+icomp] += value*coeff_row;
+                    double coeff_row = source_value[colid*nbcomp+icomp];
+                    array[irow*nbcomp+icomp] += value*coeff_row/deno;
                   }
               }
           }
-
-        //performing VS^(-1).(WT.T)
-        //VS^(-1) is the inverse of the diagonal matrix storing
-        //volumes of the source cells
-
-        for (int irow=0; irow<nbrows; irow++)
-          {
-            for (int icomp=0; icomp<nbcomp; icomp++)
-              {
-                array[irow*nbcomp+icomp] /= _source_volume[irow];
-              }
-          }
-
       }
   }
+
+  bool InterpolationMatrix::isSurfaceComputationNeeded(const std::string& method) const
+  {
+    return method=="P0";
+  }
 }
index f3ae94344bb4e863ee7fef9da5dae1050918b4a3..53a2829d078427c2327d510e7199eb70a5e64147 100644 (file)
 
 namespace ParaMEDMEM
 {
+  class GlobalizerMeshWorkingSide;
+  class GlobalizerMeshLazySide;
+
   class InterpolationMatrix : public INTERP_KERNEL::InterpolationOptions,
                               public DECOptions
   {
   public:
     
-    InterpolationMatrix(ParaMEDMEM::ParaMESH *source_support
+    InterpolationMatrix(const ParaMEDMEM::ParaFIELD *source_field
                         const ProcessorGroup& source_group,
                         const ProcessorGroup& target_group,
                         const DECOptions& dec_opt,
@@ -41,22 +44,43 @@ namespace ParaMEDMEM
     virtual ~InterpolationMatrix();
     void addContribution(MEDCouplingPointSet& distant_support, int iproc_distant,
                          int* distant_elems, const std::string& srcMeth, const std::string& targetMeth);
+    void finishContributionW(GlobalizerMeshWorkingSide& globalizer);
+    void finishContributionL(GlobalizerMeshLazySide& globalizer);
     void multiply(MEDCouplingFieldDouble& field) const;
     void transposeMultiply(MEDCouplingFieldDouble& field)const;
     void prepare();
     int getNbRows() const { return _row_offsets.size(); }
     MPIAccessDEC* getAccessDEC() { return _mapping.getAccessDEC(); }
   private:
+    void computeConservVolDenoW(GlobalizerMeshWorkingSide& globalizer);
+    void computeIntegralDenoW(GlobalizerMeshWorkingSide& globalizer);
+    void computeGlobConstraintDenoW(GlobalizerMeshWorkingSide& globalizer);
+    void computeConservVolDenoL(GlobalizerMeshLazySide& globalizer);
+    void computeIntegralDenoL(GlobalizerMeshLazySide& globalizer);
+    void computeGlobConstraintDenoL(GlobalizerMeshLazySide& globalizer);
+    
+    void computeLocalColSum(std::vector<double>& res) const;
+    void computeLocalRowSum(const std::vector<int>& distantProcs, std::vector<std::vector<int> >& resPerProcI,
+                            std::vector<std::vector<double> >& resPerProcD) const;
+    void computeGlobalRowSum(GlobalizerMeshWorkingSide& globalizer, std::vector<std::vector<double> >& denoStrorage);
+    void computeGlobalColSum(std::vector<std::vector<double> >& denoStrorage);
+    void divideByGlobalRowSum(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& resPerProcI,
+                              const std::vector<std::vector<double> >& resPerProcD, std::vector<std::vector<double> >& deno);
+  private:
+    bool isSurfaceComputationNeeded(const std::string& method) const;
+  private:
+    const ParaMEDMEM::ParaFIELD *_source_field;
     std::vector<int> _row_offsets;
     std::map<std::pair<int,int>, int > _col_offsets;
-    MEDCouplingPointSet *_source_support; 
+    MEDCouplingPointSet *_source_support;
     MxN_Mapping _mapping;
  
     const ProcessorGroup& _source_group;
     const ProcessorGroup& _target_group;
-    std::vector<double> _target_volume;
-    std::vector<double> _source_volume;
+    std::vector< std::vector<double> > _target_volume;
     std::vector<std::vector<std::pair<int,double> > > _coeffs;
+    std::vector<std::vector<double> > _deno_multiply;
+    std::vector<std::vector<double> > _deno_reverse_multiply;
   };
 }
 
index 6cfa69ef2df9eb836906fd46736d11eec7d8564d..8a97efdaca2b48249c75e06ef72f31314191765d 100644 (file)
@@ -28,8 +28,7 @@
 #include "InterpolationMatrix.hxx"
 #include "IntersectionDEC.hxx"
 #include "ElementLocator.hxx"
-
-
+#include "GlobalizerMesh.hxx"
 
 namespace ParaMEDMEM
 {  
@@ -144,21 +143,21 @@ namespace ParaMEDMEM
   */
   void IntersectionDEC::synchronize()
   {
-    ParaMEDMEM::ParaMESH* para_mesh = _local_field->getSupport();
-    //cout <<"size of Interpolation Matrix"<<sizeof(InterpolationMatrix)<<endl;
-    _interpolation_matrix = new InterpolationMatrix (para_mesh, *_source_group,*_target_group,*this,*this); 
+    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(*para_mesh, *_target_group);
+        ElementLocator locator(*_local_field, *_target_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();
@@ -166,26 +165,26 @@ namespace ParaMEDMEM
 
             //gathers pieces of the target meshes that can intersect the local mesh
             locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids);
-            std::string distantMeth;
-            locator.exchangeMethod(_method,idistant_proc,distantMeth);
             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 "<<idistant_proc_in_union<<" to proc "<<_union_group->myRank()<<std::endl;
                 _interpolation_matrix->addContribution(*distant_mesh,idistant_proc_in_union,distant_ids,_method,distantMeth);
-
                 distant_mesh->decrRef();
                 delete[] distant_ids;
                 distant_mesh=0;
                 distant_ids=0;
               }
-          }  
+          }
+        GlobalizerMeshWorkingSide globalizer(locator.getCommunicator(),_local_field->getField(),distantMeth,locator.getDistantProcIds());
+        _interpolation_matrix->finishContributionW(globalizer);
       }
 
     if (_target_group->containsMyRank())
       {
-        ElementLocator locator(*para_mesh, *_source_group);
+        ElementLocator locator(*_local_field, *_source_group);
         //transfering option from IntersectionDEC to ElementLocator
         locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment());
 
@@ -198,16 +197,18 @@ namespace ParaMEDMEM
             //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<<std::endl;
-            std::string distantMeth;
-            locator.exchangeMethod(_method,idistant_proc,distantMeth);
             if (distant_mesh!=0)
               {
+                std::string distantMeth;
+                locator.exchangeMethod(_method,idistant_proc,distantMeth);
                 distant_mesh->decrRef();
                 delete[] distant_ids;
                 distant_mesh=0;
                 distant_ids=0;
               }
-          }      
+          }
+        GlobalizerMeshLazySide globalizer(locator.getCommunicator(),_local_field->getField(),locator.getDistantProcIds());
+        _interpolation_matrix->finishContributionL(globalizer);
       }
     _interpolation_matrix->prepare();
   }
index b2d0e0bd5d7bcaf531c5aa8de3977fe7e121a736..f164a3c7ee83a6a96253b7261d8fe70cff27dd65 100644 (file)
@@ -54,6 +54,7 @@ InterpolationMatrix.hxx\
 IntersectionDEC.hxx\
 ExplicitCoincidentDEC.hxx\
 ElementLocator.hxx\
+GlobalizerMesh.hxx\
 ExplicitMapping.hxx\
 ICoCoField.hxx \
 ICoCoMEDField.hxx \
@@ -74,6 +75,7 @@ StructuredCoincidentDEC.cxx\
 ExplicitCoincidentDEC.cxx\
 IntersectionDEC.cxx\
 ElementLocator.cxx\
+GlobalizerMesh.cxx\
 MPIAccessDEC.cxx \
 TimeInterpolator.cxx \
 LinearTimeInterpolator.cxx\
index 9e019efe9d81b30fe2d331e087b189f7418bb383..e87a05297039d2a79417cf48ea77a3a29d55659c 100644 (file)
@@ -42,6 +42,9 @@ namespace ParaMEDMEM
     void sendRecv(double* field, MEDCouplingFieldDouble& field) const ;
     void reverseSendRecv(double* field, MEDCouplingFieldDouble& field) const ;
  
+    //
+    const std::vector<std::pair<int,int> >& getSendingIds() const { return _sending_ids; }//tmp
+
     MPIAccessDEC* getAccessDEC(){ return _access_DEC; }
   private :
     ProcessorGroup* _union_group;
index 35b7e859330c796a69bb3439ab2fd23c516f701e..77d95ecfc06cf390b6128816813868d8c4aba215 100644 (file)
@@ -38,6 +38,8 @@ class ParaMEDMEMTest : public CppUnit::TestFixture
   CPPUNIT_TEST(testIntersectionDEC_2D);
   CPPUNIT_TEST(testIntersectionDEC_2DP0P1);
   CPPUNIT_TEST(testIntersectionDEC_3D);
+  CPPUNIT_TEST(testIntersectionDECNonOverlapp_2D_P0P0);
+  CPPUNIT_TEST(testIntersectionDECNonOverlapp_2D_P0P1P1P0);
 
   CPPUNIT_TEST(testSynchronousEqualIntersectionWithoutInterpNativeDEC_2D);
   CPPUNIT_TEST(testSynchronousEqualIntersectionWithoutInterpDEC_2D);
@@ -81,6 +83,8 @@ public:
   void testIntersectionDEC_2D();
   void testIntersectionDEC_2DP0P1();
   void testIntersectionDEC_3D();
+  void testIntersectionDECNonOverlapp_2D_P0P0();
+  void testIntersectionDECNonOverlapp_2D_P0P1P1P0();
 #ifdef MED_ENABLE_FVM
   void testNonCoincidentDEC_2D();
   void testNonCoincidentDEC_3D();
index 27998113f5a7ca70bd738e795cece8ef656a1f80..bb377556d1fead7d6acb5061c585b05f08f17d00 100644 (file)
@@ -229,6 +229,7 @@ void ParaMEDMEMTest::testICocoTrio1()
          else
            dec_emetteur.attachLocalField((ICoCo::Field*) &champ_recepteur);
 
+          dec_emetteur.setNature(ConservativeVolumic);
 
          if(init)
             dec_emetteur.synchronize();
index 0ca5504d4a4adb20408fe5ff7b0dd628a77d8673..ffc0183938e6e2fdda7cf44931d922f57ebf0381 100644 (file)
@@ -138,7 +138,10 @@ void ParaMEDMEMTest::testIntersectionDEC_2D_(const char *srcMeth, const char *ta
       //      ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group);
       ParaMEDMEM::ComponentTopology comptopo;
       if(srcM=="P0")
-        parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+        {
+          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;
@@ -171,7 +174,10 @@ void ParaMEDMEMTest::testIntersectionDEC_2D_(const char *srcMeth, const char *ta
       //      ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group);
       ParaMEDMEM::ComponentTopology comptopo;
       if(targetM=="P0")
-        parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+        {
+          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;
@@ -342,7 +348,10 @@ void ParaMEDMEMTest::testIntersectionDEC_3D_(const char *srcMeth, const char *ta
       //      ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group);
       ParaMEDMEM::ComponentTopology comptopo;
       if(srcM=="P0")
-        parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+        {
+          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;
@@ -375,7 +384,10 @@ void ParaMEDMEMTest::testIntersectionDEC_3D_(const char *srcMeth, const char *ta
       //      ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group);
       ParaMEDMEM::ComponentTopology comptopo;
       if(targetM=="P0")
-        parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+        {
+          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;
@@ -521,6 +533,420 @@ void ParaMEDMEMTest::testAsynchronousFastSourceIntersectionDEC_2D()
   testAsynchronousIntersectionDEC_2D(0.01,1,0.11,1,true,true,true,"P0","P0");
 }
 
+void ParaMEDMEMTest::testIntersectionDECNonOverlapp_2D_P0P0()
+{
+  //
+  const double sourceCoordsAll[2][8]={{0.4,0.5,0.4,1.5,1.6,1.5,1.6,0.5},
+                                      {0.3,-0.5,1.6,-0.5,1.6,-1.5,0.3,-1.5}};
+  const double targetCoordsAll[3][16]={{0.7,1.45,0.7,1.65,0.9,1.65,0.9,1.45,  1.1,1.4,1.1,1.6,1.3,1.6,1.3,1.4},
+                                       {0.7,-0.6,0.7,0.7,0.9,0.7,0.9,-0.6,  1.1,-0.7,1.1,0.6,1.3,0.6,1.3,-0.7},
+                                       {0.7,-1.55,0.7,-1.35,0.9,-1.35,0.9,-1.55,  1.1,-1.65,1.1,-1.45,1.3,-1.45,1.3,-1.65}};
+  int conn4All[8]={0,1,2,3,4,5,6,7};
+  double targetResults[3][2]={{34.,34.},{38.333333333333336,42.666666666666664},{47.,47.}};
+  double targetResults2[3][2]={{0.28333333333333344,0.56666666666666687},{1.8564102564102569,2.0128205128205132},{1.0846153846153845,0.36153846153846159}};
+  double targetResults3[3][2]={{3.7777777777777781,7.5555555555555562},{24.511111111111113,26.355555555555558},{14.1,4.7}};
+  //
+  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<int> self_procs;
+  set<int> procs_source;
+  set<int> procs_target;
+  
+  for (int i=0; i<nproc_source; i++)
+    procs_source.insert(i);
+  for (int i=nproc_source; i<size; i++)
+    procs_target.insert(i);
+  self_procs.insert(rank);
+  //
+  ParaMEDMEM::MEDCouplingUMesh *mesh=0;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::ParaFIELD* parafield=0;
+  ICoCo::Field* icocofield=0;
+  //
+  ParaMEDMEM::CommInterface interface;
+  //
+  ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs);
+  ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target);
+  ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source);
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+  if(source_group->containsMyRank())
+    {
+      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<int> self_procs;
+  set<int> procs_source;
+  set<int> procs_target;
+  
+  for (int i=0; i<nproc_source; i++)
+    procs_source.insert(i);
+  for (int i=nproc_source; i<size; i++)
+    procs_target.insert(i);
+  self_procs.insert(rank);
+  //
+  ParaMEDMEM::MEDCouplingUMesh *mesh=0;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::ParaFIELD *parafieldP0=0,*parafieldP1=0;
+  ICoCo::Field* icocofield=0;
+  //
+  ParaMEDMEM::CommInterface interface;
+  //
+  ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs);
+  ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target);
+  ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source);
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+  if(source_group->containsMyRank())
+    {
+      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
+    {
+      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();
+        }
+      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();
+        }
+      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();
+        }
+      ParaMEDMEM::ComponentTopology comptopo;
+      paramesh=new ParaMESH(mesh,*target_group,"target mesh");
+      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();
+    }
+  else
+    {
+      dec.setMethod("P1");
+      dec.attachLocalField(parafieldP1);
+      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);*/
+    }
+  //
+  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
@@ -592,13 +1018,16 @@ void ParaMEDMEMTest::testAsynchronousIntersectionDEC_2D(double dtA, double tmaxA
       meshname<< "Mesh_2_"<< rank+1;
       
       mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0);
-    
+
       paramesh=new ParaMESH (mesh,*source_group,"source mesh");
     
       //      ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group);
       ParaMEDMEM::ComponentTopology comptopo;
       if(srcM=="P0")
-        parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+        {
+          parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+          parafield->getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic);
+        }
       else
         parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo);
 
@@ -630,12 +1059,15 @@ void ParaMEDMEMTest::testAsynchronousIntersectionDEC_2D(double dtA, double tmaxA
       meshname<< "Mesh_3_"<<rank-nproc_source+1;
       
       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 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+          parafield->getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic);
+        }
       else
         parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo);
       
index 31957b34612b8cce45627d32647baf810319002c..581f7ac2a9abc543a2a1d7f4e942f4eb4d229de2 100755 (executable)
@@ -63,6 +63,7 @@ class ParaMEDMEMBasicsTest(unittest.TestCase):
             paramesh=ParaMESH(mesh,source_group,"source mesh")
             comptopo = ComponentTopology()
             parafield = ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo)
+            parafield.getField().setNature(ConservativeVolumic)
             nb_local=mesh.getNumberOfCells()
             value = [1.0]*nb_local
             parafield.getField().setValues(value)
@@ -77,6 +78,7 @@ class ParaMEDMEMBasicsTest(unittest.TestCase):
             paramesh=ParaMESH(mesh,target_group,"target mesh")
             comptopo = ComponentTopology()
             parafield = ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo)
+            parafield.getField().setNature(ConservativeVolumic)
             nb_local=mesh.getNumberOfCells()
             value = [0.0]*nb_local
             parafield.getField().setValues(value)