]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Merge from V6_main 11/02/2013 V7_siman V6_6_0_SIMAN
authorvsr <vsr@opencascade.com>
Tue, 12 Feb 2013 13:34:55 +0000 (13:34 +0000)
committervsr <vsr@opencascade.com>
Tue, 12 Feb 2013 13:34:55 +0000 (13:34 +0000)
100 files changed:
doc/doxygen/Doxyfile_med_user.in
src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx
src/INTERP_KERNEL/CMakeLists.txt
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx
src/INTERP_KERNEL/InterpolationOptions.cxx
src/INTERP_KERNEL/InterpolationOptions.hxx
src/INTERP_KERNEL/Makefile.am
src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx
src/INTERP_KERNEL/SplitterTetra.hxx
src/INTERP_KERNEL/SplitterTetra.txx
src/INTERP_KERNEL/VolSurfUser.cxx [new file with mode: 0644]
src/INTERP_KERNEL/VolSurfUser.hxx
src/MEDCoupling/CMakeLists.txt
src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx
src/MEDCoupling/MEDCouplingCMesh.cxx
src/MEDCoupling/MEDCouplingCMesh.hxx
src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingDefinitionTime.cxx
src/MEDCoupling/MEDCouplingDefinitionTime.hxx
src/MEDCoupling/MEDCouplingExtrudedMesh.cxx
src/MEDCoupling/MEDCouplingExtrudedMesh.hxx
src/MEDCoupling/MEDCouplingField.cxx
src/MEDCoupling/MEDCouplingField.hxx
src/MEDCoupling/MEDCouplingFieldDiscretization.cxx
src/MEDCoupling/MEDCouplingFieldDiscretization.hxx
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingFieldDouble.hxx
src/MEDCoupling/MEDCouplingGaussLocalization.cxx
src/MEDCoupling/MEDCouplingGaussLocalization.hxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMemArray.txx
src/MEDCoupling/MEDCouplingMesh.cxx
src/MEDCoupling/MEDCouplingMesh.hxx
src/MEDCoupling/MEDCouplingMultiFields.cxx
src/MEDCoupling/MEDCouplingMultiFields.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingRefCountObject.hxx
src/MEDCoupling/MEDCouplingRemapper.cxx
src/MEDCoupling/MEDCouplingStructuredMesh.cxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingStructuredMesh.hxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingTimeDiscretization.cxx
src/MEDCoupling/MEDCouplingTimeDiscretization.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMeshDesc.cxx
src/MEDCoupling/MEDCouplingUMeshDesc.hxx
src/MEDCoupling/Makefile.am
src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx
src/MEDCouplingCorba/CMakeLists.txt
src/MEDCouplingCorba/Client/CMakeLists.txt
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingRemapperTest.py
src/MEDCoupling_Swig/MEDCouplingTypemaps.i
src/MEDLoader/MEDFileData.cxx
src/MEDLoader/MEDFileData.hxx
src/MEDLoader/MEDFileField.cxx
src/MEDLoader/MEDFileField.hxx
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/MEDFileMeshElt.hxx
src/MEDLoader/MEDFileMeshLL.cxx
src/MEDLoader/MEDFileMeshLL.hxx
src/MEDLoader/SauvMedConvertor.cxx
src/MEDLoader/SauvReader.cxx
src/MEDLoader/SauvReader.hxx
src/MEDLoader/SauvUtilities.hxx
src/MEDLoader/SauvWriter.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py
src/MEDLoader/Swig/MEDLoaderTypemaps.i
src/MEDPartitioner/CMakeLists.txt
src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx
src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx
src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx
src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx
src/MEDPartitioner/MEDPARTITIONER_Utils.cxx
src/MEDPartitioner/MEDPARTITIONER_Utils.hxx
src/MEDPartitioner/MEDPARTITIONER_metis.c [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_metis.h [new file with mode: 0644]
src/MEDPartitioner/Makefile.am
src/MEDPartitioner/Test/CMakeLists.txt
src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx
src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx
src/MEDPartitioner/Test/Makefile.am
src/MEDPartitioner/medpartitioner.cxx
src/ParaMEDMEM/ElementLocator.cxx
src/ParaMEDMEM/OverlapElementLocator.cxx

index 7c4a2f7682c4a3dd50d98ca4ae3b6f162d21e4e5..29b43e3d7b4161466a344b85129d3fb7648e5056 100644 (file)
@@ -119,6 +119,8 @@ FILE_PATTERNS          = MEDMEM_GMesh.* \
                          MEDCouplingUMeshDesc.* \
                          MEDCouplingPointSet.* \
                          MEDCouplingCMesh.* \
+                        MEDCouplingStructuredMesh.* \
+                        MEDCouplingCurveLinearMesh.* \
                          MEDCouplingExtrudedMesh.* \
                          MEDCouplingFieldDouble.* \
                          MEDCouplingField.* \
index 3d43cb6d5c2242e29a57429e4596e9d0be8420b8..07633641c9cf283f08f06696a9692618ef677be0 100644 (file)
@@ -61,6 +61,12 @@ namespace INTERP_KERNEL
       NORM_MAXTYPE = 33
     } NormalizedCellType;
 
+  /// 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 GenericMesh
   {};
 }
index 02d8637bdfd75b635defc98d29520c01acb148a3..ae70ca322fe7a87f3c2b866af9eb45aec63535bc 100644 (file)
@@ -37,6 +37,7 @@ SET(interpkernel_SOURCES
   InterpKernelMeshQuality.cxx
   InterpKernelCellSimplify.cxx
   InterpKernelMatrixTools.cxx
+  VolSurfUser.cxx
   Bases/InterpKernelException.cxx
   Geometric2D/InterpKernelGeo2DAbstractEdge.cxx
   Geometric2D/InterpKernelGeo2DBounds.cxx
index b0ee4f1c2a4aeb9426135812efa49fa48d375c01..143bef282a3de961db1560515a0871fc6be91076 100644 (file)
@@ -29,6 +29,7 @@
 #include "NormalizedUnstructuredMesh.hxx"
 
 #include <fstream>
+#include <sstream>
 #include <iomanip>
 #include <cstring>
 #include <limits>
@@ -1144,7 +1145,12 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::
   std::list<QuadraticPolygon *> retPolsUnderContruction;
   std::list<Edge *> edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end());
   std::map<QuadraticPolygon *, std::list<QuadraticPolygon *> > pol1ZipConsumed;
-  while(!pol1Zip.empty() || !edgesInPol2OnBoundaryL.empty())
+  std::size_t maxNbOfTurn=edgesInPol2OnBoundaryL.size(),nbOfTurn=0,iiMNT=0;
+  for(std::list<QuadraticPolygon *>::const_iterator itMNT=pol1Zip.begin();itMNT!=pol1Zip.end();itMNT++,iiMNT++)
+    nbOfTurn+=(*itMNT)->size();
+  maxNbOfTurn=maxNbOfTurn*nbOfTurn; maxNbOfTurn*=maxNbOfTurn;
+  nbOfTurn=0;
+  while(nbOfTurn<maxNbOfTurn && ((!pol1Zip.empty() || !edgesInPol2OnBoundaryL.empty())))
     {
       for(std::list<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();)
         {
@@ -1206,6 +1212,13 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::
           retPolsUnderContruction.push_back(tmp);
           pol1Zip.erase(pol1Zip.begin());
         }
+      nbOfTurn++;
+    }
+  if(nbOfTurn==maxNbOfTurn)
+    {
+      std::ostringstream oss; oss << "Error during reconstruction of residual of cell ! It appears that either source or/and target mesh is/are not conform !";
+      oss << " Number of turns is = " << nbOfTurn << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   for(std::list<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();it1++)
     {
@@ -1215,7 +1228,6 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::
           for(std::list<QuadraticPolygon *>::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++)
             delete *it6;
           delete *it1;
-          it1=retPolsUnderContruction.erase(it1);
         }
     }
 }
index 94ab498ff92e732e03a5fc6b590dbc8de8758831..87f77ab0f8276699b1ce7a7484c5706beb6049e1 100644 (file)
@@ -66,6 +66,22 @@ const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_24_STR[]="GENERAL_
 
 const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_48_STR[]="GENERAL_48";
 
+void INTERP_KERNEL::InterpolationOptions::init()
+{
+  _print_level=0;
+  _intersection_type=Triangulation;
+  _precision=1e-12;
+  _median_plane=DFT_MEDIAN_PLANE;
+  _do_rotate=true;
+  _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS;
+  _bounding_box_adjustment_abs=0.;
+  _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT;
+  _orientation=0;
+  _measure_abs=true;
+  _splitting_policy=PLANAR_FACE_5;
+  _P1P0_bary_method=false;
+}
+
 std::string INTERP_KERNEL::InterpolationOptions::getIntersectionTypeRepr() const
 {
   if(_intersection_type==INTERP_KERNEL::Triangulation)
index 6ba269bb7427b11c515bd71688baf11a786f217e..e8daeba44ac01ba8e58b9ac7629e721e0a5f0567 100644 (file)
 #define __INTERPOLATIONOPTIONS_HXX__
 
 #include "INTERPKERNELDefines.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
 
 #include <string>
 
 namespace INTERP_KERNEL
 {
   typedef enum { Triangulation, Convex, Geometric2D, PointLocator } 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
@@ -101,21 +97,8 @@ namespace INTERP_KERNEL
 
     std::string filterInterpolationMethod(const std::string& meth) const;
 
-    void init()
-    {  
-      _print_level=0;
-      _intersection_type=Triangulation;
-      _precision=1e-12;
-      _median_plane=DFT_MEDIAN_PLANE;
-      _do_rotate=true;
-      _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS;
-      _bounding_box_adjustment_abs=0.;
-      _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT;
-      _orientation=0;
-      _measure_abs=true;
-      _splitting_policy=GENERAL_48;
-      _P1P0_bary_method=false;
-    }
+    void init();
+    
     bool setInterpolationOptions(long print_level,
                                  std::string intersection_type,
                                  double precision,
index 25258d67c7aa8261cfc8e5184cbc6c95de4cef82..a2132782424b1738cb8c7b80ba52c8ade9671cb1 100644 (file)
@@ -218,6 +218,7 @@ dist_libinterpkernel_la_SOURCES = \
        TranslationRotationMatrix.cxx \
        TetraAffineTransform.cxx \
        CellModel.cxx \
+       VolSurfUser.cxx \
        UnitTetraIntersectionBary.cxx \
        InterpolationOptions.cxx \
        DirectedBoundingBox.cxx \
index ba5ea83b8fac3613406424bae70799ed8f2a6702..e3a71c91ef084490932e0422ccfe6fc7bfb5694f 100644 (file)
@@ -84,7 +84,10 @@ namespace INTERP_KERNEL
       {
         double volume = 0.;
         for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter)
+          {
             volume += (*iter)->intersectSourceCell(*iterCellS);
+            (*iter)->clearVolumesCache();
+          }
         if(volume!=0.)
           res[targetCell].insert(std::make_pair(OTT<ConnType,numPol>::indFC(*iterCellS), volume));
       }
index d535b9c3787ed855b1d4e216cd500e5e964e64fc..a58828ccca52583e77d57ae8d0ca5d14afb202a0 100644 (file)
 #include "InterpKernelHashMap.hxx"
 #include "VectorUtils.hxx"
 
-#include <assert.h>
-#include <vector>
 #include <functional>
+#include <vector>
+#include <cassert>
 #include <map>
 #include <set>
 
 namespace INTERP_KERNEL
 {
+  // Schema according to which the splitting is performed.
+    // Each line represents one tetrahedron. The numbering is as follows :
+    //
+    //          7 ------ 6
+    //         /|       /|
+    //        / |      / |
+    //       3 ------ 2  |
+    //       |  |     |  |
+    //       |  |     |  |
+    //       |  4-----|- 5
+    //       | /      | /
+    //       0 ------ 1
+
+  static const int SPLIT_NODES_5[20] = /* WHY not all well oriented ???? */
+    {
+      0, 1, 5, 2,
+      0, 4, 5, 7,
+      0, 3, 7, 2,
+      5, 6, 7, 2,
+      0, 2, 5, 7
+    };
+
+  static const int SPLIT_NODES_5_WO[20] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */
+    {
+      0, 5, 1, 2,
+      0, 4, 5, 7,
+      0, 3, 7, 2,
+      5, 7, 6, 2,
+      0, 5, 2, 7
+    };
+
+  static const int SPLIT_NODES_6[24] = /* WHY all badly oriented ???? */
+    {
+      0, 1, 5, 6,
+      0, 2, 1, 6,
+      0, 5, 4, 6,
+      0, 4, 7, 6,
+      0, 3, 2, 6,
+      0, 7, 3, 6
+    };
+  
+  static const int SPLIT_NODES_6_WO[24] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */
+    {
+      0, 5, 1, 6,
+      0, 1, 2, 6,
+      0, 4, 5, 6,
+      0, 7, 4, 6,
+      0, 2, 3, 6,
+      0, 3, 7, 6
+    };
+  
+  // Each sub-node is the barycenter of 4 other nodes.
+  // For the faces, these are on the orignal mesh.
+  // For the barycenter, the four face sub-nodes are used.
+  static const int GENERAL_24_SUB_NODES[28] = 
+    {
+      0,1,4,5,// sub-node 8  (face)
+      0,1,2,3,// sub-node 9  (face)
+      0,3,4,7,// sub-node 10 (face)
+      1,2,5,6,// sub-node 11 (face)
+      4,5,6,7,// sub-node 12 (face)
+      2,3,6,7,// sub-node 13 (face)
+      8,9,10,11// sub-node 14 (cell)
+    };
+  
+  static const int TETRA_EDGES_GENERAL_24[48] = 
+    {
+      // face with center 8
+      0,1,
+      1,5,
+      5,4,
+      4,0,
+      // face with center 9
+      0,1,
+      1,2,
+      2,3,
+      3,0,
+      // face with center 10
+      0,4,
+      4,7,
+      7,3,
+      3,0,
+      // face with center 11
+      1,5,
+      5,6,
+      6,2,
+      2,1,
+      // face with center 12
+      5,6,
+      6,7,
+      7,4,
+      4,5,
+      // face with center 13
+      2,6,
+      6,7,
+      7,3,
+      3,2
+    };
+  
   /**
    * \brief Class representing a triangular face, used as key in caching hash map in SplitterTetra.
    *
index e36dd0ae55170ba11f1371a016aedc3f76eeeae8..61b2854d6e1e9797713fabb8637ea845d84c0b65 100644 (file)
@@ -1029,30 +1029,7 @@ namespace INTERP_KERNEL
    */
   template<class MyMeshTypeT, class MyMeshTypeS>
   void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::fiveSplit(const int* const subZone, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra)
-  {
-    // Schema according to which the splitting is performed.
-    // Each line represents one tetrahedron. The numbering is as follows :
-    //
-    //          7 ------ 6
-    //         /|       /|
-    //        / |      / |
-    //       3 ------ 2  |
-    //       |  |     |  |
-    //       |  |     |  |
-    //       |  4-----|- 5
-    //       | /      | /
-    //       0 ------ 1
-
-
-    static const int SPLIT_NODES_5[20] = 
-      {
-        0, 1, 5, 2,
-        0, 4, 5, 7,
-        0, 3, 7, 2,
-        5, 6, 7, 2,
-        0, 2, 5, 7
-      };
-    
+  { 
     // create tetrahedra
     for(int i = 0; i < 5; ++i)
       {
@@ -1078,29 +1055,6 @@ namespace INTERP_KERNEL
   template<class MyMeshTypeT, class MyMeshTypeS>
   void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::sixSplit(const int* const subZone, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra)
   {
-    // Schema according to which the splitting is performed.
-    // Each line represents one tetrahedron. The numbering is as follows :
-    //
-    //          7 ------ 6
-    //         /|       /|
-    //        / |      / |
-    //       3 ------ 2  |
-    //       |  |     |  |
-    //       |  |     |  |
-    //       |  4-----|- 5
-    //       | /      | /
-    //       0 ------ 1
-
-    static const int SPLIT_NODES_6[24] = 
-      {
-        0, 1, 5, 6,
-        0, 2, 1, 6,
-        0, 5, 4, 6,
-        0, 4, 7, 6,
-        0, 3, 2, 6,
-        0, 7, 3, 6
-      };
-
     for(int i = 0; i < 6; ++i)
       {
         const double* nodes[4];
@@ -1128,39 +1082,6 @@ namespace INTERP_KERNEL
     // The two nodes of the original mesh cell used in each tetrahedron.
     // The tetrahedra all have nodes (cellCenter, faceCenter, edgeNode1, edgeNode2)
     // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes
-    static const int TETRA_EDGES[48] = 
-      {
-        // face with center 9
-        0,1,
-        1,5,
-        5,4,
-        4,0,
-        // face with center 10
-        0,1,
-        1,2,
-        2,3,
-        3,0,
-        // face with center 11
-        0,4,
-        4,7,
-        7,3,
-        3,0,
-        // face with center 12
-        1,5,
-        5,6,
-        6,2,
-        2,1,
-        // face with center 13
-        5,6,
-        6,7,
-        7,4,
-        4,5,
-        // face with center 14
-        2,6,
-        6,7,
-        7,3,
-        3,2
-      };
     
     // nodes to use for tetrahedron
     const double* nodes[4];
@@ -1177,8 +1098,8 @@ namespace INTERP_KERNEL
         for(int j = 0; j < 4; ++j)
           {
             const int row = 4*(faceCenterNode - 8) + j;
-            conn[2] = TETRA_EDGES[2*row];
-            conn[3] = TETRA_EDGES[2*row + 1];
+            conn[2] = TETRA_EDGES_GENERAL_24[2*row];
+            conn[3] = TETRA_EDGES_GENERAL_24[2*row + 1];
             nodes[2] = getCoordsOfSubNode(conn[2]);
             nodes[3] = getCoordsOfSubNode(conn[3]);
 
@@ -1341,20 +1262,6 @@ namespace INTERP_KERNEL
           {
           case GENERAL_24:
             {
-              // Each sub-node is the barycenter of 4 other nodes.
-              // For the faces, these are on the orignal mesh.
-              // For the barycenter, the four face sub-nodes are used.
-              static const int GENERAL_24_SUB_NODES[28] = 
-                {
-                  0,1,4,5,// sub-node 9 (face)
-                  0,1,2,3,// sub-node 10 (face)
-                  0,3,4,7,// sub-node 11 (face)
-                  1,2,5,6,// sub-node 12 (face)
-                  4,5,6,7,// sub-node 13 (face)
-                  2,3,6,7,// sub-node 14 (face)
-                  8,9,10,11// sub-node 15 (cell)
-                };
-
               for(int i = 0; i < 7; ++i)
                 {
                   double* barycenter = new double[3];
diff --git a/src/INTERP_KERNEL/VolSurfUser.cxx b/src/INTERP_KERNEL/VolSurfUser.cxx
new file mode 100644 (file)
index 0000000..2883825
--- /dev/null
@@ -0,0 +1,138 @@
+// Copyright (C) 2007-2012  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
+//
+// Author : Anthony Geay (CEA/DEN)
+
+#include "VolSurfUser.hxx"
+#include "InterpKernelAutoPtr.hxx"
+
+#include <cmath>
+#include <limits>
+#include <algorithm>
+
+namespace INTERP_KERNEL
+{
+  double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception)
+  {
+    double dx=pt1Seg2[0]-pt0Seg2[0],dy=pt1Seg2[1]-pt0Seg2[1];
+    double norm=sqrt(dx*dx+dy*dy);
+    if(norm==0.)
+      return std::numeric_limits<double>::max();
+    dx/=norm; dy/=norm;
+    double dx2=pt[0]-pt0Seg2[0],dy2=pt[1]-pt0Seg2[1];
+    double dotP=(dx2*dx+dy2*dy);
+    if(dotP<0. || dotP>norm)
+      return std::numeric_limits<double>::max();
+    double x=pt0Seg2[0]+dotP*dx,y=pt0Seg2[1]+dotP*dy;
+    return (x-pt[0])*(x-pt[0])+(y-pt[1])*(y-pt[1]);
+  }
+
+  double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception)
+  {
+    double matrix[12];
+    if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(pt0Tri3,pt1Tri3,pt2Tri3,matrix))
+      return std::numeric_limits<double>::max();
+    double xy0[2],xy1[2],xy2[2],xy[2]; xy0[0]=0.; xy0[1]=0.;
+    xy1[0]=matrix[0]*pt1Tri3[0]+matrix[1]*pt1Tri3[1]+matrix[2]*pt1Tri3[2]+matrix[3]; xy1[1]=0.;
+    xy2[0]=matrix[0]*pt2Tri3[0]+matrix[1]*pt2Tri3[1]+matrix[2]*pt2Tri3[2]+matrix[3];
+    xy2[1]=matrix[4]*pt2Tri3[0]+matrix[5]*pt2Tri3[1]+matrix[6]*pt2Tri3[2]+matrix[7];
+    xy[0]=matrix[0]*pt[0]+matrix[1]*pt[1]+matrix[2]*pt[2]+matrix[3];
+    xy[1]=matrix[4]*pt[0]+matrix[5]*pt[1]+matrix[6]*pt[2]+matrix[7];
+    double z=matrix[8]*pt[0]+matrix[9]*pt[1]+matrix[10]*pt[2]+matrix[11];
+    double ret=std::numeric_limits<double>::max();
+    int nbOfHint=0;
+    if(xy[0]>0. && xy[0]<xy1[0])
+      { ret=std::min(ret,sqrt(z*z+xy[1]*xy[1])); nbOfHint++; } //distance pt to edge [pt0Tri3,pt1Tri3]
+    double tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,xy1,xy2); //distance pt to edge [pt1Tri3,pt2Tri3]
+    if(tmp!=std::numeric_limits<double>::max())
+      { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; }
+    tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,xy2,xy0);//distance pt to edge [pt2Tri3,pt0Tri3]
+    if(tmp!=std::numeric_limits<double>::max())
+      { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; }
+    if(nbOfHint==3)
+      ret=std::min(ret,fabs(z));
+    return ret;
+  }
+
+  double DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords) throw(INTERP_KERNEL::Exception)
+  {
+    std::size_t nbOfEdges=std::distance(connOfPolygonBg,connOfPolygonEnd);
+    if(nbOfEdges<3)
+      throw INTERP_KERNEL::Exception("DistanceFromPtToPolygonInSpaceDim3 : trying to compute a distance to a polygon containing less than 3 edges !");
+    double baryOfNodes[3]={0.,0.,0.};
+    for(std::size_t i=0;i<nbOfEdges;i++)
+      { baryOfNodes[0]+=coords[3*connOfPolygonBg[i]]; baryOfNodes[1]+=coords[3*connOfPolygonBg[i]+1]; baryOfNodes[2]+=coords[3*connOfPolygonBg[i]+2]; }
+    std::transform(baryOfNodes,baryOfNodes+3,baryOfNodes,std::bind2nd(std::multiplies<double>(),1./((double)nbOfEdges)));
+    double matrix[12];
+    if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(coords+3*connOfPolygonBg[0],coords+3*connOfPolygonBg[1],baryOfNodes,matrix))
+      return std::numeric_limits<double>::max();
+    INTERP_KERNEL::AutoPtr<double> ptXY=new double[2*nbOfEdges]; ptXY[0]=0.; ptXY[1]=0.;
+    ptXY[2]=matrix[0]*coords[3*connOfPolygonBg[1]]+matrix[1]*coords[3*connOfPolygonBg[1]+1]+matrix[2]*coords[3*connOfPolygonBg[1]+2]+matrix[3]; ptXY[3]=0.;
+    for(std::size_t i=2;i<nbOfEdges;i++)
+      {
+        ptXY[2*i]=matrix[0]*coords[3*connOfPolygonBg[i]]+matrix[1]*coords[3*connOfPolygonBg[i]+1]+matrix[2]*coords[3*connOfPolygonBg[i]+2]+matrix[3];
+        ptXY[2*i+1]=matrix[4]*coords[3*connOfPolygonBg[i]]+matrix[5]*coords[3*connOfPolygonBg[i]+1]+matrix[6]*coords[3*connOfPolygonBg[i]+2]+matrix[7];
+      }
+    double xy[2]={matrix[0]*pt[0]+matrix[1]*pt[1]+matrix[2]*pt[2]+matrix[3],matrix[4]*pt[0]+matrix[5]*pt[1]+matrix[6]*pt[2]+matrix[7]};
+    double z=matrix[8]*pt[0]+matrix[9]*pt[1]+matrix[10]*pt[2]+matrix[11];
+    double ret=std::numeric_limits<double>::max();
+    std::size_t nbOfHint=0;
+    for(std::size_t i=0;i<nbOfEdges;i++)
+      {
+        double tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,((double *)ptXY)+2*i,((double *)ptXY)+2*((i+1)%nbOfEdges));
+        if(tmp!=std::numeric_limits<double>::max())
+          { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; }
+      }
+    if(nbOfHint==nbOfEdges)
+      ret=std::min(ret,fabs(z));
+    return ret;
+  }
+
+  /*!
+   * \param [out] matrix contain a dense matrix of size 12 with 3 rows containing each 4 colums. This matrix is the reduction of 4x4 matrix but the last
+   *              line containing [0,0,0,1] is omitted.
+   */
+  bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *p0, const double *p1, const double *p2, double *matrix)
+  {
+    double norm=sqrt((p1[0]-p0[0])*(p1[0]-p0[0])+(p1[1]-p0[1])*(p1[1]-p0[1])+(p1[2]-p0[2])*(p1[2]-p0[2]));
+    double c=(p1[0]-p0[0])/norm;
+    double s=sqrt(1-c*c);
+    double y=p1[2]-p0[2],z=p0[1]-p1[1];
+    norm=sqrt(y*y+z*z);
+    if(norm!=0.)
+      { y/=norm; z/=norm; }
+    double r0[9]={c,-z*s,y*s,
+                  z*s,y*y*(1-c)+c,y*z*(1-c),
+                  -y*s,z*y*(1-c),z*z*(1-c)+c};
+    // 2nd rotation matrix
+    double x=p2[0]-p0[0];
+    y=p2[1]-p0[1]; z=p2[2]-p0[2];
+    double y1=x*r0[3]+y*r0[4]+z*r0[5],z1=x*r0[6]+y*r0[7]+z*r0[8];
+    c=y1/sqrt(y1*y1+z1*z1);
+    s=sqrt(1.-c*c);
+    //
+    std::copy(r0,r0+3,matrix);
+    matrix[4]=c*r0[3]-s*r0[6]; matrix[5]=c*r0[4]-s*r0[7]; matrix[6]=c*r0[5]-s*r0[8];
+    matrix[8]=s*r0[3]+c*r0[6]; matrix[9]=s*r0[4]+c*r0[7]; matrix[10]=s*r0[5]+c*r0[8];
+    matrix[3]=-p0[0]*matrix[0]-p0[1]*matrix[1]-p0[2]*matrix[2];
+    matrix[7]=-p0[0]*matrix[4]-p0[1]*matrix[5]-p0[2]*matrix[6];
+    matrix[11]=-p0[0]*matrix[8]-p0[1]*matrix[9]-p0[2]*matrix[10];
+    return true;
+  }
+}
+
index e6f877bf48cbe1a17a93e431e1179c0d220389fd..20899dc59f3e547ade4136575f8326b11532fc1f 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef __VOLSURFUSER_HXX__
 #define __VOLSURFUSER_HXX__
 
+#include "InterpKernelException.hxx"
 #include "NormalizedUnstructuredMesh.hxx"
 
 namespace INTERP_KERNEL
@@ -36,6 +37,14 @@ namespace INTERP_KERNEL
 
   template<class ConnType, NumberingPolicy numPolConn>
   void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res);
+
+  double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception);
+
+  double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception);
+
+  double DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords) throw(INTERP_KERNEL::Exception);
+
+  bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3, double *matrix);
 }
 
 #endif
index ad1c6fa2b4f20addc470ee3f5504e4168fd7bfe4..a8d57ffb9993792fac3bccdb1dd72fdaa6ba640a 100644 (file)
@@ -36,6 +36,8 @@ SET(medcoupling_SOURCES
   MEDCouplingMemArray.cxx
   MEDCouplingTimeLabel.cxx
   MEDCouplingCMesh.cxx
+  MEDCouplingCurveLinearMesh.cxx
+  MEDCouplingStructuredMesh.cxx
   MEDCouplingTimeDiscretization.cxx
   MEDCouplingFieldDiscretization.cxx
   MEDCouplingRefCountObject.cxx
index fc0c0f4e9a5de28061d285c7dea7c935cbdb0895..563a5838f0eeeb2aaf62193a6fdc74aa42838ad9 100644 (file)
@@ -41,6 +41,7 @@ namespace ParaMEDMEM
     const T& operator*() const { return *_ptr; }
     operator T *() { return _ptr; }
     operator const T *() const { return _ptr; }
+    T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; }
   private:
     void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); }
     void destroyPtr() { if(_ptr) _ptr->decrRef(); }
index 2276b4d28e2e46353802dc9c68cfe20b6f0407b7..1ae822817d6032d37b8d0c1211fd7e74f44d814f 100644 (file)
@@ -19,7 +19,6 @@
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDCouplingCMesh.hxx"
-#include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingMemArray.hxx"
 #include "MEDCouplingFieldDouble.hxx"
 
@@ -34,7 +33,7 @@ MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0)
 {
 }
 
-MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingMesh(other)
+MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy)
 {
   if(deepCopy)
     {
@@ -107,6 +106,18 @@ void MEDCouplingCMesh::updateTime() const
     updateTimeWith(*_z_array);
 }
 
+std::size_t MEDCouplingCMesh::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  std::set<DataArrayDouble *> s;
+  s.insert(_x_array); s.insert(_y_array); s.insert(_z_array);
+  s.erase(NULL);
+  for(std::set<DataArrayDouble *>::const_iterator it=s.begin();it!=s.end();it++)
+    if(*it)
+      ret+=(*it)->getHeapMemorySize();
+  return MEDCouplingStructuredMesh::getHeapMemorySize()+ret;
+}
+
 /*!
  * This method copyies all tiny strings from other (name and components name).
  * @throw if other and this have not same mesh type.
@@ -116,7 +127,7 @@ void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(I
   const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
-  MEDCouplingMesh::copyTinyStringsFrom(other);
+  MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
   if(_x_array && otherC->_x_array)
     _x_array->copyStringInfoFrom(*otherC->_x_array);
   if(_y_array && otherC->_y_array)
@@ -307,35 +318,11 @@ void MEDCouplingCMesh::getSplitNodeValues(int *res) const
     }
 }
 
-int MEDCouplingCMesh::getCellIdFromPos(int i, int j, int k) const
-{
-  int tmp[3]={i,j,k};
-  int tmp2[3];
-  int spaceDim=getSpaceDimension();
-  getSplitCellValues(tmp2);
-  std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
-  return std::accumulate(tmp,tmp+spaceDim,0);
-}
-
-int MEDCouplingCMesh::getNodeIdFromPos(int i, int j, int k) const
+void MEDCouplingCMesh::getNodeGridStructure(int *res) const
 {
-  int tmp[3]={i,j,k};
-  int tmp2[3];
-  int spaceDim=getSpaceDimension();
-  getSplitNodeValues(tmp2);
-  std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
-  return std::accumulate(tmp,tmp+spaceDim,0);
-}
-
-void MEDCouplingCMesh::GetPosFromId(int nodeId, int spaceDim, const int *split, int *res)
-{
-  int work=nodeId;
-  for(int i=spaceDim-1;i>=0;i--)
-    {
-      int pos=work/split[i];
-      work=work%split[i];
-      res[i]=pos;
-    }
+  int meshDim=getMeshDimension();
+  for(int i=0;i<meshDim;i++)
+    res[i]=getCoordsAt(i)->getNbOfElems();
 }
 
 int MEDCouplingCMesh::getSpaceDimension() const
@@ -355,92 +342,6 @@ int MEDCouplingCMesh::getMeshDimension() const
   return getSpaceDimension();
 }
 
-INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) const
-{
-  switch(getMeshDimension())
-    {
-    case 3:
-      return INTERP_KERNEL::NORM_HEXA8;
-    case 2:
-      return INTERP_KERNEL::NORM_QUAD4;
-    case 1:
-      return INTERP_KERNEL::NORM_SEG2;
-    default:
-      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
-    }
-}
-
-std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingCMesh::getAllGeoTypes() const
-{
-  INTERP_KERNEL::NormalizedCellType ret;
-  switch(getMeshDimension())
-    {
-    case 3:
-      ret=INTERP_KERNEL::NORM_HEXA8;
-      break;
-    case 2:
-      ret=INTERP_KERNEL::NORM_QUAD4;
-      break;
-    case 1:
-      ret=INTERP_KERNEL::NORM_SEG2;
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getAllGeoTypes !");
-    }
-  std::set<INTERP_KERNEL::NormalizedCellType> ret2;
-  ret2.insert(ret);
-  return ret2;
-}
-
-int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
-{
-  int ret=getNumberOfCells();
-  int dim=getMeshDimension();
-  switch(type)
-    {
-    case INTERP_KERNEL::NORM_HEXA8:
-      if(dim==3)
-        return ret;
-    case INTERP_KERNEL::NORM_QUAD4:
-      if(dim==2)
-        return ret;
-    case INTERP_KERNEL::NORM_SEG2:
-      if(dim==1)
-        return ret;
-    default:
-      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
-    }
-  return 0;
-}
-
-void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
-{
-  int spaceDim=getSpaceDimension();
-  int tmpCell[3],tmpNode[3];
-  getSplitCellValues(tmpCell);
-  getSplitNodeValues(tmpNode);
-  int tmp2[3];
-  GetPosFromId(cellId,spaceDim,tmpCell,tmp2);
-  switch(spaceDim)
-    {
-    case 1:
-      conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1);
-      break;
-    case 2:
-      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1);
-      conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]);
-      break;
-    case 3:
-      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]);
-      conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]);
-      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]);
-      conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]);
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !");
-    };
-}
-
 void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
 {
   int tmp[3];
@@ -561,107 +462,6 @@ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArray
   declareAsNew();
 }
 
-/*!
- * See MEDCouplingUMesh::getDistributionOfTypes for more information
- */
-std::vector<int> MEDCouplingCMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
-{
-  //only one type of cell
-  std::vector<int> ret(3);
-  ret[0]=getTypeOfCell(0);
-  ret[1]=getNumberOfCells();
-  ret[2]=0; //ret[3*k+2]==0 because it has no sense here
-  return ret;
-}
-
-/*!
- * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information
- */
-DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
-{
-  if(code.empty())
-    throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code is empty, should not !");
-  std::size_t sz=code.size();
-  if(sz!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !");
-
-  int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]);
-  if(code[2]==-1)
-    {
-      if(code[1]==nbCells)
-        return 0;
-      else
-        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of cells mismatch !");
-    }
-  else
-    {
-      if(code[2]<-1) 
-        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !");
-      if(code[2]>=(int)idsPerType.size()) 
-        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !");
-      return idsPerType[code[2]]->deepCpy();
-    }
-}
-
-/*!
- * See MEDCouplingUMesh::splitProfilePerType for more information
- */
-void MEDCouplingCMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
-{
-  int nbCells=getNumberOfCells();
-  code.resize(3);
-  code[0]=(int)getTypeOfCell(0);
-  code[1]=nbCells;
-  code[2]=0;
-  idsInPflPerType.push_back(profile->deepCpy());
-  idsPerType.push_back(profile->deepCpy());
-}
-
-MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
-{
-  int spaceDim=getSpaceDimension();
-  MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim);
-  DataArrayDouble *coords=getCoordinatesAndOwner();
-  ret->setCoords(coords);
-  coords->decrRef();
-  switch(spaceDim)
-    {
-    case 1:
-      fill1DUnstructuredMesh(ret);
-      break;
-    case 2:
-      fill2DUnstructuredMesh(ret);
-      break;
-    case 3:
-      fill3DUnstructuredMesh(ret);
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !");
-    };
-  return ret;
-}
-
-MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const
-{
-  MEDCouplingUMesh *um=buildUnstructured();
-  MEDCouplingMesh *ret=um->buildPart(start,end);
-  um->decrRef();
-  return ret;
-}
-
-MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
-{
-  MEDCouplingUMesh *um=buildUnstructured();
-  MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr);
-  um->decrRef();
-  return ret;
-}
-
-DataArrayInt *MEDCouplingCMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
-{
-  throw INTERP_KERNEL::Exception("MEDCouplingCMesh::simplexize : not available for Cartesian mesh !");
-}
-
 void MEDCouplingCMesh::getBoundingBox(double *bbox) const
 {
   int dim=getSpaceDimension();
@@ -685,7 +485,7 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
   std::string name="MeasureOfMesh_";
   name+=getName();
   int nbelem=getNumberOfCells();
-  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS);
+  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   field->setName(name.c_str());
   DataArrayDouble* array=DataArrayDouble::New();
   array->alloc(nbelem,1);
@@ -693,6 +493,7 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
   field->setArray(array) ;
   array->decrRef();
   field->setMesh(const_cast<MEDCouplingCMesh *>(this));
+  field->synchronizeTimeWithMesh();
   int tmp[3];
   getSplitCellValues(tmp);
   int dim=getSpaceDimension();
@@ -721,23 +522,6 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) cons
   //return 0;
 }
 
-MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const
-{
-  if(getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
-  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
-  DataArrayDouble *array=DataArrayDouble::New();
-  int nbOfCells=getNumberOfCells();
-  array->alloc(nbOfCells,3);
-  double *vals=array->getPointer();
-  for(int i=0;i<nbOfCells;i++)
-    { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
-  ret->setArray(array);
-  array->decrRef();
-  ret->setMesh(this);
-  return ret;
-}
-
 int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
 {
   int dim=getSpaceDimension();
@@ -871,95 +655,6 @@ void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INT
   throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
 }
 
-void MEDCouplingCMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const
-{
-  const DataArrayDouble *c=getCoordsAt(0);
-  int nbOfCells=c->getNbOfElems()-1;
-  DataArrayInt *connI=DataArrayInt::New();
-  connI->alloc(nbOfCells+1,1);
-  int *ci=connI->getPointer();
-  DataArrayInt *conn=DataArrayInt::New();
-  conn->alloc(3*nbOfCells,1);
-  ci[0]=0;
-  int *cp=conn->getPointer();
-  for(int i=0;i<nbOfCells;i++)
-    {
-      cp[3*i]=(int)INTERP_KERNEL::NORM_SEG2;
-      cp[3*i+1]=i;
-      cp[3*i+2]=i+1;
-      ci[i+1]=3*(i+1);
-    }
-  m->setConnectivity(conn,connI,true);
-  conn->decrRef();
-  connI->decrRef();
-}
-
-void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const
-{
-  const DataArrayDouble *c1=getCoordsAt(0);
-  const DataArrayDouble *c2=getCoordsAt(1);
-  int n1=c1->getNbOfElems()-1;
-  int n2=c2->getNbOfElems()-1;
-  DataArrayInt *connI=DataArrayInt::New();
-  connI->alloc(n1*n2+1,1);
-  int *ci=connI->getPointer();
-  DataArrayInt *conn=DataArrayInt::New();
-  conn->alloc(5*n1*n2,1);
-  ci[0]=0;
-  int *cp=conn->getPointer();
-  int pos=0;
-  for(int j=0;j<n2;j++)
-    for(int i=0;i<n1;i++,pos++)
-      {
-        cp[5*pos]=(int)INTERP_KERNEL::NORM_QUAD4;
-        cp[5*pos+1]=i+1+j*(n1+1);
-        cp[5*pos+2]=i+j*(n1+1);
-        cp[5*pos+3]=i+(j+1)*(n1+1);
-        cp[5*pos+4]=i+1+(j+1)*(n1+1);
-        ci[pos+1]=5*(pos+1);
-    }
-  m->setConnectivity(conn,connI,true);
-  conn->decrRef();
-  connI->decrRef();
-}
-
-void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const
-{
-  const DataArrayDouble *c1=getCoordsAt(0);
-  const DataArrayDouble *c2=getCoordsAt(1);
-  const DataArrayDouble *c3=getCoordsAt(2);
-  int n1=c1->getNbOfElems()-1;
-  int n2=c2->getNbOfElems()-1;
-  int n3=c3->getNbOfElems()-1;
-  DataArrayInt *connI=DataArrayInt::New();
-  connI->alloc(n1*n2*n3+1,1);
-  int *ci=connI->getPointer();
-  DataArrayInt *conn=DataArrayInt::New();
-  conn->alloc(9*n1*n2*n3,1);
-  ci[0]=0;
-  int *cp=conn->getPointer();
-  int pos=0;
-  for(int k=0;k<n3;k++)
-    for(int j=0;j<n2;j++)
-      for(int i=0;i<n1;i++,pos++)
-        {
-          cp[9*pos]=(int)INTERP_KERNEL::NORM_HEXA8;
-          int tmp=(n1+1)*(n2+1);
-          cp[9*pos+1]=i+1+j*(n1+1)+k*tmp;
-          cp[9*pos+2]=i+j*(n1+1)+k*tmp;
-          cp[9*pos+3]=i+(j+1)*(n1+1)+k*tmp;
-          cp[9*pos+4]=i+1+(j+1)*(n1+1)+k*tmp;
-          cp[9*pos+5]=i+1+j*(n1+1)+(k+1)*tmp;
-          cp[9*pos+6]=i+j*(n1+1)+(k+1)*tmp;
-          cp[9*pos+7]=i+(j+1)*(n1+1)+(k+1)*tmp;
-          cp[9*pos+8]=i+1+(j+1)*(n1+1)+(k+1)*tmp;
-          ci[pos+1]=9*(pos+1);
-        }
-  m->setConnectivity(conn,connI,true);
-  conn->decrRef();
-  connI->decrRef();
-}
-
 void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
 {
   int it,order;
@@ -1041,7 +736,36 @@ void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, con
 
 void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
 {
-  throw INTERP_KERNEL::Exception("MEDCouplingCMesh::writeVTKLL : not implemented yet !");
+  std::ostringstream extent;
+  DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+  for(int i=0;i<3;i++)
+    {
+      if(thisArr[i])
+        { extent << "0 " <<  thisArr[i]->getNumberOfTuples()-1 << " "; }
+      else
+        { extent << "0 0 "; }
+    }
+  ofs << "  <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
+  ofs << "    <Piece Extent=\"" << extent.str() << "\">\n";
+  ofs << "      <PointData>\n" << pointData << std::endl;
+  ofs << "      </PointData>\n";
+  ofs << "      <CellData>\n" << cellData << std::endl;
+  ofs << "      </CellData>\n";
+  ofs << "      <Coordinates>\n";
+  for(int i=0;i<3;i++)
+    {
+      if(thisArr[i])
+        thisArr[i]->writeVTK(ofs,8,"Array");
+      else
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1);
+          coo->setIJ(0,0,0.);
+          coo->writeVTK(ofs,8,"Array");
+        }
+    }
+  ofs << "      </Coordinates>\n";
+  ofs << "    </Piece>\n";
+  ofs << "  </" << getVTKDataSetType() << ">\n";
 }
 
 std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
index 39407ebb61b38ad370837674e2035cd18a8ee09e..e1f25b51a481312ce8637b8271356b88edd5b89d 100644 (file)
 #define __PARAMEDMEM_MEDCOUPLINGCMESH_HXX__
 
 #include "MEDCoupling.hxx"
-#include "MEDCouplingMesh.hxx"
+#include "MEDCouplingStructuredMesh.hxx"
 
 namespace ParaMEDMEM
 {
   class DataArrayDouble;
   class MEDCouplingUMesh;
 
-  class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingMesh
+  class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingStructuredMesh
   {
   public:
     static MEDCouplingCMesh *New();
@@ -37,6 +37,7 @@ namespace ParaMEDMEM
     MEDCouplingMesh *deepCpy() const;
     MEDCouplingCMesh *clone(bool recDeepCpy) const;
     void updateTime() const;
+    std::size_t getHeapMemorySize() const;
     MEDCouplingMeshType getType() const { return CARTESIAN; }
     void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception);
@@ -52,13 +53,6 @@ namespace ParaMEDMEM
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
     int getMeshDimension() const;
-    int getCellIdFromPos(int i, int j, int k) const;
-    int getNodeIdFromPos(int i, int j, int k) const;
-    static void GetPosFromId(int nodeId, int spaceDim, const int *split, int *res);
-    INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const;
-    std::set<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const;
-    int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const;
-    void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const;
     void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception);
     std::string simpleRepr() const;
     std::string advancedRepr() const;
@@ -69,17 +63,9 @@ namespace ParaMEDMEM
                    const DataArrayDouble *coordsY=0,
                    const DataArrayDouble *coordsZ=0);
     // tools
-    std::vector<int> getDistributionOfTypes() const throw(INTERP_KERNEL::Exception);
-    DataArrayInt *checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception);
-    void splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception);
-    MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
-    MEDCouplingMesh *buildPart(const int *start, const int *end) const;
-    MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
-    DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception);
     void getBoundingBox(double *bbox) const;
     MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
     MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
-    MEDCouplingFieldDouble *buildOrthogonalField() const;
     int getCellContainingPoint(const double *pos, double eps) const;
     void rotate(const double *center, const double *vector, double angle);
     void translate(const double *vector);
@@ -88,12 +74,10 @@ namespace ParaMEDMEM
     DataArrayDouble *getCoordinatesAndOwner() const;
     DataArrayDouble *getBarycenterAndOwner() const;
     void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception);
-    void fill1DUnstructuredMesh(MEDCouplingUMesh *m) const;
-    void fill2DUnstructuredMesh(MEDCouplingUMesh *m) const;
-    void fill3DUnstructuredMesh(MEDCouplingUMesh *m) const;
     //some useful methods
     void getSplitCellValues(int *res) const;
     void getSplitNodeValues(int *res) const;
+    void getNodeGridStructure(int *res) const;
     //serialisation-unserialization
     void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
     void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const;
diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx
new file mode 100644 (file)
index 0000000..a35c5b9
--- /dev/null
@@ -0,0 +1,875 @@
+// Copyright (C) 2007-2012  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
+//
+// Author : Anthony Geay (CEA/DEN)
+
+#include "MEDCouplingCurveLinearMesh.hxx"
+#include "MEDCouplingPointSet.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+
+#include "VolSurfUser.txx"
+#include "PointLocatorAlgos.txx"
+
+#include <functional>
+#include <algorithm>
+#include <sstream>
+#include <numeric>
+
+using namespace ParaMEDMEM;
+
+MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh():_coords(0),_structure(0)
+{
+}
+
+MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_structure(other._structure)
+{
+  if(deepCopy)
+    {
+      if((const DataArrayDouble *)other._coords)
+        _coords=other._coords->deepCpy();
+    }
+  else
+    _coords=other._coords;
+}
+
+MEDCouplingCurveLinearMesh::~MEDCouplingCurveLinearMesh()
+{
+}
+
+MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New()
+{
+  return new MEDCouplingCurveLinearMesh;
+}
+
+MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New(const char *meshName)
+{
+  MEDCouplingCurveLinearMesh *ret=new MEDCouplingCurveLinearMesh;
+  ret->setName(meshName);
+  return ret;
+}
+
+MEDCouplingMesh *MEDCouplingCurveLinearMesh::deepCpy() const
+{
+  return clone(true);
+}
+
+MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::clone(bool recDeepCpy) const
+{
+  return new MEDCouplingCurveLinearMesh(*this,recDeepCpy);
+}
+
+void MEDCouplingCurveLinearMesh::updateTime() const
+{
+  if((const DataArrayDouble *)_coords)
+    updateTimeWith(*_coords);
+}
+
+std::size_t MEDCouplingCurveLinearMesh::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  ret+=_structure.capacity()*sizeof(int);
+  if((const DataArrayDouble *)_coords)
+    ret+=_coords->getHeapMemorySize();
+  return MEDCouplingStructuredMesh::getHeapMemorySize()+ret;
+}
+
+/*!
+ * This method copyies all tiny strings from other (name and components name).
+ * @throw if other and this have not same mesh type.
+ */
+void MEDCouplingCurveLinearMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+{ 
+  const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::copyTinyStringsFrom : meshes have not same type !");
+  MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
+  if((DataArrayDouble *)_coords && (const DataArrayDouble *)otherC->_coords)
+    _coords->copyStringInfoFrom(*otherC->_coords);
+}
+
+bool MEDCouplingCurveLinearMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
+{
+  if(!other)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::isEqualIfNotWhy : input other pointer is null !");
+  const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
+  if(!otherC)
+    {
+      reason="mesh given in input is not castable in MEDCouplingCurveLinearMesh !";
+      return false;
+    }
+  if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
+    return false;
+  std::ostringstream oss; oss.precision(15);
+  if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords))
+    {
+      oss << "Only one CurveLinearMesh between the two this and other has its coordinates defined !";
+      reason=oss.str();
+      return false;
+    }
+  if((const DataArrayDouble *)_coords)
+    {
+      if(!_coords->isEqualIfNotWhy(*(otherC->_coords),prec,reason))
+        {
+          oss << "Coordinates DataArrayDouble of differ :";
+          reason.insert(0,oss.str());
+          return false;
+        }
+      if(_structure!=otherC->_structure)
+        { reason="CurveLinearMesh structures differ !"; return false; }
+    }
+  return true;
+}
+
+bool MEDCouplingCurveLinearMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
+{
+  const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
+  if(!otherC)
+    return false;
+  if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords))
+    return false;
+  if((const DataArrayDouble *)_coords)
+    {
+      if(!_coords->isEqualWithoutConsideringStr(*(otherC->_coords),prec))
+        return false;
+      if(_structure!=otherC->_structure)
+        return false;
+    }
+  return true;
+}
+
+void MEDCouplingCurveLinearMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                            DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+{
+  if(!isEqualWithoutConsideringStr(other,prec))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalWith : Meshes are not the same !");
+}
+
+/*!
+ * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCurveLinearMesh instance too).
+ * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCurveLinearMesh, 'this' and 'other' are the same !
+ */
+void MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                       DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !");
+}
+
+void MEDCouplingCurveLinearMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  std::size_t sz=_structure.size(),i=0,nbOfNodes=1;
+  if(sz<1)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : structure should have a lgth of size 1 at least !");
+  for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++,i++)
+    {
+      if((*it)<1)
+        { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : At pos #" << i << " of structure value is " << *it << "should be >= 1 !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+      nbOfNodes*=*it;
+    }
+  if(!((const DataArrayDouble *)_coords))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not set !");
+  if(!_coords->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not allocated !");
+  if(_coords->getNumberOfComponents()<1)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array should have >= 1 components !");
+  if(_coords->getNumberOfTuples()!=(int)nbOfNodes)
+    {
+      std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : structure said that number of nodes should be equal to " << nbOfNodes << " but number of tuples in array is equal to " << _coords->getNumberOfTuples() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
+void MEDCouplingCurveLinearMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+}
+
+void MEDCouplingCurveLinearMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency1(eps);
+}
+
+int MEDCouplingCurveLinearMesh::getNumberOfCells() const
+{
+  checkCoherency();
+  std::size_t nbOfCells=1,i=0;
+  for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++,i++)
+    nbOfCells*=(*it)-1;
+  return (int)nbOfCells;
+}
+
+int MEDCouplingCurveLinearMesh::getNumberOfNodes() const
+{
+  checkCoherency();
+  std::size_t nbOfNodes=1;
+  for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++)
+    nbOfNodes*=(*it);
+  return (int)nbOfNodes;
+}
+
+void MEDCouplingCurveLinearMesh::getSplitCellValues(int *res) const
+{
+  int meshDim=getMeshDimension();
+  for(int l=0;l<meshDim;l++)
+    {
+      int val=1;
+      for(int p=0;p<meshDim-l-1;p++)
+        val*=_structure[p]-1;
+      res[meshDim-l-1]=val;
+    }
+}
+
+void MEDCouplingCurveLinearMesh::getSplitNodeValues(int *res) const
+{
+  int meshDim=getMeshDimension();
+  for(int l=0;l<meshDim;l++)
+    {
+      int val=1;
+      for(int p=0;p<meshDim-l-1;p++)
+        val*=_structure[p];
+      res[meshDim-l-1]=val;
+    }
+}
+
+void MEDCouplingCurveLinearMesh::getNodeGridStructure(int *res) const
+{
+  std::copy(_structure.begin(),_structure.end(),res);
+}
+
+int MEDCouplingCurveLinearMesh::getSpaceDimension() const
+{
+  if(!((const DataArrayDouble *)_coords))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getSpaceDimension : no array set ! impossible to deduce a space dimension !");
+  return _coords->getNumberOfComponents();
+}
+
+int MEDCouplingCurveLinearMesh::getMeshDimension() const
+{
+  return (int)_structure.size();
+}
+
+void MEDCouplingCurveLinearMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
+{
+  if(!((const DataArrayDouble *)_coords))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCoordinatesOfNode : Coordinates not set !");
+  int nbOfCompo=_coords->getNumberOfComponents();
+  if(nodeId>=0 && nodeId<_coords->getNumberOfTuples())
+    coo.insert(coo.end(),_coords->begin()+nodeId*nbOfCompo,_coords->begin()+(nodeId+1)*nbOfCompo);
+  else
+    { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::getCoordinatesOfNode : nodeId has to be in [0," << _coords->getNumberOfTuples() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+}
+
+std::string MEDCouplingCurveLinearMesh::simpleRepr() const
+{
+  std::ostringstream ret;
+  ret << "Curve linear mesh with name : \"" << getName() << "\"\n";
+  ret << "Description of mesh : \"" << getDescription() << "\"\n";
+  int tmpp1,tmpp2;
+  double tt=getTime(tmpp1,tmpp2);
+  ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
+  ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
+  ret << "The nodal stucture of curve linear mesh is : [";
+  std::copy(_structure.begin(),_structure.end(),std::ostream_iterator<int>(ret,",")); ret << "]\n";
+  ret << "The coords array is this : ";
+  if((const DataArrayDouble *)_coords)
+    _coords->reprZipWithoutNameStream(ret);
+  else
+    ret << "no array specified !";
+  return ret.str();
+}
+
+std::string MEDCouplingCurveLinearMesh::advancedRepr() const
+{
+  return simpleRepr();
+}
+
+DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() throw(INTERP_KERNEL::Exception)
+{
+  return _coords;
+}
+
+const DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() const throw(INTERP_KERNEL::Exception)
+{
+  return _coords;
+}
+
+void MEDCouplingCurveLinearMesh::setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
+{
+  if(coords!=(const DataArrayDouble *)_coords)
+    {
+      _coords=const_cast<DataArrayDouble *>(coords);
+      if(coords)
+        coords->incrRef();
+      declareAsNew();
+    }
+}
+
+void MEDCouplingCurveLinearMesh::setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) throw(INTERP_KERNEL::Exception)
+{
+  _structure.resize(0);
+  _structure.insert(_structure.end(),gridStructBg,gridStructEnd);
+}
+
+std::vector<int> MEDCouplingCurveLinearMesh::getNodeGridStructure() const throw(INTERP_KERNEL::Exception)
+{
+  return _structure;
+}
+
+void MEDCouplingCurveLinearMesh::getBoundingBox(double *bbox) const
+{
+  if(!((const DataArrayDouble *)_coords))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBoundingBox : Coordinates not set !");
+  _coords->getMinMaxPerComponent(bbox);
+}
+
+MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureField(bool isAbs) const
+{
+  checkCoherency();
+  int meshDim=getMeshDimension();
+  std::string name="MeasureOfMesh_"; name+=getName();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  field->setName(name.c_str()); field->setMesh(const_cast<MEDCouplingCurveLinearMesh *>(this)); field->synchronizeTimeWithMesh();
+  switch(meshDim)
+    {
+    case 3:
+      { getMeasureFieldMeshDim3(isAbs,field); return field.retn(); }
+    case 2:
+      { getMeasureFieldMeshDim2(isAbs,field); return field.retn(); }
+    case 1:
+      { getMeasureFieldMeshDim1(isAbs,field); return field.retn(); }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureField : mesh dimension must be in [1,2,3] !");
+    }
+}
+
+/*!
+ * \param [in,out] f field feeded with good values.
+ * \sa MEDCouplingCurveLinearMesh::getMeasureField
+ */
+void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception)
+{
+  int nbnodes=getNumberOfNodes();
+  int spaceDim=getSpaceDimension();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); field->setArray(arr);
+  if(nbnodes==0)
+    { arr->alloc(0,1); return; }
+  if(spaceDim==1)
+    {
+      arr->alloc(nbnodes-1,1);
+      std::transform(_coords->begin()+1,_coords->end(),_coords->begin(),arr->getPointer(),std::minus<double>());
+      if(isAbs)
+        arr->abs();
+    }
+  else
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=DataArrayDouble::New(); tmp->alloc(nbnodes-1,spaceDim);
+      std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),tmp->getPointer(),std::minus<double>());
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=tmp->magnitude(); field->setArray(tmp2);
+    }
+}
+
+/*!
+ * \param [in,out] f field feeded with good values.
+ * \sa MEDCouplingCurveLinearMesh::getMeasureField
+ */
+void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception)
+{
+  int nbcells=getNumberOfCells();
+  int spaceDim=getSpaceDimension();
+  if(spaceDim!=2 && spaceDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); field->setArray(arr);
+  arr->alloc(nbcells,1);
+  double *pt=arr->getPointer();
+  const double *coords=_coords->begin();
+  int nX=_structure[0]-1;
+  int conn[4];
+  for(int i=0;i<nbcells;i++,pt++)
+    {
+      int cy=i/nX,cx=i-cy*nX;
+      conn[0]=cy*(nX+1)+cx; conn[1]=(cy+1)*(nX+1)+cx; conn[2]=(cy+1)*(nX+1)+1+cx; conn[3]=cy*(nX+1)+cx+1;
+      *pt=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_QUAD4,conn,4,coords,spaceDim);
+    }
+  if(isAbs)
+    arr->abs();
+}
+
+/*!
+ * \param [in,out] f field feeded with good values.
+ * \sa MEDCouplingCurveLinearMesh::getMeasureField
+ */
+void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception)
+{
+  int nbcells=getNumberOfCells();
+  int spaceDim=getSpaceDimension();
+  if(spaceDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3 : with meshDim 3 only space dimension 3 is possible !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); field->setArray(arr);
+  arr->alloc(nbcells,1);
+  double *pt=arr->getPointer();
+  const double *coords=_coords->begin();
+  int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1);
+  int nY1=_structure[0]*_structure[1];
+  int conn[8];
+  for(int i=0;i<nbcells;i++,pt++)
+    {
+      int cz=i/nY;
+      int cy=(i-cz*nY)/nX;
+      int cx=(i-cz*nY)-nX*cy;
+      conn[0]=cz*nY1+cy*(nX+1)+cx; conn[1]=cz*nY1+(cy+1)*(nX+1)+cx; conn[2]=cz*nY1+(cy+1)*(nX+1)+1+cx; conn[3]=cz*nY1+cy*(nX+1)+cx+1;
+      conn[4]=(cz+1)*nY1+cy*(nX+1)+cx; conn[5]=(cz+1)*nY1+(cy+1)*(nX+1)+cx; conn[6]=(cz+1)*nY1+(cy+1)*(nX+1)+1+cx; conn[7]=(cz+1)*nY1+cy*(nX+1)+cx+1;
+      *pt=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_HEXA8,conn,8,coords,3);
+    }
+  if(isAbs)
+    arr->abs();
+}
+
+/*!
+ * not implemented yet !
+ */
+MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureFieldOnNode(bool isAbs) const
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldOnNode : not implemented yet !");
+}
+
+MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::buildOrthogonalField() const
+{
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  DataArrayDouble *array=DataArrayDouble::New();
+  int nbOfCells=getNumberOfCells();
+  array->alloc(nbOfCells,3);
+  double *vals=array->getPointer();
+  for(int i=0;i<nbOfCells;i++)
+    { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
+  ret->setArray(array);
+  array->decrRef();
+  ret->setMesh(this);
+  return ret;
+}
+
+/// @cond INTERNAL
+
+namespace ParaMEDMEM
+{
+  template<const int SPACEDIMM>
+  class DummyClsMCL
+  {
+  public:
+    static const int MY_SPACEDIM=SPACEDIMM;
+    static const int MY_MESHDIM=8;
+    typedef int MyConnType;
+    static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE;
+    // begin
+    // useless, but for windows compilation ...
+    const double* getCoordinatesPtr() const { return 0; }
+    const int* getConnectivityPtr() const { return 0; }
+    const int* getConnectivityIndexPtr() const { return 0; }
+    INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
+    // end
+  };
+}
+
+/// @endcond
+
+int MEDCouplingCurveLinearMesh::getCellContainingPoint(const double *pos, double eps) const
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  const double *coords=_coords->getConstPointer();
+  int nodeId=-1;
+  _coords->distanceToTuple(pos,pos+spaceDim,nodeId);
+  if(nodeId<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : internal problem 1 !");
+  int conn[8];
+  int nbOfNodes=getNumberOfNodes();
+  if(nbOfNodes==1)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : No cells in this !");
+  switch(getMeshDimension())
+    {
+    case 1:
+      if(spaceDim==1)
+        {
+          if(nodeId>0)
+            {
+              conn[0]=nodeId-1; conn[1]=nodeId;
+              if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<1> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps))
+                return nodeId-1;
+            }
+          if(nodeId<nbOfNodes-1)
+            {
+              conn[0]=nodeId; conn[1]=nodeId+1;
+              if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<1> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps))
+                return nodeId;
+            }
+        }
+    case 2:
+      if(spaceDim==2)
+        {
+          int ny=nodeId/_structure[0],nx=nodeId-ny*_structure[0];
+          if(nx>0 && ny>0)
+            {
+              conn[0]=nx-1+_structure[0]*(ny-1); conn[1]=nx-1+_structure[0]*ny; conn[2]=nx+_structure[0]*ny; conn[3]=nx+_structure[0]*(ny-1);
+              if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
+                return nx-1+(ny-1)*_structure[0];
+            }
+          if(nx<_structure[0]-1 && ny>0)
+            {
+              conn[0]=nx+_structure[0]*(ny-1); conn[1]=nx+_structure[0]*ny; conn[2]=nx+1+_structure[0]*ny; conn[3]=nx+1+_structure[0]*(ny-1);
+              if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
+                return nx+(ny-1)*_structure[0];
+            }
+          if(nx>0 && ny<_structure[1]-1)
+            {
+              conn[0]=nx-1+_structure[0]*ny; conn[1]=nx-1+_structure[0]*(ny+1); conn[2]=nx+_structure[0]*(ny+1); conn[3]=nx+_structure[0]*ny;
+              if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
+                return nx-1+ny*_structure[0];
+            }
+          if(nx<_structure[0]-1 && ny<_structure[1]-1)
+            {
+              conn[0]=nx+_structure[0]*ny; conn[1]=nx+_structure[0]*(ny+1); conn[2]=nx+1+_structure[0]*(ny+1); conn[3]=nx+1+_structure[0]*ny;
+              if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
+                return nx+ny*_structure[0];
+            }
+        }
+    case 3:
+      {
+        if(spaceDim==3)
+          {
+            int nY=_structure[0]*_structure[1];
+            int nz=nodeId/_structure[1]; int ny=(nodeId-nz*nY)/_structure[0]; int nx=(nodeId-nz*nY)-_structure[0]*ny;
+            if(nx>0 && ny>0 && nz>0)
+              {
+                conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1);
+                conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx-1+(ny-1)*_structure[0]+(nz-1)*nY;
+              }
+            if(nx<_structure[0]-1 && ny>0 && nz>0)
+              {
+                conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1);
+                conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx+(ny-1)*_structure[0]+(nz-1)*nY;
+              }
+            if(nx>0 && ny<_structure[1]-1 && nz>0)
+              {
+                conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1);
+                conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx-1+ny*_structure[0]+(nz-1)*nY;
+              }
+            if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz>0)
+              {
+                conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1);
+                conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx+ny*_structure[0]+(nz-1)*nY;
+              }
+            if(nx>0 && ny>0 && nz<_structure[2]-1)
+              {
+                conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1);
+                conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx-1+(ny-1)*_structure[0]+nz*nY;
+              }
+            if(nx<_structure[0]-1 && ny>0 && nz<_structure[2]-1)
+              {
+                conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1);
+                conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx+(ny-1)*_structure[0]+nz*nY;
+              }
+            if(nx>0 && ny<_structure[1]-1 && nz<_structure[2]-1)
+              {
+                conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1);
+                conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx-1+ny*_structure[0]+nz*nY;
+              }
+            if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz<_structure[2]-1)
+              {
+                conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1);
+                conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz;
+                if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
+                  return nx+ny*_structure[0]+nz*nY;
+              }
+          }
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : mesh dimension managed are 1, 2 or 3 !");
+    }
+}
+
+void MEDCouplingCurveLinearMesh::rotate(const double *center, const double *vector, double angle)
+{
+  if(!((DataArrayDouble *)_coords))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : no coordinates set !");
+  int spaceDim=getSpaceDimension();
+  int nbNodes=_coords->getNumberOfTuples();
+  double *coords=_coords->getPointer();
+  if(spaceDim==3)
+    MEDCouplingPointSet::Rotate3DAlg(center,vector,angle,nbNodes,coords);
+  else if(spaceDim==2)
+    MEDCouplingPointSet::Rotate2DAlg(center,angle,nbNodes,coords);
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : invalid space dim for rotation must be 2 or 3");
+  _coords->declareAsNew();
+  updateTime();
+}
+
+void MEDCouplingCurveLinearMesh::translate(const double *vector)
+{
+  if(!((DataArrayDouble *)_coords))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : no coordinates set !");
+  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();
+}
+
+void MEDCouplingCurveLinearMesh::scale(const double *point, double factor)
+{
+  if(!((DataArrayDouble *)_coords))
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : no coordinates set !");
+  double *coords=_coords->getPointer();
+  int nbNodes=_coords->getNumberOfTuples();
+  int dim=_coords->getNumberOfComponents();
+  for(int i=0;i<nbNodes;i++)
+    {
+      std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::minus<double>());
+      std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies<double>(),factor));
+      std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus<double>());
+    }
+  _coords->declareAsNew();
+  updateTime();
+}
+
+MEDCouplingMesh *MEDCouplingCurveLinearMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::mergeMyselfWith : not available for CurveLinear Mesh !");
+}
+
+DataArrayDouble *MEDCouplingCurveLinearMesh::getCoordinatesAndOwner() const
+{
+  DataArrayDouble *ret=const_cast<DataArrayDouble *>((const DataArrayDouble *)_coords);
+  if(ret)
+    ret->incrRef();
+  return ret;
+}
+
+DataArrayDouble *MEDCouplingCurveLinearMesh::getBarycenterAndOwner() const
+{
+  checkCoherency();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  int nbOfCells=getNumberOfCells();
+  ret->alloc(nbOfCells,spaceDim);
+  ret->copyStringInfoFrom(*getCoords());
+  switch(meshDim)
+    {
+    case 3:
+      { getBarycenterAndOwnerMeshDim3(ret); return ret.retn(); }
+    case 2:
+      { getBarycenterAndOwnerMeshDim2(ret); return ret.retn(); }
+    case 1:
+      { getBarycenterAndOwnerMeshDim1(ret); return ret.retn(); }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwner : mesh dimension must be in [1,2,3] !");
+    }
+}
+
+/*!
+ * \param [in,out] bary Barycenter array feeded with good values.
+ * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner
+ */
+void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const
+{
+  int nbOfCells=getNumberOfCells();
+  double *ptToFill=bary->getPointer();
+  const double *coor=_coords->getConstPointer();
+  if(getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3 : with meshDim 3 only space dimension 3 is possible !");
+  int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1);
+  int nY1=_structure[0]*_structure[1];
+  int conn[8];
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int cz=i/nY;
+      int cy=(i-cz*nY)/nX;
+      int cx=(i-cz*nY)-nX*cy;
+      conn[0]=cz*nY1+cy*(nX+1)+cx+1; conn[1]=cz*nY1+cy*(nX+1)+cx; conn[2]=cz*nY1+(cy+1)*(nX+1)+cx; conn[3]=cz*nY1+(cy+1)*(nX+1)+1+cx;
+      conn[4]=(cz+1)*nY1+cy*(nX+1)+cx+1; conn[5]=(cz+1)*nY1+cy*(nX+1)+cx; conn[6]=(cz+1)*nY1+(cy+1)*(nX+1)+cx; conn[7]=(cz+1)*nY1+(cy+1)*(nX+1)+1+cx;
+      INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_HEXA8,conn,8,coor,3,ptToFill);
+      ptToFill+=3;
+    }
+}
+
+/*!
+ * \param [in,out] bary Barycenter array feeded with good values.
+ * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner
+ */
+void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const
+{
+  int nbcells=getNumberOfCells();
+  int spaceDim=getSpaceDimension();
+  double *ptToFill=bary->getPointer();
+  const double *coor=_coords->getConstPointer();
+  if(spaceDim!=2 && spaceDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !");
+  int nX=_structure[0]-1;
+  int conn[4];
+  for(int i=0;i<nbcells;i++)
+    {
+      int cy=i/nX,cx=i-cy*nX;
+      conn[0]=cy*(nX+1)+cx; conn[1]=(cy+1)*(nX+1)+cx; conn[2]=(cy+1)*(nX+1)+1+cx; conn[3]=cy*(nX+1)+cx+1;
+      INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_QUAD4,conn,4,coor,spaceDim,ptToFill);
+      ptToFill+=spaceDim;
+    }
+}
+
+/*!
+ * \param [in,out] bary Barycenter array feeded with good values.
+ * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner
+ */
+void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const
+{
+  int spaceDim=getSpaceDimension();
+  std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),bary->getPointer(),std::plus<double>());
+  std::transform(bary->begin(),bary->end(),bary->getPointer(),std::bind2nd(std::multiplies<double>(),0.5));
+}
+
+void MEDCouplingCurveLinearMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CurveLinear Mesh !");
+}
+
+void MEDCouplingCurveLinearMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
+{
+  int it,order;
+  double time=getTime(it,order);
+  tinyInfo.clear();
+  tinyInfoD.clear();
+  littleStrings.clear();
+  littleStrings.push_back(getName());
+  littleStrings.push_back(getDescription());
+  littleStrings.push_back(getTimeUnit());
+  //
+  std::vector<std::string> littleStrings2;
+  if((const DataArrayDouble *)_coords)
+    _coords->getTinySerializationStrInformation(littleStrings2);
+  littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
+  //
+  tinyInfo.push_back(it);
+  tinyInfo.push_back(order);
+  tinyInfo.push_back((int)_structure.size());
+  for(std::vector<int>::const_iterator itt=_structure.begin();itt!=_structure.end();itt++)
+    tinyInfo.push_back(*itt);
+  std::vector<int> tinyInfo2;
+  if((const DataArrayDouble *)_coords)
+    _coords->getTinySerializationIntInformation(tinyInfo2);
+  tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
+  //
+  tinyInfoD.push_back(time);
+}
+
+void MEDCouplingCurveLinearMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
+{
+  a1->alloc(tinyInfo[2],1);
+  std::vector<int> tinyInfo2(tinyInfo.begin()+3+tinyInfo[2],tinyInfo.end());
+  a2->resizeForUnserialization(tinyInfo2);
+}
+
+void MEDCouplingCurveLinearMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
+{
+  a1=DataArrayInt::New();
+  a1->alloc((int)_structure.size(),1);
+  int *ptr=a1->getPointer();
+  for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++,ptr++)
+    *ptr=(*it);
+  int sz=0;
+  if((const DataArrayDouble *)_coords)
+    if(_coords->isAllocated())
+      sz=_coords->getNbOfElems();
+  a2=DataArrayDouble::New();
+  a2->alloc(sz,1);
+  if(sz!=0 && (const DataArrayDouble *)_coords)
+    std::copy(_coords->begin(),_coords->end(),a2->getPointer());
+}
+
+void MEDCouplingCurveLinearMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                                                 const std::vector<std::string>& littleStrings)
+{
+  setName(littleStrings[0].c_str());
+  setDescription(littleStrings[1].c_str());
+  setTimeUnit(littleStrings[2].c_str());
+  setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
+  int sz=tinyInfo[2];
+  _structure.resize(sz);
+  for(int i=0;i<sz;i++)
+    _structure[i]=tinyInfo[3+i];
+  if((int)tinyInfo.size()>sz+3)
+    {
+      _coords=DataArrayDouble::New();
+      std::vector<int> tinyInfo2(tinyInfo.begin()+3+sz,tinyInfo.end());
+      _coords->resizeForUnserialization(tinyInfo2);
+      std::copy(a2->begin(),a2->end(),_coords->getPointer());
+      std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.end());
+      _coords->finishUnserialization(tinyInfo2,littleStrings2);
+    }
+}
+
+void MEDCouplingCurveLinearMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
+{
+  std::ostringstream extent;
+  int meshDim=(int)_structure.size();
+  if(meshDim<=0 || meshDim>3)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::writeVTKLL : meshDim invalid ! must be in [1,2,3] !");
+  for(int i=0;i<3;i++)
+    { int val=i<meshDim?_structure[i]-1:0; extent << "0 " <<  val << " "; }
+  ofs << "  <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
+  ofs << "    <Piece Extent=\"" << extent.str() << "\">\n";
+  ofs << "      <PointData>\n" << pointData << std::endl;
+  ofs << "      </PointData>\n";
+  ofs << "      <CellData>\n" << cellData << std::endl;
+  ofs << "      </CellData>\n";
+  ofs << "      <Points>\n";
+  if(getSpaceDimension()==3)
+    _coords->writeVTK(ofs,8,"Points");
+  else
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->changeNbOfComponents(3,0.);
+      coo->writeVTK(ofs,8,"Points");
+    }
+  ofs << "      </Points>\n";
+  ofs << "    </Piece>\n";
+  ofs << "  </" << getVTKDataSetType() << ">\n";
+}
+
+std::string MEDCouplingCurveLinearMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
+{
+  return std::string("StructuredGrid");
+}
diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx
new file mode 100644 (file)
index 0000000..cab1c67
--- /dev/null
@@ -0,0 +1,107 @@
+// Copyright (C) 2007-2012  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
+//
+// Author : Anthony Geay (CEA/DEN)
+
+#ifndef __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__
+
+#include "MEDCoupling.hxx"
+#include "MEDCouplingStructuredMesh.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+
+namespace ParaMEDMEM
+{
+  class DataArrayDouble;
+  class MEDCouplingUMesh;
+
+  class MEDCOUPLING_EXPORT MEDCouplingCurveLinearMesh : public MEDCouplingStructuredMesh
+  {
+  public:
+    static MEDCouplingCurveLinearMesh *New();
+    static MEDCouplingCurveLinearMesh *New(const char *meshName);
+    MEDCouplingMesh *deepCpy() const;
+    MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const;
+    void updateTime() const;
+    std::size_t getHeapMemorySize() const;
+    MEDCouplingMeshType getType() const { return CURVE_LINEAR; }
+    void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
+    bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception);
+    bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const;
+    void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                              DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception);
+    void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                         DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception);
+    void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception);
+    void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception);
+    int getNumberOfCells() const;
+    int getNumberOfNodes() const;
+    int getSpaceDimension() const;
+    int getMeshDimension() const;
+    void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception);
+    std::string simpleRepr() const;
+    std::string advancedRepr() const;
+    DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception);
+    const DataArrayDouble *getCoords() const throw(INTERP_KERNEL::Exception);
+    void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception);
+    void setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) throw(INTERP_KERNEL::Exception);
+    std::vector<int> getNodeGridStructure() const throw(INTERP_KERNEL::Exception);
+    // tools
+    void getBoundingBox(double *bbox) const;
+    MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
+    MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
+    MEDCouplingFieldDouble *buildOrthogonalField() const;
+    int getCellContainingPoint(const double *pos, double eps) const;
+    void rotate(const double *center, const double *vector, double angle);
+    void translate(const double *vector);
+    void scale(const double *point, double factor);
+    MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
+    DataArrayDouble *getCoordinatesAndOwner() const;
+    DataArrayDouble *getBarycenterAndOwner() const;
+    void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception);
+    //some useful methods
+    void getSplitCellValues(int *res) const;
+    void getSplitNodeValues(int *res) const;
+    void getNodeGridStructure(int *res) const;
+    //serialisation-unserialization
+    void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
+    void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const;
+    void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const;
+    void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                         const std::vector<std::string>& littleStrings);
+  private:
+    void getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception);
+    void getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception);
+    void getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception);
+    void getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const;
+    void getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const;
+    void getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const;
+  private:
+    MEDCouplingCurveLinearMesh();
+    MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCpy);
+    ~MEDCouplingCurveLinearMesh();
+    void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception);
+    std::string getVTKDataSetType() const throw(INTERP_KERNEL::Exception);
+  private:
+    MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords;
+    std::vector<int> _structure;
+  };
+}
+
+#endif
index 0d703ce733d547a18796208ac96780a986519c2a..8663ca2f239a51b0c25ab4522ca845cb6d6879d3 100644 (file)
@@ -109,6 +109,11 @@ MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCoupling
     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice : End time strictly before Start time ...");
 }
 
+std::size_t MEDCouplingDefinitionTimeSlice::getHeapMemorySize() const
+{
+  return 0;
+}
+
 bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
 {
   double t1=getStartTime();
@@ -459,6 +464,11 @@ MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector<const MED
     }
 }
 
+std::size_t MEDCouplingDefinitionTime::getHeapMemorySize() const
+{
+  return _slices.capacity()*(sizeof(MEDCouplingDefinitionTimeSlice)+sizeof(int));
+}
+
 void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other)
 {
   std::size_t sz=other._slices.size();
index 2ef0464ebdfadc3d4042cbcda1c1fc18fd5a6a3b..4e9806662f768def085122cc8ff138776924f025 100644 (file)
@@ -51,6 +51,7 @@ namespace ParaMEDMEM
     virtual double getEndTime() const = 0;
     virtual void getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const = 0;
     virtual TypeOfTimeDiscretization getTimeType() const = 0;
+    std::size_t getHeapMemorySize() const;
     bool isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const;
     bool isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const;
     bool isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const;
@@ -142,6 +143,7 @@ namespace ParaMEDMEM
   public:
     MEDCouplingDefinitionTime();
     MEDCouplingDefinitionTime(const std::vector<const MEDCouplingFieldDouble *>& fs, const std::vector<int>& meshRefs, const std::vector<std::vector<int> >& arrRefs) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
     void assign(const MEDCouplingDefinitionTime& other);
     bool isEqual(const MEDCouplingDefinitionTime& other) const;
     double getTimeResolution() const { return _eps; }
index 663737af5d8b3b9e62070b86f2a9e1efd441d6a7..875889dadc19cb4d5f2d0c61752c5d8594fe2c16 100644 (file)
@@ -64,6 +64,18 @@ MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const
   return EXTRUDED;
 }
 
+std::size_t MEDCouplingExtrudedMesh::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if(_mesh2D)
+    ret+=_mesh2D->getHeapMemorySize();
+  if(_mesh1D)
+    ret+=_mesh1D->getHeapMemorySize();
+  if(_mesh3D_ids)
+    ret+=_mesh3D_ids->getHeapMemorySize();
+  return MEDCouplingMesh::getHeapMemorySize()+ret;
+}
+
 /*!
  * This method copyies all tiny strings from other (name and components name).
  * @throw if other and this have not same mesh type.
@@ -398,8 +410,9 @@ MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
   int nbOf1DCells=_mesh1D->getNumberOfCells();
   int nbOf3DCells=nbOf2DCells*nbOf1DCells;
   const int *renum=_mesh3D_ids->getConstPointer();
-  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   ret->setMesh(this);
+  ret->synchronizeTimeWithMesh();
   DataArrayDouble *da=DataArrayDouble::New();
   da->alloc(nbOf3DCells,1);
   double *retPtr=da->getPointer();
index 9dc8122edd43453ac3b90d391ca1e1f220f2eb62..8f9bc9c0918ae98377964298cd36f33ce3c8cc82 100644 (file)
@@ -39,6 +39,7 @@ namespace ParaMEDMEM
     static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception);
     static MEDCouplingExtrudedMesh *New();
     MEDCouplingMeshType getType() const;
+    std::size_t getHeapMemorySize() const;
     void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     int getNumberOfCells() const;
     int getNumberOfNodes() const;
index 805b4a7c595cadaf29bb122ea82bf394f2829c4a..da93e7a6e1d555a5e33489db2ddc15ec0c1d89a5 100644 (file)
@@ -127,6 +127,18 @@ void MEDCouplingField::updateTime() const
     updateTimeWith(*_type);
 }
 
+std::size_t MEDCouplingField::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  ret+=_name.capacity();
+  ret+=_desc.capacity();
+  if(_mesh)
+    ret+=_mesh->getHeapMemorySize();
+  if((const MEDCouplingFieldDiscretization *)_type)
+    ret+=_type->getHeapMemorySize();
+  return ret;
+}
+
 TypeOfField MEDCouplingField::getTypeOfField() const
 {
   return _type->getEnum();
index 69e6752ee7f4d15a61d9416dc46944c0a7a1659b..6dbe8bfddaf92747ce9a655719dce9a424d45942 100644 (file)
@@ -82,6 +82,7 @@ namespace ParaMEDMEM
     void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
     const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
     void updateTime() const;
+    std::size_t getHeapMemorySize() const;
   protected:
     MEDCouplingField(TypeOfField type);
     MEDCouplingField(const MEDCouplingField& other);
index 80b9d6a63177265ab2e73b3eaa2edfbdb5195a4e..461efc9aa4161ff148172c9e0b33d99913dbbde9 100644 (file)
@@ -128,6 +128,11 @@ void MEDCouplingFieldDiscretization::updateTime() const
 {
 }
 
+std::size_t MEDCouplingFieldDiscretization::getHeapMemorySize() const
+{
+  return 0;
+}
+
 /*!
  * Computes normL1 of DataArrayDouble instance arr.
  * @param res output parameter expected to be of size arr->getNumberOfComponents();
@@ -449,6 +454,8 @@ void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMe
 
 MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getMeasureField : mesh instance specified is NULL !");
   return mesh->getMeasureField(isAbs);
 }
 
@@ -488,8 +495,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP0::getValueOnMulti(const DataArr
         oss << ") detected outside mesh : unable to apply P0::getValueOnMulti ! ";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -522,7 +528,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationP0::computeTupleIdsToSelectFromCellI
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc((int)std::distance(startCellIds,endCellIds),1);
   std::copy(startCellIds,endCellIds,ret->getPointer());
-  ret->incrRef(); return ret;
+  return ret.retn();
 }
 
 /*!
@@ -685,6 +691,8 @@ void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfFiel
 
 MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getMeasureField : mesh instance specified is NULL !");
   return mesh->getMeasureFieldOnNode(isAbs);
 }
 
@@ -747,8 +755,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP1::getValueOnMulti(const DataArr
         oss << ") detected outside mesh : unable to apply P1::getValueOnMulti ! ";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0)
@@ -779,6 +786,14 @@ void MEDCouplingFieldDiscretizationPerCell::updateTime() const
     updateTimeWith(*_discr_per_cell);
 }
 
+std::size_t MEDCouplingFieldDiscretizationPerCell::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if(_discr_per_cell)
+    ret+=_discr_per_cell->getHeapMemorySize();
+  return ret;
+}
+
 void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception)
 {
   if(!_discr_per_cell)
@@ -951,6 +966,14 @@ std::string MEDCouplingFieldDiscretizationGauss::getStringRepr() const
   return oss.str();
 }
 
+std::size_t MEDCouplingFieldDiscretizationGauss::getHeapMemorySize() const
+{
+  std::size_t ret=_loc.capacity()*sizeof(MEDCouplingGaussLocalization);
+  for(std::vector<MEDCouplingGaussLocalization>::const_iterator it=_loc.begin();it!=_loc.end();it++)
+    ret+=(*it).getHeapMemorySize();
+  return MEDCouplingFieldDiscretizationPerCell::getHeapMemorySize()+ret;
+}
+
 const char *MEDCouplingFieldDiscretizationGauss::getRepr() const
 {
   return REPR;
@@ -992,8 +1015,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::getOffsetArr(const MEDCouplin
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
@@ -1183,6 +1205,8 @@ void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplin
 
 MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : mesh instance specified is NULL !");
   throw INTERP_KERNEL::Exception("Not implemented yet !");
 }
 
@@ -1407,8 +1431,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellFie
       valsToFill[i]=_loc[*w].getNumberOfGaussPt();
     else
       throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : orphan cell detected !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1605,6 +1628,8 @@ void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCoupl
 
 MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getMeasureField : mesh instance specified is NULL !");
   throw INTERP_KERNEL::Exception("Not implemented yet !");
 }
 
@@ -1705,6 +1730,8 @@ bool MEDCouplingFieldDiscretizationKriging::isEqualIfNotWhy(const MEDCouplingFie
 
 MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationKriging::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getMeasureField : mesh instance specified is NULL !");
   throw INTERP_KERNEL::Exception("getMeasureField on FieldDiscretizationKriging : not implemented yet !");
 }
 
@@ -1745,8 +1772,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const Da
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
   ret->alloc(nbOfTargetPoints,nbOfCompo);
   INTERP_KERNEL::matrixProduct(KnewiK->getConstPointer(),1,nbOfPts+delta,matrix3->getConstPointer(),nbOfPts+delta,nbOfTargetPoints*nbOfCompo,ret->getPointer());
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1779,8 +1805,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficie
   double *work=std::copy(arr->begin(),arr->end(),arr2->getPointer());
   std::fill(work,work+isDrift,0.);
   INTERP_KERNEL::matrixProduct(matrixInv->getConstPointer(),nbOfPts+isDrift,nbOfPts+isDrift,arr2->getConstPointer(),nbOfPts+isDrift,1,KnewiK->getPointer());
-  KnewiK->incrRef();
-  return KnewiK;
+  return KnewiK.retn();
 }
 
 /*!
@@ -1850,7 +1875,6 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::performDrift(const DataA
       destWork+=spaceDimension;
     }
   //
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
index 6efe4aae111377fbae9ca47eb5e6fd28137e0838..8e194911f71a02c4d5ce0df43a621dd2bc8c50fc 100644 (file)
@@ -46,6 +46,7 @@ namespace ParaMEDMEM
     double getPrecision() const { return _precision; }
     void setPrecision(double val) { _precision=val; }
     void updateTime() const;
+    std::size_t getHeapMemorySize() const;
     static TypeOfField getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception);
     virtual TypeOfField getEnum() const = 0;
     virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const;
@@ -191,6 +192,7 @@ namespace ParaMEDMEM
     MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds);
     ~MEDCouplingFieldDiscretizationPerCell();
     void updateTime() const;
+    std::size_t getHeapMemorySize() const;
     void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
     bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const;
     bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const;
@@ -214,6 +216,7 @@ namespace ParaMEDMEM
     MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const;
     std::string getStringRepr() const;
     const char *getRepr() const;
+    std::size_t getHeapMemorySize() const;
     int getNumberOfTuples(const MEDCouplingMesh *mesh) const;
     int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const;
     DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const;
index 36c10e825a45c29781756d585d5a48db3bf53fb5..f2fb7e1bda84e3c35bcf7b6a0e68bdce61ecf409 100644 (file)
 
 using namespace ParaMEDMEM;
 
+/*!
+ * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field.
+ *
+ * \param [in] type type of spatial discretization of a created field (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", \ref ParaMEDMEM::ON_NODES "ON_NODES", \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR").
+ * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
+ * \return a newly allocated field the caller should deal with.
+ */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
 {
   return new MEDCouplingFieldDouble(type,td);
 }
 
+/*!
+ * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field.
+ *
+ * \param [in] ft \ref MEDCouplingFieldTemplatesPage "field template" defining its spatial discretization and supporting mesh.
+ * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL")
+ * \return a newly allocated field the caller should deal with.
+ */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td)
 {
   return new MEDCouplingFieldDouble(ft,td);
 }
 
+/*!
+ * Sets time \a unit of \a this field.
+ *
+ * \param [in] unit \a unit (string) in which time is measured.
+ */
 void MEDCouplingFieldDouble::setTimeUnit(const char *unit)
 {
   _time_discr->setTimeUnit(unit);
 }
 
+/*!
+ * Returns a time unit of \a this field.
+ *
+ * \return a string describing units in which time is measured.
+ */
 const char *MEDCouplingFieldDouble::getTimeUnit() const
 {
   return _time_discr->getTimeUnit();
 }
 
+/*!
+ * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
+ * that is to say its mesh.
+ * 
+ * \throw  If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
+ *         NO_TIME.
+ */
+void MEDCouplingFieldDouble::synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception)
+{
+  _time_discr->synchronizeTimeWith(_mesh);
+}
+
 /*!
  * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method).
  * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false.
@@ -62,11 +100,12 @@ const char *MEDCouplingFieldDouble::getTimeUnit() const
  * It allows the user to perform methods
  * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field.
  * 
- * \warning The \b underlying \b mesh of the returned field is \b always the same (same pointer) than \a this \b whatever \b the \b value \b of \b recDeepCpy \b parameter.
+ * \warning The \b underlying \b mesh of the returned field is \b always the same (same pointer) than \a this **whatever the value** of \a recDeepCpy parameter.
  * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead.
  *
- * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied of only attached to the returned field.
+ * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
  * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
+ * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
 {
@@ -74,12 +113,17 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
 }
 
 /*!
- * This method behaves exactly like MEDCouplingFieldDouble::clone method \b except \b that \b here \b the \b underlying \b mesh \b is \b systematically
- * (whatever the value of the input parameter 'recDeepCpy') \b deeply \b duplicated.\n \n
+ * This method behaves exactly like MEDCouplingFieldDouble::clone method **except that here the underlying mesh is systematically **
+ * (whatever the value of the input parameter \a recDeepCpy) **deeply duplicated**.
+ *
  * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy".
  * 
  * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
  * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
+
+ * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
+ * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
+ * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
 {
@@ -94,16 +138,31 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) c
 }
 
 /*!
- * This method performs a deepCpy of \a this \b mesh \b included !
+ * This method performs a deepCpy of \a this (**mesh included**)!
  * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
- * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
+ * To avoid deep copying the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
  * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true.
+ *
+ * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
+ * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const
 {
   return cloneWithMesh(true);
 }
 
+/*!
+ * TODOC
+ * 
+ * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
+ * \param [in] deepCopy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
+ * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
+ *
+ * \ref cpp_mcfielddouble_buildnewtimereprfromthis "Here a C++ example."
+ * \ref py_mcfielddouble_buildnewtimereprfromthis "Here a Python example."
+ * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
+ */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
 {
   MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy);
@@ -191,6 +250,12 @@ std::string MEDCouplingFieldDouble::advancedRepr() const
   return ret.str();
 }
 
+void MEDCouplingFieldDouble::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<const MEDCouplingFieldDouble *> fs(1,this);
+  MEDCouplingFieldDouble::WriteVTK(fileName,fs);
+}
+
 bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception)
 {
   if(!other)
@@ -1074,12 +1139,35 @@ void MEDCouplingFieldDouble::updateTime() const
   updateTimeWith(*_time_discr);
 }
 
+std::size_t MEDCouplingFieldDouble::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if(_time_discr)
+    ret+=_time_discr->getHeapMemorySize();
+  return MEDCouplingField::getHeapMemorySize()+ret;
+}
+
 void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingField::setNature(nat);
   _type->checkCompatibilityWithNature(nat);
 }
 
+/*!
+ * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh.
+ * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME)
+ */
+void MEDCouplingFieldDouble::synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !");
+  int it=-1,ordr=-1;
+  double val=_mesh->getTime(it,ordr);
+  std::string timeUnit(_mesh->getTimeUnit());
+  setTime(val,it,ordr);
+  setTimeUnit(timeUnit.c_str());
+}
+
 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
 {
   return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
@@ -1362,7 +1450,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *ori
         }
     }
   ret->setArrays(newArr);
-  ret->incrRef(); return ret;
+  return ret.retn();
 }
 
 /*!
index 45a553b6b7a9ecf3e494578c8dd3e907bdf6306a..3b275f9de53cefab76674719e72295cad39aef41 100644 (file)
@@ -33,14 +33,16 @@ namespace ParaMEDMEM
   class MEDCOUPLING_EXPORT MEDCouplingFieldDouble : public MEDCouplingField
   {
   public:
-    static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME);
-    static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=NO_TIME);
+    static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME);
+    static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME);
     void setTimeUnit(const char *unit);
     const char *getTimeUnit() const;
+    void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception);
     void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
     void copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
     std::string simpleRepr() const;
     std::string advancedRepr() const;
+    void writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception);
     bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception);
     bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
     bool areCompatibleForMerge(const MEDCouplingField *other) const;
@@ -71,6 +73,7 @@ namespace ParaMEDMEM
     void setTimeValue(double val) throw(INTERP_KERNEL::Exception) { _time_discr->setTimeValue(val); }
     void setEndTimeValue(double val) throw(INTERP_KERNEL::Exception) { _time_discr->setEndTimeValue(val); }
     void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); }
+    void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception);
     void setStartTime(double val, int iteration, int order) { _time_discr->setStartTime(val,iteration,order); }
     void setEndTime(double val, int iteration, int order) { _time_discr->setEndTime(val,iteration,order); }
     double getTime(int& iteration, int& order) const { return _time_discr->getTime(iteration,order); }
@@ -125,6 +128,7 @@ namespace ParaMEDMEM
     int getNumberOfTuples() const throw(INTERP_KERNEL::Exception);
     int getNumberOfValues() const throw(INTERP_KERNEL::Exception);
     void updateTime() const;
+    std::size_t getHeapMemorySize() const;
     //
     void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
     void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
index 1b5df9b077c53ebc7f57aa6d5fd3ae2f0c70b168..abab57f5ae121fb1ab0a398e4389203d7e6b2470 100644 (file)
@@ -87,6 +87,15 @@ std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const
   return oss.str();
 }
 
+std::size_t ParaMEDMEM::MEDCouplingGaussLocalization::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  ret+=_ref_coord.capacity()*sizeof(double);
+  ret+=_gauss_coord.capacity()*sizeof(double);
+  ret+=_weight.capacity()*sizeof(double);
+  return ret;
+}
+
 bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const
 {
   if(_type!=other._type)
index 49f843e7e0757cea57664152a369ffcc51505930..31adcb8528588aa725b5fb19df2c17cb44ed7dbd 100644 (file)
@@ -41,6 +41,7 @@ namespace ParaMEDMEM
     int getDimension() const;
     int getNumberOfPtsInRefCell() const;
     std::string getStringRepr() const;
+    std::size_t getHeapMemorySize() const;
     void checkCoherency() const throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const;
     void pushTinySerializationIntInfo(std::vector<int>& tinyInfo) const;
index 9081b8ecb6c24b03487835a280c3cd2b60e52323..4436fa7d1b4aa82e4dae4bbbf226a668d14e215b 100644 (file)
@@ -36,7 +36,7 @@ typedef double (*MYFUNCPTR)(double);
 using namespace ParaMEDMEM;
 
 template<int SPACEDIM>
-void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const
+void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
 {
   const double *coordsPtr=getConstPointer();
   BBTree<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec/10);
@@ -59,9 +59,9 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l
                     }
               if(!commonNodes.empty())
                 {
-                  cI.push_back(cI.back()+(int)commonNodes.size()+1);
-                  c.push_back(i);
-                  c.insert(c.end(),commonNodes.begin(),commonNodes.end());
+                  cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
+                  c->pushBackSilent(i);
+                  c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
                 }
             }
         }
@@ -70,7 +70,7 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l
 
 template<int SPACEDIM>
 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
-                                                std::vector<int>& c, std::vector<int>& cI)
+                                                DataArrayInt *c, DataArrayInt *cI)
 {
   for(int i=0;i<nbOfTuples;i++)
     {
@@ -79,11 +79,21 @@ void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTr
       std::vector<int> commonNodes;
       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
         commonNodes.push_back(*it);
-      cI.push_back(cI.back()+(int)commonNodes.size());
-      c.insert(c.end(),commonNodes.begin(),commonNodes.end());
+      cI->pushBackSilent(cI->back()+(int)commonNodes.size());
+      c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
     }
 }
 
+std::size_t DataArray::getHeapMemorySize() const
+{
+  std::size_t sz1=_name.capacity();
+  std::size_t sz2=_info_on_compo.capacity();
+  std::size_t sz3=0;
+  for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
+    sz3+=(*it).capacity();
+  return sz1+sz2+sz3;
+}
+
 void DataArray::setName(const char *name)
 {
   _name=name;
@@ -130,12 +140,6 @@ void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, cons
 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
 {
   std::ostringstream oss;
-  if(_nb_of_tuples!=other._nb_of_tuples)
-    {
-      oss << "Number of tuples of DataArray mismatch : this number of tuples=" << _nb_of_tuples << " other number of tuples=" << other._nb_of_tuples;
-      reason=oss.str();
-      return false;
-    }
   if(_name!=other._name)
     {
       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
@@ -383,6 +387,8 @@ int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char
       std::ostringstream oss; oss << msg << " : end before begin !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
+  if(end==begin)
+    return 0;
   if(step<=0)
     {
       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
@@ -460,6 +466,13 @@ void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
 }
 
+std::size_t DataArrayDouble::getHeapMemorySize() const
+{
+  std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated();
+  sz*=sizeof(double);
+  return DataArray::getHeapMemorySize()+sz;
+}
+
 /*!
  * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()'
  * and if 'this' is not allocated it will change the number of components of 'this'.
@@ -541,6 +554,49 @@ void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL:
   copyStringInfoFrom(other);
 }
 
+void DataArrayDouble::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    {
+      _mem.reserve(nbOfElems);
+    }
+  else if(nbCompo==0)
+    {
+      _mem.reserve(nbOfElems);
+      _info_on_compo.resize(1);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
+}
+
+void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    _mem.pushBack(val);
+  else if(nbCompo==0)
+    {
+      _info_on_compo.resize(1);
+      _mem.pushBack(val);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
+}
+
+double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()==1)
+    return _mem.popBack();
+  else
+    throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
+}
+
+void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
+{
+  _mem.pack();
+}
+
 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
 {
   if(isAllocated())
@@ -556,9 +612,8 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::E
 {
   if(nbOfTuple<0 || nbOfCompo<0)
     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*_nb_of_tuples);
+  _mem.alloc(nbOfCompo*nbOfTuple);
   declareAsNew();
 }
 
@@ -627,16 +682,12 @@ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
  */
  void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
 {
-  if(!isMonotonic(increasing, eps))
+  if(!isMonotonic(increasing,eps))
     {
       if (increasing)
-        {
-          throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
-        }
+        throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
       else
-        {
-          throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
-        }
+        throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
     }
 }
 
@@ -655,7 +706,7 @@ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTER
     return true;
   double ref=ptr[0];
   double absEps=fabs(eps);
-  if (increasing)
+  if(increasing)
     {
       for(int i=1;i<nbOfElements;i++)
         {
@@ -767,8 +818,7 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other,
 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
-  _mem.reAlloc((int)(_info_on_compo.size())*nbOfTuples);
-  _nb_of_tuples=nbOfTuples;
+  _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
   declareAsNew();
 }
 
@@ -938,8 +988,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons
     else
       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -961,8 +1010,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) c
   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1019,8 +1067,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pai
   double *work=ret->getPointer();
   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1097,7 +1144,6 @@ void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception
   int nbOfElems=getNbOfElems();
   if(nbOfElems%newNbOfCompo!=0)
     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
-  _nb_of_tuples=nbOfElems/newNbOfCompo;
   _info_on_compo.clear();
   _info_on_compo.resize(newNbOfCompo);
   declareAsNew();
@@ -1135,8 +1181,7 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>&
   for(int i=0;i<nbOfTuples;i++)
     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1193,12 +1238,10 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI
     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
   
   int nbOfTuples=getNumberOfTuples();
-  comm=DataArrayInt::New();
-  commIndex=DataArrayInt::New();
   //
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(prec);
   //
-  std::vector<int> c,cI(1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
   switch(nbOfCompo)
     {
     case 3:
@@ -1213,10 +1256,8 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI
     default:
       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
     }
-  commIndex->alloc((int)cI.size(),1);
-  std::copy(cI.begin(),cI.end(),commIndex->getPointer());
-  comm->alloc(cI.back(),1);
-  std::copy(c.begin(),c.end(),comm->getPointer());
+  comm=c.retn();
+  commIndex=cI.retn();
 }
 
 /*!
@@ -1244,8 +1285,7 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const th
         *retPtr=val;
     }
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1263,7 +1303,7 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple
   findCommonTuples(prec,limitTupleId,c0,cI0);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
   int newNbOfTuples=-1;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
 }
 
@@ -1639,7 +1679,6 @@ void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &ar
 
 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
 {
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
   declareAsNew();
@@ -1647,7 +1686,6 @@ void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType
 
 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
 {
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
   declareAsNew();
@@ -1723,8 +1761,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw
           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
         }
     }
-  bbox->incrRef();
-  return bbox;
+  return bbox.retn();
 }
 
 /*!
@@ -1745,7 +1782,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw
  *
  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
  */
-void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception)
+void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
 {
   if(!other)
     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
@@ -1756,32 +1793,31 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do
   if(nbOfCompo!=otherNbOfCompo)
     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
   int nbOfTuplesOther=other->getNumberOfTuples();
-  std::vector<int> ret;
-  c.clear();
-  cI.resize(1); cI[0]=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
   switch(nbOfCompo)
     {
     case 3:
       {
         BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
         break;
       }
     case 2:
       {
         BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
         break;
       }
     case 1:
       {
         BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
         break;
       }
     default:
       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
     }
+  c=cArr.retn(); cI=cIArr.retn();
 }
 
 /*!
@@ -1920,6 +1956,45 @@ void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Excepti
     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
 }
 
+/*!
+ * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
+ * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
+ *
+ *
+ * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
+ * \a tupleEnd. If not an exception will be thrown.
+ *
+ * \param [in] tupleBg start pointer (included) of input external tuple
+ * \param [in] tupleEnd end pointer (not included) of input external tuple
+ * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
+ * \return the min distance.
+ * \sa MEDCouplingUMesh::distanceToPoint
+ */
+double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  int nbTuple=getNumberOfTuples();
+  int nbComps=getNumberOfComponents();
+  if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
+    { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+  if(nbTuple==0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
+  double ret0=std::numeric_limits<double>::max();
+  tupleId=-1;
+  const double *work=getConstPointer();
+  for(int i=0;i<nbTuple;i++)
+    {
+      double val=0.;
+      for(int j=0;j<nbComps;j++,work++) 
+        val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
+      if(val>=ret0)
+        continue;
+      else
+        { ret0=val; tupleId=i; }
+    }
+  return sqrt(ret0);
+}
+
 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
@@ -2230,8 +2305,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const thro
           outData[j*nbOfTuples+i]=dist;
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -2281,8 +2355,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const Da
           outData[i*nbOfTuples+j]=dist;
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
@@ -2864,8 +2937,7 @@ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArray
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
@@ -2926,8 +2998,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -2939,8 +3010,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat
           for(int i=0;i<nbOfTuple1;i++)
             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -2958,8 +3028,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat
       for(int i=0;i<nbOfTuple1;i++)
         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
       ret->copyStringInfoFrom(*a1);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -3077,8 +3146,7 @@ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const Data
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
@@ -3139,8 +3207,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -3152,8 +3219,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr
           for(int i=0;i<nbOfTuple1;i++)
             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -3171,8 +3237,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr
       for(int i=0;i<nbOfTuple1;i++)
         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
       ret->copyStringInfoFrom(*a1);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -3385,6 +3450,13 @@ void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
 }
 
+std::size_t DataArrayInt::getHeapMemorySize() const
+{
+  std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated();
+  sz*=sizeof(int);
+  return DataArray::getHeapMemorySize()+sz;
+}
+
 /*!
  * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()'
  * and if 'this' is not allocated it will change the number of components of 'this'.
@@ -3484,6 +3556,49 @@ void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Excep
   copyStringInfoFrom(other);
 }
 
+void DataArrayInt::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    {
+      _mem.reserve(nbOfElems);
+    }
+  else if(nbCompo==0)
+    {
+      _mem.reserve(nbOfElems);
+      _info_on_compo.resize(1);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
+}
+
+void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    _mem.pushBack(val);
+  else if(nbCompo==0)
+    {
+      _info_on_compo.resize(1);
+      _mem.pushBack(val);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
+}
+
+int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()==1)
+    return _mem.popBack();
+  else
+    throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
+}
+
+void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
+{
+  _mem.pack();
+}
+
 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
 {
   if(isAllocated())
@@ -3498,10 +3613,9 @@ void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
 {
   if(nbOfTuple<0 || nbOfCompo<0)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
-  _nb_of_tuples=nbOfTuple;
+    throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
   _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*_nb_of_tuples);
+  _mem.alloc(nbOfCompo*nbOfTuple);
   declareAsNew();
 }
 
@@ -3680,12 +3794,9 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
     }
   ret3->alloc((int)castsDetected.size(),1);
   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
-  ret1->incrRef();
-  castArr=ret1;
-  ret2->incrRef();
-  rankInsideCast=ret2;
-  ret3->incrRef();
-  castsPresent=ret3;
+  castArr=ret1.retn();
+  rankInsideCast=ret2.retn();
+  castsPresent=ret3.retn();
 }
 
 /*!
@@ -3718,12 +3829,12 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
  * This method invert array 'di' that is a conversion map from Old to New numbering to New to Old numbering.
+ * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [3,1,2,4,9,6,8]
  */
 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
 {
@@ -3738,6 +3849,23 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
   return ret;
 }
 
+/*!
+ * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
+ * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [0,1,2,4,5,6,8] whereas DataArrayInt::invertArrayO2N2N2O returns [3,1,2,4,9,6,8]
+ */
+DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(newNbOfElem,1);
+  int nbOfOldNodes=getNumberOfTuples();
+  const int *old2New=getConstPointer();
+  int *pt=ret->getPointer();
+  for(int i=nbOfOldNodes-1;i>=0;i--)
+    if(old2New[i]!=-1)
+      pt[old2New[i]]=i;
+  return ret;
+}
+
 /*!
  * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering.
  */
@@ -3798,6 +3926,106 @@ void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
   _mem.reverse();
 }
 
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  if(!isMonotonic(increasing))
+    {
+      if (increasing)
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
+      else
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
+    }
+}
+
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
+  int nbOfElements=getNumberOfTuples();
+  const int *ptr=getConstPointer();
+  if(nbOfElements==0)
+    return true;
+  int ref=ptr[0];
+  if(increasing)
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]>=ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  else
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]<=ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  return true;
+}
+
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
+  int nbOfElements=getNumberOfTuples();
+  const int *ptr=getConstPointer();
+  if(nbOfElements==0)
+    return true;
+  int ref=ptr[0];
+  if(increasing)
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]>ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  else
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]<ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  return true;
+}
+
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  if(!isStrictlyMonotonic(increasing))
+    {
+      if (increasing)
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
+      else
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
+    }
+}
+
 /*!
  * This method expects that 'this' and 'other' have the same number of tuples and exactly one component both. If not an exception will be thrown.
  * This method retrieves a newly created array with same number of tuples than 'this' and 'other' with one component.
@@ -3831,13 +4059,11 @@ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
         }
       retToFill[i]=(*it).second;
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
 {
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
   declareAsNew();
@@ -3845,7 +4071,6 @@ void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type,
 
 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
 {
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
   declareAsNew();
@@ -3957,7 +4182,7 @@ DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTup
 }
 
 /*!
- * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here.
+ * This method is a generalization of DataArrayInt::substr method because a not contigous range can be specified here.
  * This method is equavalent to DataArrayInt::renumberAndReduce except that convention in input is new2old and \b not old2new.
  */
 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
@@ -3994,8 +4219,7 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int
     else
       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4017,8 +4241,7 @@ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const t
   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4075,15 +4298,14 @@ DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,
   int *work=ret->getPointer();
   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
  * This method works only for arrays having single component.
  * If this contains the array a1 containing [9,10,0,6,4,11,3,7] this method returns an array a2 [5,6,0,3,2,7,1,4].
  * By doing a1.renumber(a2) the user will obtain array a3 equal to a1 sorted.
- * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldDouble::renumberCells when check is set to true.
+ * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldInt::renumberCells when check is set to true.
  * This method throws an exception if more 2 or more elements in 'this' are same.
  */
 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
@@ -4142,36 +4364,32 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data
   int *retPtr=ret->getPointer();
   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
-  ret->incrRef();
-  retI->incrRef();
-  arr=ret;
-  arrI=retI;
+  arr=ret.retn();
+  arrI=retI.retn();
 }
 
 /*!
- * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayDouble::findCommonTuples for example)
+ * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayInt::findCommonTuples for example)
  * The retrieved array minimizes the permutation.
  * Let's take an example : 
  * If 'nbOfOldTuples'==10 and 'arr'==[0,3, 5,7,9] and 'arrI'==[0,2,5] it returns the following array [0,1,2,0,3,4,5,4,6,4] and newNbOfTuples==7.
  *
  * @param nbOfOldTuples is the number of tuples in initial array.
  * @param arr is the list of tuples ids grouped by 'arrI' array
- * @param arrI is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple.
+ * @param arrIBg is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple.
+ * @param arrIEnd is the entry point of 'arr' array (end not included)
  * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application
  */
-DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
+DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
 {
-  if(!arr || !arrI)
-    throw INTERP_KERNEL::Exception("DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : presence of NULL ref of DataArrayInt in input !");
-  DataArrayInt *ret=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc(nbOfOldTuples,1);
   int *pt=ret->getPointer();
   std::fill(pt,pt+nbOfOldTuples,-1);
-  int nbOfGrps=arrI->getNumberOfTuples()-1;
-  const int *cIPtr=arrI->getConstPointer();
-  const int *cPtr=arr->getConstPointer();
+  int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
+  const int *cIPtr=arrIBg;
   for(int i=0;i<nbOfGrps;i++)
-    pt[cPtr[cIPtr[i]]]=-(i+2);
+    pt[arr[cIPtr[i]]]=-(i+2);
   int newNb=0;
   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
     {
@@ -4183,13 +4401,21 @@ DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTu
             {
               int grpId=-(pt[iNode]+2);
               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
-                pt[cPtr[j]]=newNb;
+                {
+                  if(arr[j]>=0 && arr[j]<nbOfOldTuples)
+                    pt[arr[j]]=newNb;
+                  else
+                    {
+                      std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
+                      throw INTERP_KERNEL::Exception(oss.str().c_str());
+                    }
+                }
               newNb++;
             }
         }
     }
   newNbOfTuples=newNb;
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4240,8 +4466,7 @@ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Ex
   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
     *opt+=m[*pt];
   //
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4333,7 +4558,6 @@ void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
   int nbOfElems=getNbOfElems();
   if(nbOfElems%newNbOfCompo!=0)
     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
-  _nb_of_tuples=nbOfElems/newNbOfCompo;
   _info_on_compo.clear();
   _info_on_compo.resize(newNbOfCompo);
   declareAsNew();
@@ -4384,8 +4608,7 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue)
 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
-  _mem.reAlloc((int)_info_on_compo.size()*nbOfTuples);
-  _nb_of_tuples=nbOfTuples;
+  _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
   declareAsNew();
 }
 
@@ -4405,8 +4628,7 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compo
   for(int i=0;i<nbOfTuples;i++)
     for(int j=0;j<newNbOfCompo;j++,nc++)
       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4816,15 +5038,12 @@ DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exce
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
   const int *cptr=getConstPointer();
-  std::vector<int> res;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   int nbOfTuples=getNumberOfTuples();
   for(int i=0;i<nbOfTuples;i++,cptr++)
     if(*cptr==val)
-      res.push_back(i);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)res.size(),1);
-  std::copy(res.begin(),res.end(),ret->getPointer());
-  return ret;
+      ret->pushBackSilent(i);
+  return ret.retn();
 }
 
 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
@@ -4832,15 +5051,12 @@ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::E
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
   const int *cptr=getConstPointer();
-  std::vector<int> res;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   int nbOfTuples=getNumberOfTuples();
   for(int i=0;i<nbOfTuples;i++,cptr++)
     if(*cptr!=val)
-      res.push_back(i);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)res.size(),1);
-  std::copy(res.begin(),res.end(),ret->getPointer());
-  return ret;
+      ret->pushBackSilent(i);
+  return ret.retn();
 }
 
 /*!
@@ -5031,6 +5247,32 @@ bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INT
   return locateValue(vals)!=-1;
 }
 
+
+void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  const int *ptr=getConstPointer();
+  int nbTuple=getNumberOfTuples();
+  int nbComps=getNumberOfComponents();
+  std::fill(res,res+nbComps,0);
+  for(int i=0;i<nbTuple;i++)
+    std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
+}
+
+int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  const int *ptr=getConstPointer();
+  int nbTuple=getNumberOfTuples();
+  int nbComps=getNumberOfComponents();
+  if(compId>=nbComps)
+    throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
+  int ret=0;
+  for(int i=0;i<nbTuple;i++)
+    ret+=ptr[i*nbComps+compId];
+  return ret;
+}
+
 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
 {
   if(!a1 || !a2)
@@ -5374,8 +5616,7 @@ DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *
         tmp.insert(retPtr[*p]);
       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
@@ -5472,6 +5713,9 @@ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_
    return ret;
 }
 
+/*!
+ * \sa DataArrayInt::buildSubstractionOptimized
+ */
 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
 {
   if(!other)
@@ -5496,6 +5740,33 @@ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const t
   return ret;
 }
 
+/*!
+ * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
+ * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
+ * 
+ * \param [in] other an array with one component and expected to be sorted ascendingly.
+ * \ret list of ids in \a this but not in \a other.
+ * \sa DataArrayInt::buildSubstraction
+ */
+DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
+{
+  static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
+  if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
+  checkAllocated(); other->checkAllocated();
+  if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
+  if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
+  const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  for(;work1!=pt1End;work1++)
+    {
+      if(work2!=pt2End && *work1==*work2)
+        work2++;
+      else
+        ret->pushBackSilent(*work1);
+    }
+  return ret.retn();
+}
+
 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
 {
   std::vector<const DataArrayInt *>arrs(2);
@@ -5530,8 +5801,7 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc(std::distance(data,last),1);
   std::copy(data,last,ret->getPointer());
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5661,8 +5931,7 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets
       for(int j=0;j<off;j++,retPtr++)
         *retPtr=start+j;
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5711,8 +5980,7 @@ DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges)
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5761,8 +6029,7 @@ DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5790,8 +6057,7 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(IN
         *retPtr=val;
     }
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5909,8 +6175,7 @@ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
@@ -5971,8 +6236,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -5984,8 +6248,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt
           for(int i=0;i<nbOfTuple1;i++)
             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -6003,8 +6266,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt
       for(int i=0;i<nbOfTuple1;i++)
         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
       ret->copyStringInfoFrom(*a1);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -6117,8 +6379,7 @@ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
@@ -6179,8 +6440,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -6192,8 +6452,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a
           for(int i=0;i<nbOfTuple1;i++)
             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -6211,8 +6470,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a
       for(int i=0;i<nbOfTuple1;i++)
         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
       ret->copyStringInfoFrom(*a1);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -6279,8 +6537,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -6292,8 +6549,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *
           for(int i=0;i<nbOfTuple1;i++)
             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -6311,8 +6567,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *
       for(int i=0;i<nbOfTuple1;i++)
         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
       ret->copyStringInfoFrom(*a1);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -6399,8 +6654,7 @@ DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KER
       for(int i=begin;i>end;i+=step,ptr++)
         *ptr=i;
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
index 6b8b5853f6b0cbc2f33abc5343f06fe02080a61c..eaa2727241935f361602f0499879d357f0e27209 100644 (file)
@@ -55,11 +55,13 @@ namespace ParaMEDMEM
   class MemArray
   {
   public:
-    MemArray():_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC) { }
+    MemArray():_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(CPP_DEALLOC) { }
     MemArray(const MemArray<T>& other);
     bool isNull() const { return _pointer.isNull(); }
     const T *getConstPointerLoc(int offset) const { return _pointer.getConstPointerLoc(offset); }
     const T *getConstPointer() const { return _pointer.getConstPointer(); }
+    int getNbOfElem() const { return _nb_of_elem; }
+    int getNbOfElemAllocated() const { return _nb_of_elem_alloc; }
     T *getPointer() { return _pointer.getPointer(); }
     MemArray<T> &operator=(const MemArray<T>& other);
     T operator[](int id) const { return _pointer.getConstPointer()[id]; }
@@ -73,16 +75,23 @@ namespace ParaMEDMEM
     void sort(bool asc);
     void reverse();
     void alloc(int nbOfElements) throw(INTERP_KERNEL::Exception);
+    void reserve(int newNbOfElements) throw(INTERP_KERNEL::Exception);
     void reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception);
     void useArray(const T *array, bool ownership, DeallocType type, int nbOfElem);
     void useExternalArrayWithRWAccess(const T *array, int nbOfElem);
     void writeOnPlace(int id, T element0, const T *others, int sizeOfOthers);
+    template<class InputIterator>
+    void insertAtTheEnd(InputIterator first, InputIterator last);
+    void pushBack(T elem) throw(INTERP_KERNEL::Exception);
+    T popBack() throw(INTERP_KERNEL::Exception);
+    void pack() const;
     ~MemArray() { destroy(); }
   private:
     void destroy();
     static void destroyPointer(T *pt, DeallocType type);
   private:
     int _nb_of_elem;
+    int _nb_of_elem_alloc;
     bool _ownership;
     MEDCouplingPointer<T> _pointer;
     DeallocType _dealloc;
@@ -91,6 +100,7 @@ namespace ParaMEDMEM
   class DataArray : public RefCountObject, public TimeLabel
   {
   public:
+    MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const;
     MEDCOUPLING_EXPORT void setName(const char *name);
     MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
@@ -110,8 +120,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT std::string getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int getNumberOfComponents() const { return (int)_info_on_compo.size(); }
-    MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _nb_of_tuples; }
-    MEDCOUPLING_EXPORT int getNbOfElems() const { return ((int)_info_on_compo.size())*_nb_of_tuples; }
+    MEDCOUPLING_EXPORT virtual int getNumberOfTuples() const = 0;
+    MEDCOUPLING_EXPORT virtual int getNbOfElems() const = 0;
     MEDCOUPLING_EXPORT void checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception);
@@ -124,13 +134,12 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT virtual void reprCppStream(const char *varName, std::ostream& stream) const = 0;
   protected:
-    DataArray():_nb_of_tuples(-1) { }
+    DataArray() { }
   protected:
     static void CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception);
     static void CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception);
     static void CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception);
   protected:
-    int _nb_of_tuples;
     std::string _name;
     std::vector<std::string> _info_on_compo;
   };
@@ -148,12 +157,20 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static DataArrayDouble *New();
     MEDCOUPLING_EXPORT bool isAllocated() const;
     MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); }
+    MEDCOUPLING_EXPORT int getNbOfElems() const { return _mem.getNbOfElem(); }
+    MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const;
     MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT double doubleValue() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool empty() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const;
     MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void reserve(int nbOfElems) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void pushBackSilent(double val) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT double popBackSilent() throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void pack() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT int getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); }
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception);
@@ -222,11 +239,13 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT const double *end() const { return getConstPointer()+getNbOfElems(); }
     MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo);
+    template<class InputIterator>
+    void insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); }
     MEDCOUPLING_EXPORT void checkNoNullValues() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT double getMaxValueInArray() const throw(INTERP_KERNEL::Exception);
@@ -239,6 +258,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT double normMax() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void accumulate(double *res) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT double accumulate(int compId) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT double distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *fromPolarToCart() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *fromCylToCart() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *fromSpherToCart() const throw(INTERP_KERNEL::Exception);
@@ -292,10 +312,10 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS);
   public:
     template<int SPACEDIM>
-    void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const;
+    void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const;
     template<int SPACEDIM>
     static void FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
-                                          std::vector<int>& c, std::vector<int>& cI);
+                                          DataArrayInt *c, DataArrayInt *cI);
   private:
     DataArrayDouble() { }
   private:
@@ -341,6 +361,9 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static DataArrayInt *New();
     MEDCOUPLING_EXPORT bool isAllocated() const;
     MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); }
+    MEDCOUPLING_EXPORT int getNbOfElems() const { return _mem.getNbOfElem(); }
+    MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const;
     MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int intValue() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int getHashCode() const throw(INTERP_KERNEL::Exception);
@@ -348,6 +371,11 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const;
     MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void reserve(int nbOfElems) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void pushBackSilent(int val) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT int popBackSilent() throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void pack() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT int getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); }
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const;
@@ -357,6 +385,10 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void sort(bool asc=true) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void fillWithValue(int val) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void iota(int init=0) throw(INTERP_KERNEL::Exception);
@@ -374,6 +406,7 @@ namespace ParaMEDMEM
                                               DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const;
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const;
+    MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception);
     //!alloc or useArray should have been called before.
     MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const;
@@ -390,7 +423,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool isIdentity() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool isUniform(int val) const throw(INTERP_KERNEL::Exception);
@@ -434,6 +467,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool presenceOfValue(int value) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void accumulate(int *res) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT int accumulate(int compId) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int getMaxValueInArray() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception);
@@ -456,6 +491,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildUnique() const throw(INTERP_KERNEL::Exception);
@@ -469,7 +505,9 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT std::set<int> getDifferentValues() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
-    MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo);
+    void MEDCOUPLING_EXPORT useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo);
+    template<class InputIterator>
+    void insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); }
     MEDCOUPLING_EXPORT static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception);
@@ -527,6 +565,36 @@ namespace ParaMEDMEM
     int *_pt;
     int _nb_of_compo;
   };
+
+  template<class InputIterator>
+  void DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception)
+  {
+    int nbCompo=getNumberOfComponents();
+    if(nbCompo==1)
+      _mem.insertAtTheEnd(first,last);
+    else if(nbCompo==0)
+      {
+        _info_on_compo.resize(1);
+        _mem.insertAtTheEnd(first,last);
+      }
+    else
+      throw INTERP_KERNEL::Exception("DataArrayDouble::insertAtTheEnd : not available for DataArrayDouble with number of components different than 1 !");
+  }
+  
+  template<class InputIterator>
+  void DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception)
+  {
+    int nbCompo=getNumberOfComponents();
+    if(nbCompo==1)
+      _mem.insertAtTheEnd(first,last);
+    else if(nbCompo==0)
+      {
+        _info_on_compo.resize(1);
+        _mem.insertAtTheEnd(first,last);
+      }
+    else
+      throw INTERP_KERNEL::Exception("DataArrayInt::insertAtTheEnd : not available for DataArrayInt with number of components different than 1 !");
+  }
 }
 
 #endif
index e569249d8dfddf3bdbbce777a9ca2d119c86e449..35404431b19cbec8192e72041d505a9b5c83bc22 100644 (file)
@@ -17,6 +17,7 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 // Author : Anthony Geay (CEA/DEN)
+
 #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
 #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
 
@@ -45,11 +46,12 @@ namespace ParaMEDMEM
   }
 
   template<class T>
-  MemArray<T>::MemArray(const MemArray<T>& other):_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC)
+  MemArray<T>::MemArray(const MemArray<T>& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(CPP_DEALLOC)
   {
     if(!other._pointer.isNull())
       {
-        T *pointer=new T[other._nb_of_elem];
+        _nb_of_elem_alloc=other._nb_of_elem;
+        T *pointer=new T[_nb_of_elem_alloc];
         std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer);
         useArray(pointer,true,CPP_DEALLOC,other._nb_of_elem);
       }
@@ -59,6 +61,7 @@ namespace ParaMEDMEM
   void MemArray<T>::useArray(const T *array, bool ownership, DeallocType type, int nbOfElem)
   {
     _nb_of_elem=nbOfElem;
+    _nb_of_elem_alloc=nbOfElem;
     destroy();
     if(ownership)
       _pointer.setInternal(const_cast<T *>(array));
@@ -72,6 +75,7 @@ namespace ParaMEDMEM
   void MemArray<T>::useExternalArrayWithRWAccess(const T *array, int nbOfElem)
   {
     _nb_of_elem=nbOfElem;
+    _nb_of_elem_alloc=nbOfElem;
     destroy();
     _pointer.setInternal(const_cast<T *>(array));
     _ownership=false;
@@ -81,11 +85,55 @@ namespace ParaMEDMEM
   template<class T>
   void MemArray<T>::writeOnPlace(int id, T element0, const T *others, int sizeOfOthers)
   {
-    if(id+sizeOfOthers>=_nb_of_elem)
-      reAlloc(2*_nb_of_elem+sizeOfOthers+1);
+    if(id+sizeOfOthers>=_nb_of_elem_alloc)
+      reserve(2*_nb_of_elem+sizeOfOthers+1);
     T *pointer=_pointer.getPointer();
     pointer[id]=element0;
     std::copy(others,others+sizeOfOthers,pointer+id+1);
+    _nb_of_elem=std::max<int>(_nb_of_elem,id+sizeOfOthers+1);
+  }
+  
+  template<class T>
+  template<class InputIterator>
+  void MemArray<T>::insertAtTheEnd(InputIterator first, InputIterator last)
+  {
+    T *pointer=_pointer.getPointer();
+    while(first!=last)
+      {
+        if(_nb_of_elem>=_nb_of_elem_alloc || _nb_of_elem==0)
+          {
+            reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1);
+            pointer=_pointer.getPointer();
+          }
+        pointer[_nb_of_elem++]=*first++;
+      }
+  }
+  
+  template<class T>
+  void MemArray<T>::pushBack(T elem) throw(INTERP_KERNEL::Exception)
+  {
+    if(_nb_of_elem>=_nb_of_elem_alloc)
+      reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1);
+    T *pt=getPointer();
+    pt[_nb_of_elem++]=elem;
+  }
+  
+  template<class T>
+  T MemArray<T>::popBack() throw(INTERP_KERNEL::Exception)
+  {
+    if(_nb_of_elem>0)
+      {
+        const T *pt=getConstPointer();
+        return pt[--_nb_of_elem];
+      }
+    throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !");
+  }
+  
+  template<class T>
+  void MemArray<T>::pack() const
+  {
+    if(_nb_of_elem>=0)
+      (const_cast<MemArray<T> * >(this))->reserve(_nb_of_elem);
   }
 
   template<class T>
@@ -121,7 +169,7 @@ namespace ParaMEDMEM
   }
   
   /*!
-   * @param sl is typically the number of components [in parameter]
+   * \param [in] sl is typically the number of components
    */
   template<class T>
   void MemArray<T>::repr(int sl, std::ostream& stream) const
@@ -130,8 +178,8 @@ namespace ParaMEDMEM
     if(!_pointer.isNull())
       {
         if(sl!=0)
-          stream << _nb_of_elem/sl;
-        else
+          stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc;
+       else
           stream << "Empty Data";
       }
     else
@@ -160,7 +208,7 @@ namespace ParaMEDMEM
   }
   
   /*!
-   * @param sl is typically the number of components [in parameter]
+   * \param [in] sl is typically the number of components
    */
   template<class T>
   void MemArray<T>::reprZip(int sl, std::ostream& stream) const
@@ -260,22 +308,60 @@ namespace ParaMEDMEM
     if(nbOfElements<0)
       throw INTERP_KERNEL::Exception("MemArray::alloc : request for negative length of data !");
     _nb_of_elem=nbOfElements;
-    _pointer.setInternal(new T[_nb_of_elem]);
+    _nb_of_elem_alloc=nbOfElements;
+    _pointer.setInternal(new T[_nb_of_elem_alloc]);
     _ownership=true;
     _dealloc=CPP_DEALLOC;
   }
-  
+
+  /*!
+   * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
+   * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray<T>::reAlloc method.
+   * So after the call of this method \a _nb_of_elem will be equal tostd::min<int>(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to 
+   * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation.
+   * So after the call of this method the accessible content is perfectly set.
+   * 
+   * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
+   */
+  template<class T>
+  void MemArray<T>::reserve(int newNbOfElements) throw(INTERP_KERNEL::Exception)
+  {
+    if(newNbOfElements<0)
+      throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !");
+    if(_nb_of_elem_alloc==newNbOfElements)
+      return ;
+    T *pointer=new T[newNbOfElements];
+    std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<int>(_nb_of_elem,newNbOfElements),pointer);
+    if(_ownership)
+      destroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external
+    _pointer.setInternal(pointer);
+    _nb_of_elem=std::min<int>(_nb_of_elem,newNbOfElements);
+    _nb_of_elem_alloc=newNbOfElements;
+    _ownership=true;
+    _dealloc=CPP_DEALLOC;
+  }
+
+  /*!
+   * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
+   * \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min<int>(_nb_of_elem,newNbOfElements) come from the .
+   * The remaing part of the new allocated chunk are available but not set previouly !
+   * 
+   * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
+   */
   template<class T>
   void MemArray<T>::reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception)
   {
     if(newNbOfElements<0)
       throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !");
+    if(_nb_of_elem==newNbOfElements)
+      return ;
     T *pointer=new T[newNbOfElements];
     std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<int>(_nb_of_elem,newNbOfElements),pointer);
     if(_ownership)
       destroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external
     _pointer.setInternal(pointer);
     _nb_of_elem=newNbOfElements;
+    _nb_of_elem_alloc=newNbOfElements;
     _ownership=true;
     _dealloc=CPP_DEALLOC;
   }
index e0a9c788393126f7b60ef01f48999fd7ca64e620..38e09721d8737f6f50f849362a86c4c2d1de35aa 100644 (file)
@@ -43,6 +43,11 @@ MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):_name(other._name
 {
 }
 
+std::size_t MEDCouplingMesh::getHeapMemorySize() const
+{
+  return _name.capacity()+_description.capacity()+_time_unit.capacity();
+}
+
 /*!
  * This method is only for ParaMEDMEM in ParaFIELD constructor.
  */
@@ -232,11 +237,11 @@ bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const
  */
 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
   ret->setMesh(this);
   ret->fillFromAnalytic(nbOfComp,func);
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
@@ -292,11 +297,11 @@ void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTER
  */
 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
   ret->setMesh(this);
   ret->fillFromAnalytic(nbOfComp,func);
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
@@ -312,11 +317,11 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbO
  */
 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
   ret->setMesh(this);
   ret->fillFromAnalytic2(nbOfComp,func);
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
@@ -332,11 +337,11 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nb
  */
 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
   ret->setMesh(this);
   ret->fillFromAnalytic3(nbOfComp,varsOrder,func);
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
index 2febf8c6b45bcd399432c20d544ac77db0850e3a..9f86a7445ba6bab3ee53eaa6d65d4a7d3201c440 100644 (file)
@@ -37,7 +37,8 @@ namespace ParaMEDMEM
       UNSTRUCTURED = 5,
       UNSTRUCTURED_DESC = 6,
       CARTESIAN = 7,
-      EXTRUDED = 8
+      EXTRUDED = 8,
+      CURVE_LINEAR = 9
     } MEDCouplingMeshType;
 
   class DataArrayInt;
@@ -48,6 +49,7 @@ namespace ParaMEDMEM
   class MEDCOUPLING_EXPORT MEDCouplingMesh : public RefCountObject, public TimeLabel
   {
   public:
+    std::size_t getHeapMemorySize() const;
     void setName(const char *name) { _name=name; }
     const char *getName() const { return _name.c_str(); }
     void setDescription(const char *descr) { _description=descr; }
index 94856e43d37ae78583cc142d0242f9f9d0545fb0..d261867686ec8fbb85741bc74a69fe90e443b66c 100644 (file)
@@ -190,6 +190,22 @@ void MEDCouplingMultiFields::updateTime() const
       updateTimeWith(*(*it));
 }
 
+std::size_t MEDCouplingMultiFields::getHeapMemorySize() const
+{
+  std::vector<int> tmp;
+  std::vector< std::vector<int> > tmp2;
+  std::vector<MEDCouplingMesh *> ms=getDifferentMeshes(tmp);
+  std::vector<DataArrayDouble *> arrs=getDifferentArrays(tmp2);
+  std::size_t ret=0;
+  for(std::vector<MEDCouplingMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
+    if(*it)
+      ret+=(*it)->getHeapMemorySize();
+  for(std::vector<DataArrayDouble *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
+    if(*it)
+      ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
 std::vector<MEDCouplingMesh *> MEDCouplingMultiFields::getMeshes() const throw(INTERP_KERNEL::Exception)
 {
   std::vector<MEDCouplingMesh *> ms;
index 16e25852c7e81d3a83a799db840b6046b5935458..a328a891b06b095cf5154a69fbd65c9bb865949f 100644 (file)
@@ -59,6 +59,7 @@ namespace ParaMEDMEM
     virtual std::vector<DataArrayDouble *> getArrays() const throw(INTERP_KERNEL::Exception);
     virtual std::vector<DataArrayDouble *> getDifferentArrays(std::vector< std::vector<int> >& refs) const throw(INTERP_KERNEL::Exception);
     void updateTime() const;
+    std::size_t getHeapMemorySize() const;
     void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<double>& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const;
     void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD,
                                const std::vector<MEDCouplingFieldTemplate *>& ft, const std::vector<MEDCouplingMesh *>& ms,
index f2acae753adb5d922c755edfe9f4067e4736a9ee..6a3f9df190d87a9b4c8d9efc0ff1119013e2795c 100644 (file)
@@ -75,6 +75,14 @@ void MEDCouplingPointSet::updateTime() const
     }
 }
 
+std::size_t MEDCouplingPointSet::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if(_coords)
+    ret+=_coords->getHeapMemorySize();
+  return MEDCouplingMesh::getHeapMemorySize()+ret;
+}
+
 void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords)
 {
   if( coords != _coords )
@@ -225,10 +233,11 @@ void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArra
   _coords->findCommonTuples(prec,limitNodeId,comm,commIndex);
 }
 
-std::vector<int> MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception)
 {
-  std::vector<int> c,cI;
+  DataArrayInt *c=0,*cI=0;
   getNodeIdsNearPoints(pos,1,eps,c,cI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cITmp(cI);
   return c;
 }
 
@@ -237,7 +246,7 @@ std::vector<int> MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, dou
  * Position 'pos' is expected to be of size getSpaceDimension()*nbOfNodes. If not the behabiour is not warranted.
  * This method throws an exception if no coordiantes are set.
  */
-void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
 {
   if(!_coords)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getNodeIdsNearPoint : no coordiantes set !");
@@ -257,7 +266,7 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const
 {
   if(!_coords)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !");
-  return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm,commIndex,newNbOfNodes);
+  return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes);
 }
 
 /*
@@ -411,14 +420,12 @@ void MEDCouplingPointSet::scale(const double *point, double factor)
   double *coords=_coords->getPointer();
   int nbNodes=getNumberOfNodes();
   int dim=getSpaceDimension();
-  double *tmp=new double[dim];
   for(int i=0;i<nbNodes;i++)
     {
       std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::minus<double>());
       std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies<double>(),factor));
       std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus<double>());
     }
-  delete [] tmp;
   _coords->declareAsNew();
   updateTime();
 }
@@ -703,6 +710,12 @@ void MEDCouplingPointSet::unserialization(const std::vector<double>& tinyInfoD,
     }
 }
 
+void MEDCouplingPointSet::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkCoherency : no coordinates set !");
+}
+
 /*!
  * Intersect Bounding Box given 2 Bounding Boxes.
  */
index 4e00e4770c1bde6f3bdce9a9fdd1ff5d7bb99432..41c5eb21ad8e6c6b8bbdd2be492d6188002bc4b3 100644 (file)
@@ -52,6 +52,7 @@ namespace ParaMEDMEM
     ~MEDCouplingPointSet();
   public:
     void updateTime() const;
+    std::size_t getHeapMemorySize() const;
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
     void setCoords(const DataArrayDouble *coords);
@@ -70,8 +71,8 @@ namespace ParaMEDMEM
     virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0;
     void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const;
-    std::vector<int> getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception);
-    void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception);
+    DataArrayInt *getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception);
+    void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception);
     void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const;
     DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex,
                                                          int& newNbOfNodes) const;
@@ -110,10 +111,11 @@ namespace ParaMEDMEM
     void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const;
     void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
                          const std::vector<std::string>& littleStrings);
-    virtual void getCellsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) const = 0;
-    virtual void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems) = 0;
+    virtual DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const = 0;
+    virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) = 0;
     virtual DataArrayInt *zipCoordsTraducer() = 0;
   protected:
+    void checkCoherency() const throw(INTERP_KERNEL::Exception);
     virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception) = 0;
     static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps);
     static bool intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps);
index c6eb6825a1b588640dbb0b777cbfe3f7e38ac7d8..943c40a0612216f8ffa5f587eac70485d2943d9f 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "MEDCoupling.hxx"
 
+#include <cstddef>
+
 namespace ParaMEDMEM
 {
   typedef enum
@@ -62,6 +64,7 @@ namespace ParaMEDMEM
   public:
     bool decrRef() const;
     void incrRef() const;
+    virtual std::size_t getHeapMemorySize() const = 0;
   protected:
     virtual ~RefCountObject();
   private:
index 8a489b1390c67bf9cd965067c8b57aa961a3a355..0e120ce1017c95a179dd5f2c0726ca24c41896ff 100644 (file)
@@ -666,8 +666,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou
       }
     case Integral:
       {
-        MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true);
-        MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true);
+        MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus());
+        MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus());
         const double *denoPtr=deno->getArray()->getConstPointer();
         const double *denoRPtr=denoR->getArray()->getConstPointer();
         if(trgField->getMesh()->getMeshDimension()==-1)
@@ -698,8 +698,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou
       }
     case RevIntegral:
       {
-        MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true);
-        MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true);
+        MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus());
+        MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus());
         const double *denoPtr=deno->getArray()->getConstPointer();
         const double *denoRPtr=denoR->getArray()->getConstPointer();
         if(trgField->getMesh()->getMeshDimension()==-1)
diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx
new file mode 100644 (file)
index 0000000..4d02d73
--- /dev/null
@@ -0,0 +1,379 @@
+// Copyright (C) 2007-2012  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
+//
+// Author : Anthony Geay (CEA/DEN)
+
+#include "MEDCouplingStructuredMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingUMesh.hxx"
+
+#include <numeric>
+
+using namespace ParaMEDMEM;
+
+MEDCouplingStructuredMesh::MEDCouplingStructuredMesh()
+{
+}
+
+MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCopy):MEDCouplingMesh(other)
+{
+}
+
+MEDCouplingStructuredMesh::~MEDCouplingStructuredMesh()
+{
+}
+
+std::size_t MEDCouplingStructuredMesh::getHeapMemorySize() const
+{
+  return MEDCouplingMesh::getHeapMemorySize();
+}
+
+void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingMesh::copyTinyStringsFrom(other);
+}
+
+bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
+{
+  return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason);
+}
+
+INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const
+{
+  switch(getMeshDimension())
+    {
+    case 3:
+      return INTERP_KERNEL::NORM_HEXA8;
+    case 2:
+      return INTERP_KERNEL::NORM_QUAD4;
+    case 1:
+      return INTERP_KERNEL::NORM_SEG2;
+    default:
+      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCurveLinearMesh::getTypeOfCell !");
+    }
+}
+
+std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingStructuredMesh::getAllGeoTypes() const
+{
+  INTERP_KERNEL::NormalizedCellType ret;
+  switch(getMeshDimension())
+    {
+    case 3:
+      ret=INTERP_KERNEL::NORM_HEXA8;
+      break;
+    case 2:
+      ret=INTERP_KERNEL::NORM_QUAD4;
+      break;
+    case 1:
+      ret=INTERP_KERNEL::NORM_SEG2;
+      break;
+    default:
+      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::getAllGeoTypes !");
+    }
+  std::set<INTERP_KERNEL::NormalizedCellType> ret2;
+  ret2.insert(ret);
+  return ret2;
+}
+
+int MEDCouplingStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
+{
+  int ret=getNumberOfCells();
+  int dim=getMeshDimension();
+  switch(type)
+    {
+    case INTERP_KERNEL::NORM_HEXA8:
+      if(dim==3)
+        return ret;
+    case INTERP_KERNEL::NORM_QUAD4:
+      if(dim==2)
+        return ret;
+    case INTERP_KERNEL::NORM_SEG2:
+      if(dim==1)
+        return ret;
+    default:
+      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::getTypeOfCell !");
+    }
+  return 0;
+}
+
+void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
+{
+  int meshDim=getMeshDimension();
+  int tmpCell[3],tmpNode[3];
+  getSplitCellValues(tmpCell);
+  getSplitNodeValues(tmpNode);
+  int tmp2[3];
+  GetPosFromId(cellId,meshDim,tmpCell,tmp2);
+  switch(meshDim)
+    {
+    case 1:
+      conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1);
+      break;
+    case 2:
+      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1);
+      conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]);
+      break;
+    case 3:
+      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]);
+      conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]);
+      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]);
+      conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]);
+      break;
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !");
+    };
+}
+
+/*!
+ * See MEDCouplingUMesh::getDistributionOfTypes for more information
+ */
+std::vector<int> MEDCouplingStructuredMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
+{
+  //only one type of cell
+  std::vector<int> ret(3);
+  ret[0]=getTypeOfCell(0);
+  ret[1]=getNumberOfCells();
+  ret[2]=0; //ret[3*k+2]==0 because it has no sense here
+  return ret;
+}
+
+/*!
+ * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information
+ */
+DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
+{
+  if(code.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code is empty, should not !");
+  std::size_t sz=code.size();
+  if(sz!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !");
+
+  int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]);
+  if(code[2]==-1)
+    {
+      if(code[1]==nbCells)
+        return 0;
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : number of cells mismatch !");
+    }
+  else
+    {
+      if(code[2]<-1) 
+        throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !");
+      if(code[2]>=(int)idsPerType.size()) 
+        throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !");
+      return idsPerType[code[2]]->deepCpy();
+    }
+}
+
+/*!
+ * See MEDCouplingUMesh::splitProfilePerType for more information
+ */
+void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
+{
+  int nbCells=getNumberOfCells();
+  code.resize(3);
+  code[0]=(int)getTypeOfCell(0);
+  code[1]=nbCells;
+  code[2]=0;
+  idsInPflPerType.push_back(profile->deepCpy());
+  idsPerType.push_back(profile->deepCpy());
+}
+
+MEDCouplingUMesh *MEDCouplingStructuredMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
+{
+  int meshDim=getMeshDimension();
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),meshDim);
+  DataArrayDouble *coords=getCoordinatesAndOwner();
+  ret->setCoords(coords);
+  coords->decrRef();
+  switch(meshDim)
+    {
+    case 1:
+      fill1DUnstructuredMesh(ret);
+      break;
+    case 2:
+      fill2DUnstructuredMesh(ret);
+      break;
+    case 3:
+      fill3DUnstructuredMesh(ret);
+      break;
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !");
+    };
+  return ret;
+}
+
+MEDCouplingMesh *MEDCouplingStructuredMesh::buildPart(const int *start, const int *end) const
+{
+  MEDCouplingUMesh *um=buildUnstructured();
+  MEDCouplingMesh *ret=um->buildPart(start,end);
+  um->decrRef();
+  return ret;
+}
+
+MEDCouplingMesh *MEDCouplingStructuredMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
+{
+  MEDCouplingUMesh *um=buildUnstructured();
+  MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr);
+  um->decrRef();
+  return ret;
+}
+
+DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::simplexize : not available for Cartesian mesh !");
+}
+
+MEDCouplingFieldDouble *MEDCouplingStructuredMesh::buildOrthogonalField() const
+{
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("Expected a MEDCouplingStructuredMesh with meshDim == 2 !");
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  DataArrayDouble *array=DataArrayDouble::New();
+  int nbOfCells=getNumberOfCells();
+  array->alloc(nbOfCells,3);
+  double *vals=array->getPointer();
+  for(int i=0;i<nbOfCells;i++)
+    { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
+  ret->setArray(array);
+  array->decrRef();
+  ret->setMesh(this);
+  return ret;
+}
+
+void MEDCouplingStructuredMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const
+{
+  int nbOfCells=-1;
+  getNodeGridStructure(&nbOfCells);
+  nbOfCells--;
+  DataArrayInt *connI=DataArrayInt::New();
+  connI->alloc(nbOfCells+1,1);
+  int *ci=connI->getPointer();
+  DataArrayInt *conn=DataArrayInt::New();
+  conn->alloc(3*nbOfCells,1);
+  ci[0]=0;
+  int *cp=conn->getPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      cp[3*i]=(int)INTERP_KERNEL::NORM_SEG2;
+      cp[3*i+1]=i;
+      cp[3*i+2]=i+1;
+      ci[i+1]=3*(i+1);
+    }
+  m->setConnectivity(conn,connI,true);
+  conn->decrRef();
+  connI->decrRef();
+}
+
+void MEDCouplingStructuredMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const
+{
+  int ns[2];
+  getNodeGridStructure(ns);
+  int n1=ns[0]-1;
+  int n2=ns[1]-1;
+  DataArrayInt *connI=DataArrayInt::New();
+  connI->alloc(n1*n2+1,1);
+  int *ci=connI->getPointer();
+  DataArrayInt *conn=DataArrayInt::New();
+  conn->alloc(5*n1*n2,1);
+  ci[0]=0;
+  int *cp=conn->getPointer();
+  int pos=0;
+  for(int j=0;j<n2;j++)
+    for(int i=0;i<n1;i++,pos++)
+      {
+        cp[5*pos]=(int)INTERP_KERNEL::NORM_QUAD4;
+        cp[5*pos+1]=i+1+j*(n1+1);
+        cp[5*pos+2]=i+j*(n1+1);
+        cp[5*pos+3]=i+(j+1)*(n1+1);
+        cp[5*pos+4]=i+1+(j+1)*(n1+1);
+        ci[pos+1]=5*(pos+1);
+    }
+  m->setConnectivity(conn,connI,true);
+  conn->decrRef();
+  connI->decrRef();
+}
+
+void MEDCouplingStructuredMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const
+{
+  int ns[3];
+  getNodeGridStructure(ns);
+  int n1=ns[0]-1;
+  int n2=ns[1]-1;
+  int n3=ns[2]-1;
+  DataArrayInt *connI=DataArrayInt::New();
+  connI->alloc(n1*n2*n3+1,1);
+  int *ci=connI->getPointer();
+  DataArrayInt *conn=DataArrayInt::New();
+  conn->alloc(9*n1*n2*n3,1);
+  ci[0]=0;
+  int *cp=conn->getPointer();
+  int pos=0;
+  for(int k=0;k<n3;k++)
+    for(int j=0;j<n2;j++)
+      for(int i=0;i<n1;i++,pos++)
+        {
+          cp[9*pos]=(int)INTERP_KERNEL::NORM_HEXA8;
+          int tmp=(n1+1)*(n2+1);
+          cp[9*pos+1]=i+1+j*(n1+1)+k*tmp;
+          cp[9*pos+2]=i+j*(n1+1)+k*tmp;
+          cp[9*pos+3]=i+(j+1)*(n1+1)+k*tmp;
+          cp[9*pos+4]=i+1+(j+1)*(n1+1)+k*tmp;
+          cp[9*pos+5]=i+1+j*(n1+1)+(k+1)*tmp;
+          cp[9*pos+6]=i+j*(n1+1)+(k+1)*tmp;
+          cp[9*pos+7]=i+(j+1)*(n1+1)+(k+1)*tmp;
+          cp[9*pos+8]=i+1+(j+1)*(n1+1)+(k+1)*tmp;
+          ci[pos+1]=9*(pos+1);
+        }
+  m->setConnectivity(conn,connI,true);
+  conn->decrRef();
+  connI->decrRef();
+}
+
+int MEDCouplingStructuredMesh::getCellIdFromPos(int i, int j, int k) const
+{
+  int tmp[3]={i,j,k};
+  int tmp2[3];
+  int meshDim=getMeshDimension();
+  getSplitCellValues(tmp2);
+  std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies<int>());
+  return std::accumulate(tmp,tmp+meshDim,0);
+}
+
+int MEDCouplingStructuredMesh::getNodeIdFromPos(int i, int j, int k) const
+{
+  int tmp[3]={i,j,k};
+  int tmp2[3];
+  int meshDim=getMeshDimension();
+  getSplitNodeValues(tmp2);
+  std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies<int>());
+  return std::accumulate(tmp,tmp+meshDim,0);
+}
+
+void MEDCouplingStructuredMesh::GetPosFromId(int nodeId, int meshDim, const int *split, int *res)
+{
+  int work=nodeId;
+  for(int i=meshDim-1;i>=0;i--)
+    {
+      int pos=work/split[i];
+      work=work%split[i];
+      res[i]=pos;
+    }
+}
diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.hxx b/src/MEDCoupling/MEDCouplingStructuredMesh.hxx
new file mode 100644 (file)
index 0000000..80f18ec
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2007-2012  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
+//
+// Author : Anthony Geay (CEA/DEN)
+
+#ifndef __PARAMEDMEM_MEDCOUPLINGSTRUCTUREDMESH_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGSTRUCTUREDMESH_HXX__
+
+#include "MEDCoupling.hxx"
+#include "MEDCouplingMesh.hxx"
+
+namespace ParaMEDMEM
+{
+  class MEDCOUPLING_EXPORT MEDCouplingStructuredMesh : public MEDCouplingMesh
+  {
+  public:
+    INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const;
+    std::set<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const;
+    int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const;
+    static void GetPosFromId(int nodeId, int meshDim, const int *split, int *res);
+    void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const;
+    std::size_t getHeapMemorySize() const;
+    void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
+    bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception);
+    //tools
+    std::vector<int> getDistributionOfTypes() const throw(INTERP_KERNEL::Exception);
+    DataArrayInt *checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception);
+    void splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingMesh *buildPart(const int *start, const int *end) const;
+    MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
+    DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *buildOrthogonalField() const;
+    void fill1DUnstructuredMesh(MEDCouplingUMesh *m) const;
+    void fill2DUnstructuredMesh(MEDCouplingUMesh *m) const;
+    void fill3DUnstructuredMesh(MEDCouplingUMesh *m) const;
+    //some useful methods
+    int getCellIdFromPos(int i, int j, int k) const;
+    int getNodeIdFromPos(int i, int j, int k) const;
+    virtual void getNodeGridStructure(int *res) const = 0;
+    virtual void getSplitCellValues(int *res) const = 0;
+    virtual void getSplitNodeValues(int *res) const = 0;
+  protected:
+    MEDCouplingStructuredMesh();
+    MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCpy);
+    ~MEDCouplingStructuredMesh();
+  };
+}
+
+#endif
index 7712aa874d4354f56f4764b5a902054fae09e6ad..384615a3df14c2d37ca9cce17d6374da875b3b31 100644 (file)
@@ -19,8 +19,9 @@
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDCouplingTimeDiscretization.hxx"
-#include "MEDCouplingMemArray.hxx"
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingMesh.hxx"
 
 #include <cmath>
 #include <sstream>
@@ -92,6 +93,14 @@ void MEDCouplingTimeDiscretization::updateTime() const
     updateTimeWith(*_array);
 }
 
+std::size_t MEDCouplingTimeDiscretization::getHeapMemorySize() const
+{
+  std::size_t ret=_time_unit.capacity();
+  if(_array)
+    ret+=_array->getHeapMemorySize();
+  return ret;
+}
+
 bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretization *other) const
 {
   if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
@@ -813,6 +822,11 @@ std::string MEDCouplingNoTimeLabel::getStringRepr() const
   return stream.str();
 }
 
+void MEDCouplingNoTimeLabel::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::synchronizeTimeWith : impossible to synchronize time with a MEDCouplingMesh because the time discretization is incompatible with it !");
+}
+
 bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization *other) const
 {
   if(!MEDCouplingTimeDiscretization::areCompatible(other))
@@ -1177,6 +1191,17 @@ std::string MEDCouplingWithTimeStep::getStringRepr() const
   return stream.str();
 }
 
+void MEDCouplingWithTimeStep::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception)
+{
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !");
+  int it=-1,order=-1;
+  double val=mesh->getTime(it,order);
+  _time=val; _iteration=it; _order=order;
+  std::string tUnit=mesh->getTimeUnit();
+  _time_unit=tUnit;
+}
+
 void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
 {
   MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo);
@@ -1662,6 +1687,18 @@ std::string MEDCouplingConstOnTimeInterval::getStringRepr() const
   return stream.str();
 }
 
+void MEDCouplingConstOnTimeInterval::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception)
+{
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !");
+  int it=-1,order=-1;
+  double val=mesh->getTime(it,order);
+  _start_time=val; _start_iteration=it; _start_order=order;
+  _end_time=val; _end_iteration=it; _end_order=order;
+  std::string tUnit=mesh->getTimeUnit();
+  _time_unit=tUnit;
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const
 {
   return new MEDCouplingConstOnTimeInterval(*this,deepCpy);
@@ -2039,6 +2076,26 @@ void MEDCouplingTwoTimeSteps::updateTime() const
     updateTimeWith(*_end_array);
 }
 
+void MEDCouplingTwoTimeSteps::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception)
+{
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !");
+  int it=-1,order=-1;
+  double val=mesh->getTime(it,order);
+  _start_time=val; _start_iteration=it; _start_order=order;
+  _end_time=val; _end_iteration=it; _end_order=order;
+  std::string tUnit=mesh->getTimeUnit();
+  _time_unit=tUnit;
+}
+
+std::size_t MEDCouplingTwoTimeSteps::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if(_end_array)
+    ret+=_end_array->getHeapMemorySize();
+  return MEDCouplingTimeDiscretization::getHeapMemorySize()+ret;
+}
+
 void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingTimeDiscretization::copyTinyAttrFrom(other);
index 79d6fa07a6bdde63e6ffb6b69e89b2dea8378f23..890316418fa4e2a5d3d57cf41afdce01771dab0e 100644 (file)
@@ -30,6 +30,7 @@
 
 namespace ParaMEDMEM
 {
+  class MEDCouplingMesh;
   class DataArrayDouble;
   class TimeLabel;
 
@@ -40,6 +41,7 @@ namespace ParaMEDMEM
     MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy);
   public:
     void updateTime() const;
+    virtual std::size_t getHeapMemorySize() const;
     static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type);
     void setTimeUnit(const char *unit) { _time_unit=unit; }
     const char *getTimeUnit() const { return _time_unit.c_str(); }
@@ -57,6 +59,7 @@ namespace ParaMEDMEM
     virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const;
     virtual std::string getStringRepr() const = 0;
     virtual TypeOfTimeDiscretization getEnum() const = 0;
+    virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) = 0;
     virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0;
     virtual MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const = 0;
     virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0;
@@ -158,6 +161,7 @@ namespace ParaMEDMEM
     MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy);
     std::string getStringRepr() const;
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
+    void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception);
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const;
     MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const;
@@ -218,6 +222,7 @@ namespace ParaMEDMEM
     std::string getStringRepr() const;
     void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception);
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
+    void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception);
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const;
     MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const;
@@ -300,6 +305,7 @@ namespace ParaMEDMEM
     void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception);
     void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception);
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
+    void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception);
     std::string getStringRepr() const;
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const;
@@ -350,6 +356,8 @@ namespace ParaMEDMEM
     ~MEDCouplingTwoTimeSteps();
   public:
     void updateTime() const;
+    void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
     void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception);
     void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other);
     const DataArrayDouble *getEndArray() const;
index dae38283f988e8ce48a70638fe7c81cc4942ac6f..a34d71b8043a69635880c316bfd945acc6cc5033 100644 (file)
@@ -26,6 +26,7 @@
 #include "InterpolationUtils.hxx"
 #include "PointLocatorAlgos.txx"
 #include "BBTree.txx"
+#include "SplitterTetra.hxx"
 #include "DirectedBoundingBox.hxx"
 #include "InterpKernelMeshQuality.hxx"
 #include "InterpKernelCellSimplify.hxx"
@@ -46,8 +47,6 @@
 
 using namespace ParaMEDMEM;
 
-const char MEDCouplingUMesh::PART_OF_NAME[]="PartOf_";
-
 double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14;
 
 const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_SEG4, INTERP_KERNEL::NORM_POLYL, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_TRI7, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_QUAD9, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_HEXA27, INTERP_KERNEL::NORM_POLYHED };
@@ -75,6 +74,16 @@ MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const
   return new MEDCouplingUMesh(*this,recDeepCpy);
 }
 
+std::size_t MEDCouplingUMesh::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if(_nodal_connec)
+    ret+=_nodal_connec->getHeapMemorySize();
+  if(_nodal_connec_index)
+    ret+=_nodal_connec_index->getHeapMemorySize();
+  return MEDCouplingPointSet::getHeapMemorySize()+ret;
+}
+
 void MEDCouplingUMesh::updateTime() const
 {
   MEDCouplingPointSet::updateTime();
@@ -88,8 +97,7 @@ void MEDCouplingUMesh::updateTime() const
     }
 }
 
-MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2),
-                                     _nodal_connec(0),_nodal_connec_index(0)
+MEDCouplingUMesh::MEDCouplingUMesh():_mesh_dim(-2),_nodal_connec(0),_nodal_connec_index(0)
 {
 }
 
@@ -102,7 +110,9 @@ MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2),
 void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
 {
   if(_mesh_dim<-1)
-    throw INTERP_KERNEL::Exception("No mesh dimension specified !");
+   throw INTERP_KERNEL::Exception("No mesh dimension specified !");
+  if(_mesh_dim!=-1)
+    MEDCouplingPointSet::checkCoherency();
   for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
     {
       if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim)
@@ -126,10 +136,6 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
       if(_nodal_connec_index->getInfoOnComponent(0)!="")
         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
     }
-  if(_iterator!=-1)
-    {
-      throw INTERP_KERNEL::Exception("It appears that finishInsertingCells method has not been invoked after a insertNextCell session !");
-    }
 }
 
 /*!
@@ -216,14 +222,11 @@ void MEDCouplingUMesh::allocateCells(int nbOfCells)
     {
       _nodal_connec->decrRef();
     }
-
   _nodal_connec_index=DataArrayInt::New();
-  _nodal_connec_index->alloc(nbOfCells+1,1);
-  int *pt=_nodal_connec_index->getPointer();
-  pt[0]=0;
+  _nodal_connec_index->reserve(nbOfCells+1);
+  _nodal_connec_index->pushBackSilent(0);
   _nodal_connec=DataArrayInt::New();
-  _nodal_connec->alloc(2*nbOfCells,1);
-  _iterator=0;
+  _nodal_connec->reserve(2*nbOfCells);
   _types.clear();
   declareAsNew();
 }
@@ -241,15 +244,18 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !");
   if((int)cm.getDimension()==_mesh_dim)
     {
-      int nbOfElems=_nodal_connec_index->getNbOfElems()-1;
-      if(_iterator>=nbOfElems)
-        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : allocation of cells was wide enough ! Call insertNextCell with higher value or call finishInsertingCells !");
-      int *pt=_nodal_connec_index->getPointer();
-      int idx=pt[_iterator];
-      
+      if(!cm.isDynamic())
+        if(size!=(int)cm.getNumberOfNodes())
+          {
+            std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : Trying to push a " << cm.getRepr() << " cell with a size of " << size;
+            oss << " ! Expecting " << cm.getNumberOfNodes() << " !";
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          }
+      int idx=_nodal_connec_index->back();
+      int val=idx+size+1;
+      _nodal_connec_index->pushBackSilent(val);
       _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size);
       _types.insert(type);
-      pt[++_iterator]=idx+size+1;
     }
   else
     {
@@ -265,12 +271,8 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in
  */
 void MEDCouplingUMesh::finishInsertingCells()
 {
-  const int *pt=_nodal_connec_index->getConstPointer();
-  int idx=pt[_iterator];
-
-  _nodal_connec->reAlloc(idx);
-  _nodal_connec_index->reAlloc(_iterator+1);
-  _iterator=-1;
+  _nodal_connec->pack();
+  _nodal_connec_index->pack();
   _nodal_connec->declareAsNew();
   _nodal_connec_index->declareAsNew();
   updateTime();
@@ -430,13 +432,9 @@ void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int ce
   pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
   if(pt!=da->getConstPointer()+da->getNbOfElems())
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=DataArrayInt::New();
-  cellCor2->alloc(otherC->getNumberOfCells(),1);
-  std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer());
-  bool nident=nodeCor2->isIdentity();
-  bool cident=cellCor2->isIdentity();
-  if(!nident) { nodeCor=nodeCor2; nodeCor2->incrRef(); } else nodeCor=0;
-  if(!cident) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1);
+  nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn();
+  cellCor=cellCor2->isIdentity()?0:cellCor2.retn();
 }
 
 /*!
@@ -471,10 +469,8 @@ void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *ot
     {
       throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !");
     }
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=DataArrayInt::New();
-  cellCor2->alloc(otherC->getNumberOfCells(),1);
-  std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer());
-  if(!cellCor2->isIdentity()) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1);
+  cellCor=cellCor2->isIdentity()?0:cellCor2.retn();
 }
 
 /*!
@@ -651,22 +647,19 @@ void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, cons
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out1=DataArrayInt::New(); out1->alloc(nbCells+1,1);
   int *out1Ptr=out1->getPointer();
   *out1Ptr++=0;
-  std::vector<int> out0v;
-  out0v.reserve(desc->getNumberOfTuples());
+  out0->reserve(desc->getNumberOfTuples());
   for(int i=0;i<nbCells;i++,descIPtr++,out1Ptr++)
     {
       for(const int *w1=descPtr+descIPtr[0];w1!=descPtr+descIPtr[1];w1++)
         {
           std::set<int> s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]);
           s.erase(i);
-          out0v.insert(out0v.end(),s.begin(),s.end());
+          out0->insertAtTheEnd(s.begin(),s.end());
         }
-      *out1Ptr=out0v.size();
+      *out1Ptr=out0->getNumberOfTuples();
     }
-  out0->alloc((int)out0v.size(),1);
-  std::copy(out0v.begin(),out0v.end(),out0->getPointer());
-  neighbors=out0; out0->incrRef();
-  neighborsIndx=out1; out1->incrRef();
+  neighbors=out0.retn();
+  neighborsIndx=out1.retn();
 }
 
 /// @cond INTERNAL
@@ -680,100 +673,108 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt
   checkConnectivityFullyDefined();
   int nbOfCells=getNumberOfCells();
   int nbOfNodes=getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodalIndx=DataArrayInt::New(); revNodalIndx->alloc(nbOfNodes+1,1); revNodalIndx->fillWithZero();
+  int *revNodalIndxPtr=revNodalIndx->getPointer();
   const int *conn=_nodal_connec->getConstPointer();
   const int *connIndex=_nodal_connec_index->getConstPointer();
-  std::vector< std::vector<int> > descMeshConnB(nbOfCells);
-  std::vector< std::vector<int> > revDescMeshConnB;
-  std::vector< std::vector<int> > revNodalB(nbOfNodes);
-  std::vector<int> meshDM1Conn;
-  std::vector<int> meshDM1ConnIndex(1); meshDM1ConnIndex[0]=0;
-  std::vector<int> meshDM1Type;
-  for(int eltId=0;eltId<nbOfCells;eltId++)
+  std::string name="Mesh constituent of "; name+=getName();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(name.c_str(),getMeshDimension()-1);
+  ret->setCoords(getCoords());
+  ret->allocateCells(2*nbOfCells);
+  descIndx->alloc(nbOfCells+1,1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells);
+  int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0;
+  for(int eltId=0;eltId<nbOfCells;eltId++,descIndxPtr++)
     {
       int pos=connIndex[eltId];
       int posP1=connIndex[eltId+1];
       const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[pos]);
       unsigned nbOfSons=cm.getNumberOfSons2(conn+pos+1,posP1-pos-1);
-      int *tmp=new int[posP1-pos];
+      INTERP_KERNEL::AutoPtr<int> tmp=new int[posP1-pos];
       for(unsigned i=0;i<nbOfSons;i++)
         {
           INTERP_KERNEL::NormalizedCellType cmsId;
           unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(i,conn+pos+1,posP1-pos-1,tmp,cmsId);
-          const INTERP_KERNEL::CellModel& cms=INTERP_KERNEL::CellModel::GetCellModel(cmsId);
-          std::set<int> shareableCells(revNodalB[tmp[0]].begin(),revNodalB[tmp[0]].end());
-          for(unsigned j=1;j<nbOfNodesSon && !shareableCells.empty();j++)
-            {
-              std::set<int> tmp2(revNodalB[tmp[j]].begin(),revNodalB[tmp[j]].end());
-              std::set<int> tmp3;
-              std::set_intersection(tmp2.begin(),tmp2.end(),shareableCells.begin(),shareableCells.end(),inserter(tmp3,tmp3.begin()));
-              shareableCells=tmp3;
-            }
-          std::list<int> shareableCellsL(shareableCells.begin(),shareableCells.end());
-          std::set<int> ref(tmp,tmp+nbOfNodesSon);
-          for(std::list<int>::iterator iter=shareableCellsL.begin();iter!=shareableCellsL.end();)
-            {
-              if(cms.isCompatibleWith((INTERP_KERNEL::NormalizedCellType)meshDM1Type[*iter]))
-                {
-                  std::set<int> ref2(meshDM1Conn.begin()+meshDM1ConnIndex[*iter],meshDM1Conn.begin()+meshDM1ConnIndex[(*iter)+1]);
-                  if(ref==ref2)
-                    break;
-                  else
-                    iter=shareableCellsL.erase(iter);
-                }
-              else
-                iter=shareableCellsL.erase(iter);
-            }
-          if(shareableCellsL.empty())
+          for(unsigned k=0;k<nbOfNodesSon;k++)
+            if(tmp[k]>=0)
+              revNodalIndxPtr[tmp[k]+1]++;
+          ret->insertNextCell(cmsId,nbOfNodesSon,tmp);
+          revDesc2->pushBackSilent(eltId);
+        }
+      descIndxPtr[0]=descIndxPtr[-1]+(int)nbOfSons;
+    }
+  int nbOfCellsM1=ret->getNumberOfCells();
+  std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal=DataArrayInt::New(); revNodal->alloc(revNodalIndx->back(),1);
+  std::fill(revNodal->getPointer(),revNodal->getPointer()+revNodalIndx->back(),-1);
+  int *revNodalPtr=revNodal->getPointer();
+  const int *connM1=ret->getNodalConnectivity()->getConstPointer();
+  const int *connIndexM1=ret->getNodalConnectivityIndex()->getConstPointer();
+  for(int eltId=0;eltId<nbOfCellsM1;eltId++)
+    {
+      const int *strtNdlConnOfCurCell=connM1+connIndexM1[eltId]+1;
+      const int *endNdlConnOfCurCell=connM1+connIndexM1[eltId+1];
+      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
+        if(*iter>=0)//for polyhedrons
+          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
+    }
+  //
+  DataArrayInt *commonCells=0,*commonCellsI=0;
+  FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
+  const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer());
+  int newNbOfCellsM1=-1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nM1=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfCellsM1,commonCells->begin(),
+                                                                                                            commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1);
+  std::vector<bool> isImpacted(nbOfCellsM1,false);
+  for(const int *work=commonCellsI->begin();work!=commonCellsI->end()-1;work++)
+    for(int work2=work[0];work2!=work[1];work2++)
+      isImpacted[commonCellsPtr[work2]]=true;
+  const int *o2nM1Ptr=o2nM1->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1);
+  const int *n2oM1Ptr=n2oM1->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret2=static_cast<MEDCouplingUMesh *>(ret->buildPartOfMySelf(n2oM1->begin(),n2oM1->end(),true));
+  ret2->copyTinyInfoFrom(this);
+  desc->alloc(descIndx->back(),1);
+  int *descPtr=desc->getPointer();
+  const INTERP_KERNEL::CellModel& cmsDft=INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1);
+  for(int i=0;i<nbOfCellsM1;i++,descPtr++)
+    {
+      if(!isImpacted[i])
+        *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
+      else
+        {
+          if(i!=n2oM1Ptr[o2nM1Ptr[i]])
             {
-              meshDM1Conn.insert(meshDM1Conn.end(),tmp,tmp+nbOfNodesSon);
-              meshDM1ConnIndex.push_back(meshDM1ConnIndex.back()+nbOfNodesSon);
-              int cellDM1Id=(int)meshDM1Type.size();
-              meshDM1Type.push_back((int)cmsId);
-              for(unsigned k=0;k<nbOfNodesSon;k++)
-                revNodalB[tmp[k]].push_back(cellDM1Id);
-              revDescMeshConnB.resize(cellDM1Id+1);
-              revDescMeshConnB.back().push_back(eltId);
-              descMeshConnB[eltId].push_back(nbrer(cellDM1Id,0,cms,false,0,0));
+              const INTERP_KERNEL::CellModel& cms=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connM1[connIndexM1[i]]);
+              *descPtr=nbrer(o2nM1Ptr[i],connIndexM1[i+1]-connIndexM1[i]-1,cms,true,connM1+connIndexM1[n2oM1Ptr[o2nM1Ptr[i]]]+1,connM1+connIndexM1[i]+1);
             }
           else
-            {
-              int DM1cellId=shareableCellsL.front();
-              revDescMeshConnB[DM1cellId].push_back(eltId);
-              descMeshConnB[eltId].push_back(nbrer(DM1cellId,nbOfNodesSon,cms,true,tmp,&meshDM1Conn[meshDM1ConnIndex[DM1cellId]]));
-            }
+            *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
         }
-      delete [] tmp;
     }
-  revNodalB.clear();
-  //
-  std::string name="Mesh constituent of "; name+=getName();
-  MEDCouplingUMesh *ret=MEDCouplingUMesh::New(name.c_str(),getMeshDimension()-1);
-  ret->setCoords(getCoords());
-  int nbOfCellsInConstituent=(int)meshDM1Type.size();
-  ret->allocateCells(nbOfCellsInConstituent);
-  revDescIndx->alloc(nbOfCellsInConstituent+1,1);
-  int *tmp3=revDescIndx->getPointer(); tmp3[0]=0;
-  for(int ii=0;ii<nbOfCellsInConstituent;ii++)
+  revDesc->reserve(newNbOfCellsM1);
+  revDescIndx->alloc(newNbOfCellsM1+1,1);
+  int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0;
+  const int *revDesc2Ptr=revDesc2->getConstPointer();
+  for(int i=0;i<newNbOfCellsM1;i++,revDescIndxPtr++)
     {
-      ret->insertNextCell((INTERP_KERNEL::NormalizedCellType)meshDM1Type[ii],meshDM1ConnIndex[ii+1]-meshDM1ConnIndex[ii],&meshDM1Conn[meshDM1ConnIndex[ii]]);
-      tmp3[ii+1]=tmp3[ii]+((int)revDescMeshConnB[ii].size());
+      int oldCellIdM1=n2oM1Ptr[i];
+      if(!isImpacted[oldCellIdM1])
+        {
+          revDesc->pushBackSilent(revDesc2Ptr[oldCellIdM1]);
+          revDescIndxPtr[0]=revDescIndxPtr[-1]+1;
+        }
+      else
+        {
+          for(int j=commonCellsIPtr[0];j<commonCellsIPtr[1];j++)
+            revDesc->pushBackSilent(revDesc2Ptr[commonCellsPtr[j]]);
+          revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0];
+          commonCellsIPtr++;
+        }
     }
-  ret->finishInsertingCells();
-  revDesc->alloc(tmp3[nbOfCellsInConstituent],1);
-  tmp3=revDesc->getPointer();
-  for(std::vector< std::vector<int> >::const_iterator iter2=revDescMeshConnB.begin();iter2!=revDescMeshConnB.end();iter2++)
-    tmp3=std::copy((*iter2).begin(),(*iter2).end(),tmp3);
-  meshDM1Type.clear(); meshDM1ConnIndex.clear(); meshDM1Conn.clear();
-  descIndx->alloc(nbOfCells+1,1);
-  tmp3=descIndx->getPointer(); tmp3[0]=0;
-  for(int jj=0;jj<nbOfCells;jj++)
-    tmp3[jj+1]=tmp3[jj]+((int)descMeshConnB[jj].size());
-  desc->alloc(tmp3[nbOfCells],1);
-  tmp3=desc->getPointer();
-  for(std::vector< std::vector<int> >::const_iterator iter3=descMeshConnB.begin();iter3!=descMeshConnB.end();iter3++)
-    tmp3=std::copy((*iter3).begin(),(*iter3).end(),tmp3);
   //
-  return ret;
+  return ret2.retn();
 }
 
 struct MEDCouplingAccVisit
@@ -962,9 +963,8 @@ void MEDCouplingUMesh::convertExtrudedPolyhedra() throw(INTERP_KERNEL::Exception
       else
         newc=std::copy(c+ci[i],c+ci[i+1],newc);
     }
-  _nodal_connec_index->decrRef(); _nodal_connec_index=newCi;
-  _nodal_connec->decrRef(); _nodal_connec=newC;
-  newC->incrRef(); newCi->incrRef();
+  _nodal_connec_index->decrRef(); _nodal_connec_index=newCi.retn();
+  _nodal_connec->decrRef(); _nodal_connec=newC.retn();
 }
 
 /*!
@@ -1069,7 +1069,7 @@ void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Except
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connINew=DataArrayInt::New();
   connINew->alloc(nbOfCells+1,1);
   int *connINewPtr=connINew->getPointer(); *connINewPtr++=0;
-  std::vector<int> connNew;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew=DataArrayInt::New(); connNew->alloc(0,1);
   bool changed=false;
   for(int i=0;i<nbOfCells;i++,connINewPtr++)
     {
@@ -1079,16 +1079,11 @@ void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Except
           changed=true;
         }
       else
-        connNew.insert(connNew.end(),conn+index[i],conn+index[i+1]);
-      *connINewPtr=(int)connNew.size();
+        connNew->insertAtTheEnd(conn+index[i],conn+index[i+1]);
+      *connINewPtr=connNew->getNumberOfTuples();
     }
   if(changed)
-    {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew2=DataArrayInt::New();
-      connNew2->alloc((int)connNew.size(),1);
-      std::copy(connNew.begin(),connNew.end(),connNew2->getPointer());
-      setConnectivity(connNew2,connINew,false);
-    }
+    setConnectivity(connNew,connINew,false);
 }
 
 /*!
@@ -1102,20 +1097,53 @@ void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Except
 DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception)
 {
   checkConnectivityFullyDefined();
-  std::set<int> retS;
   int nbOfCells=getNumberOfCells();
   const int *connIndex=_nodal_connec_index->getConstPointer();
   const int *conn=_nodal_connec->getConstPointer();
+  const int *maxEltPt=std::max_element(_nodal_connec->begin(),_nodal_connec->end());
+  int maxElt=maxEltPt==_nodal_connec->end()?0:std::abs(*maxEltPt)+1;
+  std::vector<bool> retS(maxElt,false);
   for(int i=0;i<nbOfCells;i++)
     for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
       if(conn[j]>=0)
-        retS.insert(conn[j]);
+        retS[conn[j]]=true;
+  int sz=0;
+  for(int i=0;i<maxElt;i++)
+    if(retS[i])
+      sz++;
   DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)retS.size(),1);
-  std::copy(retS.begin(),retS.end(),ret->getPointer());
+  ret->alloc(sz,1);
+  int *retPtr=ret->getPointer();
+  for(int i=0;i<maxElt;i++)
+    if(retS[i])
+      *retPtr++=i;
   return ret;
 }
 
+/*!
+ * \param [in,out] nodeIdsInUse an array of size typically equal to nbOfNodes.
+ * \sa MEDCouplingUMesh::getNodeIdsInUse
+ */
+void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfNodes=(int)nodeIdsInUse.size();
+  int nbOfCells=getNumberOfCells();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
+      if(conn[j]>=0)
+        {
+          if(conn[j]<nbOfNodes)
+            nodeIdsInUse[conn[j]]=true;
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+}
+
 /*!
  * Array returned is the correspondance in \b old \b to \b new format (that's why 'nbrOfNodesInUse' is returned too).
  * The returned array is newly created and should be dealt by the caller.
@@ -1124,12 +1152,14 @@ DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const throw(INTERP_KERNE
  * -1 values in returned array means that the corresponding node never appear in any nodal connectivity of cells constituting 'this'.
  * @param [out] nbrOfNodesInUse out parameter that specifies how many of nodes in 'this' is really used in nodal connectivity.
  * @return a newly allocated DataArrayInt that tells for each nodeid in \b this if it is unused (-1) or used (the corresponding new id)
+ * \throw if a cell contains in its nodal connectivity a node id >= nb of nodes an exception will be thrown.
+ * \sa MEDCouplingUMesh::computeNodeIdsAlg
  */
 DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
 {
   nbrOfNodesInUse=-1;
   int nbOfNodes=getNumberOfNodes();
-  DataArrayInt *ret=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc(nbOfNodes,1);
   int *traducer=ret->getPointer();
   std::fill(traducer,traducer+nbOfNodes,-1);
@@ -1139,10 +1169,18 @@ DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const thro
   for(int i=0;i<nbOfCells;i++)
     for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
       if(conn[j]>=0)
-        traducer[conn[j]]=1;
+        {
+          if(conn[j]<nbOfNodes)
+            traducer[conn[j]]=1;
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1169,7 +1207,7 @@ DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const throw(INTERP_KER
       else
         *retPtr=connI[i+1]-connI[i]-1-std::count(conn+connI[i]+1,conn+connI[i+1],-1);
     }
-  ret->incrRef(); return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1190,29 +1228,29 @@ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Excepti
  * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy.
  * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method.
  */
-int MEDCouplingUMesh::areCellsEqual(int cell1, int cell2, int compType) const
+int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType)
 {
   switch(compType)
     {
     case 0:
-      return areCellsEqual0(cell1,cell2);
+      return AreCellsEqual0(conn,connI,cell1,cell2);
     case 1:
-      return areCellsEqual1(cell1,cell2);
+      return AreCellsEqual1(conn,connI,cell1,cell2);
     case 2:
-      return areCellsEqual2(cell1,cell2);
+      return AreCellsEqual2(conn,connI,cell1,cell2);
+    case 3:
+      return AreCellsEqual3(conn,connI,cell1,cell2);
     case 7:
-      return areCellsEqual7(cell1,cell2);
+      return AreCellsEqual7(conn,connI,cell1,cell2);
     }
-  throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1 or 2.");
+  throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1,2 or 3.");
 }
 
 /*!
  * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 0.
  */
-int MEDCouplingUMesh::areCellsEqual0(int cell1, int cell2) const
+int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2)
 {
-  const int *conn=getNodalConnectivity()->getConstPointer();
-  const int *connI=getNodalConnectivityIndex()->getConstPointer();
   if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
     return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;
   return 0;
@@ -1221,10 +1259,8 @@ int MEDCouplingUMesh::areCellsEqual0(int cell1, int cell2) const
 /*!
  * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 1.
  */
-int MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const
+int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2)
 {
-  const int *conn=getNodalConnectivity()->getConstPointer();
-  const int *connI=getNodalConnectivityIndex()->getConstPointer();
   int sz=connI[cell1+1]-connI[cell1];
   if(sz==connI[cell2+1]-connI[cell2])
     {
@@ -1237,18 +1273,17 @@ int MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const
               if(dim!=1)
                 {
                   int sz1=2*(sz-1);
-                  int *tmp=new int[sz1];
-                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],tmp);
+                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz1];
+                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp);
                   std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work);
-                  work=std::search(tmp,tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
-                  delete [] tmp;
+                  work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
                   return work!=tmp+sz1?1:0;
                 }
               else
                 return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;//case of SEG2 and SEG3
             }
           else
-            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areCellsEqual1 : not implemented yet for meshdim == 3 !");
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual1 : not implemented yet for meshdim == 3 !");
         }
     }
   return 0;
@@ -1257,10 +1292,8 @@ int MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const
 /*!
  * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 2.
  */
-int MEDCouplingUMesh::areCellsEqual2(int cell1, int cell2) const
+int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2)
 {
-  const int *conn=getNodalConnectivity()->getConstPointer();
-  const int *connI=getNodalConnectivityIndex()->getConstPointer();
   if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
     {
       if(conn[connI[cell1]]==conn[connI[cell2]])
@@ -1273,13 +1306,25 @@ int MEDCouplingUMesh::areCellsEqual2(int cell1, int cell2) const
   return 0;
 }
 
+/*!
+ * This method is less restrictive than AreCellsEqual2. Here the geometric type is absolutely not taken into account !
+ */
+int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2)
+{
+  if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
+    {
+      std::set<int> s1(conn+connI[cell1]+1,conn+connI[cell1+1]);
+      std::set<int> s2(conn+connI[cell2]+1,conn+connI[cell2+1]);
+      return s1==s2?1:0;
+    }
+  return 0;
+}
+
 /*!
  * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 7.
  */
-int MEDCouplingUMesh::areCellsEqual7(int cell1, int cell2) const
+int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2)
 {
-  const int *conn=getNodalConnectivity()->getConstPointer();
-  const int *connI=getNodalConnectivityIndex()->getConstPointer();
   int sz=connI[cell1+1]-connI[cell1];
   if(sz==connI[cell2+1]-connI[cell2])
     {
@@ -1292,29 +1337,20 @@ int MEDCouplingUMesh::areCellsEqual7(int cell1, int cell2) const
               if(dim!=1)
                 {
                   int sz1=2*(sz-1);
-                  int *tmp=new int[sz1];
-                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],tmp);
+                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz1];
+                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp);
                   std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work);
-                  work=std::search(tmp,tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
+                  work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
                   if(work!=tmp+sz1)
-                    {
-                      delete [] tmp;
-                      return 1;
-                    }
+                    return 1;
                   else
                     {
-                      std::reverse_iterator<int *> it1(tmp+sz1);
-                      std::reverse_iterator<int *> it2(tmp);
+                      std::reverse_iterator<int *> it1((int *)tmp+sz1);
+                      std::reverse_iterator<int *> it2((int *)tmp);
                       if(std::search(it1,it2,conn+connI[cell2]+1,conn+connI[cell2+1])!=it2)
-                        {
-                          delete [] tmp;
-                          return 2;
-                        }
+                        return 2;
                       else
-                        {
-                          delete [] tmp;
-                          return 0;
-                        }
+                        return 0;
                     }
                   
                   return work!=tmp+sz1?1:0;
@@ -1340,7 +1376,7 @@ int MEDCouplingUMesh::areCellsEqual7(int cell1, int cell2) const
                 }
             }
           else
-            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areCellsEqual7 : not implemented yet for meshdim == 3 !");
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual7 : not implemented yet for meshdim == 3 !");
         }
     }
   return 0;
@@ -1382,172 +1418,165 @@ bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int
  * If in 'candidates' pool -1 value is considered as an empty value.
  * WARNING this method returns only ONE set of result !
  */
-bool MEDCouplingUMesh::areCellsEqualInPool(const std::vector<int>& candidates, int compType, std::vector<int>& result) const
+bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector<int>& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result)
 {
-  std::set<int> cand(candidates.begin(),candidates.end());
-  cand.erase(-1);
-  if(cand.size()<=1)
+  if(candidates.size()<1)
     return false;
   bool ret=false;
-  std::set<int>::const_iterator iter=cand.begin();
+  std::vector<int>::const_iterator iter=candidates.begin();
   int start=(*iter++);
-  for(;iter!=cand.end();iter++)
+  for(;iter!=candidates.end();iter++)
     {
-      int status=areCellsEqual(start,*iter,compType);
+      int status=AreCellsEqual(conn,connI,start,*iter,compType);
       if(status!=0)
         {
           if(!ret)
             {
-              result.push_back(start);
+              result->pushBackSilent(start);
               ret=true;
             }
           if(status==1)
-            result.push_back(*iter);
+            result->pushBackSilent(*iter);
           else
-            result.push_back(status==2?(*iter+1):-(*iter+1));
+            result->pushBackSilent(status==2?(*iter+1):-(*iter+1));
         }
     }
   return ret;
 }
 
 /*!
- * This method common cells base regarding 'compType' comparison policy described in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for details.
- * This method returns 2 values 'res' and 'resI'.
- * If 'res' and 'resI' are not empty before calling this method they will be cleared before set.
- * The format of 'res' and 'resI' is as explained here.
- * resI.size()-1 is the number of set of cells equal.
- * The nth set is [res.begin()+resI[n];res.begin()+resI[n+1]) with 0<=n<resI.size()-1 
+ * This method find cells that are cells equal (regarding \a compType) in \a this. The comparison is specified by \a compType.
+ * This method keeps the coordiantes of \a this. This method is time consuming and is called 
+ *
+ * \param [in] compType input specifying the technique used to compare cells each other.
+ *   - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy.
+ *   - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation)
+ * and their type equal. For 1D mesh the policy 1 is equivalent to 0.
+ *   - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy
+ * can be used for users not sensitive to orientation of cell
+ * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned.
+ * \param [out] commonCells
+ * \param [out] commonCellsI
+ * \return the correspondance array old to new in a newly allocated array.
+ * 
  */
-template<int SPACEDIM>
-void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector<int>& res, std::vector<int>& resI) const
+void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
 {
-  res.clear(); resI.clear();
-  resI.push_back(0);
-  std::vector<double> bbox;
-  int nbOfCells=getNumberOfCells();
-  getBoundingBoxForBBTree(bbox);
-  double bb[2*SPACEDIM];
-  double eps=getCaracteristicDimension();
-  eps*=1.e-12;
-  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps);
-  const int *conn=getNodalConnectivity()->getConstPointer();
-  const int *connI=getNodalConnectivityIndex()->getConstPointer();
-  const double *coords=getCoords()->getConstPointer();
-  std::vector<bool> isFetched(nbOfCells);
-  for(int k=0;k<nbOfCells;k++)
+  checkConnectivityFullyDefined();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New();
+  getReverseNodalConnectivity(revNodal,revNodalI);
+  FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr);
+}
+
+void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI,
+                                          DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCells=DataArrayInt::New(),commonCellsI=DataArrayInt::New(); commonCells->alloc(0,1);
+  int nbOfCells=nodalI->getNumberOfTuples()-1;
+  commonCellsI->reserve(1); commonCellsI->pushBackSilent(0);
+  const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer();
+  const int *connPtr=nodal->getConstPointer(),*connIPtr=nodalI->getConstPointer();
+  std::vector<bool> isFetched(nbOfCells,false);
+  if(startCellId==0)
     {
-      if(!isFetched[k])
+      for(int i=0;i<nbOfCells;i++)
         {
-          for(int j=0;j<SPACEDIM;j++)
-            { bb[2*j]=std::numeric_limits<double>::max(); bb[2*j+1]=-std::numeric_limits<double>::max(); }
-          for(const int *pt=conn+connI[k]+1;pt!=conn+connI[k+1];pt++)
-            if(*pt>-1)
-              {
-                for(int j=0;j<SPACEDIM;j++)
+          if(!isFetched[i])
+            {
+              const int *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<int>(),-1));
+              std::vector<int> v,v2;
+              if(connOfNode!=connPtr+connIPtr[i+1])
+                {
+                  const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i);
+                  v2.insert(v2.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1]);
+                  connOfNode++;
+                }
+              for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++)
+                if(*connOfNode>=0)
                   {
-                    bb[2*j]=std::min(bb[2*j],coords[SPACEDIM*(*pt)+j]);
-                    bb[2*j+1]=std::max(bb[2*j+1],coords[SPACEDIM*(*pt)+j]);
+                    v=v2;
+                    const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i);
+                    std::vector<int>::iterator it=std::set_intersection(v.begin(),v.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin());
+                    v2.resize(std::distance(v2.begin(),it));
                   }
-              }
-          std::vector<int> candidates1;
-          myTree.getIntersectingElems(bb,candidates1);
-          std::vector<int> candidates;
-          for(std::vector<int>::const_iterator iter=candidates1.begin();iter!=candidates1.end();iter++)
-            if(!isFetched[*iter])
-              candidates.push_back(*iter);
-          if(areCellsEqualInPool(candidates,compType,res))
+              if(v2.size()>1)
+                {
+                  if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells))
+                    {
+                      int pos=commonCellsI->back();
+                      commonCellsI->pushBackSilent(commonCells->getNumberOfTuples());
+                      for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++)
+                        isFetched[*it]=true;
+                    }
+                }
+            }
+        }
+    }
+  else
+    {
+      for(int i=startCellId;i<nbOfCells;i++)
+        {
+          if(!isFetched[i])
             {
-              int pos=resI.back();
-              resI.push_back((int)res.size());
-              for(std::vector<int>::const_iterator it=res.begin()+pos;it!=res.end();it++)
-                isFetched[*it]=true;
+              const int *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<int>(),-1));
+              std::vector<int> v,v2;
+              if(connOfNode!=connPtr+connIPtr[i+1])
+                {
+                  v2.insert(v2.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1]);
+                  connOfNode++;
+                }
+              for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++)
+                if(*connOfNode>=0)
+                  {
+                    v=v2;
+                    std::vector<int>::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin());
+                    v2.resize(std::distance(v2.begin(),it));
+                  }
+              if(v2.size()>1)
+                {
+                  if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells))
+                    {
+                      int pos=commonCellsI->back();
+                      commonCellsI->pushBackSilent(commonCells->getNumberOfTuples());
+                      for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++)
+                        isFetched[*it]=true;
+                    }
+                }
             }
-          isFetched[k]=true;
         }
     }
+  commonCellsArr=commonCells.retn();
+  commonCellsIArr=commonCellsI.retn();
 }
 
 /*!
- * This method could potentially modify 'this'. This method merges cells if there are cells equal in 'this'. The comparison is specified by 'compType'.
- * This method keeps the coordiantes of 'this'.
+ * This method could potentially modify \a this. This method merges cells if there are cells equal in \a this. The comparison is specified by \a compType.
+ * This method keeps the coordiantes of \a this.
  *
- * @param compType input specifying the technique used to compare cells each other.
+ * \param [in] compType input specifying the technique used to compare cells each other.
  *   - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy.
  *   - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation)
  * and their type equal. For 1D mesh the policy 1 is equivalent to 0.
  *   - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy
  * can be used for users not sensitive to orientation of cell
- * @return the correspondance array old to new.
+ * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned
+ * \return the correspondance array old to new in a newly allocated array.
  * 
  * \warning This method modifies can modify significantly the geometric type order in \a this.
  * In view of the MED file writing, a renumbering of cells in \a this (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
  */
-DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId) throw(INTERP_KERNEL::Exception)
 {
-  int spaceDim=getSpaceDimension();
-  int nbOfCells=getNumberOfCells();
-  std::vector<int> commonCells;
-  std::vector<int> commonCellsI;
-  switch(spaceDim)
-    {
-    case 3:
-      {
-        findCommonCellsBase<3>(compType,commonCells,commonCellsI);
-        break;
-      }
-    case 2:
-      {
-        findCommonCellsBase<2>(compType,commonCells,commonCellsI);
-        break;
-      }
-    case 1:
-      {
-        findCommonCellsBase<1>(compType,commonCells,commonCellsI);
-        break;
-      }
-    default:
-      throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3.");
-    }
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc(nbOfCells,1);
-  int *retPtr=ret->getPointer();
-  std::fill(retPtr,retPtr+nbOfCells,0);
-  const std::size_t nbOfTupleSmCells=commonCellsI.size()-1;
-  int id=-1;
-  std::vector<int> cellsToKeep;
-  for(std::size_t i=0;i<nbOfTupleSmCells;i++)
-    {
-      for(std::vector<int>::const_iterator it=commonCells.begin()+commonCellsI[i];it!=commonCells.begin()+commonCellsI[i+1];it++)
-        retPtr[*it]=id;
-      id--;
-    }
-  id=0;
-  std::map<int,int> m;
-  for(int i=0;i<nbOfCells;i++)
-    {
-      int val=retPtr[i];
-      if(val==0)
-        {
-          retPtr[i]=id++;
-          cellsToKeep.push_back(i);
-        }
-      else
-        {
-          std::map<int,int>::const_iterator iter=m.find(val);
-          if(iter==m.end())
-            {
-              m[val]=id;
-              retPtr[i]=id++;
-              cellsToKeep.push_back(i);
-            }
-          else
-            retPtr[i]=(*iter).second;
-        }
-    }
-  MEDCouplingUMesh *self=(MEDCouplingUMesh *)buildPartOfMySelf(&cellsToKeep[0],&cellsToKeep[0]+cellsToKeep.size(),true);
+  DataArrayInt *commonCells=0,*commonCellsI=0;
+  findCommonCells(compType,startCellId,commonCells,commonCellsI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
+  int newNbOfCells=-1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(),
+                                                                                                          commonCellsI->end(),newNbOfCells);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2O(newNbOfCells);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> self=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(ret2->begin(),ret2->end(),true));
   setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true);
-  self->decrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1564,8 +1593,16 @@ DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) throw(INTE
 bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=mesh->zipConnectivityTraducer(compType);
   int nbOfCells=getNumberOfCells();
+  static const int possibleCompType[]={0,1,2};
+  if(std::find(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),compType)==possibleCompType+sizeof(possibleCompType)/sizeof(int))
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::areCellsIncludedIn : only following policies are possible : ";
+      std::copy(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),std::ostream_iterator<int>(oss," "));
+      oss << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=mesh->zipConnectivityTraducer(compType,nbOfCells);
   arr=o2n->substr(nbOfCells);
   arr->setName(other->getName());
   int tmp;
@@ -1586,45 +1623,26 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com
 bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
-  int spaceDim=mesh->getSpaceDimension();
-  std::vector<int> commonCells;
-  std::vector<int> commonCellsI;
-  switch(spaceDim)
-    {
-    case 3:
-      {
-        findCommonCellsBase<3>(7,commonCells,commonCellsI);
-        break;
-      }
-    case 2:
-      {
-        findCommonCellsBase<2>(7,commonCells,commonCellsI);
-        break;
-      }
-    case 1:
-      {
-        findCommonCellsBase<1>(7,commonCells,commonCellsI);
-        break;
-      }
-    default:
-      throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3.");
-    }
+  DataArrayInt *commonCells=0,*commonCellsI=0;
   int thisNbCells=getNumberOfCells();
+  mesh->findCommonCells(7,thisNbCells,commonCells,commonCellsI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
+  const int *commonCellsPtr=commonCells->getConstPointer(),*commonCellsIPtr=commonCellsI->getConstPointer();
   int otherNbCells=other->getNumberOfCells();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=DataArrayInt::New();
   arr2->alloc(otherNbCells,1);
   arr2->fillWithZero();
   int *arr2Ptr=arr2->getPointer();
-  int nbOfCommon=(int)commonCellsI.size()-1;
+  int nbOfCommon=commonCellsI->getNumberOfTuples()-1;
   for(int i=0;i<nbOfCommon;i++)
     {
-      int start=commonCells[commonCellsI[i]];
+      int start=commonCellsPtr[commonCellsIPtr[i]];
       if(start<thisNbCells)
         {
-          for(int j=commonCellsI[i]+1;j!=commonCellsI[i+1];j++)
+          for(int j=commonCellsIPtr[i]+1;j!=commonCellsIPtr[i+1];j++)
             {
-              int sig=commonCells[j]>0?1:-1;
-              int val=std::abs(commonCells[j])-1;
+              int sig=commonCellsPtr[j]>0?1:-1;
+              int val=std::abs(commonCellsPtr[j])-1;
               if(val>=thisNbCells)
                 arr2Ptr[val-thisNbCells]=sig*(start+1);
             }
@@ -1633,8 +1651,7 @@ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataAr
   arr2->setName(other->getName());
   if(arr2->presenceOfValue(0))
     return false;
-  arr=arr2;
-  arr2->incrRef();
+  arr=arr2.retn();
   return true;
 }
 
@@ -1873,12 +1890,10 @@ void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDC
 
 DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
 {
-  std::vector<int> cellIdsKept;
+  DataArrayInt *cellIdsKept=0;
   fillCellIdsToKeepFromNodeIds(partBg,partEnd,true,cellIdsKept);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)cellIdsKept.size(),1);
-  std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer());
-  return ret;
+  cellIdsKept->setName(getName());
+  return cellIdsKept;
 }
 
 /*!
@@ -1887,28 +1902,38 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *part
  * 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 ['begin','end') tab will be kept.
  *
- * @param begin input start of array of node ids.
- * @param end input end of array of node ids.
- * @param fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in.
- * @param cellIdsKept in/out array where all candidate cell ids are put at the end.
+ * \param [in] begin input start of array of node ids.
+ * \param [in] end input end of array of node ids.
+ * \param [in] fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in.
+ * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
  */
-void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector<int>& cellIdsKept) const
+void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
 {
-  std::set<int> fastFinder(begin,end);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
+  checkConnectivityFullyDefined();
+  int tmp=-1;
+  int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1;
+  std::vector<bool> fastFinder(sz,false);
+  for(const int *work=begin;work!=end;work++)
+    if(*work>=0 && *work<sz)
+      fastFinder[*work]=true;
   int nbOfCells=getNumberOfCells();
   const int *conn=getNodalConnectivity()->getConstPointer();
   const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
   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=(int)connOfCell.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(((int)locMerge.size()==refLgth && fullyIn) || (locMerge.size()!=0 && !fullyIn))
-        cellIdsKept.push_back(i);
+      int ref=0,nbOfHit=0;
+      for(const int *work2=conn+connIndex[i]+1;work2!=conn+connIndex[i+1];work2++)
+        if(*work2>=0)
+          {
+            ref++;
+            if(fastFinder[*work2])
+              nbOfHit++;
+          }
+      if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
+        cellIdsKept->pushBackSilent(i);
     }
+  cellIdsKeptArr=cellIdsKept.retn();
 }
 
 /*!
@@ -1916,13 +1941,10 @@ void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int
  */
 DataArrayInt *MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const
 {
-  std::vector<int> cellIdsKept;
+  DataArrayInt *cellIdsKept=0;
   fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)cellIdsKept.size(),1);
-  std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer());
-  ret->setName(getName());
-  return ret;
+  cellIdsKept->setName(getName());
+  return cellIdsKept;
 }
 
 /*!
@@ -1933,9 +1955,10 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const i
  */
 MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const
 {
-  std::vector<int> cellIdsKept;
+  DataArrayInt *cellIdsKept=0;
   fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept);
-  return buildPartOfMySelf(&cellIdsKept[0],&cellIdsKept[0]+cellIdsKept.size(),true);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept2(cellIdsKept);
+  return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true);
 }
 
 /*!
@@ -1990,32 +2013,32 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const
 DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception)
 {
   checkFullyDefined();
-  DataArrayInt *desc=DataArrayInt::New();
-  DataArrayInt *descIndx=DataArrayInt::New();
-  DataArrayInt *revDesc=DataArrayInt::New();
-  DataArrayInt *revDescIndx=DataArrayInt::New();
-  //
-  MEDCouplingUMesh *meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
-  meshDM1->decrRef();
-  desc->decrRef();
-  descIndx->decrRef();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New();
   //
-  DataArrayInt *tmp=revDescIndx->deltaShiftIndex();
-  DataArrayInt *faceIds=tmp->getIdsEqual(1);
-  tmp->decrRef();
-  int nbOfFaces=faceIds->getNumberOfTuples();
-  const int *faces=faceIds->getConstPointer();
-  std::set<int> ret;
-  for(const int *w=faces;w!=faces+nbOfFaces;w++)
-    ret.insert(revDesc->getIJ(revDescIndx->getIJ(*w,0),0));
-  faceIds->decrRef();
+  buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx)->decrRef();
+  desc=(DataArrayInt*)0; descIndx=(DataArrayInt*)0;
   //
-  revDescIndx->decrRef();
-  revDesc->decrRef();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=revDescIndx->deltaShiftIndex();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faceIds=tmp->getIdsEqual(1); tmp=(DataArrayInt*)0;
+  const int *revDescPtr=revDesc->getConstPointer();
+  const int *revDescIndxPtr=revDescIndx->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<bool> ret1(nbOfCells,false);
+  int sz=0;
+  for(const int *pt=faceIds->begin();pt!=faceIds->end();pt++)
+    if(!ret1[revDescPtr[revDescIndxPtr[*pt]]])
+      { ret1[revDescPtr[revDescIndxPtr[*pt]]]=true; sz++; }
   //
   DataArrayInt *ret2=DataArrayInt::New();
-  ret2->alloc((int)ret.size(),1);
-  std::copy(ret.begin(),ret.end(),ret2->getPointer());
+  ret2->alloc(sz,1);
+  int *ret2Ptr=ret2->getPointer();
+  sz=0;
+  for(std::vector<bool>::const_iterator it=ret1.begin();it!=ret1.end();it++,sz++)
+    if(*it)
+      *ret2Ptr++=sz;
   ret2->setName("BoundaryCells");
   return ret2;
 }
@@ -2077,8 +2100,8 @@ void MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSa
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s_renum1=DataArrayInt::Aggregate(s2_renum2,s1arr_renum1,0);
   s_renum1->sort();
   //
-  s0arr->incrRef(); cellIdsRk0=s0arr;
-  s_renum1->incrRef(); cellIdsRk1=s_renum1;
+  cellIdsRk0=s0arr.retn();
+  cellIdsRk1=s_renum1.retn();
 }
 
 /*!
@@ -2202,9 +2225,9 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On
   cellsToModifyConn0_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end());
   cellsToModifyConn1_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end());
   //
-  cellIdsNeededToBeRenum=cellsToModifyConn0_torenum; cellsToModifyConn0_torenum->incrRef();
-  cellIdsNotModified=cellsToModifyConn1_torenum; cellsToModifyConn1_torenum->incrRef();
-  nodeIdsToDuplicate=s3; s3->incrRef();
+  cellIdsNeededToBeRenum=cellsToModifyConn0_torenum.retn();
+  cellIdsNotModified=cellsToModifyConn1_torenum.retn();
+  nodeIdsToDuplicate=s3.retn();
 }
 
 /*!
@@ -2374,15 +2397,16 @@ void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INT
  * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be
  * added in 'elems' parameter.
  */
-void MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) const
+DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
 {
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1);
   if(getMeshDimension()==-1)
     {
-      elems.push_back(0);
-      return;
+      elems->pushBackSilent(0);
+      return elems.retn();
     }
   int dim=getSpaceDimension();
-  double* elem_bb=new double[2*dim];
+  INTERP_KERNEL::AutoPtr<double> elem_bb=new double[2*dim];
   const int* conn      = getNodalConnectivity()->getConstPointer();
   const int* conn_index= getNodalConnectivityIndex()->getConstPointer();
   const double* coords = getCoords()->getConstPointer();
@@ -2414,11 +2438,9 @@ void MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps, std
             }
         }
       if (intersectsBoundingBox(elem_bb, bbox, dim, eps))
-        {
-          elems.push_back(ielem);
-        }
+        elems->pushBackSilent(ielem);
     }
-  delete [] elem_bb;
+  return elems.retn();
 }
 
 /*!
@@ -2426,15 +2448,16 @@ void MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps, std
  * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be
  * added in 'elems' parameter.
  */
-void MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems)
+DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
 {
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1);
   if(getMeshDimension()==-1)
     {
-      elems.push_back(0);
-      return;
+      elems->pushBackSilent(0);
+      return elems.retn();
     }
   int dim=getSpaceDimension();
-  double* elem_bb=new double[2*dim];
+  INTERP_KERNEL::AutoPtr<double> elem_bb=new double[2*dim];
   const int* conn      = getNodalConnectivity()->getConstPointer();
   const int* conn_index= getNodalConnectivityIndex()->getConstPointer();
   const double* coords = getCoords()->getConstPointer();
@@ -2465,12 +2488,10 @@ void MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundi
                 }
             }
         }
-      if (intersectsBoundingBox(bbox, elem_bb, dim, eps))
-        {
-          elems.push_back(ielem);
-        }
+      if(intersectsBoundingBox(bbox, elem_bb, dim, eps))
+        elems->pushBackSilent(ielem);
     }
-  delete [] elem_bb;
+  return elems.retn();
 }
 
 /*!
@@ -2495,12 +2516,13 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) co
  * The coordinates array is not considered here.
  *
  * \param [in] type the geometric type
- * \return the 
+ * \return cell ids in this having geometric type \a type.
  */
 DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
 {
   
-  std::vector<int> v;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(0,1);
   checkConnectivityFullyDefined();
   int nbCells=getNumberOfCells();
   int mdim=getMeshDimension();
@@ -2512,12 +2534,9 @@ DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellT
   for(int i=0;i<nbCells;i++)
     {
       if((INTERP_KERNEL::NormalizedCellType)pt[ptI[i]]==type)
-        v.push_back(i);
+        ret->pushBackSilent(i);
     }
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc((int)v.size(),1);
-  std::copy(v.begin(),v.end(),ret->getPointer());
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -2680,8 +2699,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const
     }
   else
     ret->setCoords(_coords);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const
@@ -2745,7 +2763,7 @@ void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connInd
  * Copy constructor. If 'deepCpy' is false 'this' is a shallow copy of other.
  * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied.
  */
-MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_iterator(-1),_mesh_dim(other._mesh_dim),
+MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_mesh_dim(other._mesh_dim),
                                                                                  _nodal_connec(0),_nodal_connec_index(0),
                                                                                 _types(other._types)
 {
@@ -2800,10 +2818,7 @@ void MEDCouplingUMesh::checkConnectivityFullyDefined() const throw(INTERP_KERNEL
 int MEDCouplingUMesh::getNumberOfCells() const
 { 
   if(_nodal_connec_index)
-    if(_iterator==-1)
-      return _nodal_connec_index->getNumberOfTuples()-1;
-    else
-      return _iterator;
+    return _nodal_connec_index->getNumberOfTuples()-1;
   else
     if(_mesh_dim==-1)
       return 1;
@@ -2944,19 +2959,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int
   ret->setConnectivity(newConn,newConnI,false);
   ret->_types=types;
   ret->copyTinyInfoFrom(this);
-  std::string name(getName());
-  std::size_t sz=strlen(PART_OF_NAME);
-  if(name.length()>=sz)
-    name=name.substr(0,sz);
-  if(name!=PART_OF_NAME)
-    {
-      std::ostringstream stream; stream << PART_OF_NAME << getName();
-      ret->setName(stream.str().c_str());
-    }
-  else
-    ret->setName(getName());
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -3005,19 +3008,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin
   connRetArr->decrRef();
   connIndexRetArr->decrRef();
   ret->copyTinyInfoFrom(this);
-  std::string name(getName());
-  std::size_t sz=strlen(PART_OF_NAME);
-  if(name.length()>=sz)
-    name=name.substr(0,sz);
-  if(name!=PART_OF_NAME)
-    {
-      std::ostringstream stream; stream << PART_OF_NAME << getName();
-      ret->setName(stream.str().c_str());
-    }
-  else
-    ret->setName(getName());
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -3034,7 +3025,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
   std::string name="MeasureOfMesh_";
   name+=getName();
   int nbelem=getNumberOfCells();
-  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS);
+  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   field->setName(name.c_str());
   DataArrayDouble* array=DataArrayDouble::New();
   array->alloc(nbelem,1);
@@ -3042,6 +3033,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
   field->setArray(array) ;
   array->decrRef();
   field->setMesh(const_cast<MEDCouplingUMesh *>(this));
+  field->synchronizeTimeWithMesh();
   if(getMeshDimension()!=-1)
     {
       int ipt;
@@ -3145,7 +3137,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
 {
   if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
     throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !");
-  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   DataArrayDouble *array=DataArrayDouble::New();
   int nbOfCells=getNumberOfCells();
   int nbComp=getMeshDimension()+1;
@@ -3191,6 +3183,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
   ret->setArray(array);
   array->decrRef();
   ret->setMesh(this);
+  ret->synchronizeTimeWithSupport();
   return ret;
 }
 
@@ -3202,7 +3195,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *be
 {
   if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
     throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !");
-  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   DataArrayDouble *array=DataArrayDouble::New();
   std::size_t nbelems=std::distance(begin,end);
   int nbComp=getMeshDimension()+1;
@@ -3248,6 +3241,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *be
   ret->setArray(array);
   array->decrRef();
   ret->setMesh(this);
+  ret->synchronizeTimeWithSupport();
   return ret;
 }
 
@@ -3261,7 +3255,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const
     throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !");
    if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2)
      throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !");
-   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
    DataArrayDouble *array=DataArrayDouble::New();
    int nbOfCells=getNumberOfCells();
    int spaceDim=getSpaceDimension();
@@ -3279,6 +3273,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const
    ret->setArray(array);
    array->decrRef();
    ret->setMesh(this);
+   ret->synchronizeTimeWithSupport();
    return ret;   
 }
 
@@ -3305,7 +3300,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const dou
   if(candidates->empty())
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !");
   std::vector<int> nodes;
-  std::vector<int> cellIds2D,cellIds1D;
+  DataArrayInt *cellIds1D=0;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false));
   subMesh->findNodesOnPlane(origin,vec,eps,nodes);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New(),desc2=DataArrayInt::New();
@@ -3314,34 +3309,29 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const dou
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New(),revDescIndx2=DataArrayInt::New();
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc2=subMesh->buildDescendingConnectivity(desc2,descIndx2,revDesc2,revDescIndx2);//meshDim==2 spaceDim==3
   revDesc2=0; revDescIndx2=0;
-  mDesc2->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds2D);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=mDesc2->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3
   revDesc1=0; revDescIndx1=0;
   mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds1DTmp(cellIds1D);
   //
   std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2);
-  for(std::vector<int>::const_iterator it=cellIds1D.begin();it!=cellIds1D.end();it++)
+  for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++)
     cut3DCurve[*it]=-1;
   mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve);
   std::vector< std::pair<int,int> > cut3DSurf(mDesc2->getNumberOfCells());
   AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,mDesc2->getNodalConnectivity()->getConstPointer(),mDesc2->getNodalConnectivityIndex()->getConstPointer(),
                               mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(),
                               desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf);
-  std::vector<int> conn,connI,cellIds2;
-  connI.push_back(0);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New());
+  connI->pushBackSilent(0); conn->alloc(0,1); cellIds2->alloc(0,1);
   subMesh->assemblyForSplitFrom3DSurf(cut3DSurf,desc2->getConstPointer(),descIndx2->getConstPointer(),conn,connI,cellIds2);
-  if(cellIds2.empty())
+  if(cellIds2->empty())
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane !");
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3D",2);
   ret->setCoords(mDesc1->getCoords());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
-  c->alloc((int)conn.size(),1); std::copy(conn.begin(),conn.end(),c->getPointer());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New();
-  cI->alloc((int)connI.size(),1); std::copy(connI.begin(),connI.end(),cI->getPointer());
-  ret->setConnectivity(c,cI,true);
-  cellIds=candidates->selectByTupleId(&cellIds2[0],&cellIds2[0]+cellIds2.size());
-  ret->incrRef();
-  return ret;
+  ret->setConnectivity(conn,connI,true);
+  cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end());
+  return ret.retn();
 }
 
 /*!
@@ -3367,7 +3357,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const
   if(candidates->empty())
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3D surf cells in this intercepts the specified plane considering bounding boxes !");
   std::vector<int> nodes;
-  std::vector<int> cellIds1D;
+  DataArrayInt *cellIds1D=0;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false));
   subMesh->findNodesOnPlane(origin,vec,eps,nodes);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New();
@@ -3376,9 +3366,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New();
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=subMesh->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3
   mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds1DTmp(cellIds1D);
   //
   std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2);
-  for(std::vector<int>::const_iterator it=cellIds1D.begin();it!=cellIds1D.end();it++)
+  for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++)
     cut3DCurve[*it]=-1;
   mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve);
   int ncellsSub=subMesh->getNumberOfCells();
@@ -3386,7 +3377,8 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const
   AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,subMesh->getNodalConnectivity()->getConstPointer(),subMesh->getNodalConnectivityIndex()->getConstPointer(),
                               mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(),
                               desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf);
-  std::vector<int> conn,connI,cellIds2; connI.push_back(0);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); connI->pushBackSilent(0);
+  conn->alloc(0,1);
   const int *nodal=subMesh->getNodalConnectivity()->getConstPointer();
   const int *nodalI=subMesh->getNodalConnectivityIndex()->getConstPointer();
   for(int i=0;i<ncellsSub;i++)
@@ -3395,9 +3387,9 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const
         {
           if(cut3DSurf[i].first!=-2)
             {
-              conn.push_back((int)INTERP_KERNEL::NORM_SEG2); conn.push_back(cut3DSurf[i].first); conn.push_back(cut3DSurf[i].second);
-              connI.push_back((int)conn.size());
-              cellIds2.push_back(i);
+              conn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(cut3DSurf[i].first); conn->pushBackSilent(cut3DSurf[i].second);
+              connI->pushBackSilent(conn->getNumberOfTuples());
+              cellIds2->pushBackSilent(i);
             }
           else
             {
@@ -3406,25 +3398,20 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const
               int nbOfEdges=nodalI[cellId3DSurf+1]-offset;
               for(int j=0;j<nbOfEdges;j++)
                 {
-                  conn.push_back((int)INTERP_KERNEL::NORM_SEG2); conn.push_back(nodal[offset+j]); conn.push_back(nodal[offset+(j+1)%nbOfEdges]);
-                  connI.push_back((int)conn.size());
-                  cellIds2.push_back(cellId3DSurf);
+                  conn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(nodal[offset+j]); conn->pushBackSilent(nodal[offset+(j+1)%nbOfEdges]);
+                  connI->pushBackSilent(conn->getNumberOfTuples());
+                  cellIds2->pushBackSilent(cellId3DSurf);
                 }
             }
         }
     }
-  if(cellIds2.empty())
+  if(cellIds2->empty())
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3DSurf cells in this intercepts the specified plane !");
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3DSurf",1);
   ret->setCoords(mDesc1->getCoords());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
-  c->alloc((int)conn.size(),1); std::copy(conn.begin(),conn.end(),c->getPointer());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New();
-  cI->alloc((int)connI.size(),1); std::copy(connI.begin(),connI.end(),cI->getPointer());
-  ret->setConnectivity(c,cI,true);
-  cellIds=candidates->selectByTupleId(&cellIds2[0],&cellIds2[0]+cellIds2.size());
-  ret->incrRef();
-  return ret;
+  ret->setConnectivity(conn,connI,true);
+  cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end());
+  return ret.retn();
 }
 
 /*!
@@ -3444,7 +3431,7 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, co
   double vec2[3];
   vec2[0]=vec[1]; vec2[1]=-vec[0]; vec2[2]=0.;//vec2 is the result of cross product of vec with (0,0,1)
   double angle=acos(vec[2]/normm);
-  std::vector<int> cellIds;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds;
   double bbox[6];
   if(angle>eps)
     {
@@ -3454,19 +3441,15 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, co
       mw->setCoords(coo);
       mw->getBoundingBox(bbox);
       bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps;
-      mw->getCellsInBoundingBox(bbox,eps,cellIds);
+      cellIds=mw->getCellsInBoundingBox(bbox,eps);
     }
   else
     {
       getBoundingBox(bbox);
       bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps;
-      getCellsInBoundingBox(bbox,eps,cellIds);
+      cellIds=getCellsInBoundingBox(bbox,eps);
     }
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-  ret->alloc((int)cellIds.size(),1);
-  std::copy(cellIds.begin(),cellIds.end(),ret->getPointer());
-  ret->incrRef();
-  return ret;
+  return cellIds.retn();
 }
 
 /*!
@@ -3538,6 +3521,134 @@ void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps,
    f->decrRef();
 }
 
+/*!
+ * This method computes the distance from a point \a pt to \a this and the first \a cellId and \a nodeId in \a this corresponding to the returned distance. 
+ * \a this is expected to be a mesh so that its space dimension is equal to its
+ * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment.
+ * Distance from \a ptBg to \a ptEnd is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates).
+ * 
+ * This method firstly find the closer node in \a this to the requested point whose coordinates are defined by [ \a ptBg, \a ptEnd ). Then for this node found 
+ * the cells sharing this node (if any) are considered to find if the distance to these cell are smaller than the result found previously. If no cells are linked
+ * to the node that minimizes distance with the input point then -1 is returned in cellId.
+ *
+ * So this method is more accurate (so, more costly) than simply searching for the closest point in \a this.
+ * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this.
+ *
+ * \param [in] ptBg the start pointer (included) of the coordinates of the point
+ * \param [in] ptEnd the end pointer (not included) of the coordinates of the point
+ * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
+ * \return the positive value of the distance.
+ * \throw if distance from \a ptBg to \a ptEnd is not equal to the space dimension. An exception is also thrown if mesh dimension of \a this is not equal to space
+ * dimension - 1.
+ * \sa DataArrayDouble::distanceToTuple
+ */
+double MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId, int& nodeId) const throw(INTERP_KERNEL::Exception)
+{
+  int meshDim=getMeshDimension(),spaceDim=getSpaceDimension();
+  if(meshDim!=spaceDim-1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint works only for spaceDim=meshDim+1 !");
+  if(meshDim!=2 && meshDim!=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !");
+  checkFullyDefined();
+  if((int)std::distance(ptBg,ptEnd)!=spaceDim)
+    { std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoint : input point has to have dimension equal to the space dimension of this (" << spaceDim << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+  nodeId=-1;
+  double ret0=_coords->distanceToTuple(ptBg,ptEnd,nodeId);
+  if(nodeId==-1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : something wrong with nodes in this !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds=getCellIdsLyingOnNodes(&nodeId,&nodeId+1,false);
+  switch(meshDim)
+    {
+    case 2:
+      {
+        distanceToPoint3DSurfAlg(ptBg,cellIds,ret0,cellId);
+        return ret0;
+      }
+    case 1:
+      {
+        distanceToPoint2DCurveAlg(ptBg,cellIds,ret0,cellId);
+        return ret0;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !");
+    }
+  
+  return ret0;
+}
+
+
+/*!
+ * \param [in] pt the start pointer (included) of the coordinates of the point
+ * \param [in] cellIds
+ * \param [in,out] ret0 the min distance between \a this and the external input point
+ * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
+ * \sa MEDCouplingUMesh::distanceToPoint
+ */
+void MEDCouplingUMesh::distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const throw(INTERP_KERNEL::Exception)
+{
+  const double *coords=_coords->getConstPointer();
+  cellId=-1; 
+  if(cellIds->empty())
+    return;
+  const int *ptr=_nodal_connec->getConstPointer();
+  const int *ptrI=_nodal_connec_index->getConstPointer();
+  for(const int *zeCell=cellIds->begin();zeCell!=cellIds->end();zeCell++)
+    {
+      switch((INTERP_KERNEL::NormalizedCellType)ptr[ptrI[*zeCell]])
+        {
+        case INTERP_KERNEL::NORM_TRI3:
+          {
+            double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*ptr[ptrI[*zeCell]+1],coords+3*ptr[ptrI[*zeCell]+2],coords+3*ptr[ptrI[*zeCell]+3]);
+            if(tmp<ret0)
+              { ret0=tmp; cellId=*zeCell; }
+            break;
+          }
+        case INTERP_KERNEL::NORM_QUAD4:
+        case INTERP_KERNEL::NORM_POLYGON:
+          {
+            double tmp=INTERP_KERNEL::DistanceFromPtToPolygonInSpaceDim3(pt,ptr+ptrI[*zeCell]+1,ptr+ptrI[*zeCell+1],coords);
+            if(tmp<ret0)
+              { ret0=tmp; cellId=*zeCell; }
+            break;
+          }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint3DSurfAlg : not managed cell type ! Supporting TRI3, QUAD4 and POLYGON !");
+        }
+    }
+}
+
+/*!
+ * \param [in] pt the start pointer (included) of the coordinates of the point
+ * \param [in] cellIds
+ * \param [in,out] ret0 the min distance between \a this and the external input point
+ * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
+ * \sa MEDCouplingUMesh::distanceToPoint
+ */
+void MEDCouplingUMesh::distanceToPoint2DCurveAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const throw(INTERP_KERNEL::Exception)
+{
+  const double *coords=_coords->getConstPointer();
+  if(cellIds->empty())
+    { cellId=-1; return; }
+  const int *ptr=_nodal_connec->getConstPointer();
+  const int *ptrI=_nodal_connec_index->getConstPointer();
+  for(const int *zeCell=cellIds->begin();zeCell!=cellIds->end();zeCell++)
+    {
+       switch((INTERP_KERNEL::NormalizedCellType)ptr[ptrI[*zeCell]])
+        {
+        case INTERP_KERNEL::NORM_SEG2:
+          {
+            double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*ptr[ptrI[*zeCell]+1],coords+2*ptr[ptrI[*zeCell]+2]);
+            if(tmp!=std::numeric_limits<double>::max()) tmp=sqrt(tmp);
+            if(tmp<ret0)
+              { ret0=tmp; cellId=*zeCell; }
+            break;
+          }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint2DCurveAlg : not managed cell type ! Supporting SEG2 !");
+        }
+    }
+}
+
 /*!
  * Returns a cell if any that contains the point located on 'pos' with precison eps.
  * If 'pos' is outside 'this' -1 is returned. If several cells contain this point the cell with the smallest id is returned.
@@ -3833,77 +3944,27 @@ DataArrayInt *MEDCouplingUMesh::convexEnvelop2D() throw(INTERP_KERNEL::Exception
   int nbOfCells=getNumberOfCells();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecIndexOut=DataArrayInt::New();
   nodalConnecIndexOut->alloc(nbOfCells+1,1);
-  std::vector<int> nodalConnecOut;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecOut(DataArrayInt::New());
   int *workIndexOut=nodalConnecIndexOut->getPointer();
   *workIndexOut=0;
   const int *nodalConnecIn=_nodal_connec->getConstPointer();
   const int *nodalConnecIndexIn=_nodal_connec_index->getConstPointer();
   std::set<INTERP_KERNEL::NormalizedCellType> types;
-  std::vector<int> isChanged;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> isChanged(DataArrayInt::New());
+  isChanged->alloc(0,1);
   for(int i=0;i<nbOfCells;i++,workIndexOut++)
     {
-      std::size_t pos=nodalConnecOut.size();
+      int pos=nodalConnecOut->getNumberOfTuples();
       if(BuildConvexEnvelopOf2DCellJarvis(coords,nodalConnecIn+nodalConnecIndexIn[i],nodalConnecIn+nodalConnecIndexIn[i+1],nodalConnecOut))
-        isChanged.push_back(i);
-      types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut[pos]);
-      workIndexOut[1]=(int)nodalConnecOut.size();
+        isChanged->pushBackSilent(i);
+      types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut->getIJ(pos,0));
+      workIndexOut[1]=nodalConnecOut->getNumberOfTuples();
     }
-  if(isChanged.empty())
+  if(isChanged->empty())
     return 0;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecOut2=DataArrayInt::New();
-  nodalConnecOut2->alloc((int)nodalConnecOut.size(),1);
-  std::copy(nodalConnecOut.begin(),nodalConnecOut.end(),nodalConnecOut2->getPointer());
-  setConnectivity(nodalConnecOut2,nodalConnecIndexOut,false);
+  setConnectivity(nodalConnecOut,nodalConnecIndexOut,false);
   _types=types;
-  DataArrayInt *ret=DataArrayInt::New(); ret->alloc((int)isChanged.size(),1);
-  std::copy(isChanged.begin(),isChanged.end(),ret->getPointer());
-  return ret;
-}
-
-/*!
- * This method is expected to be applied on a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown.
- * This method analyzes only linear extruded 3D cells (NORM_HEXA8,NORM_PENTA6,NORM_HEXGP12...)
- * If some extruded cells does not fulfill the MED norm for extruded cells (first face of 3D cell should be oriented to the exterior of the 3D cell).
- * Some viewers are very careful of that (SMESH), but ParaVis ignore that.
- */
-void MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells(std::vector<int>& cells) throw(INTERP_KERNEL::Exception)
-{
-  const char msg[]="check3DCellsWellOriented detection works only for 3D cells !";
-  if(getMeshDimension()!=3)
-    throw INTERP_KERNEL::Exception(msg);
-  int spaceDim=getSpaceDimension();
-  if(spaceDim!=3)
-    throw INTERP_KERNEL::Exception(msg);
-  //
-  int nbOfCells=getNumberOfCells();
-  int *conn=_nodal_connec->getPointer();
-  const int *connI=_nodal_connec_index->getConstPointer();
-  const double *coo=getCoords()->getConstPointer();
-  double vec0[3],vec1[3];
-  for(int i=0;i<nbOfCells;i++)
-    {
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
-      if(cm.isExtruded() && !cm.isDynamic() && !cm.isQuadratic())
-        {
-          INTERP_KERNEL::AutoPtr<int> tmp=new int[connI[i+1]-connI[i]-1];
-          int nbOfNodes=cm.fillSonCellNodalConnectivity(0,conn+connI[i]+1,tmp);
-          INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(tmp,nbOfNodes,coo,vec0);
-          const double *pt0=coo+3*conn[connI[i]+1];
-          const double *pt1=coo+3*conn[connI[i]+nbOfNodes+1];
-          vec1[0]=pt0[0]-pt1[0]; vec1[1]=pt0[1]-pt1[1]; vec1[2]=pt0[2]-pt1[2];
-          double dot=vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2];
-          if(dot<0)
-            {
-              cells.push_back(i);
-              std::copy(conn+connI[i]+1,conn+connI[i+1],(int *)tmp);
-              for(int j=1;j<nbOfNodes;j++)
-                {
-                  conn[connI[i]+1+j]=tmp[nbOfNodes-j];
-                  conn[connI[i]+1+j+nbOfNodes]=tmp[nbOfNodes+nbOfNodes-j];
-                }
-            }
-        }
-    }
+  return isChanged.retn();
 }
 
 /*!
@@ -4395,8 +4456,8 @@ void MEDCouplingUMesh::tessellate2DCurve(double eps) throw(INTERP_KERNEL::Except
   const int *connI=_nodal_connec_index->getConstPointer();
   const double *coords=_coords->getConstPointer();
   std::vector<double> addCoo;
-  std::vector<int> newConn;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  std::vector<int> newConn;//no direct DataArrayInt because interface with Geometric2D
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI(DataArrayInt::New());
   newConnI->alloc(nbCells+1,1);
   int *newConnIPtr=newConnI->getPointer();
   *newConnIPtr=0;
@@ -4453,12 +4514,15 @@ void MEDCouplingUMesh::tessellate2DCurve(double eps) throw(INTERP_KERNEL::Except
 
 /*!
  * This methods modify this by converting each cells into simplex cell, that is too say triangle for meshdim==2 or tetra for meshdim==3.
- * This cut into simplex is performed following the parameter 'policy'. This method so typically increases the number of cells of this.
- * This method returns new2old array that specifies a each cell of 'this' after the call what was its id it comes.
+ * This cut into simplex is performed following the parameter \a policy. This method so typically increases the number of cells of \a this.
+ * This method \b keeps the number of nodes \b unchanged. That's why the splitting policy in 3D INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here.
+ * This method returns new2old newly allocated array that specifies a each cell of \a this after the call what was its id it comes.
  * 
- * The semantic of 'policy' parameter :
+ * The semantic of \a policy parameter :
  * - 1 only QUAD4. For QUAD4 the cut is done along 0-2 diagonal for QUAD4
  * - 2 only QUAD4. For QUAD4 the cut is done along 1-3 diagonal for QUAD4
+ * - PLANAR_FACE_5 only HEXA8. All HEXA8 are split into 5 TETRA4
+ * - PLANAR_FACE_6 only HEXA8. All HEXA8 are split into 6 TETRA4
  */
 DataArrayInt *MEDCouplingUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
 {
@@ -4468,8 +4532,12 @@ DataArrayInt *MEDCouplingUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exce
       return simplexizePol0();
     case 1:
       return simplexizePol1();
+    case (int) INTERP_KERNEL::PLANAR_FACE_5:
+      return simplexizePlanarFace5();
+    case (int) INTERP_KERNEL::PLANAR_FACE_6:
+      return simplexizePlanarFace6();
     default:
-      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be 0 or 1 !");
+      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n  - 0 or 1 (only available for meshdim=2) \n  - PLANAR_FACE_5, PLANAR_FACE_6  (only for meshdim=3)");
     }
 }
 
@@ -4491,26 +4559,129 @@ bool MEDCouplingUMesh::areOnlySimplexCells() const throw(INTERP_KERNEL::Exceptio
 }
 
 /*!
- * This method implements policy 0 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
+ * This method implements policy 0 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  int nbOfCells=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+  ret->alloc(nbOfCells+nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
+  int *retPt=ret->getPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
+  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->getConstPointer();
+  const int *ci=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+        {
+          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+3],
+                            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+3],oldc[ci[0]+4]};
+          pt=std::copy(tmp,tmp+8,pt);
+          ptI[1]=ptI[0]+4;
+          ptI[2]=ptI[0]+8;
+          *retPt++=i;
+          *retPt++=i;
+          ptI+=2;
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn.retn();
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI.retn();
+  computeTypes();
+  updateTime();
+  return ret.retn();
+}
+
+/*!
+ * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  int nbOfCells=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+  ret->alloc(nbOfCells+nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
+  int *retPt=ret->getPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
+  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->getConstPointer();
+  const int *ci=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+        {
+          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+4],
+                            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+2],oldc[ci[0]+3],oldc[ci[0]+4]};
+          pt=std::copy(tmp,tmp+8,pt);
+          ptI[1]=ptI[0]+4;
+          ptI[2]=ptI[0]+8;
+          *retPt++=i;
+          *retPt++=i;
+          ptI+=2;
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn.retn();
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI.retn();
+  computeTypes();
+  updateTime();
+  return ret.retn();
+}
+
+/*!
+ * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
  */
-DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
 {
-  if(getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !");
   int nbOfCells=getNumberOfCells();
-  DataArrayInt *ret=DataArrayInt::New();
-  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
-  ret->alloc(nbOfCells+nbOfCutCells,1);
-  if(nbOfCutCells==0)
-    {
-      ret->iota(0);
-      return ret;
-    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
+  ret->alloc(nbOfCells+4*nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
   int *retPt=ret->getPointer();
-  DataArrayInt *newConn=DataArrayInt::New();
-  DataArrayInt *newConnI=DataArrayInt::New();
-  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
-  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1);
+  newConn->alloc(getMeshLength()+16*nbOfCutCells,1);//21
   int *pt=newConn->getPointer();
   int *ptI=newConnI->getPointer();
   ptI[0]=0;
@@ -4518,16 +4689,15 @@ DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
   const int *ci=_nodal_connec_index->getConstPointer();
   for(int i=0;i<nbOfCells;i++,ci++)
     {
-      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
         {
-          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+3],
-                            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+3],oldc[ci[0]+4]};
-          pt=std::copy(tmp,tmp+8,pt);
-          ptI[1]=ptI[0]+4;
-          ptI[2]=ptI[0]+8;
-          *retPt++=i;
-          *retPt++=i;
-          ptI+=2;
+          for(int j=0;j<5;j++,pt+=5,ptI++)
+            {
+              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
+              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+3]+1];
+              *retPt++=i;
+              ptI[1]=ptI[0]+5;
+            }
         }
       else
         {
@@ -4538,35 +4708,32 @@ DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
         }
     }
   _nodal_connec->decrRef();
-  _nodal_connec=newConn;
+  _nodal_connec=newConn.retn();
   _nodal_connec_index->decrRef();
-  _nodal_connec_index=newConnI;
+  _nodal_connec_index=newConnI.retn();
   computeTypes();
   updateTime();
-  return ret;
+  return ret.retn();
 }
 
 /*!
- * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
+ * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
  */
-DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
 {
-  if(getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !");
   int nbOfCells=getNumberOfCells();
-  DataArrayInt *ret=DataArrayInt::New();
-  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
-  ret->alloc(nbOfCells+nbOfCutCells,1);
-  if(nbOfCutCells==0)
-    {
-      ret->iota(0);
-      return ret;
-    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
+  ret->alloc(nbOfCells+5*nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
   int *retPt=ret->getPointer();
-  DataArrayInt *newConn=DataArrayInt::New();
-  DataArrayInt *newConnI=DataArrayInt::New();
-  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
-  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1);
+  newConn->alloc(getMeshLength()+21*nbOfCutCells,1);
   int *pt=newConn->getPointer();
   int *ptI=newConnI->getPointer();
   ptI[0]=0;
@@ -4574,16 +4741,15 @@ DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
   const int *ci=_nodal_connec_index->getConstPointer();
   for(int i=0;i<nbOfCells;i++,ci++)
     {
-      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
         {
-          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+4],
-                            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+2],oldc[ci[0]+3],oldc[ci[0]+4]};
-          pt=std::copy(tmp,tmp+8,pt);
-          ptI[1]=ptI[0]+4;
-          ptI[2]=ptI[0]+8;
-          *retPt++=i;
-          *retPt++=i;
-          ptI+=2;
+          for(int j=0;j<6;j++,pt+=5,ptI++)
+            {
+              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
+              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+3]+1];
+              *retPt++=i;
+              ptI[1]=ptI[0]+5;
+            }
         }
       else
         {
@@ -4594,12 +4760,12 @@ DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
         }
     }
   _nodal_connec->decrRef();
-  _nodal_connec=newConn;
+  _nodal_connec=newConn.retn();
   _nodal_connec_index->decrRef();
-  _nodal_connec_index=newConnI;
+  _nodal_connec_index=newConnI.retn();
   computeTypes();
   updateTime();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4810,7 +4976,9 @@ void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cell
 
 /*!
  * This method tries to orient correctly polhedrons cells.
- * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3. An exception is also thrown when the attempt of reparation fails.
+ * 
+ * \throw when 'this' is not a mesh with meshdim==3 and spacedim==3. An exception is also thrown when the attempt of reparation fails.
+ * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells
  */
 void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception)
 {
@@ -4820,20 +4988,130 @@ void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Excepti
   int *conn=_nodal_connec->getPointer();
   const int *connI=_nodal_connec_index->getConstPointer();
   const double *coordsPtr=_coords->getConstPointer();
-  bool isModified=false;
   for(int i=0;i<nbOfCells;i++)
     {
       INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
       if(type==INTERP_KERNEL::NORM_POLYHED)
-        if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+        {
+          try
+            {
+              if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+                TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
+            }
+          catch(INTERP_KERNEL::Exception& e)
+            {
+              std::ostringstream oss; oss << "Something wrong in polyhedron #" << i << " : " << e.what();
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+    }
+  updateTime();
+}
+
+/*!
+ * This method is expected to be applied on a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown.
+ * This method analyzes only linear extruded 3D cells (NORM_HEXA8,NORM_PENTA6,NORM_HEXGP12...)
+ * If some extruded cells does not fulfill the MED norm for extruded cells (first face of 3D cell should be oriented to the exterior of the 3D cell).
+ * Some viewers are very careful of that (SMESH), but ParaVis ignore that.
+ *
+ * \ret a newly allocated int array with one components containing cell ids renumbered to fit the convention of MED (MED file and MEDCoupling)
+ * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells
+ */
+DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="check3DCellsWellOriented detection works only for 3D cells !";
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception(msg);
+  int spaceDim=getSpaceDimension();
+  if(spaceDim!=3)
+    throw INTERP_KERNEL::Exception(msg);
+  //
+  int nbOfCells=getNumberOfCells();
+  int *conn=_nodal_connec->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=getCoords()->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cells(DataArrayInt::New()); cells->alloc(0,1);
+  for(int i=0;i<nbOfCells;i++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+      if(cm.isExtruded() && !cm.isDynamic() && !cm.isQuadratic())
+        {
+          if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coo))
+            {
+              CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]);
+              cells->pushBackSilent(i);
+            }
+        }
+    }
+  return cells.retn();
+}
+
+/*!
+ * This method is a faster method to correct orientation of all 3D cells in \a this.
+ * This method works only if \a this is a 3D mesh, that is to say a mesh with mesh dimension 3 and a space dimension 3.
+ * This method makes the hypothesis that \a this a coherent that is to say MEDCouplingUMesh::checkCoherency2 should throw no exception.
+ * 
+ * \ret a newly allocated int array with one components containing cell ids renumbered to fit the convention of MED (MED file and MEDCoupling)
+ * \sa MEDCouplingUMesh::orientCorrectlyPolyhedrons, 
+ */
+DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply findAndCorrectBadOriented3DCells on it : must be meshDim==3 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  int *conn=_nodal_connec->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      switch(type)
+        {
+        case INTERP_KERNEL::NORM_TETRA4:
+          {
+            if(!IsTetra4WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+              {
+                std::swap(*(conn+connI[i]+2),*(conn+connI[i]+3));
+                ret->pushBackSilent(i);
+              }
+            break;
+          }
+        case INTERP_KERNEL::NORM_PYRA5:
+          {
+            if(!IsPyra5WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+              {
+                std::swap(*(conn+connI[i]+2),*(conn+connI[i]+4));
+                ret->pushBackSilent(i);
+              }
+            break;
+          }
+        case INTERP_KERNEL::NORM_PENTA6:
+        case INTERP_KERNEL::NORM_HEXA8:
+        case INTERP_KERNEL::NORM_HEXGP12:
+          {
+            if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+              {
+                CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]);
+                ret->pushBackSilent(i);
+              }
+            break;
+          }
+        case INTERP_KERNEL::NORM_POLYHED:
           {
-            TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
-            isModified=true;
+            if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+              {
+                TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
+                ret->pushBackSilent(i);
+              }
+            break;
           }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orientCorrectly3DCells : Your mesh contains type of cell not supported yet ! send mail to anthony.geay@cea.fr to add it !");
+        }
     }
-  if(isModified)
-    _nodal_connec->declareAsNew();
   updateTime();
+  return ret.retn();
 }
 
 /*!
@@ -4869,7 +5147,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : SpaceDimension must be equal to 2 or 3 !");
   if(meshDim!=2 && meshDim!=3)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : MeshDimension must be equal to 2 or 3 !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   ret->setMesh(this);
   int nbOfCells=getNumberOfCells();
   DataArrayDouble *arr=DataArrayDouble::New();
@@ -4910,8 +5188,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP
       conn+=connI[i+1]-connI[i];
     }
   ret->setName("EdgeRatio");
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
@@ -4929,7 +5207,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTE
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : SpaceDimension must be equal to 2 or 3 !");
   if(meshDim!=2 && meshDim!=3)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : MeshDimension must be equal to 2 or 3 !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   ret->setMesh(this);
   int nbOfCells=getNumberOfCells();
   DataArrayDouble *arr=DataArrayDouble::New();
@@ -4970,8 +5248,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTE
       conn+=connI[i+1]-connI[i];
     }
   ret->setName("AspectRatio");
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
@@ -4989,7 +5267,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERN
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : SpaceDimension must be equal to 3 !");
   if(meshDim!=2)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : MeshDimension must be equal to 2 !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   ret->setMesh(this);
   int nbOfCells=getNumberOfCells();
   DataArrayDouble *arr=DataArrayDouble::New();
@@ -5018,8 +5296,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERN
       conn+=connI[i+1]-connI[i];
     }
   ret->setName("Warp");
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
@@ -5037,7 +5315,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERN
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : SpaceDimension must be equal to 3 !");
   if(meshDim!=2)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : MeshDimension must be equal to 2 !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
   ret->setMesh(this);
   int nbOfCells=getNumberOfCells();
   DataArrayDouble *arr=DataArrayDouble::New();
@@ -5066,8 +5344,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERN
       conn+=connI[i+1]-connI[i];
     }
   ret->setName("Skew");
-  ret->incrRef();
-  return ret;
+  ret->synchronizeTimeWithSupport();
+  return ret.retn();
 }
 
 /*!
@@ -5376,8 +5654,7 @@ DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Ex
   checkConnectivityFullyDefined();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER);
   renumberCells(ret->getConstPointer(),false);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5402,6 +5679,17 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const
   return true;
 }
 
+/*!
+ * This method is a specialization of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method that is called here.
+ * The geometric type order is specified by MED file.
+ * 
+ * \sa  MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder
+ */
+bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception)
+{
+  return checkConsecutiveCellTypesAndOrder(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER);
+}
+
 /*!
  * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check
  * that the order is specified in array defined by [orderBg,orderEnd). 
@@ -5460,10 +5748,8 @@ DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::Norma
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  nbPerType=tmpb;
-  tmpa->incrRef();
-  tmpb->incrRef();
-  return tmpa;
+  nbPerType=tmpb.retn();
+  return tmpa.retn();
 }
 
 /*!
@@ -5584,8 +5870,8 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons
   std::vector<const MEDCouplingUMesh *> m1ssmSingle;
   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > m1ssmSingleAuto;
   int fake=0,rk=0;
-  std::vector<int> ret1Data;
-  std::vector<int> ret2Data;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1(DataArrayInt::New()),ret2(DataArrayInt::New());
+  ret1->alloc(0,1); ret2->alloc(0,1);
   for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++)
     {
       if(meshDim!=(*it)->getMeshDimension())
@@ -5600,11 +5886,9 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons
           MEDCouplingUMesh *singleCell=static_cast<MEDCouplingUMesh *>((*it2)->buildPartOfMySelf(&fake,&fake+1,true));
           m1ssmSingleAuto.push_back(singleCell);
           m1ssmSingle.push_back(singleCell);
-          ret1Data.push_back((*it2)->getNumberOfCells()); ret2Data.push_back(rk);
+          ret1->pushBackSilent((*it2)->getNumberOfCells()); ret2->pushBackSilent(rk);
         }
     }
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc((int)m1ssmSingle.size(),1); std::copy(ret1Data.begin(),ret1Data.end(),ret1->getPointer());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)m1ssmSingle.size(),1); std::copy(ret2Data.begin(),ret2Data.end(),ret2->getPointer());
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum=m1ssmSingle2->sortCellsInMEDFileFrmt();
   std::vector<const MEDCouplingUMesh *> m1ssmfinal(m1ssm.size());
@@ -5613,8 +5897,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal);
   szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer());
   idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer());
-  ret0->incrRef();
-  return ret0;
+  return ret0.retn();
 }
 
 /*!
@@ -5624,16 +5907,13 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons
 DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception)
 {
   checkFullyDefined();
-  std::vector<int> r;
   const int *conn=_nodal_connec->getConstPointer();
   const int *connIndex=_nodal_connec_index->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   for(const int *w=begin;w!=end;w++)
     if((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]==type)
-      r.push_back(*w);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)r.size(),1);
-  std::copy(r.begin(),r.end(),ret->getPointer());
-  return ret;
+      ret->pushBackSilent(*w);
+  return ret.retn();
 }
 
 /*!
@@ -5706,8 +5986,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::Normalized
     }
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true));
   ret->copyTinyInfoFrom(this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5747,13 +6026,12 @@ MEDCouplingMesh *MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other)
  */
 DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const
 {
-  DataArrayDouble *ret=DataArrayDouble::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
   int spaceDim=getSpaceDimension();
   int nbOfCells=getNumberOfCells();
   ret->alloc(nbOfCells,spaceDim);
   ret->copyStringInfoFrom(*getCoords());
   double *ptToFill=ret->getPointer();
-  double *tmp=new double[spaceDim];
   const int *nodal=_nodal_connec->getConstPointer();
   const int *nodalI=_nodal_connec_index->getConstPointer();
   const double *coor=_coords->getConstPointer();
@@ -5763,8 +6041,7 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const
       INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(type,nodal+nodalI[i]+1,nodalI[i+1]-nodalI[i]-1,coor,spaceDim,ptToFill);
       ptToFill+=spaceDim;
     }
-  delete [] tmp;
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5819,8 +6096,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da) t
       *cip++=2*(i+1);
     }
   ret->setConnectivity(c,cI,true);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5928,8 +6204,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vector<const MEDCoupling
   ret->setConnectivity(c,cI,true);
   c->decrRef();
   cI->decrRef();
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /// @endcond
@@ -6135,7 +6410,7 @@ void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<ME
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1(comm),tmp2(commI);
   int oldNbOfNodes=coo->getNumberOfTuples();
   int newNbOfNodes;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm,commI,newNbOfNodes);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm->begin(),commI->begin(),commI->end(),newNbOfNodes);
   if(oldNbOfNodes==newNbOfNodes)
     return ;
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes);
@@ -6271,6 +6546,58 @@ bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end
   return INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION;
 }
 
+/*!
+ * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [begin,end).
+ */
+bool MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords)
+{
+  double vec0[3],vec1[3];
+  std::size_t sz=std::distance(begin,end);
+  if(sz%2!=0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented : the length of nodal connectivity of extruded cell is not even !");
+  int nbOfNodes=(int)sz/2;
+  INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(begin,nbOfNodes,coords,vec0);
+  const double *pt0=coords+3*begin[0];
+  const double *pt1=coords+3*begin[nbOfNodes];
+  vec1[0]=pt1[0]-pt0[0]; vec1[1]=pt1[1]-pt0[1]; vec1[2]=pt1[2]-pt0[2];
+  return (vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2])<0.;
+}
+
+void MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end)
+{
+  std::size_t sz=std::distance(begin,end);
+  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz];
+  std::size_t nbOfNodes(sz/2);
+  std::copy(begin,end,(int *)tmp);
+  for(std::size_t j=1;j<nbOfNodes;j++)
+    {
+      begin[j]=tmp[nbOfNodes-j];
+      begin[j+nbOfNodes]=tmp[nbOfNodes+nbOfNodes-j];
+    }
+}
+
+bool MEDCouplingUMesh::IsTetra4WellOriented(const int *begin, const int *end, const double *coords)
+{
+  std::size_t sz=std::distance(begin,end);
+  if(sz!=4)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::IsTetra4WellOriented : Tetra4 cell with not 4 nodes ! Call checkCoherency2 !");
+  double vec0[3],vec1[3];
+  const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[1],*pt2=coords+3*begin[2],*pt3=coords+3*begin[3];
+  vec0[0]=pt1[0]-pt0[0]; vec0[1]=pt1[1]-pt0[1]; vec0[2]=pt1[2]-pt0[2]; vec1[0]=pt2[0]-pt0[0]; vec1[1]=pt2[1]-pt0[1]; vec1[2]=pt2[2]-pt0[2]; 
+  return ((vec0[1]*vec1[2]-vec0[2]*vec1[1])*(pt3[0]-pt0[0])+(vec0[2]*vec1[0]-vec0[0]*vec1[2])*(pt3[1]-pt0[1])+(vec0[0]*vec1[1]-vec0[1]*vec1[0])*(pt3[2]-pt0[2]))<0;
+}
+
+bool MEDCouplingUMesh::IsPyra5WellOriented(const int *begin, const int *end, const double *coords)
+{
+  std::size_t sz=std::distance(begin,end);
+  if(sz!=5)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::IsPyra5WellOriented : Pyra5 cell with not 5 nodes ! Call checkCoherency2 !");
+  double vec0[3];
+  INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(begin,4,coords,vec0);
+  const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[4];
+  return (vec0[0]*(pt1[0]-pt0[0])+vec0[1]*(pt1[1]-pt0[1])+vec0[2]*(pt1[2]-pt0[2]))<0.;
+}
+
 /*!
  * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [\b begin, \b end) 
  * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to
@@ -6280,9 +6607,9 @@ bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end
  * \param [in] coords the coordinates with nb of components exactly equal to 3
  * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell
  * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded)
- * \param [out] the result is put at the end of the vector without any alteration of the data.
+ * \param [out] res the result is put at the end of the vector without any alteration of the data.
  */
-void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, std::vector<int>& res) throw(INTERP_KERNEL::Exception)
+void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res) throw(INTERP_KERNEL::Exception)
 {
   int nbFaces=std::count(begin+1,end,-1)+1;
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> v=DataArrayDouble::New(); v->alloc(nbFaces,3);
@@ -6303,7 +6630,7 @@ void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble
   const int *comm1Ptr=comm1->getConstPointer();
   const int *commI1Ptr=commI1->getConstPointer();
   int nbOfGrps1=commI1Auto->getNumberOfTuples()-1;
-  res.push_back((int)INTERP_KERNEL::NORM_POLYHED);
+  res->pushBackSilent((int)INTERP_KERNEL::NORM_POLYHED);
   //
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm=MEDCouplingUMesh::New("",3);
   mm->setCoords(const_cast<DataArrayDouble *>(coords)); mm->allocateCells(1); mm->insertNextCell(INTERP_KERNEL::NORM_POLYHED,(int)std::distance(begin+1,end),begin+1);
@@ -6323,8 +6650,8 @@ void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble
         {
           if(commI2Ptr[j+1]-commI2Ptr[j]<=1)
             {
-              res.insert(res.end(),begin,end);
-              res.push_back(-1);
+              res->insertAtTheEnd(begin,end);
+              res->pushBackSilent(-1);
             }
           else
             {
@@ -6354,13 +6681,13 @@ void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble
                 {
                   int l=0;
                   for(const int *work=conn4+connI4[k]+1;work!=conn4+connI4[k+1];work++,l++)
-                    res.push_back(idsNodePtr[*work]);
-                  res.push_back(-1);
+                    res->pushBackSilent(idsNodePtr[*work]);
+                  res->pushBackSilent(-1);
                 }
             }
         }
     }
-  res.pop_back();
+  res->popBackSilent();
 }
 
 /*!
@@ -6422,52 +6749,70 @@ void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, c
  */
 void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception)
 {
-  std::vector<std::pair<int,int> > edges;
+  std::list< std::pair<int,int> > edgesOK,edgesFinished;
   std::size_t nbOfFaces=std::count(begin,end,-1)+1;
-  int *bgFace=begin;
-  std::vector<bool> isPerm(nbOfFaces);
-  for(std::size_t i=0;i<nbOfFaces;i++)
+  std::vector<bool> isPerm(nbOfFaces,false);//field on faces False: I don't know, True : oriented
+  isPerm[0]=true;
+  int *bgFace=begin,*endFace=std::find(begin+1,end,-1);
+  std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
+  for(std::size_t l=0;l<nbOfEdgesInFace;l++) { std::pair<int,int> p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); edgesOK.push_back(p1); }
+  //
+  while(std::find(isPerm.begin(),isPerm.end(),false)!=isPerm.end())
     {
-      int *endFace=std::find(bgFace+1,end,-1);
-      std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
-      for(std::size_t l=0;l<nbOfEdgesInFace;l++)
-        {
-          std::pair<int,int> p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]);
-          edges.push_back(p1);
-        }
-      int *bgFace2=endFace+1;
-      for(std::size_t k=i+1;k<nbOfFaces;k++)
+      bgFace=begin;
+      std::size_t smthChanged=0;
+      for(std::size_t i=0;i<nbOfFaces;i++)
         {
-          int *endFace2=std::find(bgFace2+1,end,-1);
-          std::size_t nbOfEdgesInFace2=std::distance(bgFace2,endFace2);
-          for(std::size_t j=0;j<nbOfEdgesInFace2;j++)
+          endFace=std::find(bgFace+1,end,-1);
+          nbOfEdgesInFace=std::distance(bgFace,endFace);
+          if(!isPerm[i])
             {
-              std::pair<int,int> p2(bgFace2[j],bgFace2[(j+1)%nbOfEdgesInFace2]);
-              if(std::find(edges.begin(),edges.end(),p2)!=edges.end())
+              bool b;
+              for(std::size_t j=0;j<nbOfEdgesInFace;j++)
                 {
-                  if(isPerm[k])
-                    throw INTERP_KERNEL::Exception("Fail to repare polyhedron ! Polyedron looks bad !");
-                  std::vector<int> tmp(nbOfEdgesInFace2-1);
-                  std::copy(bgFace2+1,endFace2,tmp.rbegin());
-                  std::copy(tmp.begin(),tmp.end(),bgFace2+1);
-                  isPerm[k]=true;
-                  continue;
+                  std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
+                  std::pair<int,int> p2(p1.second,p1.first);
+                  bool b1=std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end();
+                  bool b2=std::find(edgesOK.begin(),edgesOK.end(),p2)!=edgesOK.end();
+                  if(b1 || b2) { b=b2; isPerm[i]=true; smthChanged++; break; }
+                }
+              if(isPerm[i])
+                { 
+                  if(!b)
+                    std::reverse(bgFace+1,endFace);
+                  for(std::size_t j=0;j<nbOfEdgesInFace;j++)
+                    {
+                      std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
+                      std::pair<int,int> p2(p1.second,p1.first);
+                      if(std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end())
+                        { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+                      if(std::find(edgesFinished.begin(),edgesFinished.end(),p1)!=edgesFinished.end() || std::find(edgesFinished.begin(),edgesFinished.end(),p2)!=edgesFinished.end())
+                        { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+                      std::list< std::pair<int,int> >::iterator it=std::find(edgesOK.begin(),edgesOK.end(),p2);
+                      if(it!=edgesOK.end())
+                        {
+                          edgesOK.erase(it);
+                          edgesFinished.push_back(p1);
+                        }
+                      else
+                        edgesOK.push_back(p1);
+                    }
                 }
             }
-          bgFace2=endFace2+1;
+          bgFace=endFace+1;
         }
-      bgFace=endFace+1;
+      if(smthChanged==0)
+        { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired !"); }
     }
+  if(!edgesOK.empty())
+    { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired : Some edges are shared only once !"); }
   if(INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION)
     {//not lucky ! The first face was not correctly oriented : reorient all faces...
       bgFace=begin;
       for(std::size_t i=0;i<nbOfFaces;i++)
         {
-          int *endFace=std::find(bgFace+1,end,-1);
-          std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
-          std::vector<int> tmp(nbOfEdgesInFace-1);
-          std::copy(bgFace+1,endFace,tmp.rbegin());
-          std::copy(tmp.begin(),tmp.end(),bgFace+1);
+          endFace=std::find(bgFace+1,end,-1);
+          std::reverse(bgFace+1,endFace);
           bgFace=endFace+1;
         }
     }
@@ -6498,7 +6843,7 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const throw(INTERP_KERNEL::
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodesExpected+1,1);
   int *work=ret->getPointer();  *work++=INTERP_KERNEL::NORM_POLYGON;
   if(nbOfNodesExpected<1)
-    { ret->incrRef(); return ret; }
+    return ret.retn();
   int prevCell=0;
   int prevNode=nodalPtr[nodalIPtr[0]+1];
   *work++=n2oPtr[prevNode];
@@ -6528,7 +6873,7 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const throw(INTERP_KERNEL::
       else
         throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected cell !");
     }
-  ret->incrRef(); return ret;
+  return ret.retn();
 }
 
 /*!
@@ -6548,15 +6893,14 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const throw(INTERP_KERNEL::
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(m->getNodalConnectivity()->getNumberOfTuples(),1);
   int *work=ret->getPointer();  *work++=INTERP_KERNEL::NORM_POLYHED;
   if(nbOfCells<1)
-    { ret->incrRef(); return ret; }
+    return ret.retn();
   work=std::copy(conn+connI[0]+1,conn+connI[1],work);
   for(int i=1;i<nbOfCells;i++)
     {
       *work++=-1;
       work=std::copy(conn+connI[i]+1,conn+connI[i+1],work);
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -6687,8 +7031,8 @@ MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1
   std::vector< std::vector<int> > intersectEdge2;
   BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2);
   subDiv2.clear(); dd5=0; dd6=0;
-  std::vector<int> cr,crI;
-  std::vector<int> cNb1,cNb2;
+  std::vector<int> cr,crI; //no DataArrayInt because interface with Geometric2D
+  std::vector<int> cNb1,cNb2; //no DataArrayInt because interface with Geometric2D
   BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo,
                                     /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2);
   //
@@ -6704,12 +7048,12 @@ MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Intersect2D",2);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn=DataArrayInt::New(); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connI=DataArrayInt::New(); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c1=DataArrayInt::New(); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); cellNb1=c1;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c2=DataArrayInt::New(); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); cellNb2=c2;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c1=DataArrayInt::New(); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c2=DataArrayInt::New(); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer());
   ret->setConnectivity(conn,connI,true);
   ret->setCoords(coo);
-  ret->incrRef(); c1->incrRef(); c2->incrRef();
-  return ret;
+  cellNb1=c1.retn(); cellNb2=c2.retn();
+  return ret.retn();
 }
 
 /// @endcond
@@ -6776,7 +7120,15 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo
         }
       if(!edges1.empty())
         {
-          INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2);
+          try
+            {
+              INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2);
+            }
+          catch(INTERP_KERNEL::Exception& e)
+            {
+              std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what();
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
         }
       for(std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.begin();it!=mappRev.end();it++)
         (*it).second->decrRef();
@@ -6985,7 +7337,7 @@ void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3D
  */
 void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,
                                                   const int *desc, const int *descIndx,
-                                                  std::vector<int>& nodalRes, std::vector<int>& nodalResIndx, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception)
+                                                  DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const throw(INTERP_KERNEL::Exception)
 {
   checkFullyDefined();
   if(getMeshDimension()!=3 || getSpaceDimension()!=3)
@@ -7051,9 +7403,9 @@ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<i
       conn.push_back(end);
       if(conn.size()>3)
         {
-          nodalRes.insert(nodalRes.end(),conn.begin(),conn.end());
-          nodalResIndx.push_back((int)nodalRes.size());
-          cellIds.push_back(i);
+          nodalRes->insertAtTheEnd(conn.begin(),conn.end());
+          nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples());
+          cellIds->pushBackSilent(i);
         }
     }
 }
@@ -7067,7 +7419,7 @@ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<i
  * 
  * @return false if the input connectivity represents already the convex hull, true if the input cell needs to be reordered.
  */
-bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, std::vector<int>& nodalConnecOut) throw(INTERP_KERNEL::Exception)
+bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut) throw(INTERP_KERNEL::Exception)
 {
   std::size_t sz=std::distance(nodalConnBg,nodalConnEnd);
   if(sz>=4)
@@ -7133,18 +7485,18 @@ bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, co
           std::copy(nodalConnBg+1,nodalConnEnd,it);
           if(std::search(tmp3.begin(),tmp3.end(),tmpOut.begin(),tmpOut.end())!=tmp3.end())
             {
-              nodalConnecOut.insert(nodalConnecOut.end(),nodalConnBg,nodalConnEnd);
+              nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd);
               return false;
             }
           if(std::search(tmp3.rbegin(),tmp3.rend(),tmpOut.begin(),tmpOut.end())!=tmp3.rend())
             {
-              nodalConnecOut.insert(nodalConnecOut.end(),nodalConnBg,nodalConnEnd);
+              nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd);
               return false;
             }
           else
             {
-              nodalConnecOut.push_back((int)INTERP_KERNEL::NORM_POLYGON);
-              nodalConnecOut.insert(nodalConnecOut.end(),tmpOut.begin(),tmpOut.end());
+              nodalConnecOut->pushBackSilent((int)INTERP_KERNEL::NORM_POLYGON);
+              nodalConnecOut->insertAtTheEnd(tmpOut.begin(),tmpOut.end());
               return true;
             }
         }
@@ -7178,7 +7530,7 @@ bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, cons
   *arrIPtr++=0;
   int previousArrI=0;
   const int *arrPtr=arr->getConstPointer();
-  std::vector<int> arrOut;
+  std::vector<int> arrOut;//no utility to switch to DataArrayInt because copy always needed
   for(int i=0;i<nbOfGrps;i++,arrIPtr++)
     {
       if(*arrIPtr-previousArrI>offsetForRemoval)
@@ -7261,10 +7613,8 @@ void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  arrOut=arro;
-  arrIndexOut=arrIo;
-  arro->incrRef();
-  arrIo->incrRef();
+  arrOut=arro.retn();
+  arrIndexOut=arrIo.retn();
 }
 
 /*!
@@ -7331,8 +7681,8 @@ void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const in
           *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
         }
     }
-  arrOut=arro; arro->incrRef();
-  arrIndexOut=arrIo; arrIo->incrRef();
+  arrOut=arro.retn();
+  arrIndexOut=arrIo.retn();
 }
 
 /*!
@@ -7389,41 +7739,86 @@ void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, c
  * \param [in] arrIn arr origin array from which the extraction will be done.
  * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
  * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process.
+ * \sa MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed, MEDCouplingUMesh::partitionBySpreadZone
  */
 DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception)
 {
-  if(!arrIn || !arrIndxIn)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !");
+  int seed=0,nbOfDepthPeelingPerformed=0;
+  return ComputeSpreadZoneGraduallyFromSeed(&seed,&seed+1,arrIn,arrIndxIn,-1,nbOfDepthPeelingPerformed);
+}
+
+/*!
+ * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn.
+ * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method.
+ * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]].
+ * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step.
+ * A negative value in \b arrIn means that it is ignored.
+ * This method is usefull to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1.
+ * \param [in] seedBg the begin pointer (included) of an array containing the seed of the search zone
+ * \param [in] seedEnd the end pointer (not included) of an array containing the seed of the search zone
+ * \param [in] arrIn arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [in] nbOfDepthPeeling the max number of peels requested in search. By default -1, that is to say, no limit.
+ * \param [out] nbOfDepthPeelingPerformed the number of peels effectively performed. May be different from \a nbOfDepthPeeling
+ * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process.
+ * \sa MEDCouplingUMesh::partitionBySpreadZone
+ */
+DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception)
+{
+  nbOfDepthPeelingPerformed=0;
+  if(!arrIndxIn)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed : arrIndxIn input pointer is NULL !");
   int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
   if(nbOfTuples<=0)
     {
       DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1);
       return ret;
     }
-  const int *arrInPtr=arrIn->getConstPointer();
-  const int *arrIndxPtr=arrIndxIn->getConstPointer();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
-  arro->alloc(nbOfTuples,1);
-  arro->fillWithValue(-1);
-  int *arroPtr=arro->getPointer();
-  std::set<int> s; s.insert(0);
-  while(!s.empty())
+  //
+  std::vector<bool> fetched(nbOfTuples,false);
+  return ComputeSpreadZoneGraduallyFromSeedAlg(fetched,seedBg,seedEnd,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed);
+}
+
+DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception)
+{
+  nbOfDepthPeelingPerformed=0;
+  if(!seedBg || !seedEnd || !arrIn || !arrIndxIn)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !");
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  std::vector<bool> fetched2(nbOfTuples,false);
+  int i=0;
+  for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++)
     {
-      std::set<int> s2;
-      for(std::set<int>::const_iterator it=s.begin();it!=s.end();it++)
-        {
-          for(const int *work=arrInPtr+arrIndxPtr[*it];work!=arrInPtr+arrIndxPtr[*it+1];work++)
-            {
-              if(*work>=0 && arroPtr[*work]<0)
-                {
-                  arroPtr[*work]=1;
-                  s2.insert(*work);
-                }
-            }
-        }
-      s=s2;
+      if(*seedElt>=0 && *seedElt<nbOfTuples)
+        { fetched[*seedElt]=true; fetched2[*seedElt]=true; }
+      else
+        { std::ostringstream oss; oss << "MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : At pos #" << i << " of seeds value is " << *seedElt << "! Should be in [0," << nbOfTuples << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
     }
-  return arro->getIdsEqual(1);
+  const int *arrInPtr=arrIn->getConstPointer();
+  const int *arrIndxPtr=arrIndxIn->getConstPointer();
+  int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits<int>::max();
+  std::vector<int> idsToFetch1(seedBg,seedEnd);
+  std::vector<int> idsToFetch2;
+  std::vector<int> *idsToFetch=&idsToFetch1;
+  std::vector<int> *idsToFetchOther=&idsToFetch2;
+  while(!idsToFetch->empty() && nbOfDepthPeelingPerformed<targetNbOfDepthPeeling)
+    {
+      for(std::vector<int>::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++)
+        for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++)
+          if(!fetched[*it2])
+            { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); }
+      std::swap(idsToFetch,idsToFetchOther);
+      idsToFetchOther->clear();
+      nbOfDepthPeelingPerformed++;
+    }
+  int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true);
+  i=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(lgth,1);
+  int *retPtr=ret->getPointer();
+  for(std::vector<bool>::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++)
+    if(*it)
+      *retPtr++=i;
+  return ret.retn();
 }
 
 /*!
@@ -7489,8 +7884,8 @@ void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, con
           *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
         }
     }
-  arrOut=arro; arro->incrRef();
-  arrIndexOut=arrIo; arrIo->incrRef();
+  arrOut=arro.retn();
+  arrIndexOut=arrIo.retn();
 }
 
 /*!
@@ -7582,7 +7977,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTER
     }
   //
   ret->finishInsertingCells();
-  ret->incrRef(); return ret;
+  return ret.retn();
 }
 
 /*!
@@ -7592,6 +7987,28 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTER
  */
 std::vector<DataArrayInt *> MEDCouplingUMesh::partitionBySpreadZone() const throw(INTERP_KERNEL::Exception)
 {
+  //#if 0
+  int nbOfCellsCur=getNumberOfCells();
+  std::vector<DataArrayInt *> ret;
+  if(nbOfCellsCur<=0)
+    return ret;
+  DataArrayInt *neigh=0,*neighI=0;
+  computeNeighborsOfCells(neigh,neighI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighAuto(neigh),neighIAuto(neighI);
+  std::vector<bool> fetchedCells(nbOfCellsCur,false);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret2;
+  int seed=0;
+  while(seed<nbOfCellsCur)
+    {
+      int nbOfPeelPerformed=0;
+      ret2.push_back(ComputeSpreadZoneGraduallyFromSeedAlg(fetchedCells,&seed,&seed+1,neigh,neighI,-1,nbOfPeelPerformed));
+      seed=(int)std::distance(fetchedCells.begin(),std::find(fetchedCells.begin()+seed,fetchedCells.end(),false));
+    }
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::iterator it=ret2.begin();it!=ret2.end();it++)
+    ret.push_back((*it).retn());
+  return ret;
+  //#endif
+#if 0
   int nbOfCellsCur=getNumberOfCells();
   DataArrayInt *neigh=0,*neighI=0;
   computeNeighborsOfCells(neigh,neighI);
@@ -7619,6 +8036,7 @@ std::vector<DataArrayInt *> MEDCouplingUMesh::partitionBySpreadZone() const thro
   for(std::vector<DataArrayInt *>::const_iterator it=ret.begin();it!=ret.end();it++)
     (*it)->incrRef();
   return ret;
+#endif
 }
 
 /*!
@@ -7642,8 +8060,7 @@ DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vec
       retPtr[0]=code[3*i+2];
       retPtr[1]=code[3*i+2]+code[3*i+1];
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),
index 7da64ee503f7b51ffcd1abf92bad0c82a2bfcbc4..c97142d8cd8e5ca4e17179f0e01cecd208aee177 100644 (file)
@@ -42,6 +42,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *clone(bool recDeepCpy) const;
     MEDCOUPLING_EXPORT void updateTime() const;
+    MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const;
     MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED; }
     MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const;
@@ -91,11 +92,12 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT std::string getVTKDataSetType() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception);
     //tools
-    MEDCOUPLING_EXPORT int areCellsEqual(int cell1, int cell2, int compType) const;
-    MEDCOUPLING_EXPORT int areCellsEqual0(int cell1, int cell2) const;
-    MEDCOUPLING_EXPORT int areCellsEqual1(int cell1, int cell2) const;
-    MEDCOUPLING_EXPORT int areCellsEqual2(int cell1, int cell2) const;
-    MEDCOUPLING_EXPORT int areCellsEqual7(int cell1, int cell2) const;
+    MEDCOUPLING_EXPORT static int AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType);
+    MEDCOUPLING_EXPORT static int AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2);
+    MEDCOUPLING_EXPORT static int AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2);
+    MEDCOUPLING_EXPORT static int AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2);
+    MEDCOUPLING_EXPORT static int AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2);
+    MEDCOUPLING_EXPORT static int AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2);
     MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const;
     MEDCOUPLING_EXPORT void convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd);
     MEDCOUPLING_EXPORT void convertAllToPoly();
@@ -106,9 +108,11 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionBySpreadZone() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception);
@@ -142,8 +146,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT void getCellsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) const;
-    MEDCOUPLING_EXPORT void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems);
+    MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const;
+    MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps);
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
     MEDCOUPLING_EXPORT DataArrayDouble *getPartMeasureField(bool isAbs, const int *begin, const int *end) const;
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
@@ -155,12 +159,14 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool isContiguous1D() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void project1D(const double *pt, const double *v, double eps, double *res) const;
+    MEDCOUPLING_EXPORT double distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId, int& nodeId) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const;
     MEDCOUPLING_EXPORT void getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const;
     MEDCOUPLING_EXPORT void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const;
     MEDCOUPLING_EXPORT void checkButterflyCells(std::vector<int>& cells, double eps=1e-12) const;
     MEDCOUPLING_EXPORT DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT void findAndCorrectBadOriented3DExtrudedCells(std::vector<int>& cells) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getBoundingBoxForBBTree(std::vector<double>& bbox) const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy);
     MEDCOUPLING_EXPORT bool isFullyQuadratic() const;
@@ -188,6 +194,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT MEDCouplingUMesh *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const;
+    MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const;
     MEDCOUPLING_EXPORT DataArrayInt *getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const throw(INTERP_KERNEL::Exception);
@@ -214,11 +221,15 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static void MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords);
     MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords);
-    MEDCOUPLING_EXPORT static void SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, std::vector<int>& res) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static bool Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords);
+    MEDCOUPLING_EXPORT static void CorrectExtrudedStaticCell(int *begin, int *end);
+    MEDCOUPLING_EXPORT static bool IsTetra4WellOriented(const int *begin, const int *end, const double *coords);
+    MEDCOUPLING_EXPORT static bool IsPyra5WellOriented(const int *begin, const int *end, const double *coords);
+    MEDCOUPLING_EXPORT static void SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static void ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, std::vector<int>& nodalConnecOut) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static bool RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
                                                             DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception);
@@ -233,6 +244,9 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
                                                                   const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static void FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI,
+                                                      DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) throw(INTERP_KERNEL::Exception);
   private:
     MEDCouplingUMesh();
     MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy);
@@ -243,17 +257,17 @@ namespace ParaMEDMEM
     //tools
     DataArrayInt *simplexizePol0() throw(INTERP_KERNEL::Exception);
     DataArrayInt *simplexizePol1() throw(INTERP_KERNEL::Exception);
+    DataArrayInt *simplexizePlanarFace5() throw(INTERP_KERNEL::Exception);
+    DataArrayInt *simplexizePlanarFace6() throw(INTERP_KERNEL::Exception);
     void subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex) throw(INTERP_KERNEL::Exception);
-    void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector<int>& cellIdsKept) const;
+    void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const;
     void split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve) throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const;
     DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const;
     DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception);
-    template<int SPACEDIM>
-    void findCommonCellsBase(int compType, std::vector<int>& res, std::vector<int>& resI) const;
-    bool areCellsEqualInPool(const std::vector<int>& candidates, int compType, std::vector<int>& result) const;
+    static bool AreCellsEqualInPool(const std::vector<int>& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ;
     MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const;
     MEDCouplingUMesh *buildPartOfMySelfKeepCoords2(int start, int end, int step) const;
     template<int SPACEDIM>
@@ -265,6 +279,9 @@ namespace ParaMEDMEM
     MEDCouplingUMesh *buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildUnionOf2DMesh() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception);
+    void distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const throw(INTERP_KERNEL::Exception);
+    void distanceToPoint2DCurveAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const throw(INTERP_KERNEL::Exception);
+    static DataArrayInt *ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception);
     static void FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception);
     static void AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret);
     static void IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
@@ -281,21 +298,17 @@ namespace ParaMEDMEM
                                               const int *nodal3DCurve, const int *nodalIndx3DCurve,
                                               const int *desc, const int *descIndx, std::vector< std::pair<int,int> >& cut3DSurf) throw(INTERP_KERNEL::Exception);
     void assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,
-                                    const int *desc, const int *descIndx, std::vector<int>& nodalRes, std::vector<int>& nodalResIndx, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
+                                    const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const throw(INTERP_KERNEL::Exception);
   public:
     MEDCOUPLING_EXPORT static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector<int>& code) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static const int N_MEDMEM_ORDER=24;
     MEDCOUPLING_EXPORT static const INTERP_KERNEL::NormalizedCellType MEDMEM_ORDER[N_MEDMEM_ORDER];
     /// @endcond
   private:
-    //! this iterator stores current position in _nodal_connec array.
-    mutable int _iterator;
     int _mesh_dim;
     DataArrayInt *_nodal_connec;
     DataArrayInt *_nodal_connec_index;
     std::set<INTERP_KERNEL::NormalizedCellType> _types;
-  private:
-    static const char PART_OF_NAME[];
   public:
     static double EPS_FOR_POLYH_ORIENTATION;
   };
index 22905de8578ee2ed3692a5687c15430a9fe2cdaf..998a2a0434b766f80cac2332a772f58dc9c1c41c 100644 (file)
@@ -21,6 +21,7 @@
 #include "MEDCouplingUMeshDesc.hxx"
 #include "CellModel.hxx"
 #include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
 #include <limits>
 #include <sstream>
@@ -57,6 +58,21 @@ MEDCouplingUMeshDesc *MEDCouplingUMeshDesc::New(const char *meshName, int meshDi
   return ret;
 }
 
+std::size_t MEDCouplingUMeshDesc::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if(_desc_connec)
+    ret+=_desc_connec->getHeapMemorySize();
+  if(_desc_connec_index)
+    ret+=_desc_connec_index->getHeapMemorySize();
+  if(_nodal_connec_face)
+    ret+=_nodal_connec_face->getHeapMemorySize();
+  if(_nodal_connec_face_index)
+    ret+=_nodal_connec_face_index->getHeapMemorySize();
+  return MEDCouplingPointSet::getHeapMemorySize()+ret;
+}
+
+
 MEDCouplingMesh *MEDCouplingUMeshDesc::deepCpy() const
 {
   throw INTERP_KERNEL::Exception("Not implemented yet !");
@@ -266,8 +282,9 @@ void MEDCouplingUMeshDesc::unserialization(const std::vector<double>& tinyInfoD,
   setMeshDimension(tinyInfo[2]);
 }
 
-void MEDCouplingUMeshDesc::getCellsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) const
+DataArrayInt *MEDCouplingUMeshDesc::getCellsInBoundingBox(const double *bbox, double eps) const
 {
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1);
   int dim=getSpaceDimension();
   double* elem_bb=new double[2*dim];
   const int* conn      = _desc_connec->getConstPointer();
@@ -303,16 +320,16 @@ void MEDCouplingUMeshDesc::getCellsInBoundingBox(const double *bbox, double eps,
                 }
             }
         }
-      if (intersectsBoundingBox(elem_bb, bbox, dim, eps))
-        {
-          elems.push_back(ielem);
-        }
+      if(intersectsBoundingBox(elem_bb, bbox, dim, eps))
+        elems->pushBackSilent(ielem);
     }
   delete [] elem_bb;
+  return elems.retn();
 }
 
-void MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector<int>& elems)
+DataArrayInt *MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps)
 {
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1);
   int dim=getSpaceDimension();
   double* elem_bb=new double[2*dim];
   const int* conn      = _desc_connec->getConstPointer();
@@ -349,11 +366,10 @@ void MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBo
             }
         }
       if (intersectsBoundingBox(bbox, elem_bb, dim, eps))
-        {
-          elems.push_back(ielem);
-        }
+        elems->pushBackSilent(ielem);
     }
   delete [] elem_bb;
+  return elems.retn();
 }
 
 DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
index 37e27e1f37da5f36730f0f107bb2b462a41e2016..18d3eb74a0e0d116916117cc5044a75be5c5f2b8 100644 (file)
@@ -34,6 +34,7 @@ namespace ParaMEDMEM
   public:
     MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New();
     MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(const char *meshName, int meshDim);
+    MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const;
     MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const;
     MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception);
@@ -65,8 +66,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const;
     MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const;
     MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings);
-    MEDCOUPLING_EXPORT void getCellsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) const;
-    MEDCOUPLING_EXPORT void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector<int>& elems);
+    MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const;
+    MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps);
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
index 2434ecf7d40ae46d7fb180aa89dd33dcab484752..4202fab88a46cc37624c1c76d7ed3afef9aba5f7 100644 (file)
@@ -39,7 +39,7 @@ MEDCouplingUMeshDesc.hxx MEDCouplingNatureOfField.hxx MEDCouplingFieldTemplate.h
 MEDCouplingNormalizedCartesianMesh.hxx MEDCouplingNormalizedCartesianMesh.txx                     \
 MEDCouplingRemapper.hxx MEDCouplingExtrudedMesh.hxx MEDCouplingGaussLocalization.hxx              \
 MEDCouplingAutoRefCountObjectPtr.hxx MEDCouplingMultiFields.hxx MEDCouplingDefinitionTime.hxx     \
-MEDCouplingFieldOverTime.hxx
+MEDCouplingFieldOverTime.hxx MEDCouplingCurveLinearMesh.hxx MEDCouplingStructuredMesh.hxx
 
 # Libraries targets
 
@@ -51,7 +51,8 @@ dist_libmedcoupling_la_SOURCES = \
        MEDCouplingPointSet.cxx MEDCouplingUMeshDesc.cxx  MEDCouplingFieldTemplate.cxx      \
        MEDCouplingExtrudedMesh.cxx MEDCouplingMesh.cxx MEDCouplingGaussLocalization.cxx    \
        MEDCouplingNatureOfField.cxx MEDCouplingMultiFields.cxx                             \
-       MEDCouplingDefinitionTime.cxx MEDCouplingFieldOverTime.cxx
+       MEDCouplingDefinitionTime.cxx MEDCouplingFieldOverTime.cxx                          \
+       MEDCouplingCurveLinearMesh.cxx MEDCouplingStructuredMesh.cxx
 
 libmedcoupling_la_LDFLAGS= 
 
index 9a55bea575f206a4bffc91bbebd2cf45ac1999ea..c26bbe173aa7e941c874904d7a1cc147e26378f6 100644 (file)
@@ -581,7 +581,7 @@ void MEDCouplingBasicsTest1::testBuildPartOfMySelf()
   CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(mesh->getAllTypes().begin())));
   CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllTypes().size());
   CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllTypes().begin());
-  CPPUNIT_ASSERT(name=="PartOf_Toto");
+  CPPUNIT_ASSERT(name=="Toto");
   CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords());
   CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells());
   const int subConn[10]={4,0,3,4,1,4,7,8,5,4};
@@ -599,7 +599,7 @@ void MEDCouplingBasicsTest1::testBuildPartOfMySelf()
   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(name=="PartOf_Toto");
+  CPPUNIT_ASSERT(name=="Toto");
   CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords());
   CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells());
   const int subConn2[14]={4,0,3,4,1,3,4,5,2,4,6,7,4,3};
@@ -612,7 +612,7 @@ void MEDCouplingBasicsTest1::testBuildPartOfMySelf()
   MEDCouplingPointSet *subMeshSimple2=subMeshSimple->buildPartOfMySelf(tab3,tab3+3,true);
   subMesh->decrRef();
   name=subMeshSimple2->getName();
-  CPPUNIT_ASSERT(name=="PartOf_Toto");
+  CPPUNIT_ASSERT(name=="Toto");
   subMeshSimple2->decrRef();
   //
   mesh->decrRef();
@@ -1364,7 +1364,7 @@ void MEDCouplingBasicsTest1::testMergeField1()
   std::string name=f3->getName();
   CPPUNIT_ASSERT(name=="MeasureOfMesh_");
   CPPUNIT_ASSERT(f3->getTypeOfField()==ON_CELLS);
-  CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(7,f3->getNumberOfTuples());
   double values[7]={0.25,0.125,0.125,0.25,0.25,0.5,0.5};
@@ -1410,10 +1410,15 @@ bool func3(const double *pt, double *res)
 void MEDCouplingBasicsTest1::testFillFromAnalytic()
 {
   MEDCouplingUMesh *m=build2DTargetMesh_1();
+  m->setTime(3.4,5,6); m->setTimeUnit("us");
+  int a,b;
   MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,func1);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14);
+  CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b);
+  CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us"));
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
   double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9};
@@ -1427,7 +1432,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic()
   f1=m->fillFromAnalytic(ON_NODES,1,func1);
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   double values2[9]={-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4};
@@ -1441,7 +1446,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic()
   f1=m->fillFromAnalytic(ON_NODES,2,func2);
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8};
@@ -1470,7 +1475,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2()
   MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,"y+x");
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
   double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9};
@@ -1484,7 +1489,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2()
   f1=m->fillFromAnalytic(ON_NODES,1,"y+2*x");
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1};
@@ -1497,7 +1502,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2()
   f1=m->fillFromAnalytic(ON_NODES,1,"2.*x+y");
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   tmp=f1->getArray()->getConstPointer();
@@ -1511,7 +1516,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2()
   f1=m->fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec");
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8};
@@ -1540,12 +1545,12 @@ void MEDCouplingBasicsTest1::testApplyFunc()
   MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2);
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   f1->applyFunc(1,func1);
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2};
@@ -1564,7 +1569,7 @@ void MEDCouplingBasicsTest1::testApplyFunc2()
   MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2);
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   //
@@ -1574,7 +1579,7 @@ void MEDCouplingBasicsTest1::testApplyFunc2()
   CPPUNIT_ASSERT_THROW(f2->applyFunc("a/0"),INTERP_KERNEL::Exception);
   f2->applyFunc("abs(u)^2.4+2*u");
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   double values2[18]={-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987,
@@ -1591,7 +1596,7 @@ void MEDCouplingBasicsTest1::testApplyFunc2()
   //
   f1->applyFunc(1,"x+y");
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2};
@@ -1614,7 +1619,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields()
   MEDCouplingFieldDouble *f3=(*f1)+(*f2);
   f3->checkCoherency();
   CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME);
   double values1[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8};
   const double *tmp=f3->getArray()->getConstPointer();
   std::transform(tmp,tmp+9,values1,values1,std::minus<double>());
@@ -1626,7 +1631,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields()
   f3=(*f1)*(*f2);
   f3->checkCoherency();
   CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME);
   double values2[9]={0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96};
   tmp=f3->getArray()->getConstPointer();
   std::transform(tmp,tmp+9,values2,values2,std::minus<double>());
@@ -1639,7 +1644,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields()
   MEDCouplingFieldDouble *f4=(*f1)-(*f3);
   f4->checkCoherency();
   CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME);
   double values3[9]={0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4};
   tmp=f4->getArray()->getConstPointer();
   std::transform(tmp,tmp+9,values3,values3,std::minus<double>());
@@ -1653,23 +1658,23 @@ void MEDCouplingBasicsTest1::testOperationsOnFields()
   f4=(*f3)/(*f2);
   f4->checkCoherency();
   CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME);
   tmp=f4->getArray()->getConstPointer();
   for(int i=0;i<9;i++)
     CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,tmp[i],1.e-12);
   f3->decrRef();
   f4->decrRef();
   //
-  f4=f2->buildNewTimeReprFromThis(ONE_TIME,false);
+  f4=f2->buildNewTimeReprFromThis(NO_TIME,false);
   f4->checkCoherency();
   CPPUNIT_ASSERT(f4->getArray()==f2->getArray());
   CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME);
+  CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME);
   CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception);
-  MEDCouplingFieldDouble *f5=f4->buildNewTimeReprFromThis(NO_TIME,false);
+  MEDCouplingFieldDouble *f5=f4->buildNewTimeReprFromThis(ONE_TIME,false);
   CPPUNIT_ASSERT(f4->getArray()==f5->getArray());
   CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f5->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME);
   f3=(*f1)+(*f5);
   tmp=f3->getArray()->getConstPointer();
   double values4[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8};
@@ -1681,17 +1686,17 @@ void MEDCouplingBasicsTest1::testOperationsOnFields()
   f4->decrRef();
   f3->decrRef();
   //
-  f4=f2->buildNewTimeReprFromThis(ONE_TIME,true);
+  f4=f2->buildNewTimeReprFromThis(NO_TIME,true);
   f4->checkCoherency();
   CPPUNIT_ASSERT(f4->getArray()!=f2->getArray());
   CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME);
+  CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME);
   CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception);
-  f5=f4->buildNewTimeReprFromThis(NO_TIME,true);
+  f5=f4->buildNewTimeReprFromThis(ONE_TIME,true);
   CPPUNIT_ASSERT(f4->getArray()!=f5->getArray());
   CPPUNIT_ASSERT(f2->getArray()!=f5->getArray());
   CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f5->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME);
   f3=(*f1)+(*f5);
   tmp=f3->getArray()->getConstPointer();
   double values5[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8};
@@ -1711,12 +1716,14 @@ void MEDCouplingBasicsTest1::testOperationsOnFields()
 void MEDCouplingBasicsTest1::testOperationsOnFields2()
 {
   MEDCouplingUMesh *m=build3DSurfTargetMesh_1();
+  m->setTime(3.4,5,6); m->setTimeUnit("us");
+  int a,b;
   MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z");
   MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c");
   MEDCouplingFieldDouble *f3=(*f1)/(*f2);
   f3->checkCoherency();
   CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME);
   const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391,
                              0.7407407407407407, 1.129032258064516, 0.81632653061224492,
                              0.86538461538461531, 1.0919540229885056, 0.84302325581395343};
@@ -1730,6 +1737,9 @@ void MEDCouplingBasicsTest1::testOperationsOnFields2()
   f2->decrRef();
   //
   f1=m->buildOrthogonalField();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14);
+  CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b);
+  CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us"));
   f2=m->fillFromAnalytic(ON_CELLS,1,"x");
   f3=(*f1)*(*f2);
   const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637};
@@ -1758,7 +1768,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields3()
   (*f1)/=(*f2);
   f1->checkCoherency();
   CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
-  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME);
   const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391,
                              0.7407407407407407, 1.129032258064516, 0.81632653061224492,
                              0.86538461538461531, 1.0919540229885056, 0.84302325581395343};
index f6953bbd88142de3ece2c114ba2e2fcfc4ef7fdc..cfc4f7ec61126a448e061839bcff7aee2bfbf14c 100644 (file)
@@ -1989,7 +1989,12 @@ void MEDCouplingBasicsTest2::testGetNodeIdsOfCell1()
 void MEDCouplingBasicsTest2::testGetEdgeRatioField1()
 {
   MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  m1->setTime(3.4,5,6); m1->setTimeUnit("us");
+  int a,b;
   MEDCouplingFieldDouble *f1=m1->getEdgeRatioField();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14);
+  CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b);
+  CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us"));
   CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples());
   CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
index fcc86c4ac9454d9d38e51e45dbc937648c46651b..230547686bb0e39cdb12e928ff563ad09aeb1cc8 100644 (file)
@@ -1256,24 +1256,26 @@ void MEDCouplingBasicsTest3::testGetNodeIdsNearPoints1()
   mesh->setCoords(tmp2);
   tmp2->decrRef();
   const double pts[6]={0.2,0.2,0.1,0.3,-0.3,0.7};
-  std::vector<int> c=mesh->getNodeIdsNearPoint(pts,1e-7);
-  CPPUNIT_ASSERT_EQUAL(3,(int)c.size());
-  CPPUNIT_ASSERT_EQUAL(4,c[0]);
-  CPPUNIT_ASSERT_EQUAL(9,c[1]);
-  CPPUNIT_ASSERT_EQUAL(11,c[2]);
-  c.clear();
-  std::vector<int> cI;
+  DataArrayInt *c=mesh->getNodeIdsNearPoint(pts,1e-7);
+  CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0));
+  CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0));
+  CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0));
+  c->decrRef();
+  DataArrayInt *cI=0;
   mesh->getNodeIdsNearPoints(pts,3,1e-7,c,cI);
-  CPPUNIT_ASSERT_EQUAL(4,(int)cI.size());
-  CPPUNIT_ASSERT_EQUAL(4,(int)c.size());
-  CPPUNIT_ASSERT_EQUAL(4,c[0]);
-  CPPUNIT_ASSERT_EQUAL(9,c[1]);
-  CPPUNIT_ASSERT_EQUAL(11,c[2]);
-  CPPUNIT_ASSERT_EQUAL(6,c[3]);
-  CPPUNIT_ASSERT_EQUAL(0,cI[0]);
-  CPPUNIT_ASSERT_EQUAL(3,cI[1]);
-  CPPUNIT_ASSERT_EQUAL(3,cI[2]);
-  CPPUNIT_ASSERT_EQUAL(4,cI[3]);
+  CPPUNIT_ASSERT_EQUAL(4,cI->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(4,c->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0));
+  CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0));
+  CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0));
+  CPPUNIT_ASSERT_EQUAL(6,c->getIJ(3,0));
+  CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0));
+  CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(1,0));
+  CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(2,0));
+  CPPUNIT_ASSERT_EQUAL(4,cI->getIJ(3,0));
+  c->decrRef();
+  cI->decrRef();
   mesh->decrRef();
 }
 
index e422be808d08be5c64c369a321945463744942be..a802556adf204351d9a98e5af5a4a0c64b17e48b 100644 (file)
@@ -398,11 +398,16 @@ void MEDCouplingBasicsTest4::testApplyFuncThree1()
 void MEDCouplingBasicsTest4::testFillFromAnalyticTwo1()
 {
   MEDCouplingUMesh *m1=build3DSurfTargetMesh_1();
+  m1->setTime(3.4,5,6); m1->setTimeUnit("us");
+  int a,b;
   CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic2(ON_NODES,1,"y+z"),INTERP_KERNEL::Exception);
   m1->getCoords()->setInfoOnComponent(0,"x [m]");
   m1->getCoords()->setInfoOnComponent(1,"y");
   m1->getCoords()->setInfoOnComponent(2,"z");
   MEDCouplingFieldDouble *f1=m1->fillFromAnalytic2(ON_NODES,1,"y+z");
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14);
+  CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b);
+  CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us"));
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2};
@@ -415,11 +420,16 @@ void MEDCouplingBasicsTest4::testFillFromAnalyticTwo1()
 void MEDCouplingBasicsTest4::testFillFromAnalyticThree1()
 {
   MEDCouplingUMesh *m1=build3DSurfTargetMesh_1();
+  m1->setTime(3.4,5,6); m1->setTimeUnit("us");
+  int a,b;
   std::vector<std::string> vs(3);
   vs[0]="x"; vs[1]="Y"; vs[2]="z";
   CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"),INTERP_KERNEL::Exception);
   vs[1]="y";
   MEDCouplingFieldDouble *f1=m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z");
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14);
+  CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b);
+  CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us"));
   CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
   const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2};
@@ -1589,11 +1599,11 @@ void MEDCouplingBasicsTest4::testFindAndCorrectBadOriented3DExtrudedCells1()
   m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+48);
   m->finishInsertingCells();
   //
-  std::vector<int> v;
-  m->findAndCorrectBadOriented3DExtrudedCells(v);
-  CPPUNIT_ASSERT_EQUAL(4,(int)v.size());
-  CPPUNIT_ASSERT(std::equal(v.begin(),v.end(),invalidCells));
+  DataArrayInt *v=m->findAndCorrectBadOriented3DExtrudedCells();
+  CPPUNIT_ASSERT_EQUAL(4,v->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(v->begin(),v->end(),invalidCells));
   CPPUNIT_ASSERT(std::equal(connExp,connExp+64,m->getNodalConnectivity()->getConstPointer()));
+  v->decrRef();
   //
   m->decrRef();
 }
@@ -1650,9 +1660,9 @@ void MEDCouplingBasicsTest4::testNonRegressionCopyTinyStrings()
   MEDCouplingFieldDouble *f1=m->getMeasureField(true);
   f1->getArray()->setInfoOnComponent(0,"P [N/m^2]");
   DataArrayDouble *bary=m->getBarycenterAndOwner();
-  MEDCouplingFieldDouble *f2=f1->buildNewTimeReprFromThis(ONE_TIME,false);
+  MEDCouplingFieldDouble *f2=f1->buildNewTimeReprFromThis(NO_TIME,false);
   f2->setArray(bary);
-  CPPUNIT_ASSERT_THROW(f2->copyTinyAttrFrom(f1),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(f1->copyTinyAttrFrom(f2),INTERP_KERNEL::Exception);
   m->decrRef();
   f1->decrRef();
   bary->decrRef();
@@ -1892,12 +1902,13 @@ void MEDCouplingBasicsTest4::testDAIBuildOld2NewArrayFromSurjectiveFormat2()
   b->alloc(3,1);
   std::copy(arrI,arrI+3,b->getPointer());
   int newNbTuple=-1;
-  DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a,b,newNbTuple);
+  DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a->begin(),b->begin(),b->end(),newNbTuple);
   const int expected[10]={0,1,2,0,3,4,5,4,6,4};
   CPPUNIT_ASSERT_EQUAL(10,ret->getNbOfElems());
   CPPUNIT_ASSERT_EQUAL(7,newNbTuple);
   CPPUNIT_ASSERT_EQUAL(1,ret->getNumberOfComponents());
   CPPUNIT_ASSERT(std::equal(expected,expected+10,ret->getConstPointer()));
+  CPPUNIT_ASSERT_THROW(DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(9,a->begin(),b->begin(),b->end(),newNbTuple),INTERP_KERNEL::Exception);
   ret->decrRef();
   b->decrRef();
   a->decrRef();
index 9e98601c0517d764fb9302a2bf320da2e21a252c..7b1c4392d1c7b3193e479338a7478943506528ce 100644 (file)
@@ -1672,3 +1672,306 @@ void MEDCouplingBasicsTest5::testDAIPartitionByDifferentValues1()
   CPPUNIT_ASSERT(std::equal(expected2_3,expected2_3+4,e[3]->begin()));
   e[0]->decrRef(); e[1]->decrRef(); e[2]->decrRef(); e[3]->decrRef();
 }
+
+void MEDCouplingBasicsTest5::testDAICheckMonotonic1()
+{
+  const int data1[6]={-1,0,2,2,4,5};
+  const int data2[6]={6,2,0,-8,-9,-56};
+  const int data3[6]={-1,0,3,2,4,6};
+  const int data4[6]={7,5,2,3,0,-6};
+  DataArrayInt *d=DataArrayInt::New();
+  d->useArray(data1,false,CPP_DEALLOC,6,1);
+  CPPUNIT_ASSERT(d->isMonotonic(true));
+  CPPUNIT_ASSERT(!d->isMonotonic(false));
+  d->checkMonotonic(true);
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception);
+  d->useArray(data2,false,CPP_DEALLOC,6,1);
+  CPPUNIT_ASSERT(d->isMonotonic(false));
+  CPPUNIT_ASSERT(!d->isMonotonic(true));
+  d->checkMonotonic(false);
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception);
+  d->useArray(data3,false,CPP_DEALLOC,6,1);
+  CPPUNIT_ASSERT(!d->isMonotonic(false));
+  CPPUNIT_ASSERT(!d->isMonotonic(true));
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception);
+  d->useArray(data4,false,CPP_DEALLOC,6,1);
+  CPPUNIT_ASSERT(!d->isMonotonic(false));
+  CPPUNIT_ASSERT(!d->isMonotonic(true));
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception);
+  d->useArray(data4,false,CPP_DEALLOC,0,1);
+  CPPUNIT_ASSERT(d->isMonotonic(true));
+  CPPUNIT_ASSERT(d->isMonotonic(false));
+  d->checkMonotonic(true);
+  d->checkMonotonic(false);
+  d->useArray(data4,false,CPP_DEALLOC,3,2);//throw because nbComp!=1
+  CPPUNIT_ASSERT_THROW(d->isMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(d->isMonotonic(false),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception);
+  d->decrRef();
+}
+
+void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp6()
+{
+  // coordinates
+  DataArrayDouble *coords=DataArrayDouble::New();
+  const double coordsData[16]={2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15};
+  coords->useArray(coordsData,false,CPP_DEALLOC,8,2);
+  // connectivity
+  DataArrayInt *conn=DataArrayInt::New();
+  const int connData[9]={8,0,3,5,1,4,6,7,2};
+  conn->useArray(connData,false,CPP_DEALLOC,9,1);
+  DataArrayInt *connI=DataArrayInt::New();
+  const int connIData[2]={0,9};
+  connI->useArray(connIData,false,CPP_DEALLOC,2,1);
+  MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fixe",2);
+  m1->setCoords(coords);
+  m1->setConnectivity(conn,connI,true);
+  coords->decrRef(); conn->decrRef(); connI->decrRef();
+  //
+  coords=DataArrayDouble::New();
+  const double coordsData2[26]={-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839};
+  coords->useArray(coordsData2,false,CPP_DEALLOC,13,2);
+  // connectivity
+  conn=DataArrayInt::New();
+  const int connData2[18]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12};
+  conn->useArray(connData2,false,CPP_DEALLOC,18,1);
+  connI=DataArrayInt::New();
+  const int connIData2[3]={0,9,18};
+  connI->useArray(connIData2,false,CPP_DEALLOC,3,1);
+  //
+  MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2);
+  m2->setCoords(coords);
+  m2->setConnectivity(conn,connI,true);
+  coords->decrRef(); conn->decrRef(); connI->decrRef();
+  //
+  DataArrayInt *d1=0,*d2=0;
+  MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2);
+  CPPUNIT_ASSERT_EQUAL(4,m3->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(4,d1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(43,m3->getNumberOfNodes());
+  bool areMerged=false;
+  int newNbOfNodes=-1;
+  m3->mergeNodes(1e-12,areMerged,newNbOfNodes)->decrRef();
+  CPPUNIT_ASSERT_EQUAL(35,m3->getNumberOfNodes());
+  m3->zipCoords();
+  CPPUNIT_ASSERT_EQUAL(23,m3->getNumberOfNodes());
+  //
+  MEDCouplingFieldDouble *f=m3->getMeasureField(true);
+  const double *vals=f->getArray()->getConstPointer();
+  const double valuesExpected[4]={1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694};
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i],vals[i],1e-12);
+  f->decrRef();
+  //
+  m1->decrRef();
+  m2->decrRef();
+  m3->decrRef();
+  d1->decrRef();
+  d2->decrRef();
+}
+
+void MEDCouplingBasicsTest5::testDAIBuildSubstractionOptimized1()
+{
+  const int tab1[7]={1,3,5,6,7,9,13};
+  const int tab2[3]={3,5,9};
+  const int tab3[3]={1,3,5};
+  DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1);
+  DataArrayInt *da2=DataArrayInt::New(); da2->useArray(tab2,false,CPP_DEALLOC,3,1);
+  DataArrayInt *da3=DataArrayInt::New(); da3->useArray(tab3,false,CPP_DEALLOC,3,1);
+  DataArrayInt *da4=DataArrayInt::New(); da4->useArray(tab1,false,CPP_DEALLOC,7,1);
+  //
+  DataArrayInt *a=0;
+  a=da1->buildSubstractionOptimized(da2);
+  CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents());
+  const int expected1_0[4]={1,6,7,13};
+  CPPUNIT_ASSERT(std::equal(expected1_0,expected1_0+4,a->begin()));
+  a->decrRef();
+  //
+  a=da1->buildSubstractionOptimized(da3);
+  CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents());
+  const int expected2_0[4]={6,7,9,13};
+  CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+4,a->begin()));
+  a->decrRef();
+  //
+  a=da1->buildSubstractionOptimized(da4);
+  CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents());
+  a->decrRef();
+  //
+  da1->decrRef();
+  da2->decrRef();
+  da3->decrRef();
+  da4->decrRef();
+}
+
+void MEDCouplingBasicsTest5::testDAIIsStrictlyMonotonic1()
+{
+  const int tab1[7]={1,3,5,6,7,9,13};
+  DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1);
+  CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true));
+  da1->checkStrictlyMonotonic(true);
+  CPPUNIT_ASSERT(da1->isMonotonic(true));
+  da1->checkMonotonic(true);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception);
+  da1->decrRef();
+  //
+  int tab2[7]={1,3,5,6,6,9,13};
+  da1=DataArrayInt::New(); da1->useArray(tab2,false,CPP_DEALLOC,7,1);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(da1->isMonotonic(true));
+  da1->checkMonotonic(true);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception);
+  da1->decrRef();
+  //
+  const int tab3[7]={1,3,5,6,5,9,13};
+  da1=DataArrayInt::New(); da1->useArray(tab3,false,CPP_DEALLOC,7,1);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception);
+  da1->decrRef();
+  //
+  const int tab4[7]={13,9,7,6,5,3,1};
+  da1=DataArrayInt::New(); da1->useArray(tab4,false,CPP_DEALLOC,7,1);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false));
+  da1->checkStrictlyMonotonic(false);
+  CPPUNIT_ASSERT(da1->isMonotonic(false));
+  da1->checkMonotonic(false);
+  da1->decrRef();
+  //
+  const int tab5[7]={13,9,6,6,5,3,1};
+  da1=DataArrayInt::New(); da1->useArray(tab5,false,CPP_DEALLOC,7,1);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(da1->isMonotonic(false));
+  da1->checkMonotonic(false);
+  da1->decrRef();
+  //
+  const int tab6[7]={13,9,5,6,5,3,1};
+  da1=DataArrayInt::New(); da1->useArray(tab6,false,CPP_DEALLOC,7,1);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(true));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT(!da1->isMonotonic(false));
+  CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception);
+  da1->decrRef();
+  //
+  da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,0,1);
+  CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true));
+  da1->checkStrictlyMonotonic(true);
+  CPPUNIT_ASSERT(da1->isMonotonic(true));
+  da1->checkMonotonic(true);
+  CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false));
+  da1->checkStrictlyMonotonic(false);
+  CPPUNIT_ASSERT(da1->isMonotonic(false));
+  da1->checkMonotonic(false);
+  da1->decrRef();
+  //
+  da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,1,1);
+  CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true));
+  da1->checkStrictlyMonotonic(true);
+  CPPUNIT_ASSERT(da1->isMonotonic(true));
+  da1->checkMonotonic(true);
+  CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false));
+  da1->checkStrictlyMonotonic(false);
+  CPPUNIT_ASSERT(da1->isMonotonic(false));
+  da1->checkMonotonic(false);
+  da1->decrRef();
+}
+
+void MEDCouplingBasicsTest5::testSimplexize3()
+{
+  const int conn[24]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
+  MEDCouplingUMesh *m=MEDCouplingUMesh::New("toto",3);
+  m->allocateCells(0);
+  m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+0);
+  m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4);
+  m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+12);
+  m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+20);
+  const double coords[72]={0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.,2.,0.,0.,2.,1.,0.,3.,1.,0.,3.,0.,0.,2.,0.,1.,2.,1.,1.,3.,1.,1.,3.,0.,1.,4.,0.,0.,4.,1.,0.,5.,1.,0.,5.,0.,0.,4.,0.,1.,4.,1.,1.,5.,1.,1.,5.,0.,1.,6.,0.,0.,6.,1.,0.,7.,0.,0.,6.,0.,1.};
+  DataArrayDouble *c=DataArrayDouble::New();
+  c->useArray(coords,false,CPP_DEALLOC,24,3);
+  m->setCoords(c);
+  c->decrRef();
+  m->checkCoherency2();
+  //
+  MEDCouplingUMesh *m1=static_cast<MEDCouplingUMesh *>(m->deepCpy());
+  DataArrayInt *d1=m1->simplexize(INTERP_KERNEL::PLANAR_FACE_5);
+  m1->checkCoherency2();
+  MEDCouplingFieldDouble *f1=m1->getMeasureField(ON_CELLS);
+  const double vol1Expected[12]={1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6};
+  CPPUNIT_ASSERT_EQUAL(1,f1->getArray()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(12,f1->getArray()->getNumberOfTuples());
+  for(int i=0;i<12;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1Expected[i],f1->getIJ(i,0),1e-12);
+  const int connExpected1[60]={14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23};
+  const int connIExpected1[13]={0,5,10,15,20,25,30,35,40,45,50,55,60};
+  const int n2o1[12]={0,1,1,1,1,1,2,2,2,2,2,3};
+  CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivity()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(60,m1->getNodalConnectivity()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivityIndex()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(13,m1->getNodalConnectivityIndex()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(connExpected1,connExpected1+60,m1->getNodalConnectivity()->begin()));
+  CPPUNIT_ASSERT(std::equal(connIExpected1,connIExpected1+13,m1->getNodalConnectivityIndex()->begin()));
+  CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(n2o1,n2o1+12,d1->begin()));
+  f1->decrRef();
+  m1->decrRef();
+  d1->decrRef();
+  //
+  MEDCouplingUMesh *m2=static_cast<MEDCouplingUMesh *>(m->deepCpy());
+  DataArrayInt *d2=m2->simplexize(INTERP_KERNEL::PLANAR_FACE_6);
+  m2->checkCoherency2();
+  MEDCouplingFieldDouble *f2=m2->getMeasureField(ON_CELLS);
+  const double vol2Expected[14]={1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6};
+  CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(14,f2->getArray()->getNumberOfTuples());
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(vol2Expected[i],f2->getIJ(i,0),1e-12);
+  const int connExpected2[70]={14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23};
+  const int connIExpected2[15]={0,5,10,15,20,25,30,35,40,45,50,55,60,65,70};
+  const int n2o2[14]={0,1,1,1,1,1,1,2,2,2,2,2,2,3};
+  CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivity()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(70,m2->getNodalConnectivity()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivityIndex()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(15,m2->getNodalConnectivityIndex()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(connExpected2,connExpected2+70,m2->getNodalConnectivity()->begin()));
+  CPPUNIT_ASSERT(std::equal(connIExpected2,connIExpected2+15,m2->getNodalConnectivityIndex()->begin()));
+  CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(14,d2->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(n2o2,n2o2+14,d2->begin()));
+  f2->decrRef();
+  m2->decrRef();
+  d2->decrRef();
+  //
+  m->decrRef();
+}
index 1ee856333a77f0c01e8cade367922aa76ff27f8c..92e1ad52ea051e9ef489e6e22876c3e628237c20 100644 (file)
@@ -69,6 +69,11 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testIntersect2DMeshesTmp5 );
     CPPUNIT_TEST( testDAIBuildUnique1 );
     CPPUNIT_TEST( testDAIPartitionByDifferentValues1 );
+    CPPUNIT_TEST( testDAICheckMonotonic1 );
+    CPPUNIT_TEST( testIntersect2DMeshesTmp6 );
+    CPPUNIT_TEST( testDAIBuildSubstractionOptimized1 );
+    CPPUNIT_TEST( testDAIIsStrictlyMonotonic1 );
+    CPPUNIT_TEST( testSimplexize3 );
     CPPUNIT_TEST_SUITE_END();
   public:
     void testUMeshTessellate2D1();
@@ -104,6 +109,11 @@ namespace ParaMEDMEM
     void testIntersect2DMeshesTmp5();
     void testDAIBuildUnique1();
     void testDAIPartitionByDifferentValues1();
+    void testDAICheckMonotonic1();
+    void testIntersect2DMeshesTmp6();
+    void testDAIBuildSubstractionOptimized1();
+    void testDAIIsStrictlyMonotonic1();
+    void testSimplexize3();
   };
 }
 
index 07af5fb49f5881f07393dd7df47cd1fda04d859c..7b0b7bb52046b12a8b0f3b5a63a0dd1b11d7372b 100644 (file)
@@ -38,6 +38,8 @@ SET(medcouplingcorba_SOURCES
   MEDCouplingMeshServant.cxx
   MEDCouplingPointSetServant.cxx
   MEDCouplingExtrudedMeshServant.cxx
+  MEDCouplingStructuredMeshServant.cxx
+  MEDCouplingCurveLinearMeshServant.cxx
   MEDCouplingCMeshServant.cxx
   MEDCouplingUMeshServant.cxx
   MEDCouplingFieldServant.cxx
index c7486da92540a94fe5a055952d8585fb68fc8ff0..912daa5f090b3900f1104c04e3f10938bcad2d0b 100644 (file)
@@ -31,6 +31,7 @@ SET(medcouplingclient_SOURCES
   DataArrayDoubleClient.cxx
   DataArrayIntClient.cxx
   MEDCouplingCMeshClient.cxx
+  MEDCouplingCurveLinearMeshClient.cxx
   MEDCouplingExtrudedMeshClient.cxx
   MEDCouplingFieldDoubleClient.cxx
   MEDCouplingFieldOverTimeClient.cxx
index bc59a44def7662ccf5e8c429ecbc9191d590c7c6..b4446b1ddc98b947bdb8d83cab1b981c9309b2c5 100644 (file)
@@ -372,7 +372,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(NORM_QUAD4,mesh.getAllTypes()[1]);
         self.assertEqual(1,len(subMesh.getAllTypes()));
         self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]);
-        self.assertEqual(name,"PartOf_Toto");
+        self.assertEqual(name,"Toto");
         self.assertEqual(2,subMesh.getNumberOfCells());
         subConn=[4,0,3,4,1,4,7,8,5,4];
         subConnIndex=[0,5,10];
@@ -387,7 +387,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(2,len(subMesh.getAllTypes()));
         self.assertEqual(NORM_TRI3,subMesh.getAllTypes()[0]);
         self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[1]);
-        self.assertEqual(name,"PartOf_Toto");
+        self.assertEqual(name,"Toto");
         self.assertEqual(3,subMesh.getNumberOfCells());
         subConn2=[4,0,3,4,1,3,4,5,2,4,6,7,4,3]
         subConnIndex2=[0,5,9,14]
@@ -952,7 +952,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         name=f3.getName();
         self.assertEqual(name,"MeasureOfMesh_");
         self.assertEqual(f3.getTypeOfField(),ON_CELLS);
-        self.assertEqual(f3.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f3.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f3.getNumberOfComponents());
         self.assertEqual(7,f3.getNumberOfTuples());
         values=[0.25,0.125,0.125,0.25,0.25,0.5,0.5]
@@ -964,11 +964,14 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         pass
 
     def testFillFromAnalytic(self):
-        m=MEDCouplingDataForTest.build2DTargetMesh_1();             
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m.setTime(3.4,5,6); m.setTimeUnit("us");
         f1=m.fillFromAnalytic(ON_CELLS,1,"x+y");
+        self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2])
+        self.assertEqual("us",f1.getTimeUnit())
         f1.checkCoherency();                    
         self.assertEqual(f1.getTypeOfField(),ON_CELLS);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(5,f1.getNumberOfTuples());
         values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9]
@@ -981,7 +984,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_NODES,1,"x+y");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         values2=[-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4]
@@ -994,7 +997,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(2,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8]
@@ -1020,7 +1023,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_CELLS,1,"y+x");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_CELLS);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(5,f1.getNumberOfTuples());
         values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9]
@@ -1033,7 +1036,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_NODES,1,"y+2*x");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1]
@@ -1045,7 +1048,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_NODES,1,"2.*x+y");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         tmp=f1.getArray().getValues();
@@ -1058,7 +1061,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(2,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8]
@@ -1080,12 +1083,12 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(2,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         f1.applyFunc(1,"x+y");
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2]
@@ -1101,7 +1104,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec");
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(2,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         #
@@ -1111,7 +1114,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertRaises(InterpKernelException, f2.applyFunc, "a/0");
         f2.applyFunc("abs(u)^2.4+2*u");
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(2,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         values2=[-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987,
@@ -1127,7 +1130,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         #
         f1.applyFunc(1,"x+y");
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2]
@@ -1147,7 +1150,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f3=f1+f2;
         f3.checkCoherency();
         self.assertEqual(f3.getTypeOfField(),ON_NODES);
-        self.assertEqual(f3.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f3.getTimeDiscretization(),ONE_TIME);
         values1=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8]
         tmp=f3.getArray().getValues();
         self.assertEqual(len(values1),len(tmp))
@@ -1158,7 +1161,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f3=f1*f2;
         f3.checkCoherency();
         self.assertEqual(f3.getTypeOfField(),ON_NODES);
-        self.assertEqual(f3.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f3.getTimeDiscretization(),ONE_TIME);
         values2=[0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96]
         tmp=f3.getArray().getValues();
         self.assertEqual(len(values2),len(tmp))
@@ -1170,7 +1173,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f4=f1-f3;
         f4.checkCoherency();
         self.assertEqual(f4.getTypeOfField(),ON_NODES);
-        self.assertEqual(f4.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f4.getTimeDiscretization(),ONE_TIME);
         values3=[0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4]
         tmp=f4.getArray().getValues();
         self.assertEqual(len(values3),len(tmp))
@@ -1182,20 +1185,20 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f4=f3/f2;
         f4.checkCoherency();
         self.assertEqual(f4.getTypeOfField(),ON_NODES);
-        self.assertEqual(f4.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f4.getTimeDiscretization(),ONE_TIME);
         tmp=f4.getArray().getValues();
         for i in xrange(len(tmp)):
             self.assertTrue(abs(tmp[i]-2.)<1.e-12)
             pass
         #
-        f4=f2.buildNewTimeReprFromThis(ONE_TIME,False);
+        f4=f2.buildNewTimeReprFromThis(NO_TIME,False);
         f4.checkCoherency();
         self.assertEqual(f4.getTypeOfField(),ON_NODES);
-        self.assertEqual(f4.getTimeDiscretization(),ONE_TIME);
+        self.assertEqual(f4.getTimeDiscretization(),NO_TIME);
         self.assertRaises(InterpKernelException,f1.__add__,f4);
-        f5=f4.buildNewTimeReprFromThis(NO_TIME,False);
+        f5=f4.buildNewTimeReprFromThis(ONE_TIME,False);
         self.assertEqual(f5.getTypeOfField(),ON_NODES);
-        self.assertEqual(f5.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f5.getTimeDiscretization(),ONE_TIME);
         f3=f1+f5;
         tmp=f3.getArray().getValues();
         values4=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8]
@@ -1204,14 +1207,14 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             self.assertTrue(abs(tmp[i]-values4[i])<1.e-12)
             pass
         #
-        f4=f2.buildNewTimeReprFromThis(ONE_TIME,True);
+        f4=f2.buildNewTimeReprFromThis(NO_TIME,True);
         f4.checkCoherency();
         self.assertEqual(f4.getTypeOfField(),ON_NODES);
-        self.assertEqual(f4.getTimeDiscretization(),ONE_TIME);
+        self.assertEqual(f4.getTimeDiscretization(),NO_TIME);
         self.assertRaises(InterpKernelException,f1.__add__,f4);
-        f5=f4.buildNewTimeReprFromThis(NO_TIME,True);
+        f5=f4.buildNewTimeReprFromThis(ONE_TIME,True);
         self.assertEqual(f5.getTypeOfField(),ON_NODES);
-        self.assertEqual(f5.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f5.getTimeDiscretization(),ONE_TIME);
         f3=f1+f5;
         tmp=f3.getArray().getValues();
         values5=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8]
@@ -1223,12 +1226,13 @@ class MEDCouplingBasicsTest(unittest.TestCase):
 
     def testOperationsOnFields2(self):
         m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        m.setTime(3.4,5,6); m.setTimeUnit("us");
         f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z");
         f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c");
         f3=f1/f2;
         f3.checkCoherency();
         self.assertEqual(f3.getTypeOfField(),ON_NODES);
-        self.assertEqual(f3.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f3.getTimeDiscretization(),ONE_TIME);
         expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391,
                    0.7407407407407407, 1.129032258064516, 0.81632653061224492,
                    0.86538461538461531, 1.0919540229885056, 0.84302325581395343]
@@ -1239,6 +1243,8 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             self.assertTrue(abs(expected1[i]-val[i])<1.e-12);
         #
         f1=m.buildOrthogonalField();
+        self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2])
+        self.assertEqual("us",f1.getTimeUnit())
         f2=m.fillFromAnalytic(ON_CELLS,1,"x");
         f3=f1*f2;
         expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637]
@@ -1261,7 +1267,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1/=f2
         f1.checkCoherency();
         self.assertEqual(f1.getTypeOfField(),ON_NODES);
-        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(f1.getTimeDiscretization(),ONE_TIME);
         expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391,
                    0.7407407407407407, 1.129032258064516, 0.81632653061224492,
                    0.86538461538461531, 1.0919540229885056, 0.84302325581395343]
@@ -3644,7 +3650,10 @@ class MEDCouplingBasicsTest(unittest.TestCase):
 
     def testGetEdgeRatioField1(self):
         m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m1.setTime(3.4,5,6); m1.setTimeUnit("us");
         f1=m1.getEdgeRatioField();
+        self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2])
+        self.assertEqual("us",f1.getTimeUnit())
         self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples());
         self.assertEqual(5,f1.getNumberOfTuples());
         self.assertEqual(1,f1.getNumberOfComponents());
@@ -5508,6 +5517,10 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(pt[1],tmp.getIJ(0,1));
         ret,tmp=m2.areCellsIncludedIn(m,0)
         self.assertTrue(not ret);
+        m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m,m2)
+        c,cI=m3.findCommonCells(2,m.getNumberOfCells())
+        self.assertTrue(c.isEqual(DataArrayInt([1,5,3,6])))
+        self.assertTrue(cI.isEqual(DataArrayInt([0,2,4])))
         pass
 
     def testSwigErrorProtection1(self):
@@ -5721,31 +5734,31 @@ class MEDCouplingBasicsTest(unittest.TestCase):
 
     def testSwigErrorProtection3(self):
         da=DataArrayInt.New()
-        da.setValues([1,2,3,4],4,3)
+        da.setValues([1,2,3,4,0,0,0,0,0,0,0,0],4,3)
         self.assertEqual([1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0],da.getValues())
         self.assertEqual(3,da.getNumberOfComponents());
         self.assertEqual(4,da.getNumberOfTuples());
         da=DataArrayInt.New()
-        da.setValues((1,2,3,4,4,3),4,3)
+        da.setValues(((1,2,3),(4,4,3),(0,0,0),(0,0,0)),4,3)
         self.assertEqual([1, 2, 3, 4, 4, 3, 0, 0, 0, 0, 0, 0],da.getValues())
         self.assertEqual(3,da.getNumberOfComponents());
         self.assertEqual(4,da.getNumberOfTuples());
-        da.setValues(10*[1]+290*[2],4,3)
+        da.setValues((10*[1]+290*[2])[:12],4,3)
         self.assertEqual(10*[1]+[2,2],da.getValues())
         self.assertEqual(3,da.getNumberOfComponents());
         self.assertEqual(4,da.getNumberOfTuples());
         #
         da=DataArrayDouble.New()
-        da.setValues([1,2,3.,4],4,3)
+        da.setValues([1,2,3.,4,0,0,0,0,0,0,0,0],4,3)
         self.assertEqual([1., 2., 3., 4., 0., 0., 0., 0., 0., 0., 0., 0.],da.getValues())
         self.assertEqual(3,da.getNumberOfComponents());
         self.assertEqual(4,da.getNumberOfTuples());
         da=DataArrayDouble.New()
-        da.setValues((1,2,3,4.,4,3),4,3)
+        da.setValues(((1,2,3),(4.,4,3),(0,0,0),(0,0,0)),4,3)
         self.assertEqual([1., 2., 3., 4., 4., 3., 0., 0., 0., 0., 0., 0.],da.getValues())
         self.assertEqual(3,da.getNumberOfComponents());
         self.assertEqual(4,da.getNumberOfTuples());
-        da.setValues(10*[1]+290*[2],4,3)
+        da.setValues((10*[1]+290*[2])[:12],4,3)
         self.assertEqual(10*[1.]+[2.,2.],da.getValues())
         self.assertEqual(3,da.getNumberOfComponents());
         self.assertEqual(4,da.getNumberOfTuples());
@@ -6907,11 +6920,14 @@ class MEDCouplingBasicsTest(unittest.TestCase):
 
     def testFillFromAnalyticTwo1(self):
         m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        m1.setTime(3.4,5,6); m1.setTimeUnit("us");
         self.assertRaises(InterpKernelException,m1.fillFromAnalytic2,ON_NODES,1,"y+z");
         m1.getCoords().setInfoOnComponent(0,"x [m]");
         m1.getCoords().setInfoOnComponent(1,"y");
         m1.getCoords().setInfoOnComponent(2,"z");
         f1=m1.fillFromAnalytic2(ON_NODES,1,"y+z");
+        self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2])
+        self.assertEqual("us",f1.getTimeUnit())
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2]
@@ -6922,11 +6938,14 @@ class MEDCouplingBasicsTest(unittest.TestCase):
 
     def testFillFromAnalyticThree1(self):
         m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        m1.setTime(3.4,5,6); m1.setTimeUnit("us");
         vs=3*[None];
         vs[0]="x"; vs[1]="Y"; vs[2]="z";
         self.assertRaises(InterpKernelException,m1.fillFromAnalytic3,ON_NODES,1,vs,"y+z");
         vs[1]="y";
         f1=m1.fillFromAnalytic3(ON_NODES,1,vs,"y+z");
+        self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2])
+        self.assertEqual("us",f1.getTimeUnit())
         self.assertEqual(1,f1.getNumberOfComponents());
         self.assertEqual(9,f1.getNumberOfTuples());
         expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2]
@@ -7904,6 +7923,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(4,len(v));
         self.assertEqual(v.getValues(),invalidCells);
         self.assertEqual(connExp,m.getNodalConnectivity().getValues());
+        self.assertTrue(m.findAndCorrectBadOriented3DExtrudedCells().empty())
         #
         pass
 
@@ -7952,9 +7972,9 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         f1=m.getMeasureField(True)
         f1.getArray().setInfoOnComponent(0,"P [N/m^2]")
         bary=m.getBarycenterAndOwner()
-        f2=f1.buildNewTimeReprFromThis(ONE_TIME,False)
+        f2=f1.buildNewTimeReprFromThis(NO_TIME,False)
         f2.setArray(bary)
-        self.assertRaises(InterpKernelException,f2.copyTinyAttrFrom,f1)
+        self.assertRaises(InterpKernelException,f1.copyTinyAttrFrom,f2)
         pass
 
     def testDaDSetPartOfValuesAdv1(self):
@@ -8128,6 +8148,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(7,newNbTuple);
         self.assertEqual(1,ret.getNumberOfComponents());
         self.assertEqual(expected,ret.getValues());
+        self.assertRaises(InterpKernelException,DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2,9,a,b);
         pass
 
     def testDADIReverse1(self):
@@ -8152,7 +8173,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         for i in xrange(6):
             self.assertAlmostEqual(arr2[5-i],b.getIJ(i,0),14);
             pass
-        b.setValues(arr2,5,1);
+        b.setValues(arr2[:5],5,1);
         self.assertAlmostEqual(9.,b.back(),14)
         b.reverse();
         for i in xrange(5):
@@ -10397,6 +10418,701 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertRaises(InterpKernelException,m3D.getCellsInBoundingBox,[(0,3,0),(3,0,1)],-1e-12)
         pass
 
+    def testDAICheckMonotonic1(self):
+        data1=[-1,0,2,2,4,5]
+        data2=[6,2,0,-8,-9,-56]
+        data3=[-1,0,3,2,4,6]
+        data4=[7,5,2,3,0,-6]
+        d=DataArrayInt.New(data1);
+        self.assertTrue(d.isMonotonic(True));
+        self.assertTrue(not d.isMonotonic(False));
+        d.checkMonotonic(True);
+        self.assertRaises(InterpKernelException,d.checkMonotonic,False)
+        d=DataArrayInt.New(data2);
+        self.assertTrue(d.isMonotonic(False));
+        self.assertTrue(not d.isMonotonic(True));
+        d.checkMonotonic(False);
+        self.assertRaises(InterpKernelException,d.checkMonotonic,True)
+        d=DataArrayInt.New(data3);
+        self.assertTrue(not d.isMonotonic(False));
+        self.assertTrue(not d.isMonotonic(True));
+        self.assertRaises(InterpKernelException,d.checkMonotonic,True)
+        self.assertRaises(InterpKernelException,d.checkMonotonic,False)
+        d=DataArrayInt.New(data4);
+        self.assertTrue(not d.isMonotonic(False));
+        self.assertTrue(not d.isMonotonic(True));
+        self.assertRaises(InterpKernelException,d.checkMonotonic,True)
+        self.assertRaises(InterpKernelException,d.checkMonotonic,False)
+        d=DataArrayInt.New(0,1)
+        self.assertTrue(d.isMonotonic(True));
+        self.assertTrue(d.isMonotonic(False));
+        d.checkMonotonic(True);
+        d.checkMonotonic(False);
+        d=DataArrayInt.New(data4,3,2);#throw because nbComp!=1
+        self.assertRaises(InterpKernelException,d.isMonotonic,True)
+        self.assertRaises(InterpKernelException,d.isMonotonic,False)
+        self.assertRaises(InterpKernelException,d.checkMonotonic,True)
+        self.assertRaises(InterpKernelException,d.checkMonotonic,False)
+        pass
+
+    def testSwigDASetItemOnEmpty1(self):
+        d=DataArrayInt(0,1)
+        isThrow=False
+        try:
+            d[0:1000:2]=4
+        except InterpKernelException as e:
+            isThrow=True
+            pass
+        self.assertTrue(isThrow)
+        d[:]=4
+        d[::2]=5
+        #
+        d=DataArrayDouble(0,1)
+        isThrow=False
+        try:
+            d[0:1000:2]=4
+        except InterpKernelException as e:
+            isThrow=True
+            pass
+        self.assertTrue(isThrow)
+        d[:]=4
+        d[::2]=5
+        d=DataArrayInt([],0,1)
+        d2=DataArrayInt(0)
+        self.assertTrue(d2.isEqual(d))
+        d=DataArrayDouble([],0,1)
+        d2=DataArrayDouble(0)
+        self.assertTrue(d2.isEqual(d,1e-12))
+        pass
+
+    def testSwigDAITransformWithIndArr1(self):
+        arr=DataArrayInt([0,4,5,1])
+        d=DataArrayInt([7,8,9,10])
+        self.assertRaises(InterpKernelException,arr.transformWithIndArr,d)
+        pass
+
+    def testIntersect2DMeshesTmp6(self):
+        # coordinates
+        coords=DataArrayDouble.New([2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15],8,2);
+        # connectivity
+        conn=DataArrayInt.New([8,0,3,5,1,4,6,7,2])
+        connI=DataArrayInt.New([0,9]);
+        m1=MEDCouplingUMesh.New("Fixe",2);
+        m1.setCoords(coords);
+        m1.setConnectivity(conn,connI,True);
+        #
+        coords=DataArrayDouble.New([-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839],13,2);
+        # connectivity
+        conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12]);
+        connI=DataArrayInt.New([0,9,18]);
+        #
+        m2=MEDCouplingUMesh.New("Mobile",2);
+        m2.setCoords(coords);
+        m2.setConnectivity(conn,connI,True);
+        #
+        m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10);
+        self.assertTrue(d1.isEqual(DataArrayInt([0,0,0,0])));
+        self.assertTrue(d2.isEqual(DataArrayInt([0,1,-1,-1])));
+        self.assertEqual(4,m3.getNumberOfCells());
+        self.assertEqual(4,d1.getNumberOfTuples());
+        self.assertEqual(4,d2.getNumberOfTuples());
+        self.assertEqual(43,m3.getNumberOfNodes());
+        dI,areMerged,newNbOfNodes=m3.mergeNodes(1e-12)
+        self.assertEqual(35,m3.getNumberOfNodes());
+        m3.zipCoords();
+        self.assertEqual(23,m3.getNumberOfNodes());
+        #
+        f=m3.getMeasureField(True);
+        valuesExpected=DataArrayDouble([1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694])
+        self.assertTrue(f.getArray().isEqual(valuesExpected,1e-12))
+        pass
+
+    def testDAPushBack(self):
+        d=DataArrayDouble(0,1)
+        for i in xrange(8):
+            d.pushBackSilent(i)
+            pass
+        self.assertEqual(d.getNumberOfTuples(),8)
+        self.assertEqual(d.getNbOfElemAllocated(),8)
+        d.pushBackSilent(4.44)
+        self.assertEqual(d.getNumberOfTuples(),9)
+        self.assertEqual(d.getNbOfElemAllocated(),16)
+        self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12))
+        e=d.deepCpy()
+        self.assertEqual(e.getNumberOfTuples(),9)
+        self.assertEqual(e.getNbOfElemAllocated(),9)
+        self.assertTrue(e.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12))
+        self.assertAlmostEqual(d.popBackSilent(),4.44,12)
+        self.assertEqual(d.getNumberOfTuples(),8)
+        self.assertEqual(d.getNbOfElemAllocated(),16)
+        self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.]),1e-12))
+        f=DataArrayDouble()
+        f.reserve(1000)
+        f.pushBackSilent(4.)
+        self.assertTrue(f.isEqual(DataArrayDouble([4.]),1e-12))
+        self.assertEqual(f.getNumberOfTuples(),1)
+        self.assertEqual(f.getNbOfElemAllocated(),1000)
+        ff=f[:]
+        self.assertTrue(ff.isEqual(DataArrayDouble([4.]),1e-12))
+        self.assertEqual(ff.getNumberOfTuples(),1)
+        self.assertEqual(ff.getNbOfElemAllocated(),1)
+        d=DataArrayDouble()
+        d.pushBackSilent(4.44)
+        d.pushBackSilent(5.55)
+        d.pushBackSilent(6.66)
+        self.assertTrue(d.isEqual(DataArrayDouble([4.44,5.55,6.66]),1e-12))
+        #
+        d=DataArrayInt(0,1)
+        for i in xrange(8):
+            d.pushBackSilent(i)
+            pass
+        self.assertEqual(d.getNumberOfTuples(),8)
+        self.assertEqual(d.getNbOfElemAllocated(),8)
+        d.pushBackSilent(444)
+        self.assertEqual(d.getNumberOfTuples(),9)
+        self.assertEqual(d.getNbOfElemAllocated(),16)
+        self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444])))
+        e=d.deepCpy()
+        self.assertEqual(e.getNumberOfTuples(),9)
+        self.assertEqual(e.getNbOfElemAllocated(),9)
+        self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444])))
+        self.assertEqual(d.popBackSilent(),444)
+        self.assertEqual(d.getNumberOfTuples(),8)
+        self.assertEqual(d.getNbOfElemAllocated(),16)
+        self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7])))
+        f=DataArrayInt()
+        f.reserve(1000)
+        f.pushBackSilent(4)
+        self.assertTrue(f.isEqual(DataArrayInt([4])))
+        self.assertEqual(f.getNumberOfTuples(),1)
+        self.assertEqual(f.getNbOfElemAllocated(),1000)
+        ff=f[:]
+        self.assertTrue(ff.isEqual(DataArrayInt([4])))
+        self.assertEqual(ff.getNumberOfTuples(),1)
+        self.assertEqual(ff.getNbOfElemAllocated(),1)
+        d=DataArrayInt()
+        d.pushBackSilent(444)
+        d.pushBackSilent(555)
+        d.pushBackSilent(666)
+        self.assertTrue(d.isEqual(DataArrayInt([444,555,666])))
+        #
+        d=DataArrayInt()
+        d.alloc(10,1)
+        d.setInfoOnComponent(0,"ABC")
+        d.setName("dEf")
+        d.iota(7)
+        e=DataArrayInt([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e))
+        self.assertEqual(10,d.getNbOfElemAllocated())
+        d.pushBackSilent(55)
+        e=DataArrayInt([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e))
+        self.assertEqual(20,d.getNbOfElemAllocated())
+        d.reserve(4)
+        e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e))
+        self.assertEqual(4,d.getNbOfElemAllocated())
+        d.pushBackSilent(5)
+        e=DataArrayInt([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e))
+        self.assertEqual(8,d.getNbOfElemAllocated())
+        self.assertEqual(5,d.popBackSilent())
+        e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e))
+        self.assertEqual(8,d.getNbOfElemAllocated())
+        self.assertRaises(InterpKernelException,d.reserve,-1)
+        e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e))
+        self.assertEqual(8,d.getNbOfElemAllocated())
+        d.reserve(0)
+        e=DataArrayInt([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e))
+        self.assertEqual(0,d.getNbOfElemAllocated())
+        #
+        d=DataArrayDouble()
+        d.alloc(10,1)
+        d.setInfoOnComponent(0,"ABC")
+        d.setName("dEf")
+        d.iota(7)
+        e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14))
+        self.assertEqual(10,d.getNbOfElemAllocated())
+        d.pushBackSilent(55)
+        e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14))
+        self.assertEqual(20,d.getNbOfElemAllocated())
+        d.reserve(4)
+        e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14))
+        self.assertEqual(4,d.getNbOfElemAllocated())
+        d.pushBackSilent(5)
+        e=DataArrayDouble([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14))
+        self.assertEqual(8,d.getNbOfElemAllocated())
+        self.assertEqual(5.,d.popBackSilent())
+        e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14))
+        self.assertEqual(8,d.getNbOfElemAllocated())
+        self.assertRaises(InterpKernelException,d.reserve,-1)
+        e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14))
+        self.assertEqual(8,d.getNbOfElemAllocated())
+        d.reserve(0)
+        e=DataArrayDouble([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e,1e-14))
+        self.assertEqual(0,d.getNbOfElemAllocated())
+        pass
+
+    def testDAIBuildSubstractionOptimized1(self):
+        da1=DataArrayInt.New([1,3,5,6,7,9,13])
+        da2=DataArrayInt.New([3,5,9])
+        da3=DataArrayInt.New([1,3,5])
+        da4=DataArrayInt.New([1,3,5,6,7,9,13])
+        #
+        a=da1.buildSubstractionOptimized(da2);
+        self.assertTrue(a.isEqual(DataArrayInt([1,6,7,13])));
+        #
+        a=da1.buildSubstractionOptimized(da3);
+        self.assertTrue(a.isEqual(DataArrayInt([6,7,9,13])));
+        #
+        a=da1.buildSubstractionOptimized(da4);
+        self.assertTrue(a.isEqual(DataArrayInt([])));
+        pass
+
+    def testDAIIsStrictlyMonotonic1(self):
+        da1=DataArrayInt.New([1,3,5,6,7,9,13])
+        self.assertTrue(da1.isStrictlyMonotonic(True));
+        da1.checkStrictlyMonotonic(True);
+        self.assertTrue(da1.isMonotonic(True));
+        da1.checkMonotonic(True);
+        self.assertTrue(not da1.isStrictlyMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False)
+        self.assertTrue(not da1.isMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,False)
+        #
+        da1=DataArrayInt.New([1,3,5,6,6,9,13])
+        self.assertTrue(not da1.isStrictlyMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True)
+        self.assertTrue(da1.isMonotonic(True));
+        da1.checkMonotonic(True);
+        self.assertTrue(not da1.isStrictlyMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False)
+        self.assertTrue(not da1.isMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,False)
+        #
+        da1=DataArrayInt.New([1,3,5,6,5,9,13])
+        self.assertTrue(not da1.isStrictlyMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True)
+        self.assertTrue(not da1.isMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,True)
+        self.assertTrue(not da1.isStrictlyMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False)
+        self.assertTrue(not da1.isMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,False)
+        #
+        da1=DataArrayInt.New([13,9,7,6,5,3,1])
+        self.assertTrue(not da1.isStrictlyMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True)
+        self.assertTrue(not da1.isMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,True)
+        self.assertTrue(da1.isStrictlyMonotonic(False));
+        da1.checkStrictlyMonotonic(False);
+        self.assertTrue(da1.isMonotonic(False));
+        da1.checkMonotonic(False);
+        #
+        da1=DataArrayInt.New([13,9,6,6,5,3,1])
+        self.assertTrue(not da1.isStrictlyMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True)
+        self.assertTrue(not da1.isMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,True)
+        self.assertTrue(not da1.isStrictlyMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False)
+        self.assertTrue(da1.isMonotonic(False));
+        da1.checkMonotonic(False);
+        #
+        da1=DataArrayInt.New([13,9,5,6,5,3,1])
+        self.assertTrue(not da1.isStrictlyMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True)
+        self.assertTrue(not da1.isMonotonic(True));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,True)
+        self.assertTrue(not da1.isStrictlyMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False)
+        self.assertTrue(not da1.isMonotonic(False));
+        self.assertRaises(InterpKernelException,da1.checkMonotonic,False)
+        #
+        da1=DataArrayInt.New([])
+        self.assertTrue(da1.isStrictlyMonotonic(True));
+        da1.checkStrictlyMonotonic(True);
+        self.assertTrue(da1.isMonotonic(True));
+        da1.checkMonotonic(True);
+        self.assertTrue(da1.isStrictlyMonotonic(False));
+        da1.checkStrictlyMonotonic(False);
+        self.assertTrue(da1.isMonotonic(False));
+        da1.checkMonotonic(False);
+        #
+        da1=DataArrayInt.New([13])
+        self.assertTrue(da1.isStrictlyMonotonic(True));
+        da1.checkStrictlyMonotonic(True);
+        self.assertTrue(da1.isMonotonic(True));
+        da1.checkMonotonic(True);
+        self.assertTrue(da1.isStrictlyMonotonic(False));
+        da1.checkStrictlyMonotonic(False);
+        self.assertTrue(da1.isMonotonic(False));
+        da1.checkMonotonic(False);
+        pass
+
+    def testFindAndCorrectBadOriented3DCells1(self):
+        nbOfDisc=20
+        vects=([0,0,-1],[0.3,0.7,0.2],[-0.3,0.7,0.2],[-0.3,-0.7,0.2])
+        #
+        m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented
+        m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented
+        m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented 
+        m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented
+        m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0)
+        self.assertRaises(InterpKernelException,m4.insertNextCell,NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11,12]);
+        m4.insertNextCell(NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11]); #Well oriented
+        c0=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) ; m0.setCoords(c0)
+        c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.],5,3) ; m1.setCoords(c1)
+        c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,0.,1.],6,3) ; m2.setCoords(c2)
+        c3=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; m3.setCoords(c3)
+        c4=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.8,0.,0.,0.45,0.,0.,   0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.,0.8,0.,1.,0.45,0.,1.],12,3) ; m4.setCoords(c4)
+        m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4])
+        expected1=DataArrayDouble([0.16666666666666666,0.3333333333333333,0.5,1.,1.])
+        for v in vects:
+            for i in xrange(nbOfDisc):
+                mm=m.deepCpy()
+                mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi)
+                mm2=mm.deepCpy()
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14))
+                self.assertTrue(mm.findAndCorrectBadOriented3DCells().empty())
+                self.assertTrue(mm.isEqual(mm2,1e-14))
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14))
+                mm.convertAllToPoly()
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14))
+                pass
+            pass
+        #
+        mOK=m.deepCpy()
+        m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,2,1,3]); #Not well oriented
+        m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented 
+        m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented 
+        m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,3,2,1,4,7,6,5]); #Not well oriented
+        m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,[0,5,4,3,2,1,6,11,10,9,8,7]); #Not well oriented
+        m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4)
+        m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4])
+        expected2=DataArrayDouble([-0.16666666666666666,0.3333333333333333,0.5,-1.,-1.])
+        for v in vects:
+            for i in xrange(nbOfDisc):
+                mm=m.deepCpy()
+                mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi)
+                mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly()
+                self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected2,1e-14))
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected2,1e-14))
+                self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([0,3,4])))
+                mOK.setCoords(mm.getCoords())
+                self.assertTrue(mm.isEqual(mOK,1e-14))
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14))
+                mmm=mm.deepCpy()
+                self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty())
+                mm.convertAllToPoly()
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14))
+                pass
+            pass
+        #
+        m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented
+        m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,3,2,1,4]); #Not well oriented 
+        m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,2,1,3,5,4]); #Not well oriented 
+        m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented
+        m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,range(12)); #Well oriented
+        m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4)
+        m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4])
+        expected3=DataArrayDouble([0.16666666666666666,-0.3333333333333333,-0.5,1.,1.])
+        for v in vects:
+            for i in xrange(nbOfDisc):
+                mm=m.deepCpy()
+                mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi)
+                mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly()
+                self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected3,1e-14))
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected3,1e-14))
+                self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([1,2])))
+                mOK.setCoords(mm.getCoords())
+                self.assertTrue(mm.isEqual(mOK,1e-14))
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14))
+                mmm=mm.deepCpy()
+                self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty())
+                mm.convertAllToPoly()
+                self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14))
+                pass
+            pass
+        pass
+
+    def testSwigCellOrientation1(self):
+        coords=DataArrayDouble([-0.21606,-0.10803,0.29999999999999999,-0.21606,-0.10803,0.37700000000000006,0,-0.10803,0.29999999999999999,0,-0.10803,0.37700000000000006,0,0.10803,0.29999999999999999,0,0.10803,0.37700000000000006,-0.21606,0.10803,0.29999999999999999,-0.21606,0.10803,0.37700000000000006,0,0.03601,0.29999999999999999,0,0.03601,0.37700000000000006,0,-0.03601,0.29999999999999999,0,-0.03601,0.37700000000000006],12,3)
+        conn=[[0,2,10,8,4,6],[1,3,11,9,5,7],[0,1,3,2],[2,3,11,10],[10,11,9,8],[8,9,5,4],[4,5,7,6],[6,7,1,0]]
+        for i in xrange(256):
+            mesh=MEDCouplingUMesh("FluidMesh_1",3);
+            mesh.allocateCells(0)
+            conn2=[elt[:] for elt in conn]
+            code=bin(i)[2:] ; code='0'*(8-len(code))+code
+            for face,rev in zip(conn2,code):
+                if bool(int(rev)):
+                    face.reverse()
+                    pass
+                pass
+            conn3=[elt+[-1] for elt in conn2]
+            conn3=sum(conn3,[])[:-1]
+            mesh.insertNextCell(NORM_POLYHED,conn3)
+            mesh.setCoords(coords)
+            mesh.orientCorrectlyPolyhedrons()
+            self.assertTrue(mesh.getBarycenterAndOwner().isEqual(DataArrayDouble([-0.10803,0.,0.3385],1,3),1e-12))
+            pass
+        pass
+
+    def testSwigCheckConsecutiveCellTypesForMEDFileFrmt1(self):
+        m1=MEDCouplingUMesh("",2) ; m1.allocateCells(0)
+        m1.insertNextCell(NORM_QUAD4,[0,1,2,3])
+        m1.insertNextCell(NORM_TRI3,[0,1,2])
+        d=DataArrayDouble(4,3) ; d[:]=0.
+        m1.setCoords(d)
+        self.assertTrue(m1.checkConsecutiveCellTypes())
+        self.assertTrue(not m1.checkConsecutiveCellTypesForMEDFileFrmt())
+        m1.renumberCells([1,0])
+        self.assertTrue(m1.checkConsecutiveCellTypes())
+        self.assertTrue(m1.checkConsecutiveCellTypesForMEDFileFrmt())
+        pass
+
+    def testSwigDAAccumulate1(self):
+        d=DataArrayInt(10) ; d.iota(0)
+        self.assertEqual([45],d.accumulate())
+        self.assertEqual(45,d.accumulate(0))
+        d=DataArrayInt(30) ; d.iota(0) ; d.rearrange(3)
+        self.assertEqual([135,145,155],d.accumulate())
+        self.assertEqual(135,d.accumulate(0))
+        self.assertEqual(145,d.accumulate(1))
+        self.assertEqual(155,d.accumulate(2))
+        d=DataArrayDouble(10) ; d.iota(0.)
+        self.assertEqual([45.],d.accumulate())
+        self.assertEqual(45.,d.accumulate(0))
+        d=DataArrayDouble(30) ; d.iota(0) ; d.rearrange(3)
+        self.assertEqual([135.,145.,155.],d.accumulate())
+        self.assertEqual(135.,d.accumulate(0))
+        self.assertEqual(145.,d.accumulate(1))
+        self.assertEqual(155.,d.accumulate(2))
+        pass
+
+    def testSwigUMeshDistanceToMesh1(self):
+        m=MEDCouplingUMesh("toto",2)
+        coords=DataArrayDouble([2.3,3.4,5.6,6.5,-4.3,3.2,-9.8,7.6,-5.4],3,3)
+        m.setCoords(coords)
+        m.allocateCells(0)
+        m.insertNextCell(NORM_TRI3,[0,1,2])
+        a,b,c=m.distanceToPoint([-0.335,2.27,1.21])
+        self.assertEqual(0,b) ; self.assertEqual(0,c)
+        self.assertAlmostEqual(0.022360988100374124,a,14);
+        a,b,c=m.distanceToPoint(DataArrayDouble([-0.335,2.27,1.21],1,3))
+        self.assertEqual(0,b) ; self.assertEqual(0,c)
+        self.assertAlmostEqual(0.022360988100374124,a,14);
+        a,b=coords.distanceToTuple([-0.335,2.27,1.21])
+        self.assertAlmostEqual(5.243302871282566,a,14)
+        self.assertEqual(0,b)
+        #
+        m=MEDCouplingUMesh("toto",2)
+        coords=DataArrayDouble([0.,0.,0., 8.,0.,0., 8.,8.,0., 0.,8.,0.],4,3)
+        m.setCoords(coords)
+        m.allocateCells(0)
+        m.insertNextCell(NORM_QUAD4,[0,1,2,3])
+        m.checkCoherency2()
+        self.assertEqual([4,0,1,2,3],m.getNodalConnectivity().getValues())
+        a,b,c=m.distanceToPoint([5.,2.,0.1])
+        self.assertAlmostEqual(0.1,a,14) ; self.assertEqual(0,b) ; self.assertEqual(1,c)
+        a,b,c=m.distanceToPoint([5.,-2.,4.])
+        self.assertAlmostEqual(sqrt(2*2+4*4),a,14) ; self.assertEqual(0,b) ; self.assertEqual(1,c)
+        m.allocateCells(0)
+        m.insertNextCell(NORM_POLYGON,[0,1,2,3])
+        m.checkCoherency2()
+        self.assertEqual([5,0,1,2,3],m.getNodalConnectivity().getValues())
+        a,b,c=m.distanceToPoint([11.,3.,4.])
+        self.assertAlmostEqual(sqrt(3*3+4*4),a,14) ; self.assertEqual(0,b) ; self.assertEqual(1,c)
+        a,b,c=m.distanceToPoint([4.,12.,5.])
+        self.assertAlmostEqual(sqrt(4*4+5*5),a,14) ; self.assertEqual(0,b) ; self.assertEqual(2,c)
+        d=DataArrayDouble([-1.2,3.,2.],1,3)
+        for elt in d:
+            a,b,c=m.distanceToPoint(d)
+            self.assertAlmostEqual(sqrt(1.2*1.2+2*2),a,14) ; self.assertEqual(0,b) ; self.assertEqual(0,c)
+            pass
+        #
+        m=MEDCouplingUMesh("toto",1)
+        coords=DataArrayDouble([0.,0.,4.,0.,0.,4.],3,2) ; m.setCoords(coords)
+        m.allocateCells(0) ; m.insertNextCell(NORM_SEG2,[0,1]) ; m.insertNextCell(NORM_SEG2,[1,2])
+        a,b,c=m.distanceToPoint([-0.1,4.1])
+        self.assertAlmostEqual(0.14142135623730925,a,14) ; self.assertEqual(-1,b) ; self.assertEqual(2,c)
+        a,b,c=m.distanceToPoint([0.,3.9])
+        self.assertAlmostEqual(0.07071067811865482,a,14) ; self.assertEqual(1,b) ; self.assertEqual(2,c)
+        pass
+
+    def testSwigNonRegressionPartitionBySpreadZone1(self):
+        m=MEDCouplingCMesh()
+        arr=DataArrayDouble(6) ; arr.iota(0.)
+        m.setCoords(arr,arr,arr)
+        m=m.buildUnstructured()
+        mPart=m[50,80,85,87,92,122]
+        zones=mPart.partitionBySpreadZone()
+        self.assertEqual(4,len(zones))
+        self.assertTrue(zones[0].isEqual(DataArrayInt([0])))
+        self.assertTrue(zones[1].isEqual(DataArrayInt([1,2])))
+        self.assertTrue(zones[2].isEqual(DataArrayInt([3,4])))
+        self.assertTrue(zones[3].isEqual(DataArrayInt([5])))
+        #
+        n,ni=m.computeNeighborsOfCells()
+        a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(0,n,ni)
+        self.assertEqual(13,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity())
+        a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed([1],n,ni)
+        self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity())
+        a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed((2,),n,ni)
+        self.assertEqual(11,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity())
+        a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(DataArrayInt([3]),n,ni)
+        self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity())
+        pass
+
+    def testSwigUMeshInsertNextCell1(self):
+        m=MEDCouplingUMesh("toto",2)
+        #
+        coords=DataArrayDouble([0.,0.,1.,1.,1.,0.]) ; m.setCoords(coords)
+        da=DataArrayInt([0,1,2])
+        m.allocateCells(0)
+        for i in xrange(5):
+            m.insertNextCell(NORM_TRI3,da)
+            pass
+        self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2])))
+        self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20])))
+        #
+        da=DataArrayInt([0,1,2,3])
+        m.allocateCells(0)
+        for i in xrange(5):
+            m.insertNextCell(NORM_TRI3,3,da)
+            pass
+        self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2])))
+        self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20])))
+        #
+        da=DataArrayInt([0,1])
+        m.allocateCells(0)
+        self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,3,da)
+        #
+        da=DataArrayInt([0,1,2,0,1,3,0,1,4,0,1,5,0,1,6],5,3)
+        m.allocateCells(0)
+        for t in da:
+            m.insertNextCell(NORM_TRI3,t)
+            pass
+        self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,3,3,0,1,4,3,0,1,5,3,0,1,6])))
+        self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20])))
+        self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,None)
+        pass
+
+    def testSwigCurveLinearMesh1(self):
+        m=MEDCouplingCurveLinearMesh("toto")
+        m.setNodeGridStructure([2,3])
+        coords=DataArrayDouble([0.,0., 2.,0., 0.,1., 1.9,1.1, 0.3,1.9, 2.2,2.1],6,2)
+        m.setCoords(coords)
+        m.checkCoherency()
+        m0=m.deepCpy()
+        self.assertTrue(m0.isEqual(m,1e-12))
+        m.getCoords().setInfoOnComponents(["X [m]","Y [m]"])
+        self.assertTrue(not m0.isEqual(m,1e-12))
+        m0=m.deepCpy()
+        self.assertTrue(m0.isEqual(m,1e-12))
+        self.assertEqual(m.getNodeGridStructure(),(2,3))
+        pass
+
+    def testSimplexize3(self):
+        m=MEDCouplingUMesh("toto",3)
+        m.allocateCells(0)
+        m.insertNextCell(NORM_TETRA4,[0,1,2,3])
+        m.insertNextCell(NORM_HEXA8,[4,5,6,7,8,9,10,11])
+        m.insertNextCell(NORM_HEXA8,[12,13,14,15,16,17,18,19])
+        m.insertNextCell(NORM_TETRA4,[20,21,22,23])
+        c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3)
+        c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; c2+=[2.,0.,0.]
+        c3=c2+[2.,0.,0.]
+        c4=c1+[6.,0.,0.]
+        c=DataArrayDouble.Aggregate([c1,c2,c3,c4])
+        m.setCoords(c)
+        m.checkCoherency2()
+        #
+        m1=m.deepCpy()
+        d1=m1.simplexize(PLANAR_FACE_5)
+        m1.checkCoherency2()
+        vol1=m1.getMeasureField(ON_CELLS).getArray()
+        self.assertTrue(vol1.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6]),1e-12))
+        self.assertEqual(m1.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23])
+        self.assertEqual(m1.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60])
+        self.assertTrue(d1.isEqual(DataArrayInt([0,1,1,1,1,1,2,2,2,2,2,3])))
+        #
+        m2=m.deepCpy()
+        d2=m2.simplexize(PLANAR_FACE_6)
+        m2.checkCoherency2()
+        vol2=m2.getMeasureField(ON_CELLS).getArray()
+        self.assertTrue(vol2.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6]),1e-12))
+        self.assertEqual(m2.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23])
+        self.assertEqual(m2.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60,65,70])
+        self.assertTrue(d2.isEqual(DataArrayInt([0,1,1,1,1,1,1,2,2,2,2,2,2,3])))
+        pass
+
+    def testSwigCurveLinearMesh2(self):
+        c=MEDCouplingCMesh()
+        #2D
+        arr1=DataArrayDouble([0,1,3,7])
+        arr2=DataArrayDouble([0,1,1.5])
+        c.setCoords(arr1,arr2)
+        u=c.buildUnstructured()
+        coo=u.getCoords()
+        cl=MEDCouplingCurveLinearMesh()
+        cl.setCoords(coo)
+        cl.setNodeGridStructure([4,3])
+        cl.checkCoherency2()
+        li1=[1.,2.,4.,0.5,1.,2.]
+        self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14))
+        self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14))
+        li1_1=[0.5,0.5,2.,0.5,5.,0.5,0.5,1.25,2.,1.25,5.,1.25]
+        self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14))
+        self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14))
+        #3D
+        c.setCoords(arr1,arr2,arr2)
+        u=c.buildUnstructured()
+        coo=u.getCoords()
+        cl=MEDCouplingCurveLinearMesh()
+        cl.setCoords(coo)
+        cl.setNodeGridStructure([4,3,3])
+        cl.checkCoherency2()
+        li2=[1.,2.,4.,0.5, 1.,2.,0.5,1.,2.,0.25,0.5,1.]
+        li2_1=[0.5,0.5,0.5,2.,0.5,0.5,5.,0.5,0.5,0.5,1.25,0.5,2.,1.25,0.5,5.,1.25,0.5,0.5,0.5,1.25,2.,0.5,1.25,5.,0.5,1.25,0.5,1.25,1.25,2.,1.25,1.25,5.,1.25,1.25]
+        self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14))
+        self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14))
+        self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14))
+        self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14))
+        #1D spaceDim 1
+        coo=DataArrayDouble(5) ; coo.iota(0.)
+        coo=coo*coo
+        cl.setCoords(coo)
+        cl.setNodeGridStructure([5])
+        cl.checkCoherency2()
+        li3=[1.,3.,5.,7.]
+        li3_1=[0.5,2.5,6.5,12.5]
+        self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14))
+        self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14))
+        self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14))
+        self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14))
+        #1D spaceDim 2
+        coo=DataArrayDouble.Meld(coo,coo)
+        cl.setCoords(coo)
+        cl.checkCoherency2()
+        li4=[sqrt(2.)*elt for elt in [1.,3.,5.,7.]]
+        li4_1=[0.5,0.5,2.5,2.5,6.5,6.5,12.5,12.5]
+        self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14))
+        self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14))
+        self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14))
+        self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14))
+        pass
+
+    def testSwigCurveLinearMeshNonRegression1(self):
+        coords=DataArrayDouble([0.0, 0.0, 0.10000000149011612, 0.6000000238418579, 0.10000000149011612, 0.30000001192092896, 1.100000023841858, 0.10000000149011612, 0.20000000298023224, 0.10000000149011612, 0.6000000238418579, 0.20000000298023224, 0.699999988079071, 0.6000000238418579, 0.10000000149011612, 1.2000000476837158, 0.6000000238418579, 0.30000001192092896, 0.10000000149011612, 1.100000023841858, 0.30000001192092896, 0.5, 1.100000023841858, 0.20000000298023224, 1.0, 1.2000000476837158, 0.10000000149011612, 0.0, 0.10000000149011612, 0.5, 0.5, 0.10000000149011612, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 0.699999988079071, 0.10000000149011612, 0.6000000238418579, 0.699999988079071, 0.6000000238418579, 0.6000000238418579, 0.5, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 0.10000000149011612, 1.0, 0.6000000238418579, 0.699999988079071, 1.2000000476837158, 0.699999988079071, 0.8999999761581421, 1.0, 0.5, 0.10000000149011612, 0.10000000149011612, 1.2000000476837158, 0.699999988079071, 0.10000000149011612, 1.0, 1.0, 0.10000000149011612, 1.100000023841858, 0.10000000149011612, 0.6000000238418579, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 1.100000023841858, 1.100000023841858, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 1.2000000476837158, 1.0, 0.5, 1.100000023841858, 1.2000000476837158, 1.2000000476837158, 1.100000023841858, 1.0],27,3)
+        m=MEDCouplingCurveLinearMesh("toto")
+        m.setCoords(coords)
+        m.setNodeGridStructure([3,3,3])
+        #
+        vol=m.getMeasureField(False).getArray()
+        self.assertTrue(vol.isEqual(DataArrayDouble([0.11450000709295281, 0.10583334351579375,0.11149999939029423,0.08866666863113633, 0.1404166805123294,0.1250000135352219,0.1270833433481557,0.13258334288001067]),1e-12))
+        self.assertTrue(vol.isEqual(m.buildUnstructured().getMeasureField(False).getArray(),1e-12))
+        #
+        self.assertTrue(m.getBarycenterAndOwner().isEqual(m.buildUnstructured().getBarycenterAndOwner(),1e-12))
+        pass
+
     def setUp(self):
         pass
     pass
index 48c3ec0e32fdb91bbba71f166adf421ae4934046..8f47503cfd3c4b6864ab58ff992a0bf74aaf84c4 100644 (file)
@@ -29,6 +29,7 @@
 #include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingExtrudedMesh.hxx"
 #include "MEDCouplingCMesh.hxx"
+#include "MEDCouplingCurveLinearMesh.hxx"
 #include "MEDCouplingField.hxx"
 #include "MEDCouplingFieldDouble.hxx"
 #include "MEDCouplingFieldTemplate.hxx"
@@ -60,6 +61,11 @@ using namespace INTERP_KERNEL;
   $result=convertMesh($1,$owner);
 }
 
+%typemap(out) ParaMEDMEM::MEDCouplingStructuredMesh*
+{
+  $result=convertMesh($1,$owner);
+}
+
 %typemap(out) ParaMEDMEM::MEDCouplingFieldDiscretization*
 {
   $result=convertFieldDiscretization($1,$owner);
@@ -143,6 +149,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::DataArrayInt::renumberAndReduce;
 %newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2O;
 %newobject ParaMEDMEM::DataArrayInt::invertArrayN2O2O2N;
+%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2OBis;
 %newobject ParaMEDMEM::DataArrayInt::getIdsEqual;
 %newobject ParaMEDMEM::DataArrayInt::getIdsNotEqual;
 %newobject ParaMEDMEM::DataArrayInt::getIdsEqualList;
@@ -163,6 +170,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::DataArrayInt::buildComplement;
 %newobject ParaMEDMEM::DataArrayInt::buildUnion;
 %newobject ParaMEDMEM::DataArrayInt::buildSubstraction;
+%newobject ParaMEDMEM::DataArrayInt::buildSubstractionOptimized;
 %newobject ParaMEDMEM::DataArrayInt::buildIntersection;
 %newobject ParaMEDMEM::DataArrayInt::buildUnique;
 %newobject ParaMEDMEM::DataArrayInt::deltaShiftIndex;
@@ -256,6 +264,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingMesh::buildUnstructured;
 %newobject ParaMEDMEM::MEDCouplingMesh::MergeMeshes;
 %newobject ParaMEDMEM::MEDCouplingPointSet::zipCoordsTraducer;
+%newobject ParaMEDMEM::MEDCouplingPointSet::getCellsInBoundingBox;
 %newobject ParaMEDMEM::MEDCouplingPointSet::findBoundaryNodes;
 %newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh;
 %newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray;
@@ -278,6 +287,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes;
 %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshesOnSameCoords;
 %newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGradually;
+%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed;
 %newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt;
 %newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes;
 %newobject ParaMEDMEM::MEDCouplingUMesh::sortCellsInMEDFileFrmt;
@@ -294,6 +304,8 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField;
 %newobject ParaMEDMEM::MEDCouplingUMesh::keepCellIdsByType;
 %newobject ParaMEDMEM::MEDCouplingUMesh::Build0DMeshFromCoords;
+%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells;
+%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DCells;
 %newobject ParaMEDMEM::MEDCouplingUMesh::findCellIdsOnBoundary;
 %newobject ParaMEDMEM::MEDCouplingUMesh::computeSkin;
 %newobject ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes;
@@ -308,6 +320,9 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingCMesh::New;
 %newobject ParaMEDMEM::MEDCouplingCMesh::clone;
 %newobject ParaMEDMEM::MEDCouplingCMesh::getCoordsAt;
+%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::New;
+%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::clone;
+%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::getCoords;
 %newobject ParaMEDMEM::MEDCouplingMultiFields::New;
 %newobject ParaMEDMEM::MEDCouplingMultiFields::deepCpy;
 %newobject ParaMEDMEM::MEDCouplingFieldOverTime::New;
@@ -373,7 +388,57 @@ namespace INTERP_KERNEL
 }
 
 %include "MEDCouplingTimeLabel.hxx"
-%include "MEDCouplingRefCountObject.hxx"
+
+namespace ParaMEDMEM
+{
+  typedef enum
+    {
+      C_DEALLOC = 2,
+      CPP_DEALLOC = 3
+    } DeallocType;
+
+  typedef enum
+    {
+      ON_CELLS = 0,
+      ON_NODES = 1,
+      ON_GAUSS_PT = 2,
+      ON_GAUSS_NE = 3,
+      ON_NODES_KR = 4
+    } TypeOfField;
+
+  typedef enum
+    {
+      NO_TIME = 4,
+      ONE_TIME = 5,
+      LINEAR_TIME = 6,
+      CONST_ON_TIME_INTERVAL = 7
+    } TypeOfTimeDiscretization;
+
+  const char *MEDCouplingVersionStr();
+  int MEDCouplingVersion();
+  PyObject *MEDCouplingVersionMajMinRel()
+  {
+    int tmp0=0,tmp1=0,tmp2=0;
+    MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2);
+    PyObject *res = PyList_New(3);
+    PyList_SetItem(res,0,SWIG_From_int(tmp0));
+    PyList_SetItem(res,1,SWIG_From_int(tmp1));
+    PyList_SetItem(res,2,SWIG_From_int(tmp2));
+    return res;
+  }
+
+  class MEDCOUPLING_EXPORT RefCountObject
+  {
+  protected:
+    RefCountObject();
+    RefCountObject(const RefCountObject& other);
+    ~RefCountObject();
+  public:
+    bool decrRef() const;
+    void incrRef() const;
+    virtual std::size_t getHeapMemorySize() const;
+  };
+}
 
 namespace ParaMEDMEM
 {
@@ -382,7 +447,8 @@ namespace ParaMEDMEM
       UNSTRUCTURED = 5,
       UNSTRUCTURED_DESC = 6,
       CARTESIAN = 7,
-      EXTRUDED = 8
+      EXTRUDED = 8,
+      CURVE_LINEAR = 9
     } MEDCouplingMeshType;
 
   class DataArrayInt;
@@ -662,55 +728,44 @@ namespace ParaMEDMEM
 
          PyObject *buildPart(PyObject *li) const throw(INTERP_KERNEL::Exception)
          {
-           void *da=0;
-           int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 |  0 );
-           if (!SWIG_IsOK(res1))
-             {
-               int size;
-               INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size);
-               MEDCouplingMesh *ret=self->buildPart(tmp,((const int *)tmp)+size);
-               return convertMesh(ret, SWIG_POINTER_OWN | 0 );
-             }
-           else
-             {
-               DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da);
-               if(!da2)
-                 throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !");
-               da2->checkAllocated();
-               MEDCouplingMesh *ret=self->buildPart(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems());
-               ret->setName(da2->getName().c_str());
-               return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+           int szArr,sw,iTypppArr;
+           std::vector<int> stdvecTyyppArr;
+           const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+           MEDCouplingMesh *ret=self->buildPart(tmp,tmp+szArr);
+           if(sw==3)//DataArrayInt
+             { 
+               void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0);
+               DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp);
+               std::string name=argpt->getName();
+               if(!name.empty())
+                 ret->setName(name.c_str());
              }
+           return convertMesh(ret, SWIG_POINTER_OWN | 0 );
          }
         
-        PyObject *buildPartAndReduceNodes(PyObject *li) const throw(INTERP_KERNEL::Exception)
-        {
-          void *da=0;
-          DataArrayInt *arr=0;
-          MEDCouplingMesh *ret=0;
-           int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 |  0 );
-           if (!SWIG_IsOK(res1))
-             {
-               int size;
-               INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size);
-               ret=self->buildPartAndReduceNodes(tmp,((const int *)tmp)+size,arr);
+         PyObject *buildPartAndReduceNodes(PyObject *li) const throw(INTERP_KERNEL::Exception)
+         {
+           int szArr,sw,iTypppArr;
+           std::vector<int> stdvecTyyppArr;
+           DataArrayInt *arr=0;
+           const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+           MEDCouplingMesh *ret=self->buildPartAndReduceNodes(tmp,tmp+szArr,arr);
+           if(sw==3)//DataArrayInt
+             { 
+               void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0);
+               DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp);
+               std::string name=argpt->getName();
+               if(!name.empty())
+                 ret->setName(name.c_str());
              }
-           else
-             {
-               DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da);
-               if(!da2)
-                 throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !");
-               da2->checkAllocated();
-               ret=self->buildPartAndReduceNodes(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),arr);
-               ret->setName(da2->getName().c_str());
-             }
-          PyObject *res = PyList_New(2);
-          PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 );
-          PyObject *obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
-          PyList_SetItem(res,0,obj0);
-          PyList_SetItem(res,1,obj1);
-          return res;
-        }
+           //
+           PyObject *res = PyList_New(2);
+           PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 );
+           PyObject *obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
+           PyList_SetItem(res,0,obj0);
+           PyList_SetItem(res,1,obj1);
+           return res;
+         }
 
         PyObject *getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
         {
@@ -756,18 +811,18 @@ namespace ParaMEDMEM
           return ret;
         }
 
-         void translate(PyObject *vector) throw(INTERP_KERNEL::Exception)
-         {
-           double val;
-           DataArrayDouble *a;
-           DataArrayDoubleTuple *aa;
-           std::vector<double> bb;
-           int sw;
-           int spaceDim=self->getSpaceDimension();
-           const char msg[]="Python wrap of MEDCouplingPointSet::translate : ";
-           const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val,a,aa,bb,msg,1,spaceDim,true);
-           self->translate(vectorPtr);
-         }
+        void translate(PyObject *vector) throw(INTERP_KERNEL::Exception)
+        {
+          double val;
+          DataArrayDouble *a;
+          DataArrayDoubleTuple *aa;
+          std::vector<double> bb;
+          int sw;
+          int spaceDim=self->getSpaceDimension();
+          const char msg[]="Python wrap of MEDCouplingPointSet::translate : ";
+          const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val,a,aa,bb,msg,1,spaceDim,true);
+          self->translate(vectorPtr);
+        }
 
          void rotate(PyObject *center, double alpha) throw(INTERP_KERNEL::Exception)
          {
@@ -845,10 +900,10 @@ namespace ParaMEDMEM
 %extend ParaMEDMEM::DataArrayInt
 {
   PyObject *getDifferentValues() const throw(INTERP_KERNEL::Exception)
-   {
-     std::set<int> ret=self->getDifferentValues();
-     return convertIntArrToPyList3(ret);
-   }
+  {
+    std::set<int> ret=self->getDifferentValues();
+    return convertIntArrToPyList3(ret);
+  }
 
   PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception)
   {
@@ -930,7 +985,7 @@ namespace ParaMEDMEM
       void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const throw(INTERP_KERNEL::Exception);
       void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
                            const std::vector<std::string>& littleStrings) throw(INTERP_KERNEL::Exception);
-      virtual void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems) throw(INTERP_KERNEL::Exception);
+      virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception);
       virtual DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception);
       virtual DataArrayInt *findBoundaryNodes() const;
       %extend 
@@ -966,111 +1021,74 @@ namespace ParaMEDMEM
              ret1->incrRef();
              return SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0);
            }
+           
            PyObject *buildPartOfMySelf(PyObject *li, bool keepCoords=true) const throw(INTERP_KERNEL::Exception)
            {
-             void *da=0;
-             int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 |  0 );
-             if (!SWIG_IsOK(res1))
-               {
-                 int size;
-                 INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size);
-                 MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,((const int *)tmp)+size,keepCoords);
-                 return convertMesh(ret, SWIG_POINTER_OWN | 0 );
-               }
-             else
-               {
-                 DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da);
-                 if(!da2)
-                   throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !");
-                 da2->checkAllocated();
-                 MEDCouplingPointSet *ret=self->buildPartOfMySelf(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),keepCoords);
-                 ret->setName(da2->getName().c_str());
-                 return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+             int szArr,sw,iTypppArr;
+             std::vector<int> stdvecTyyppArr;
+             const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+             MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,tmp+szArr,keepCoords);
+             if(sw==3)//DataArrayInt
+               { 
+                 void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0);
+                 DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp);
+                 std::string name=argpt->getName();
+                 if(!name.empty())
+                   ret->setName(name.c_str());
                }
+             return convertMesh(ret, SWIG_POINTER_OWN | 0 );
            }
+           
            PyObject *buildPartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception)
            {
-             void *da=0;
-             int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 |  0 );
-             if (!SWIG_IsOK(res1))
-               {
-                 int size;
-                 INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size);
-                 MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,((const int *)tmp)+size,fullyIn);
-                 return convertMesh(ret, SWIG_POINTER_OWN | 0 );
-               }
-             else
-               {
-                 DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da);
-                 if(!da2)
-                   throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !");
-                 da2->checkAllocated();
-                 MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn);
-                 ret->setName(da2->getName().c_str());
-                 return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+             int szArr,sw,iTypppArr;
+             std::vector<int> stdvecTyyppArr;
+             const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+             MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,tmp+szArr,fullyIn);
+             if(sw==3)//DataArrayInt
+               { 
+                 void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0);
+                 DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp);
+                 std::string name=argpt->getName();
+                 if(!name.empty())
+                   ret->setName(name.c_str());
                }
+             return convertMesh(ret, SWIG_POINTER_OWN | 0 );
            }
+
            PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception)
            {
-             void *da=0;
-             int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 |  0 );
-             if (!SWIG_IsOK(res1))
-               {
-                 int size;
-                 INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size);
-                 MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,((const int *)tmp)+size,fullyIn);
-                 return convertMesh(ret, SWIG_POINTER_OWN | 0 );
-               }
-             else
-               {
-                 DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da);
-                 if(!da2)
-                   throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !");
-                 da2->checkAllocated();
-                 MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn);
-                 ret->setName(da2->getName().c_str());
-                 return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+             int szArr,sw,iTypppArr;
+             std::vector<int> stdvecTyyppArr;
+             const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+             MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,tmp+szArr,fullyIn);
+             if(sw==3)//DataArrayInt
+               { 
+                 void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0);
+                 DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp);
+                 std::string name=argpt->getName();
+                 if(!name.empty())
+                   ret->setName(name.c_str());
                }
+             return convertMesh(ret, SWIG_POINTER_OWN | 0 );
            }
 
            void renumberNodes(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception)
            {
-             void *da=0;
-             int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 );
-             if (!SWIG_IsOK(res1))
-               {
-                 int size;
-                 INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size);
-                 self->renumberNodes(tmp,newNbOfNodes);
-               }
-             else
-               {
-                 DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da);
-                 if(!da2)
-                   throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !");
-                 da2->checkAllocated();
-                 self->renumberNodes(da2->getConstPointer(),newNbOfNodes);
-               }
+             int szArr,sw,iTypppArr;
+             std::vector<int> stdvecTyyppArr;
+             const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+             self->renumberNodes(tmp,newNbOfNodes);
            }
+
            void renumberNodes2(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception)
            {
-             void *da=0;
-             int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 );
-             if (!SWIG_IsOK(res1))
-               {
-                 int size;
-                 INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size);
-                 self->renumberNodes2(tmp,newNbOfNodes);
-               }
-             else
-               {
-                 DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da);
-                 if(!da2)
-                   throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !");
-                 da2->checkAllocated();
-                 self->renumberNodes2(da2->getConstPointer(),newNbOfNodes);
-               }
+             int szArr,sw,iTypppArr;
+             std::vector<int> stdvecTyyppArr;
+             const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+             self->renumberNodes2(tmp,newNbOfNodes);
            }
+
            PyObject *findNodesOnLine(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception)
              {
                int spaceDim=self->getSpaceDimension();
@@ -1109,6 +1127,7 @@ namespace ParaMEDMEM
                std::copy(nodes.begin(),nodes.end(),ret->getPointer());
                return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
              }
+           
            PyObject *getNodeIdsNearPoint(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception)
            {
              double val;
@@ -1119,16 +1138,13 @@ namespace ParaMEDMEM
              int spaceDim=self->getSpaceDimension();
              const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoint : ";
              const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true);
-             std::vector<int> tmp=self->getNodeIdsNearPoint(pos,eps);
-             DataArrayInt *ret=DataArrayInt::New();
-             ret->alloc((int)tmp.size(),1);
-             std::copy(tmp.begin(),tmp.end(),ret->getPointer());
+             DataArrayInt *ret=self->getNodeIdsNearPoint(pos,eps);
              return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
            }
 
            PyObject *getNodeIdsNearPoints(PyObject *pt, int nbOfNodes, double eps) const throw(INTERP_KERNEL::Exception)
            {
-             std::vector<int> c,cI;
+             DataArrayInt *c=0,*cI=0;
              //
              double val;
              DataArrayDouble *a;
@@ -1140,69 +1156,32 @@ namespace ParaMEDMEM
              const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,nbOfNodes,spaceDim,true);
              self->getNodeIdsNearPoints(pos,nbOfNodes,eps,c,cI);
              PyObject *ret=PyTuple_New(2);
-             MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New();
-             MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New();
-             d0->alloc(c.size(),1);
-             d1->alloc(cI.size(),1);
-             std::copy(c.begin(),c.end(),d0->getPointer());
-             std::copy(cI.begin(),cI.end(),d1->getPointer());
-             PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-             PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-             d0->incrRef();
-             d1->incrRef();
+             PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+             PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
              return ret;
            }
 
            PyObject *getNodeIdsNearPoints(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception)
            {
-             std::vector<int> c,cI;
+             DataArrayInt *c=0,*cI=0;
              int spaceDim=self->getSpaceDimension();
-             void *da=0;
-             int res1=SWIG_ConvertPtr(pt,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 |  0 );
-             if (!SWIG_IsOK(res1))
-               {
-                 int size;
-                 INTERP_KERNEL::AutoPtr<double> tmp=convertPyToNewDblArr2(pt,&size);
-                 int nbOfPoints=size/spaceDim;
-                 if(size%spaceDim!=0)
-                   {
-                     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCellsContainingPoints : Invalid list length ! Must be a multiple of self.getSpaceDimension() !");
-                   }
-                 self->getNodeIdsNearPoints(tmp,nbOfPoints,eps,c,cI);
-               }
-             else
-               {
-                 DataArrayDouble *da2=reinterpret_cast< DataArrayDouble * >(da);
-                 if(!da2)
-                   throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCellsContainingPoints : Not null DataArrayDouble instance expected !");
-                 da2->checkAllocated();
-                 int size=da2->getNumberOfTuples();
-                 int nbOfCompo=da2->getNumberOfComponents();
-                 if(nbOfCompo!=spaceDim)
-                   {
-                     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCellsContainingPoints : Invalid DataArrayDouble nb of components ! Expected same as self.getSpaceDimension() !");
-                   }
-                 self->getNodeIdsNearPoints(da2->getConstPointer(),size,eps,c,cI);
-               }
+             double val;
+             DataArrayDouble *a;
+             DataArrayDoubleTuple *aa;
+             std::vector<double> bb;
+             int sw;
+             int nbOfTuples=-1;
+             const double *ptPtr=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::getNodeIdsNearPoints",spaceDim,true,nbOfTuples);
+             self->getNodeIdsNearPoints(ptPtr,nbOfTuples,eps,c,cI);
+             //
              PyObject *ret=PyTuple_New(2);
-             MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New();
-             MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New();
-             d0->alloc(c.size(),1);
-             d1->alloc(cI.size(),1);
-             std::copy(c.begin(),c.end(),d0->getPointer());
-             std::copy(cI.begin(),cI.end(),d1->getPointer());
-             PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-             PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-             d0->incrRef();
-             d1->incrRef();
+             PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+             PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
              return ret;
            }
 
            PyObject *getCellsInBoundingBox(PyObject *bbox, double eps) const throw(INTERP_KERNEL::Exception)
            {
-             std::vector<int> elems;
-             //
-             //
              double val;
              DataArrayDouble *a;
              DataArrayDoubleTuple *aa;
@@ -1212,11 +1191,8 @@ namespace ParaMEDMEM
              const char msg[]="Python wrap of MEDCouplingPointSet::getCellsInBoundingBox : ";
              const double *tmp=convertObjToPossibleCpp5_Safe(bbox,sw,val,a,aa,bb,msg,spaceDim,2,true);
              //
-             self->getCellsInBoundingBox(tmp,eps,elems);
-             DataArrayInt *ret=DataArrayInt::New();
-             ret->alloc((int)elems.size(),1);
-             std::copy(elems.begin(),elems.end(),ret->getPointer());
-             return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
+             DataArrayInt *elems=self->getCellsInBoundingBox(tmp,eps);
+             return SWIG_NewPointerObj(SWIG_as_voidptr(elems),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
            }
 
            void duplicateNodesInCoords(PyObject *li) throw(INTERP_KERNEL::Exception)
@@ -1408,11 +1384,12 @@ namespace ParaMEDMEM
     DataArrayInt *findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *computeSkin() const throw(INTERP_KERNEL::Exception);
     bool checkConsecutiveCellTypes() const throw(INTERP_KERNEL::Exception);
+    bool checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *rearrange2ConsecutiveCellTypes() throw(INTERP_KERNEL::Exception);
     DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception);
     DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception);
-    DataArrayInt *zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception);
+    DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception);
     DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
@@ -1431,6 +1408,8 @@ namespace ParaMEDMEM
     MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception);
     std::string cppRepr() const throw(INTERP_KERNEL::Exception);
+    DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception);
+    DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
@@ -1636,11 +1615,12 @@ namespace ParaMEDMEM
 
       void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, PyObject *li) throw(INTERP_KERNEL::Exception)
       {
-        int sz;
-        INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&sz);
-        if(size>sz)
+        int szArr,sw,iTypppArr;
+        std::vector<int> stdvecTyyppArr;
+        const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+        if(size>szArr)
           {
-            std::ostringstream oss; oss << "Wrap of MEDCouplingUMesh::insertNextCell : request of connectivity with length " << size << " whereas the length of input is " << sz << " !";
+            std::ostringstream oss; oss << "Wrap of MEDCouplingUMesh::insertNextCell : request of connectivity with length " << size << " whereas the length of input is " << szArr << " !";
             throw INTERP_KERNEL::Exception(oss.str().c_str());
           }
         self->insertNextCell(type,size,tmp);
@@ -1648,9 +1628,10 @@ namespace ParaMEDMEM
 
       void insertNextCell(INTERP_KERNEL::NormalizedCellType type, PyObject *li) throw(INTERP_KERNEL::Exception)
       {
-        int sz;
-        INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&sz);
-        self->insertNextCell(type,sz,tmp);
+        int szArr,sw,iTypppArr;
+        std::vector<int> stdvecTyyppArr;
+        const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr);
+        self->insertNextCell(type,szArr,tmp);
       }
       
       DataArrayInt *getNodalConnectivity() throw(INTERP_KERNEL::Exception)
@@ -1676,6 +1657,59 @@ namespace ParaMEDMEM
           PyList_SetItem(res,i,PyInt_FromLong(*iL));
         return res;
       }
+      
+      static PyObject *ComputeSpreadZoneGraduallyFromSeed(PyObject *seed, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling=-1) throw(INTERP_KERNEL::Exception)
+      {
+        int szArr,sw,iTypppArr;
+        std::vector<int> stdvecTyyppArr;
+        const int *seedPtr=convertObjToPossibleCpp1_Safe(seed,sw,szArr,iTypppArr,stdvecTyyppArr);
+        int nbOfDepthPeelingPerformed=0;
+        DataArrayInt *ret0=MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(seedPtr,seedPtr+szArr,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed);
+        PyObject *res=PyTuple_New(2);
+        PyTuple_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyTuple_SetItem(res,1,PyInt_FromLong(nbOfDepthPeelingPerformed));
+        return res;
+      }
+
+      PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception)
+      {
+        DataArrayInt *v0=0,*v1=0;
+        self->findCommonCells(compType,startCellId,v0,v1);
+        PyObject *res = PyList_New(2);
+        PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        return res;
+      }
+
+      static PyObject *FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI) throw(INTERP_KERNEL::Exception)
+      {
+        DataArrayInt *v0=0,*v1=0;
+        MEDCouplingUMesh::FindCommonCellsAlg(compType,startCellId,nodal,nodalI,revNodal,revNodalI,v0,v1);
+        PyObject *res = PyList_New(2);
+        PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        return res;
+      }
+      
+      PyObject *distanceToPoint(PyObject *point) const throw(INTERP_KERNEL::Exception)
+      {
+        double val;
+        DataArrayDouble *a;
+        DataArrayDoubleTuple *aa;
+        std::vector<double> bb;
+        int sw;
+        int nbOfCompo=self->getSpaceDimension();
+        const double *pt=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::distanceToPoint",1,nbOfCompo,true);
+        //
+        int cellId=-1,nodeId=-1;
+        double ret0=self->distanceToPoint(pt,pt+nbOfCompo,cellId,nodeId);
+        PyObject *ret=PyTuple_New(3);
+        PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0));
+        PyTuple_SetItem(ret,1,PyInt_FromLong(cellId));
+        PyTuple_SetItem(ret,2,PyInt_FromLong(nodeId));
+        return ret;
+      }
+
       PyObject *mergeNodes(double precision) throw(INTERP_KERNEL::Exception)
       {
         bool ret1;
@@ -2073,16 +2107,6 @@ namespace ParaMEDMEM
         return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
       }
 
-      PyObject *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception)
-      {
-        std::vector<int> cells;
-        self->findAndCorrectBadOriented3DExtrudedCells(cells);
-        DataArrayInt *ret=DataArrayInt::New();
-        ret->alloc((int)cells.size(),1);
-        std::copy(cells.begin(),cells.end(),ret->getPointer());
-        return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
-      }
-
       PyObject *getFastAveragePlaneOfThis() const throw(INTERP_KERNEL::Exception)
       {
         double vec[3];
@@ -2445,7 +2469,15 @@ namespace ParaMEDMEM
     }
   };
 
-  class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingMesh
+  class MEDCouplingStructuredMesh : public ParaMEDMEM::MEDCouplingMesh
+  {
+  public:
+    void updateTime() const throw(INTERP_KERNEL::Exception);
+    int getCellIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception);
+    int getNodeIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception);
+  };
+
+  class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingStructuredMesh
   {
   public:
     static MEDCouplingCMesh *New();
@@ -2455,7 +2487,6 @@ namespace ParaMEDMEM
                    const DataArrayDouble *coordsY=0,
                    const DataArrayDouble *coordsZ=0) throw(INTERP_KERNEL::Exception);
     void setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception);
-    void updateTime() const throw(INTERP_KERNEL::Exception);
     %extend {
       MEDCouplingCMesh()
       {
@@ -2478,6 +2509,45 @@ namespace ParaMEDMEM
       }
     }
   };
+
+  class MEDCouplingCurveLinearMesh : public ParaMEDMEM::MEDCouplingStructuredMesh
+  {
+  public:
+    static MEDCouplingCurveLinearMesh *New();
+    static MEDCouplingCurveLinearMesh *New(const char *meshName);
+    MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const;
+    void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception);
+    std::vector<int> getNodeGridStructure() const throw(INTERP_KERNEL::Exception);
+    %extend {
+      MEDCouplingCurveLinearMesh()
+      {
+        return MEDCouplingCurveLinearMesh::New();
+      }
+      MEDCouplingCurveLinearMesh(const char *meshName)
+      {
+        return MEDCouplingCurveLinearMesh::New(meshName);
+      }
+      std::string __str__() const
+      {
+        return self->simpleRepr();
+      }
+      DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception)
+      {
+        DataArrayDouble *ret=self->getCoords();
+        if(ret)
+          ret->incrRef();
+        return ret;
+      }
+      void setNodeGridStructure(PyObject *gridStruct) throw(INTERP_KERNEL::Exception)
+      {
+        int szArr,sw,iTypppArr;
+        std::vector<int> stdvecTyyppArr;
+        const int *tmp=convertObjToPossibleCpp1_Safe(gridStruct,sw,szArr,iTypppArr,stdvecTyyppArr);
+        self->setNodeGridStructure(tmp,tmp+szArr);
+      }
+    }
+  };
+  
 }
 %extend ParaMEDMEM::MEDCouplingFieldDiscretizationKriging
 {
@@ -2779,17 +2849,17 @@ namespace ParaMEDMEM
      return DataArrayDouble::New();
    }
 
-   static DataArrayDouble *New(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception)
+   static DataArrayDouble *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception)
    {
      const char *msg="ParaMEDMEM::DataArrayDouble::New : Available API are : \n-DataArrayDouble.New()\n--DataArrayDouble.New([1.,3.,4.])\n-DataArrayDouble.New([1.,3.,4.],3)\n-DataArrayDouble.New([1.,3.,4.,5.],2,2)\n-DataArrayDouble.New(5)\n-DataArrayDouble.New(5,2) !";
      if(PyList_Check(elt0) || PyTuple_Check(elt0))
        {
-         if(elt1)
+         if(nbOfTuples)
            {
-             if(PyInt_Check(elt1))
+             if(PyInt_Check(nbOfTuples))
                {
-                 int nbOfTuples=PyInt_AS_LONG(elt1);
-                 if(nbOfTuples<0)
+                 int nbOfTuples1=PyInt_AS_LONG(nbOfTuples);
+                 if(nbOfTuples1<0)
                    throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !");
                  if(elt2)
                    {
@@ -2799,8 +2869,8 @@ namespace ParaMEDMEM
                          if(nbOfCompo<0)
                            throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !");
                          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
-                         std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples,nbOfCompo);
-                         ret->alloc(nbOfTuples,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
+                         std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,nbOfCompo);
+                         ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                          ret->incrRef();
                          return ret;
                        }
@@ -2811,8 +2881,8 @@ namespace ParaMEDMEM
                    {//DataArrayDouble.New([1.,3.,4.],3)
                      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
                      int tmpp1=-1;
-                     std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples,tmpp1);
-                     ret->alloc(nbOfTuples,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
+                     std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,tmpp1);
+                     ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                      ret->incrRef();
                      return ret;
                    }
@@ -2832,20 +2902,20 @@ namespace ParaMEDMEM
        }
      else if(PyInt_Check(elt0))
        {
-         int nbOfTuples=PyInt_AS_LONG(elt0);
-         if(nbOfTuples<0)
+         int nbOfTuples1=PyInt_AS_LONG(elt0);
+         if(nbOfTuples1<0)
            throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !");
-         if(elt1)
+         if(nbOfTuples)
            {
              if(!elt2)
                {
-                 if(PyInt_Check(elt1))
+                 if(PyInt_Check(nbOfTuples))
                    {//DataArrayDouble.New(5,2)
-                     int nbOfCompo=PyInt_AS_LONG(elt1);
+                     int nbOfCompo=PyInt_AS_LONG(nbOfTuples);
                      if(nbOfCompo<0)
                        throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !");
                      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
-                     ret->alloc(nbOfTuples,nbOfCompo);
+                     ret->alloc(nbOfTuples1,nbOfCompo);
                      ret->incrRef();
                      return ret;
                    }
@@ -2858,7 +2928,7 @@ namespace ParaMEDMEM
          else
            {//DataArrayDouble.New(5)
              MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
-             ret->alloc(nbOfTuples,1);
+             ret->alloc(nbOfTuples1,1);
              ret->incrRef();
              return ret;
            }
@@ -2867,9 +2937,9 @@ namespace ParaMEDMEM
        throw INTERP_KERNEL::Exception(msg);
    }
    
-   DataArrayDouble(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception)
+   DataArrayDouble(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception)
    {
-     return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,elt1,elt2);
+     return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,nbOfTuples,elt2);
    }
 
    std::string __str__() const
@@ -2898,20 +2968,51 @@ namespace ParaMEDMEM
    {
      return self->iterator();
    }
-
-   void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple) throw(INTERP_KERNEL::Exception)
+   
+   void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception)
    {
-     double *tmp=new double[nbOfTuples*nbOfElsPerTuple];
-     try
+     const char *msg="ParaMEDMEM::DataArrayDouble::setValues : Available API are : \n-DataArrayDouble.setValues([1.,3.,4.])\n-DataArrayDouble.setValues([1.,3.,4.],3)\n-DataArrayDouble.setValues([1.,3.,4.,5.],2,2)\n-DataArrayDouble.setValues([(1.,1.7),(3.,3.7),(4.,4.7)])\n !";
+     if(PyList_Check(li) || PyTuple_Check(li))
        {
-         fillArrayWithPyListDbl(li,tmp,nbOfTuples*nbOfElsPerTuple,0.,false);
-       }
-     catch(INTERP_KERNEL::Exception& e)
-       {
-         delete [] tmp;
-         throw e;
+         if(nbOfTuples)
+           {
+             if(PyInt_Check(nbOfTuples))
+               {
+                 int nbOfTuples1=PyInt_AS_LONG(nbOfTuples);
+                 if(nbOfTuples1<0)
+                   throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive set of allocated memory !");
+                 if(nbOfComp)
+                   {
+                     if(PyInt_Check(nbOfComp))
+                       {//DataArrayDouble.setValues([1.,3.,4.,5.],2,2)
+                         int nbOfCompo=PyInt_AS_LONG(nbOfComp);
+                         if(nbOfCompo<0)
+                           throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive number of components !");
+                         std::vector<double> tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,nbOfCompo);
+                         self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer());
+                       }
+                     else
+                       throw INTERP_KERNEL::Exception(msg);
+                   }
+                 else
+                   {//DataArrayDouble.setValues([1.,3.,4.],3)
+                     int tmpp1=-1;
+                     std::vector<double> tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,tmpp1);
+                     self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer());
+                   }
+               }
+             else
+               throw INTERP_KERNEL::Exception(msg);
+           }
+         else
+           {// DataArrayDouble.setValues([1.,3.,4.])
+             int tmpp1=-1,tmpp2=-1;
+             std::vector<double> tmp=fillArrayWithPyListDbl2(li,tmpp1,tmpp2);
+             self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer());
+           }
        }
-     self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple);
+     else
+       throw INTERP_KERNEL::Exception(msg);
    }
 
    PyObject *getValues() throw(INTERP_KERNEL::Exception)
@@ -3199,6 +3300,24 @@ namespace ParaMEDMEM
      return res;
    }
 
+   PyObject *distanceToTuple(PyObject *tuple) const throw(INTERP_KERNEL::Exception)
+   {
+     double val;
+     DataArrayDouble *a;
+     DataArrayDoubleTuple *aa;
+     std::vector<double> bb;
+     int sw;
+     int tupleId=-1,nbTuples=-1,nbOfCompo=self->getNumberOfComponents();
+     const double *pt=convertObjToPossibleCpp5_Safe(tuple,sw,val,a,aa,bb,"Python wrap of DataArrayDouble::distanceToTuple",1,nbOfCompo,true);
+     //
+     int cellId=-1,nodeId=-1;
+     double ret0=self->distanceToTuple(pt,pt+nbOfCompo,tupleId);
+     PyObject *ret=PyTuple_New(2);
+     PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0));
+     PyTuple_SetItem(ret,1,PyInt_FromLong(tupleId));
+     return ret;
+   }
+
    void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception)
    {
      std::vector<int> tmp;
@@ -3246,14 +3365,11 @@ namespace ParaMEDMEM
      const char msg[]="Python wrap of DataArrayDouble::computeTupleIdsNearTuples : ";
      const double *pos=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,msg,nbComp,true,nbTuples);
      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> inpu=DataArrayDouble::New(); inpu->useArray(pos,false,CPP_DEALLOC,nbTuples,nbComp);
-     std::vector<int> c,cI;
+     DataArrayInt *c=0,*cI=0;
      self->computeTupleIdsNearTuples(inpu,eps,c,cI);
-     DataArrayInt *ret0=DataArrayInt::New(),*ret1=DataArrayInt::New();
-     ret0->alloc((int)c.size(),1); std::copy(c.begin(),c.end(),ret0->getPointer());
-     ret1->alloc((int)cI.size(),1); std::copy(cI.begin(),cI.end(),ret1->getPointer());
      PyObject *ret=PyTuple_New(2);
-     PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-     PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+     PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+     PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
      return ret;
    }
 
@@ -4176,20 +4292,12 @@ namespace ParaMEDMEM
    
    PyObject *computeTupleIdsNearTuples(const DataArrayDouble *other, double eps)
    {
-     std::vector<int> c,cI;
+     DataArrayInt *c=0,*cI=0;
      //
      self->computeTupleIdsNearTuples(other,eps,c,cI);
      PyObject *ret=PyTuple_New(2);
-     MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New();
-     MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New();
-     d0->alloc(c.size(),1);
-     d1->alloc(cI.size(),1);
-     std::copy(c.begin(),c.end(),d0->getPointer());
-     std::copy(cI.begin(),cI.end(),d1->getPointer());
-     PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-     PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-     d0->incrRef();
-     d1->incrRef();
+     PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+     PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
      return ret;
    }
  };
@@ -4490,28 +4598,28 @@ namespace ParaMEDMEM
      return DataArrayInt::New();
    }
 
-   static DataArrayInt *New(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception)
+   static DataArrayInt *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception)
    {
      const char *msg="ParaMEDMEM::DataArrayInt::New : Available API are : \n-DataArrayInt.New()\n--DataArrayInt.New([1,3,4])\n-DataArrayInt.New([1,3,4],3)\n-DataArrayInt.New([1,3,4,5],2,2)\n-DataArrayInt.New(5)\n-DataArrayInt.New(5,2) !";
      if(PyList_Check(elt0) || PyTuple_Check(elt0))
        {
-         if(elt1)
+         if(nbOfTuples)
            {
-             if(PyInt_Check(elt1))
+             if(PyInt_Check(nbOfTuples))
                {
-                 int nbOfTuples=PyInt_AS_LONG(elt1);
-                 if(nbOfTuples<0)
+                 int nbOfTuples1=PyInt_AS_LONG(nbOfTuples);
+                 if(nbOfTuples1<0)
                    throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !");
-                 if(elt2)
+                 if(nbOfComp)
                    {
-                     if(PyInt_Check(elt2))
+                     if(PyInt_Check(nbOfComp))
                        {//DataArrayInt.New([1,3,4,5],2,2)
-                         int nbOfCompo=PyInt_AS_LONG(elt2);
+                         int nbOfCompo=PyInt_AS_LONG(nbOfComp);
                          if(nbOfCompo<0)
                            throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !");
                          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-                         std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples,nbOfCompo);
-                         ret->alloc(nbOfTuples,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
+                         std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo);
+                         ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                          ret->incrRef();
                          return ret;
                        }
@@ -4522,8 +4630,8 @@ namespace ParaMEDMEM
                    {//DataArrayInt.New([1,3,4],3)
                      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
                      int tmpp1=-1;
-                     std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples,tmpp1);
-                     ret->alloc(nbOfTuples,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
+                     std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1);
+                     ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                      ret->incrRef();
                      return ret;
                    }
@@ -4543,20 +4651,20 @@ namespace ParaMEDMEM
        }
      else if(PyInt_Check(elt0))
        {
-         int nbOfTuples=PyInt_AS_LONG(elt0);
-         if(nbOfTuples<0)
+         int nbOfTuples1=PyInt_AS_LONG(elt0);
+         if(nbOfTuples1<0)
            throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !");
-         if(elt1)
+         if(nbOfTuples)
            {
-             if(!elt2)
+             if(!nbOfComp)
                {
-                 if(PyInt_Check(elt1))
+                 if(PyInt_Check(nbOfTuples))
                    {//DataArrayInt.New(5,2)
-                     int nbOfCompo=PyInt_AS_LONG(elt1);
+                     int nbOfCompo=PyInt_AS_LONG(nbOfTuples);
                      if(nbOfCompo<0)
                        throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !");
                      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-                     ret->alloc(nbOfTuples,nbOfCompo);
+                     ret->alloc(nbOfTuples1,nbOfCompo);
                      ret->incrRef();
                      return ret;
                    }
@@ -4569,7 +4677,7 @@ namespace ParaMEDMEM
          else
            {//DataArrayInt.New(5)
              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-             ret->alloc(nbOfTuples,1);
+             ret->alloc(nbOfTuples1,1);
              ret->incrRef();
              return ret;
            }
@@ -4578,9 +4686,9 @@ namespace ParaMEDMEM
        throw INTERP_KERNEL::Exception(msg);
    }
 
-   DataArrayInt(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception)
+   DataArrayInt(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception)
    {
-     return ParaMEDMEM_DataArrayInt_New__SWIG_1(elt0,elt1,elt2);
+     return ParaMEDMEM_DataArrayInt_New__SWIG_1(elt0,nbOfTuples,nbOfComp);
    }
 
    std::string __str__() const
@@ -4609,30 +4717,73 @@ namespace ParaMEDMEM
    {
      return self->iterator();
    }
-
-   static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI) throw(INTERP_KERNEL::Exception)
+   
+   PyObject *accumulate() const throw(INTERP_KERNEL::Exception)
+   {
+     int sz=self->getNumberOfComponents();
+     INTERP_KERNEL::AutoPtr<int> tmp=new int[sz];
+     self->accumulate(tmp);
+     return convertIntArrToPyList(tmp,sz);
+   }
+   
+   static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, PyObject *arr, PyObject *arrI) throw(INTERP_KERNEL::Exception)
    {
      int newNbOfTuples=-1;
-     DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arr,arrI,newNbOfTuples);
+     int szArr,szArrI,sw,iTypppArr,iTypppArrI;
+     std::vector<int> stdvecTyyppArr,stdvecTyyppArrI;
+     const int *arrPtr=convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr);
+     const int *arrIPtr=convertObjToPossibleCpp1_Safe(arrI,sw,szArrI,iTypppArrI,stdvecTyyppArrI);
+     DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arrPtr,arrIPtr,arrIPtr+szArrI,newNbOfTuples);
      PyObject *ret=PyTuple_New(2);
      PyTuple_SetItem(ret,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0));
      PyTuple_SetItem(ret,1,PyInt_FromLong(newNbOfTuples));
      return ret;
    }
 
-   void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple) throw(INTERP_KERNEL::Exception)
+   void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception)
    {
-     int *tmp=new int[nbOfTuples*nbOfElsPerTuple];
-     try
-       {
-         fillArrayWithPyListInt(li,tmp,nbOfTuples*nbOfElsPerTuple,0,false);
-       }
-     catch(INTERP_KERNEL::Exception& e)
+     const char *msg="ParaMEDMEM::DataArrayInt::setValues : Available API are : \n-DataArrayInt.setValues([1,3,4])\n-DataArrayInt.setValues([1,3,4],3)\n-DataArrayInt.setValues([1,3,4,5],2,2)\n-DataArrayInt.New(5)\n !";
+     if(PyList_Check(li) || PyTuple_Check(li))
        {
-         delete [] tmp;
-         throw e;
+         if(nbOfTuples)
+           {
+             if(PyInt_Check(nbOfTuples))
+               {
+                 int nbOfTuples1=PyInt_AS_LONG(nbOfTuples);
+                 if(nbOfTuples<0)
+                   throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive set of allocated memory !");
+                 if(nbOfComp)
+                   {
+                     if(PyInt_Check(nbOfComp))
+                       {//DataArrayInt.setValues([1,3,4,5],2,2)
+                         int nbOfCompo=PyInt_AS_LONG(nbOfComp);
+                         if(nbOfCompo<0)
+                           throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive number of components !");
+                         std::vector<int> tmp=fillArrayWithPyListInt2(li,nbOfTuples1,nbOfCompo);
+                         self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer());
+                       }
+                     else
+                       throw INTERP_KERNEL::Exception(msg);
+                   }
+                 else
+                   {//DataArrayInt.setValues([1,3,4],3)
+                     int tmpp1=-1;
+                     std::vector<int> tmp=fillArrayWithPyListInt2(li,nbOfTuples1,tmpp1);
+                     self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer());
+                   }
+               }
+             else
+               throw INTERP_KERNEL::Exception(msg);
+           }
+         else
+           {// DataArrayInt.setValues([1,3,4])
+             int tmpp1=-1,tmpp2=-1;
+             std::vector<int> tmp=fillArrayWithPyListInt2(li,tmpp1,tmpp2);
+             self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer());
+           }
        }
-     self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple);
+     else
+       throw INTERP_KERNEL::Exception(msg);
    }
 
    PyObject *getValues() throw(INTERP_KERNEL::Exception)
@@ -6347,14 +6498,16 @@ namespace ParaMEDMEM
   class MEDCouplingFieldDouble : public ParaMEDMEM::MEDCouplingField
   {
   public:
-    static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME);
-    static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=NO_TIME);
+    static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME);
+    static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME);
     void setTimeUnit(const char *unit);
     const char *getTimeUnit() const;
+    void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception);
     void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
     void copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
     std::string simpleRepr() const;
     std::string advancedRepr() const;
+    void writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *clone(bool recDeepCpy) const;
     MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const;
     MEDCouplingFieldDouble *deepCpy() const;
@@ -6362,6 +6515,7 @@ namespace ParaMEDMEM
     TypeOfTimeDiscretization getTimeDiscretization() const throw(INTERP_KERNEL::Exception);
     double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception);
     double getIJK(int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception);
+    void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception);
     void setArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception);
     void setEndArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception);
     void setTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception);
@@ -6439,12 +6593,12 @@ namespace ParaMEDMEM
     MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception);
     %extend {
-      MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME)
+      MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME)
       {
         return MEDCouplingFieldDouble::New(type,td);
       }
 
-      MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=NO_TIME)
+      MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME)
       {
         return MEDCouplingFieldDouble::New(ft,td);
       }
@@ -7126,19 +7280,6 @@ namespace ParaMEDMEM
   };
 }
 
-%inline %{
-  PyObject *MEDCouplingVersionMajMinRel()
-  {
-    int tmp0=0,tmp1=0,tmp2=0;
-    MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2);
-    PyObject *res = PyList_New(3);
-    PyList_SetItem(res,0,SWIG_From_int(tmp0));
-    PyList_SetItem(res,1,SWIG_From_int(tmp1));
-    PyList_SetItem(res,2,SWIG_From_int(tmp2));
-    return res;
-  }
-%}
-
 %pythoncode %{
 import os
 __filename=os.environ.get('PYTHONSTARTUP')
index 5c8042f5ecc6323988e8577041bb17e480ba1990..1998d7fdfe386981d9b8027c2632bd5143e42c7f 100644 (file)
@@ -285,6 +285,39 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12);
             pass
         pass
+
+    # Bug when source mesh is not homogeneously oriented in source mesh
+    def testNonRegressionNonHomegenousOrriented3DCells(self):
+        csrc=DataArrayDouble([-0.15240000188350677,0,0,-0.1086929515004158,0,0,-0.15240000188350677,0.018142856657505035,0,-0.13054648041725159,0.0090714283287525177,0.019050000235438347,-0.13054648041725159,0.0090714283287525177,0],5,3)
+        src1=MEDCouplingUMesh("src",3) ; src1.allocateCells(0) ; src1.insertNextCell(NORM_TETRA4,[0,1,4,3]) ; src1.insertNextCell(NORM_TETRA4,[2,0,4,3])
+        src2=MEDCouplingUMesh("src",3) ; src2.allocateCells(0) ; src2.insertNextCell(NORM_TETRA4,[0,4,1,3]) ; src2.insertNextCell(NORM_TETRA4,[2,0,4,3])
+        src1.setCoords(csrc) ; src2.setCoords(csrc)
+        ctrg=DataArrayDouble([-0.15240000188350677,-0.038100000470876694,0,0.32379999756813049,-0.038100000470876694,0,-0.15240000188350677,0.076200000941753387,0,0.32379999756813049,0.076200000941753387,0,-0.15240000188350677,-0.038100000470876694,0.076200000941753387,0.32379999756813049,-0.038100000470876694,0.076200000941753387,-0.15240000188350677,0.076200000941753387,0.076200000941753387,0.32379999756813049,0.076200000941753387,0.076200000941753387],8,3)
+        trg=MEDCouplingUMesh("trg",3) ; trg.allocateCells(0) ; trg.insertNextCell(NORM_HEXA8,[0,1,3,2,4,5,7,6])
+        trg.setCoords(ctrg)
+        rem1=MEDCouplingRemapper() ; rem1.setSplittingPolicy(PLANAR_FACE_5) ; rem1.prepare(src1,trg,"P0P0")
+        rem2=MEDCouplingRemapper() ; rem2.setSplittingPolicy(PLANAR_FACE_5) ; rem2.prepare(src1,trg,"P0P0")
+        mat1=rem1.getCrudeMatrix() ; mat2=rem2.getCrudeMatrix()
+        self.assertEqual(1,len(mat1)) ; self.assertEqual(1,len(mat2))
+        self.assertEqual(mat1[0].keys(),mat2[0].keys()) ; self.assertEqual([0,1],mat1[0].keys())
+        self.assertAlmostEqual(1.25884108122e-06,mat1[0][0],16) ; self.assertAlmostEqual(1.25884108122e-06,mat2[0][0],16)
+        self.assertAlmostEqual(1.25884086663e-06,mat1[0][1],16) ; self.assertAlmostEqual(1.25884086663e-06,mat2[0][1],16)
+        #
+        d=DataArrayDouble([13.45,27.67],2,1)
+        f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f1.setMesh(src1) ; f1.setArray(d) ; f1.setNature(RevIntegral)
+        f2=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f2.setMesh(src2) ; f2.setArray(d) ; f2.setNature(RevIntegral)
+        f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300)
+        expected1=DataArrayDouble([0.012480539537637884])
+        self.assertTrue(f11.getArray().isEqual(expected1,1e-15))
+        self.assertTrue(f22.getArray().isEqual(expected1,1e-15))
+        #
+        f1.setNature(Integral) ; f2.setNature(Integral)
+        f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300)
+        #
+        expected2=DataArrayDouble([41.12])
+        self.assertTrue(f11.getArray().isEqual(expected2,1e-13))
+        self.assertTrue(f22.getArray().isEqual(expected2,1e-13))
+        pass
     
     def build2DSourceMesh_1(self):
         sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7]
index c168124294a071549462ba225c8aa5c52205cf94..faac758321c176b8785116a543f60447d3088d2f 100644 (file)
@@ -30,6 +30,8 @@ static PyObject *convertMesh(ParaMEDMEM::MEDCouplingMesh *mesh, int owner) throw
     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner);
   if(dynamic_cast<ParaMEDMEM::MEDCouplingCMesh *>(mesh))
     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh,owner);
+  if(dynamic_cast<ParaMEDMEM::MEDCouplingCurveLinearMesh *>(mesh))
+    ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh,owner);
   if(!ret)
     throw INTERP_KERNEL::Exception("Not recognized type of mesh on downcast !");
   return ret;
@@ -453,6 +455,8 @@ static std::vector<int> fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples,
           PyObject *o=PyList_GetItem(pyLi,i);
           fillArrayWithPyListInt3(o,size2,ret);
         }
+      if(size1==0)
+        size2=1;
     }
   else if(PyTuple_Check(pyLi))
     {
@@ -462,6 +466,8 @@ static std::vector<int> fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples,
           PyObject *o=PyTuple_GetItem(pyLi,i);
           fillArrayWithPyListInt3(o,size2,ret);
         }
+      if(size1==0)
+        size2=1;
     }
   else
     throw INTERP_KERNEL::Exception("fillArrayWithPyListInt2 : Unrecognized type ! Should be a tuple or a list !");
@@ -470,66 +476,6 @@ static std::vector<int> fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples,
   return ret;
 }
 
-/*
- * will become obsolete -> fillArrayWithPyListInt2
- */
-static void fillArrayWithPyListInt(PyObject *pyLi, int *arrToFill, int sizeOfArray, int dftVal, bool chckSize) throw(INTERP_KERNEL::Exception)
-{
-  if(PyList_Check(pyLi))
-    {
-      int size=PyList_Size(pyLi);
-      if(chckSize)
-        if(size!=sizeOfArray)
-          {
-            std::ostringstream oss; oss << "fillArrayWithPyListInt : List expected to be of size " << sizeOfArray << " but the size is " << size << " !";
-            throw INTERP_KERNEL::Exception(oss.str().c_str());
-          }
-      for(int i=0;i<size;i++)
-        {
-          PyObject *o=PyList_GetItem(pyLi,i);
-          if(PyInt_Check(o))
-            {
-              int val=(int)PyInt_AS_LONG(o);
-              if(i<sizeOfArray)
-                arrToFill[i]=val;
-            }
-          else
-            throw INTERP_KERNEL::Exception("fillArrayWithPyListInt : List must contain integers only !");
-        }
-      for(int i=size;i<sizeOfArray;i++)
-        arrToFill[i]=dftVal;
-      return;
-      
-    }
-  else if(PyTuple_Check(pyLi))
-    {
-      int size=PyTuple_Size(pyLi);
-      if(chckSize)
-        if(size!=sizeOfArray)
-          {
-            std::ostringstream oss; oss << "fillArrayWithPyListInt : Tuple expected to be of size " << sizeOfArray << " but the size is " << size << " !";
-            throw INTERP_KERNEL::Exception(oss.str().c_str());
-          }
-      for(int i=0;i<size;i++)
-        {
-          PyObject *o=PyTuple_GetItem(pyLi,i);
-          if(PyInt_Check(o))
-            {
-              int val=(int)PyInt_AS_LONG(o);
-              if(i<sizeOfArray)
-                arrToFill[i]=val;
-            }
-          else
-            throw INTERP_KERNEL::Exception("tuple must contain integers only");
-        }
-      for(int i=size;i<sizeOfArray;i++)
-        arrToFill[i]=dftVal;
-      return;
-    }
-  else
-    throw INTERP_KERNEL::Exception("fillArrayWithPyListInt : not a list");
-}
-
 static PyObject *convertDblArrToPyList(const double *ptr, int size) throw(INTERP_KERNEL::Exception)
 {
   PyObject *ret=PyList_New(size);
@@ -696,6 +642,8 @@ static std::vector<double> fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTupl
           PyObject *o=PyList_GetItem(pyLi,i);
           fillArrayWithPyListDbl3(o,size2,ret);
         }
+      if(size1==0)
+        size2=1;
     }
   else if(PyTuple_Check(pyLi))
     {
@@ -705,6 +653,8 @@ static std::vector<double> fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTupl
           PyObject *o=PyTuple_GetItem(pyLi,i);
           fillArrayWithPyListDbl3(o,size2,ret);
         }
+      if(size1==0)
+        size2=1;
     }
   else
     throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl2 : Unrecognized type ! Should be a tuple or a list !");
@@ -713,77 +663,6 @@ static std::vector<double> fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTupl
   return ret;
 }
 
-/*
- * will become obsolete -> fillArrayWithPyListDbl2
- */
-static void fillArrayWithPyListDbl(PyObject *pyLi, double *arrToFill, int sizeOfArray, double dftVal, bool chckSize) throw(INTERP_KERNEL::Exception)
-{
-  if(PyList_Check(pyLi))
-    {
-      int size=PyList_Size(pyLi);
-      if(chckSize)
-        if(size!=sizeOfArray)
-          {
-            std::ostringstream oss; oss << "fillArrayWithPyListDbl : List expected to be of size " << sizeOfArray << " but the size is " << size << " !";
-            throw INTERP_KERNEL::Exception(oss.str().c_str());
-          }
-      for(int i=0;i<size;i++)
-        {
-          PyObject *o=PyList_GetItem(pyLi,i);
-          if(PyFloat_Check(o))
-            {
-              double val=PyFloat_AS_DOUBLE(o);
-              if(i<sizeOfArray)
-                arrToFill[i]=val;
-            }
-          else if(PyInt_Check(o))
-            {
-              long val0=PyInt_AS_LONG(o);
-              double val=val0;
-              if(i<sizeOfArray)
-                arrToFill[i]=val;
-            }
-          else
-            throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl : list must contain floats/integers only");
-        }
-      for(int i=size;i<sizeOfArray;i++)
-        arrToFill[i]=dftVal;
-      return;
-    }
-  else if(PyTuple_Check(pyLi))
-    {
-      int size=PyTuple_Size(pyLi);
-      if(chckSize)
-        if(size!=sizeOfArray)
-          {
-            std::ostringstream oss; oss << "fillArrayWithPyListDbl : Tuple expected to be of size " << sizeOfArray << " but the size is " << size << " !";
-            throw INTERP_KERNEL::Exception(oss.str().c_str());
-          }
-      for(int i=0;i<size;i++)
-        {
-          PyObject *o=PyTuple_GetItem(pyLi,i);
-          if(PyFloat_Check(o))
-            {
-              double val=PyFloat_AS_DOUBLE(o);
-              arrToFill[i]=val;
-            }
-          else if(PyInt_Check(o))
-            {
-              long val0=PyInt_AS_LONG(o);
-              double val=val0;
-              arrToFill[i]=val;
-            }
-          else
-            throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl : tuple must contain floats/integers only");
-        }
-      for(int i=size;i<sizeOfArray;i++)
-        arrToFill[i]=dftVal;
-      return ;
-    }
-  else
-    throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl : not a list nor a tuple");
-}
-
 //convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(pyLi,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh")
 template<class T>
 static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, const char *typeStr, typename std::vector<T>& ret)
@@ -1107,13 +986,14 @@ static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int&
     }
   if(PySlice_Check(value))
     {
-      Py_ssize_t strt,stp,step;
+      Py_ssize_t strt=2,stp=2,step=2;
       PySliceObject *oC=reinterpret_cast<PySliceObject *>(value);
       if(PySlice_GetIndices(oC,nbelem,&strt,&stp,&step)!=0)
-        {
-          std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elemnts is : " << nbelem;
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
+        if(nbelem!=0 || strt!=0 || stp!=0)
+          {
+            std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elements is : " << nbelem;
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          }
       p.first=strt;
       p.second.first=stp;
       p.second.second=step;
@@ -1197,13 +1077,14 @@ static void convertObjToPossibleCpp22(PyObject *value, int nbelem, int& sw, int&
     }
   if(PySlice_Check(value))
     {
-      Py_ssize_t strt,stp,step;
+      Py_ssize_t strt=2,stp=2,step=2;
       PySliceObject *oC=reinterpret_cast<PySliceObject *>(value);
       if(PySlice_GetIndices(oC,nbelem,&strt,&stp,&step)!=0)
-        {
-          std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elemnts is : " << nbelem;
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
+        if(nbelem!=0 || strt!=0 || stp!=0)
+          {
+            std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elements is : " << nbelem;
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          }
       p.first=strt;
       p.second.first=stp;
       p.second.second=step;
index 61f1429f310af06946731886c38affb4135dedb4..fbabd4709e1fb50064f3bba2aaa411de901aadad 100644 (file)
@@ -32,6 +32,29 @@ MEDFileData *MEDFileData::New()
   return new MEDFileData;
 }
 
+MEDFileData *MEDFileData::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFields> fields;
+  if((const MEDFileFields *)_fields)
+    fields=_fields->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> meshes;
+  if((const MEDFileMeshes *)_meshes)
+    meshes=_meshes->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileData> ret=MEDFileData::New();
+  ret->_fields=fields; ret->_meshes=meshes;
+  return ret.retn();
+}
+
+std::size_t MEDFileData::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if((const MEDFileFields *)_fields)
+    ret+=_fields->getHeapMemorySize();
+  if((const MEDFileMeshes *)_meshes)
+    ret+=_meshes->getHeapMemorySize();
+  return ret;
+}
+
 MEDFileFields *MEDFileData::getFields() const
 {
   return const_cast<MEDFileFields *>(static_cast<const MEDFileFields *>(_fields));
index 64b946ec0d1ef3b33c1165d0ccf4b48dd4141692..c732aad9dff4614f227911589bcd9c2e046c7c69 100644 (file)
@@ -35,6 +35,8 @@ namespace ParaMEDMEM
   public:
     static MEDFileData *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileData *New();
+    MEDFileData *deepCpy() const throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
     MEDFileFields *getFields() const;
     MEDFileMeshes *getMeshes() const;
     void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception);
index 70d126a7d90d04787bfe4c00a6f490b768b3adec..a94f554730ab9edc0efda88fc1759c3f8f4feafb 100644 (file)
@@ -100,6 +100,16 @@ MEDFileFieldLoc::MEDFileFieldLoc(const char *locName, INTERP_KERNEL::NormalizedC
   _nb_gauss_pt=_w.size();
 }
 
+MEDFileFieldLoc *MEDFileFieldLoc::deepCpy() const
+{
+  return new MEDFileFieldLoc(*this);
+}
+
+std::size_t MEDFileFieldLoc::getHeapMemorySize() const
+{
+  return (_ref_coo.capacity()+_gs_coo.capacity()+_w.capacity())*sizeof(double)+_name.capacity();
+}
+
 void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const
 {
   static const char OFF7[]="\n    ";
@@ -390,6 +400,18 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(const
   return new MEDFileFieldPerMeshPerTypePerDisc(other);
 }
 
+std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySize() const
+{
+  return _profile.capacity()+_localization.capacity()+5*sizeof(int);
+}
+
+MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCpy(MEDFileFieldPerMeshPerType *father) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> ret=new MEDFileFieldPerMeshPerTypePerDisc(*this);
+  ret->_father=father;
+  return ret.retn();
+}
+
 MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField atype, int profileIt) throw(INTERP_KERNEL::Exception)
 try:_type(atype),_father(fath)
   {
@@ -919,6 +941,27 @@ MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh
   return new MEDFileFieldPerMeshPerType(fath,geoType);
 }
 
+std::size_t MEDFileFieldPerMeshPerType::getHeapMemorySize() const
+{
+  std::size_t ret=_field_pm_pt_pd.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc>);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
+    ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
+MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerMesh *father) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerType> ret=new MEDFileFieldPerMeshPerType(*this);
+  ret->_father=father;
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++)
+    {
+      if((const MEDFileFieldPerMeshPerTypePerDisc *)*it)
+        ret->_field_pm_pt_pd[i]=(*it)->deepCpy((MEDFileFieldPerMeshPerType *)ret);
+    }
+  return ret.retn();
+}
+
 void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
 {
   std::vector<int> pos=addNewEntryIfNecessary(field,offset,nbOfCells);
@@ -1426,6 +1469,28 @@ MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileField1TSWithoutSDA *fath, c
   return new MEDFileFieldPerMesh(fath,mesh);
 }
 
+std::size_t MEDFileFieldPerMesh::getHeapMemorySize() const
+{
+  std::size_t ret=_mesh_name.capacity()+_field_pm_pt.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType >);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
+    if((const MEDFileFieldPerMeshPerType *)*it)
+      ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
+MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCpy(MEDFileField1TSWithoutSDA *father) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > ret=new MEDFileFieldPerMesh(*this);
+  ret->_father=father;
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++)
+    {
+      if((const MEDFileFieldPerMeshPerType *)*it)
+        ret->_field_pm_pt[i]=(*it)->deepCpy((MEDFileFieldPerMesh *)(ret));
+    }
+  return ret.retn();
+}
+
 void MEDFileFieldPerMesh::simpleRepr(int bkOffset, std::ostream& oss, int id) const
 {
   std::string startLine(bkOffset,' ');
@@ -1925,7 +1990,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField t
           return finishField(type,glob,dads,locs,mesh,isPfl);
         }
       else
-        return finishField3(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl);
+        return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl);
     }
 }
 
@@ -2084,8 +2149,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const
         }
     }
   //
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -2110,22 +2174,20 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, cons
   m2->setName(mesh->getName());
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=finishField(type,glob,dads,locs,m2,isPfl);
   isPfl=true;
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
  * This method is the complement of MEDFileFieldPerMesh::finishField2 method except that this method works for node profiles.
  */
-MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField3(const MEDFileFieldGlobsReal *glob,
-                                                          const std::vector<std::pair<int,int> >& dads, const std::vector<int>& locs,
-                                                          const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception)
+MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileFieldGlobsReal *glob,
+                                                              const std::vector<std::pair<int,int> >& dads, const std::vector<int>& locs,
+                                                              const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception)
 {
   if(da->isIdentity())
     {
       int nbOfTuples=da->getNumberOfTuples();
-      const std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes2(1,INTERP_KERNEL::NORM_ERROR);
-      if(nbOfTuples==ComputeNbOfElems(glob,ON_NODES,geoTypes2,dads,locs))//No problem for NORM_ERROR because it is in context of node
+      if(nbOfTuples==mesh->getNumberOfNodes())//No problem for NORM_ERROR because it is in context of node
         return finishField(ON_NODES,glob,dads,locs,mesh,isPfl);
     }
   // Treatment of particular case where nodal field on pfl is requested with a meshDimRelToMax=1.
@@ -2144,8 +2206,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField3(const MEDFileFieldGlob
           meshuc->finishInsertingCells();
           ret->setMesh(meshuc);
           ret->checkCoherency();
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
     }
   //
@@ -2162,12 +2223,11 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField3(const MEDFileFieldGlob
       ret->getArray()->renumberInPlace(da3->getConstPointer());
       mesh2->setName(mesh->getName());
       ret->setMesh(mesh2);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
-      std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishField3 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!";
+      std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishFieldNode2 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!";
       oss << "So it is impossible to return a well definied MEDCouplingFieldDouble instance on specified mesh on a specified meshDim !" << std::endl;
       oss << "To retrieve correctly such a field you have 3 possibilities :" << std::endl;
       oss << " - use an another meshDim compatible with the field on nodes (MED file does not have such information)" << std::endl;
@@ -2201,8 +2261,7 @@ DataArrayDouble *MEDFileFieldPerMesh::finishField4(const std::vector<std::pair<i
   for(int i=0;i<nbOfComp;i++)
     da->setInfoOnComponent(i,infos[i].c_str());
   safePfl->incrRef();
-  da->incrRef();
-  return da;
+  return da.retn();
 }
 
 MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder) throw(INTERP_KERNEL::Exception):_mesh_iteration(meshIteration),_mesh_order(meshOrder),
@@ -2361,6 +2420,34 @@ MEDFileFieldGlobs *MEDFileFieldGlobs::New()
   return new MEDFileFieldGlobs;
 }
 
+std::size_t MEDFileFieldGlobs::getHeapMemorySize() const
+{
+  std::size_t ret=_file_name.capacity()+_pfls.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>)+_locs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc>);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=_pfls.begin();it!=_pfls.end();it++)
+    ret+=(*it)->getHeapMemorySize();
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=_locs.begin();it!=_locs.end();it++)
+    ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
+MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFieldGlobs> ret=new MEDFileFieldGlobs(*this);
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++)
+    {
+      if((const DataArrayInt *)*it)
+        ret->_pfls[i]=(*it)->deepCpy();
+    }
+  i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++)
+    {
+      if((const MEDFileFieldLoc*)*it)
+        ret->_locs[i]=(*it)->deepCpy();
+    }
+  return ret.retn();
+}
+
 MEDFileFieldGlobs::MEDFileFieldGlobs(const char *fname):_file_name(fname)
 {
 }
@@ -2720,6 +2807,14 @@ MEDFileFieldGlobsReal::MEDFileFieldGlobsReal():_globals(MEDFileFieldGlobs::New()
 {
 }
 
+std::size_t MEDFileFieldGlobsReal::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if((const MEDFileFieldGlobs *)_globals)
+    ret+=_globals->getHeapMemorySize();
+  return ret;
+}
+
 void MEDFileFieldGlobsReal::simpleRepr(std::ostream& oss) const
 {
   oss << "Globals information on fields :" << "\n*******************************\n\n";
@@ -2739,6 +2834,13 @@ void MEDFileFieldGlobsReal::shallowCpyGlobs(const MEDFileFieldGlobsReal& other)
   _globals=other._globals;
 }
 
+void MEDFileFieldGlobsReal::deepCpyGlobs(const MEDFileFieldGlobsReal& other)
+{
+  _globals=other._globals;
+  if((const MEDFileFieldGlobs *)_globals)
+    _globals=other._globals->deepCpy();
+}
+
 void MEDFileFieldGlobsReal::appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception)
 {
   _globals->appendGlobs(*other._globals,eps);
@@ -3515,7 +3617,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtLevel(TypeOfField t
   if(mName==0)
     mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder());
   else
-    mm=MEDFileMesh::New(glob->getFileName(),mName,-1,-1);
+    mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder());
   return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm);
 }
 
@@ -3535,7 +3637,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtTopLevel(TypeOfFiel
   if(mName==0)
     mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder());
   else
-    mm=MEDFileMesh::New(glob->getFileName(),mName,-1,-1);
+    mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder());
   int absDim=getDimension();
   int meshDimRelToMax=absDim-mm->getMeshDimension();
   return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm);
@@ -3555,8 +3657,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF
     case 0:
       {
         //no need to test _field_per_mesh.empty() because geMeshName has already done it
-        ret->incrRef();
-        return ret;
+        return ret.retn();
       }
     case 3:
     case 1:
@@ -3575,10 +3676,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF
             ret->renumberCells(cellRenum->getConstPointer(),true);
           }
         if(renumPol==1)
-          {
-            ret->incrRef();
-            return ret;
-          }
+          return ret.retn();
       }
     case 2:
       {
@@ -3596,8 +3694,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF
             MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeRenumSafe=nodeRenum->checkAndPreparePermutation();
             ret->renumberNodes(nodeRenumSafe->getConstPointer());
           }
-        ret->incrRef();
-        return ret;
+        return ret.retn();
       }
     default:
       throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : unsupported renum policy ! Dealing with policy 0 1 2 and 3 !");
@@ -3720,6 +3817,30 @@ const MEDFileFieldPerMeshPerTypePerDisc *MEDFileField1TSWithoutSDA::getLeafGiven
   return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId);
 }
 
+std::size_t MEDFileField1TSWithoutSDA::getHeapMemorySize() const
+{
+  std::size_t ret=_dt_unit.capacity()+_field_per_mesh.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh >);
+  if((const DataArrayDouble *)_arr)
+    ret+=_arr->getHeapMemorySize();
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++)
+    ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
+MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> ret=new MEDFileField1TSWithoutSDA(*this);
+  if((const DataArrayDouble *)_arr)
+    ret->_arr=_arr->deepCpy();
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,i++)
+    {
+      if((const MEDFileFieldPerMesh *)*it)
+        ret->_field_per_mesh[i]=(*it)->deepCpy((MEDFileField1TSWithoutSDA *)ret);
+    }
+  return ret.retn();
+}
+
 DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray()
 {
   DataArrayDouble *ret=_arr;
@@ -3747,9 +3868,9 @@ MEDFileField1TS *MEDFileField1TS::New(const char *fileName, const char *fieldNam
 /*!
  * \warning this is a shallow copy constructor
  */
-MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool deepCpy)
+MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent)
 {
-  return new MEDFileField1TS(other,deepCpy);
+  return new MEDFileField1TS(other,shallowCopyOfContent);
 }
 
 MEDFileField1TS *MEDFileField1TS::New()
@@ -3775,8 +3896,8 @@ void MEDFileField1TS::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
       std::string info=getInfo()[i];
       std::string c,u;
       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
-      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);
-      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);
+      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str);
+      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str);
     }
   if(getName().empty())
     throw INTERP_KERNEL::Exception("MEDFileField1TS::write : MED file does not accept field with empty name !");
@@ -3867,9 +3988,9 @@ catch(INTERP_KERNEL::Exception& e)
 /*!
  * \warning this is a shallow copy constructor
  */
-MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool deepCpy)
+MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent)
 {
-  if(!deepCpy)
+  if(!shallowCopyOfContent)
     {
       const MEDFileField1TSWithoutSDA *otherPtr(&other);
       otherPtr->incrRef();
@@ -4095,6 +4216,23 @@ void MEDFileField1TS::setLocNameOnLeaf(const char *mName, INTERP_KERNEL::Normali
     }
 }
 
+std::size_t MEDFileField1TS::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if((const MEDFileField1TSWithoutSDA *)_content)
+    ret+=_content->getHeapMemorySize();
+  return ret+MEDFileFieldGlobsReal::getHeapMemorySize();
+}
+
+MEDFileField1TS *MEDFileField1TS::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret=new MEDFileField1TS(*this);
+  if((const MEDFileField1TSWithoutSDA *)_content)
+    ret->_content=_content->deepCpy();
+  ret->deepCpyGlobs(*this);
+  return ret.retn();
+}
+
 int MEDFileField1TS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception)
 {
   return _content->copyTinyInfoFrom(field);
@@ -4293,9 +4431,32 @@ try:_name(fieldName),_infos(infos),_field_type(ft)
   finishLoading(fid,nbOfStep);
 }
 catch(INTERP_KERNEL::Exception& e)
-  {
-    throw e;
-  }
+{
+  throw e;
+}
+
+std::size_t MEDFileFieldMultiTSWithoutSDA::getHeapMemorySize() const
+{
+  std::size_t ret=_name.capacity()+_infos.capacity()*sizeof(std::string)+_time_steps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA>);
+  for(std::vector<std::string>::const_iterator it=_infos.begin();it!=_infos.end();it++)
+    ret+=(*it).capacity();
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++)
+    if((const MEDFileField1TSWithoutSDA *)(*it))
+      ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
+MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTSWithoutSDA> ret=new MEDFileFieldMultiTSWithoutSDA(*this);
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++)
+    {
+      if((const MEDFileField1TSWithoutSDA *)*it)
+        ret->_time_steps[i]=(*it)->deepCpy();
+    }
+  return ret.retn();
+}
 
 const std::vector<std::string>& MEDFileFieldMultiTSWithoutSDA::getInfo() const throw(INTERP_KERNEL::Exception)
 {
@@ -4523,8 +4684,8 @@ void MEDFileFieldMultiTSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable&
       std::string info=infos[i];
       std::string c,u;
       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
-      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy());
-      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy());
+      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy());
+      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy());
     }
   if(_name.empty())
     throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::write : MED file does not accept field with empty name !");
@@ -4828,9 +4989,26 @@ MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName, const char *
   return new MEDFileFieldMultiTS(fileName,fieldName);
 }
 
-MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy)
+MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent)
+{
+  return new MEDFileFieldMultiTS(other,shallowCopyOfContent);
+}
+
+std::size_t MEDFileFieldMultiTS::getHeapMemorySize() const
 {
-  return new MEDFileFieldMultiTS(other,deepCpy);
+  std::size_t ret=0;
+  if((const MEDFileFieldMultiTSWithoutSDA*)_content)
+    ret+=_content->getHeapMemorySize();
+  return ret+MEDFileFieldGlobsReal::getHeapMemorySize();
+}
+
+MEDFileFieldMultiTS *MEDFileFieldMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ret=new MEDFileFieldMultiTS(*this);
+  if((const MEDFileFieldMultiTSWithoutSDA *)_content)
+    ret->_content=_content->deepCpy();
+  ret->deepCpyGlobs(*this);
+  return ret.retn();
 }
 
 MEDFileField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception)
@@ -4838,8 +5016,7 @@ MEDFileField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const throw(INTE
   const MEDFileField1TSWithoutSDA *item=_content->getTimeStepAtPos2(pos);
   MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret=MEDFileField1TS::New(*item,false);
   ret->shallowCpyGlobs(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 MEDFileField1TS *MEDFileFieldMultiTS::getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception)
@@ -5014,9 +5191,9 @@ catch(INTERP_KERNEL::Exception& e)
     throw e;
   }
 
-MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy)
+MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent)
 {
-  if(!deepCpy)
+  if(!shallowCopyOfContent)
     {
       const MEDFileFieldMultiTSWithoutSDA *otherPtr(&other);
       otherPtr->incrRef();
@@ -5195,6 +5372,28 @@ MEDFileFields *MEDFileFields::New(const char *fileName) throw(INTERP_KERNEL::Exc
   return new MEDFileFields(fileName);
 }
 
+std::size_t MEDFileFields::getHeapMemorySize() const
+{
+  std::size_t ret=_fields.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTSWithoutSDA>);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
+    if((const MEDFileFieldMultiTSWithoutSDA *)*it)
+      ret+=(*it)->getHeapMemorySize();
+  return ret+MEDFileFieldGlobsReal::getHeapMemorySize();
+}
+
+MEDFileFields *MEDFileFields::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFields> ret=new MEDFileFields(*this);
+  std::size_t i=0;
+  for( std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
+    {
+      if((const MEDFileFieldMultiTSWithoutSDA*)*it)
+        ret->_fields[i]=(*it)->deepCpy();
+    }
+  ret->deepCpyGlobs(*this);
+  return ret.retn();
+}
+
 int MEDFileFields::getNumberOfFields() const
 {
   return _fields.size();
@@ -5482,8 +5681,7 @@ MEDFileFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const throw(INTERP_KERN
   const MEDFileFieldMultiTSWithoutSDA *fmts=_fields[i];
   MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ret=MEDFileFieldMultiTS::New(*fmts,false);
   ret->shallowCpyGlobs(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 MEDFileFieldMultiTS *MEDFileFields::getFieldWithName(const char *fieldName) const throw(INTERP_KERNEL::Exception)
index 6ddb6f2093abd4981a74e02f01de0538953a28b5..cf17442a76eb26be4b1d0af222cee43c1591edb3 100644 (file)
@@ -54,6 +54,8 @@ namespace ParaMEDMEM
     static MEDFileFieldLoc *New(med_idt fid, const char *locName);
     static MEDFileFieldLoc *New(med_idt fid, int id);
     static MEDFileFieldLoc *New(const char *locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w);
+    std::size_t getHeapMemorySize() const;
+    MEDFileFieldLoc *deepCpy() const;
     int MEDLOADER_EXPORT getNbOfGaussPtPerCell() const { return _nb_gauss_pt; }
     void MEDLOADER_EXPORT writeLL(med_idt fid) const;
     std::string MEDLOADER_EXPORT repr() const;
@@ -92,6 +94,8 @@ namespace ParaMEDMEM
     static MEDFileFieldPerMeshPerTypePerDisc *NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt) throw(INTERP_KERNEL::Exception);
     static MEDFileFieldPerMeshPerTypePerDisc *New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId);
     static MEDFileFieldPerMeshPerTypePerDisc *New(const MEDFileFieldPerMeshPerTypePerDisc& other);
+    std::size_t getHeapMemorySize() const;
+    MEDFileFieldPerMeshPerTypePerDisc *deepCpy(MEDFileFieldPerMeshPerType *father) const throw(INTERP_KERNEL::Exception);
     void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
@@ -164,6 +168,8 @@ namespace ParaMEDMEM
   public:
     static MEDFileFieldPerMeshPerType *New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception);
     static MEDFileFieldPerMeshPerType *NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
+    MEDFileFieldPerMeshPerType *deepCpy(MEDFileFieldPerMesh *father) const throw(INTERP_KERNEL::Exception);
     void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
@@ -217,6 +223,8 @@ namespace ParaMEDMEM
   public:
     static MEDFileFieldPerMesh *New(MEDFileField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh);
     static MEDFileFieldPerMesh *NewOnRead(med_idt fid, MEDFileField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
+    MEDFileFieldPerMesh *deepCpy(MEDFileField1TSWithoutSDA *_father) const throw(INTERP_KERNEL::Exception);
     void simpleRepr(int bkOffset,std::ostream& oss, int id) const;
     void copyTinyInfoFrom(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception);
     void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<int>& code2, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
@@ -262,9 +270,9 @@ namespace ParaMEDMEM
                                          const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs,
                                          const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes,
                                          const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception);
-    MEDCouplingFieldDouble *finishField3(const MEDFileFieldGlobsReal *glob,
-                                         const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs,
-                                         const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *finishFieldNode2(const MEDFileFieldGlobsReal *glob,
+                                             const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs,
+                                             const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *finishField4(const std::vector< std::pair<int,int> >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const throw(INTERP_KERNEL::Exception);
     void assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) throw(INTERP_KERNEL::Exception);
     static void SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, 
@@ -289,6 +297,8 @@ namespace ParaMEDMEM
   public:
     static MEDFileFieldGlobs *New(const char *fname);
     static MEDFileFieldGlobs *New();
+    std::size_t getHeapMemorySize() const;
+    MEDFileFieldGlobs *deepCpy() const throw(INTERP_KERNEL::Exception);
     void simpleRepr(std::ostream& oss) const;
     void appendGlobs(const MEDFileFieldGlobs& other, double eps) throw(INTERP_KERNEL::Exception);
     void loadProfileInFile(med_idt fid, int id, const char *pflName) throw(INTERP_KERNEL::Exception);
@@ -343,8 +353,10 @@ namespace ParaMEDMEM
   public:
     MEDFileFieldGlobsReal(const char *fname);
     MEDFileFieldGlobsReal();
+    std::size_t getHeapMemorySize() const;
     void simpleRepr(std::ostream& oss) const;
     void shallowCpyGlobs(const MEDFileFieldGlobsReal& other);
+    void deepCpyGlobs(const MEDFileFieldGlobsReal& other);
     void appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception);
     virtual std::vector<std::string> getPflsReallyUsed() const = 0;
     virtual std::vector<std::string> getLocsReallyUsed() const = 0;
@@ -460,6 +472,8 @@ namespace ParaMEDMEM
   public:
     MEDFileField1TSWithoutSDA();
     MEDFileField1TSWithoutSDA(const char *fieldName, int csit, int fieldtype, int iteration, int order, const std::vector<std::string>& infos);
+    MEDFileField1TSWithoutSDA *deepCpy() const throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
     DataArrayDouble *getOrCreateAndGetArray();
     const DataArrayDouble *getOrCreateAndGetArray() const;
   protected:
@@ -483,7 +497,7 @@ namespace ParaMEDMEM
   {
   public:
     static MEDFileField1TS *New(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
-    static MEDFileField1TS *New(const MEDFileField1TSWithoutSDA& other, bool deepCpy);
+    static MEDFileField1TS *New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent);
     static MEDFileField1TS *New();
     std::string simpleRepr() const;
     void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception);
@@ -498,6 +512,8 @@ namespace ParaMEDMEM
     void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception);
     // direct forwarding to MEDFileField1TSWithoutSDA instance _content
   public:
+    std::size_t getHeapMemorySize() const;
+    MEDFileField1TS *deepCpy() const throw(INTERP_KERNEL::Exception);
     int copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception);
     int getDimension() const;
     int getIteration() const;
@@ -544,7 +560,7 @@ namespace ParaMEDMEM
   private:
     void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception);
     MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
-    MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool deepCpy);
+    MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent);
     MEDFileField1TS();
   protected:
     MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> _content;
@@ -555,6 +571,8 @@ namespace ParaMEDMEM
   public:
     static MEDFileFieldMultiTSWithoutSDA *New(med_idt fid, const char *fieldName, int id, int ft, const std::vector<std::string>& infos, int nbOfStep) throw(INTERP_KERNEL::Exception);
     MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
+    MEDFileFieldMultiTSWithoutSDA *deepCpy() const throw(INTERP_KERNEL::Exception);
     int getNumberOfTS() const;
     void eraseEmptyTS() throw(INTERP_KERNEL::Exception);
     void eraseTimeStepIds(const int *startIds, const int *endIds) throw(INTERP_KERNEL::Exception);
@@ -618,7 +636,9 @@ namespace ParaMEDMEM
     static MEDFileFieldMultiTS *New();
     static MEDFileFieldMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileFieldMultiTS *New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception);
-    static MEDFileFieldMultiTS *New(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy);
+    static MEDFileFieldMultiTS *New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent);
+    std::size_t getHeapMemorySize() const;
+    MEDFileFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception);
     //
     MEDFileField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception);
     MEDFileField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception);
@@ -669,7 +689,7 @@ std::vector< std::vector<DataArrayDouble *> > getFieldSplitedByType2(int iterati
     MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTSWithoutSDA> getContent();
   private:
     MEDFileFieldMultiTS();
-    MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy);
+    MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent);
     MEDFileFieldMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception);
     MEDFileFieldMultiTS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception);
   protected:
@@ -698,6 +718,8 @@ std::vector< std::vector<DataArrayDouble *> > getFieldSplitedByType2(int iterati
   public:
     static MEDFileFields *New();
     static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
+    MEDFileFields *deepCpy() const throw(INTERP_KERNEL::Exception);
     void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception);
     void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception);
     int getNumberOfFields() const;
index 5c5ccd8f86eb99458176ac048df611bf8194cac0..987e61bd07dd86be49611719a5a66419c9c4e603 100644 (file)
@@ -38,6 +38,20 @@ MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.)
 {
 }
 
+std::size_t MEDFileMesh::getHeapMemorySize() const
+{
+  std::size_t ret=_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity();
+  for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
+    {
+      ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
+      for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
+        ret+=(*it2).capacity();
+    }
+  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+    ret+=(*it).first.capacity()+sizeof(int);
+  return ret;
+}
+
 MEDFileMesh *MEDFileMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
 {
   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
@@ -58,15 +72,19 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName) throw(INTERP_KERNEL::Excepti
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
         ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it);
-        ret->incrRef();
-        return (MEDFileUMesh *)ret;
+        return (MEDFileUMesh *)ret.retn();
       }
     case CARTESIAN:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
         ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it);
-        ret->incrRef();
-        return (MEDFileCMesh *)ret;
+        return (MEDFileCMesh *)ret.retn();
+      }
+    case CURVE_LINEAR:
+      {
+        MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
+        ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it);
+        return (MEDFileCMesh *)ret.retn();
       }
     default:
       {
@@ -90,15 +108,13 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, i
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
         ret->loadUMeshFromFile(fid,mName,dt,it);
-        ret->incrRef();
-        return (MEDFileUMesh *)ret;
+        return (MEDFileUMesh *)ret.retn();
       }
     case CARTESIAN:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
         ret->loadCMeshFromFile(fid,mName,dt,it);
-        ret->incrRef();
-        return (MEDFileCMesh *)ret;
+        return (MEDFileCMesh *)ret.retn();
       }
     default:
       {
@@ -749,6 +765,26 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *ot
     }
 }
 
+void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
+{
+  ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
+}
+
+void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
+{
+  std::string fam(familyNameToChange);
+  for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
+    {
+      std::vector<std::string>& fams((*it).second);
+      std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
+      if(it2!=fams.end())
+        {
+          fams.erase(it2);
+          fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
+        }
+    }
+}
+
 /*!
  * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
  * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
@@ -759,9 +795,22 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *ot
  */
 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception)
 {
-  std::vector<std::string> famAlreadyExisting(_families.size());
+  return FindOrCreateAndGiveFamilyWithId(_families,id,created);
+}
+
+/*!
+ * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
+ * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
+ * If there is no family whose family id is equal to 'id' a family is created with a name different from those
+ * already existing. In this case 'created' will be returned with a value set to true, and internal state
+ * will be modified.
+ * This method will throws an exception if it is not possible to create a unique family name.
+ */
+std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<std::string> famAlreadyExisting(families.size());
   int ii=0;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++,ii++)
+  for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
     {
       if((*it).second!=id)
         {
@@ -776,7 +825,7 @@ std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
   created=true;
   std::ostringstream oss; oss << "Family_" << id;
   std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
-  _families[ret]=id;
+  families[ret]=id;
   return ret;
 }
 
@@ -847,6 +896,24 @@ int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
   return ret;
 }
 
+int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
+{
+  int m1=-std::numeric_limits<int>::max();
+  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+    m1=std::max((*it).second,m1);
+  int m2=getMaxFamilyIdInArrays();
+  return std::max(m1,m2);
+}
+
+int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
+{
+  int m1=std::numeric_limits<int>::max();
+  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+    m1=std::min((*it).second,m1);
+  int m2=getMinFamilyIdInArrays();
+  return std::min(m1,m2);
+}
+
 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
@@ -855,7 +922,7 @@ DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERN
     v.insert((*it).second);
   ret->alloc((int)v.size(),1);
   std::copy(v.begin(),v.end(),ret->getPointer());
-  ret->incrRef(); return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1006,7 +1073,7 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
 /*!
  * This method normalizes fam id with the following policy.
  * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
- * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
+ * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
  * This method will throw an exception if a same family id is detected in different level.
  */
 void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
@@ -1302,6 +1369,21 @@ void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL
             }
         }
     }
+  if(_desc_name.empty())
+    _desc_name=m->getDescription();
+  else
+    {
+      std::string name(m->getDescription());
+      if(!name.empty())
+        {
+          if(_desc_name!=name)
+            {
+              std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
+              oss << name << "' ! Names must match !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+    }
 }
 
 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
@@ -1346,6 +1428,50 @@ MEDFileUMesh *MEDFileUMesh::New()
   return new MEDFileUMesh;
 }
 
+std::size_t MEDFileUMesh::getHeapMemorySize() const
+{
+  std::size_t ret=MEDFileMesh::getHeapMemorySize();
+  if((const DataArrayDouble*)_coords)
+    ret+=_coords->getHeapMemorySize();
+  if((const DataArrayInt *)_fam_coords)
+    ret+=_fam_coords->getHeapMemorySize();
+  if((const DataArrayInt *)_num_coords)
+    ret+=_num_coords->getHeapMemorySize();
+  if((const DataArrayInt *)_rev_num_coords)
+    ret+=_rev_num_coords->getHeapMemorySize();
+  ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+    if((const MEDFileUMeshSplitL1*) *it)
+      ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
+MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
+  return ret.retn();
+}
+
+MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
+  if((const DataArrayDouble*)_coords)
+    ret->_coords=_coords->deepCpy();
+  if((const DataArrayInt*)_fam_coords)
+    ret->_fam_coords=_fam_coords->deepCpy();
+  if((const DataArrayInt*)_num_coords)
+    ret->_num_coords=_num_coords->deepCpy();
+  if((const DataArrayInt*)_rev_num_coords)
+    ret->_rev_num_coords=_rev_num_coords->deepCpy();
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
+    {
+      if((const MEDFileUMeshSplitL1 *)(*it))
+        ret->_ms[i]=(*it)->deepCpy();
+    }
+  return ret.retn();
+}
+
 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
 {
   if(!MEDFileMesh::isEqual(other,eps,what))
@@ -1428,7 +1554,6 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh
             return false;
         }
     }
-  //std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> > _ms;
   return true;
 }
 
@@ -1666,6 +1791,52 @@ std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToM
   return ret;
 }
 
+int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+{
+  int ret=-std::numeric_limits<int>::max(),tmp=-1;
+  if((const DataArrayInt *)_fam_coords)
+    {
+      int val=_fam_coords->getMaxValue(tmp);
+      ret=std::max(ret,val);
+    }
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+    {
+      if((const MEDFileUMeshSplitL1 *)(*it))
+        {
+          const DataArrayInt *da=(*it)->getFamilyField();
+          if(da)
+            {
+              int val=_fam_coords->getMaxValue(tmp);
+              ret=std::max(ret,val);
+            }
+        }
+    }
+  return ret;
+}
+
+int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+{
+  int ret=std::numeric_limits<int>::max(),tmp=-1;
+  if((const DataArrayInt *)_fam_coords)
+    {
+      int val=_fam_coords->getMinValue(tmp);
+      ret=std::min(ret,val);
+    }
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+    {
+      if((const MEDFileUMeshSplitL1 *)(*it))
+        {
+          const DataArrayInt *da=(*it)->getFamilyField();
+          if(da)
+            {
+              int val=_fam_coords->getMinValue(tmp);
+              ret=std::min(ret,val);
+            }
+        }
+    }
+  return ret;
+}
+
 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
 {
   int lev=0;
@@ -1832,8 +2003,7 @@ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::v
       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
       ret->setCoords(c);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   std::vector<int> famIds=getFamiliesIds(fams);
   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
@@ -1858,10 +2028,7 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve
           if(renum)
             return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
           else
-            {
-              da->incrRef();
-              return da;
-            }
+            return da.retn();
         }
       else
         throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
@@ -1873,6 +2040,13 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve
     return l1->getFamilyPartArr(0,0,renum);
 }
 
+/*!
+ * Returns a pointer to mesh at the specified level.
+ * 
+ * \return a pointer to unstructured mesh that need to be managed by the caller.
+ * \warning the returned pointer has to be managed by the caller.
+ * \sa MEDFileUMesh::getGenMeshAtLevel
+ */
 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
 {
   synchronizeTinyInfoOnLeaves();
@@ -1892,6 +2066,13 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu
   return l1->getWholeMesh(renum);
 }
 
+/*!
+ * Returns a pointer to mesh at the specified level.
+ * 
+ * \return a pointer to unstructured mesh that need to be managed by the caller.
+ * \warning the returned pointer has to be managed by the caller.
+ * \sa MEDFileUMesh::getMeshAtLevel
+ */
 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
 {
   return getMeshAtLevel(meshDimRelToMax,renum);
@@ -2110,9 +2291,9 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *
       newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
       _fam_coords=newFam;
     }
-  nodesDuplicated=nodeIdsToDuplicate; nodeIdsToDuplicate->incrRef();
-  cellsModified=cellsToModifyConn0; cellsToModifyConn0->incrRef();
-  cellsNotModified=cellsToModifyConn1; cellsToModifyConn1->incrRef();
+  nodesDuplicated=nodeIdsToDuplicate.retn();
+  cellsModified=cellsToModifyConn0.retn();
+  cellsNotModified=cellsToModifyConn1.retn();
 }
 
 /*!
@@ -2180,19 +2361,173 @@ bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode
     {
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
-      o2nRenumCell=o2nRenumCellRet; o2nRenumCellRet->incrRef();
+      o2nRenumCell=o2nRenumCellRet.retn();
     }
   return ret;
 }
 
-void MEDFileUMesh::addNodeGroup(const std::string& name, const std::vector<int>& ids) throw(INTERP_KERNEL::Exception)
+struct MEDLoaderAccVisit1
+{
+  MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
+  int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
+  int _new_nb_of_nodes;
+};
+
+/*!
+ * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
+ * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
+ * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
+ * -1 values in returned array means that the corresponding old node is no more used.
+ *
+ * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched NULL pointer is returned and nothing
+ *         is modified in \a this.
+ * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
+ *  set coordinates.
+ */
+DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
+{
+  const DataArrayDouble *coo=getCoords();
+  if(!coo)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
+  int nbOfNodes=coo->getNumberOfTuples();
+  std::vector<bool> nodeIdsInUse(nbOfNodes,false);
+  std::vector<int> neLevs=getNonEmptyLevels();
+  for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
+    {
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
+      m->computeNodeIdsAlg(nodeIdsInUse);
+    }
+  int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
+  if(nbrOfNodesInUse==nbOfNodes)
+    return 0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
+  std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
+  if((const DataArrayInt *)_fam_coords)
+    newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
+  if((const DataArrayInt *)_num_coords)
+    newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
+  _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _rev_num_coords=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+    {
+      if((MEDFileUMeshSplitL1*)*it)
+        (*it)->renumberNodesInConn(ret->begin());
+    }
+  return ret.retn();
+}
+
+/*!
+ * This method is here only to add a group on node.
+ * MEDFileUMesh::setGroupsAtLevel with 1 in the first parameter.
+ *
+ * \param [in] ids node ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
+ */
+void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
 {
   const DataArrayDouble *coords=_coords;
   if(!coords)
-    throw INTERP_KERNEL::Exception("addNodeGroup : no coords set !");
-  DataArrayInt *sub=_fam_coords->selectByTupleIdSafe(&ids[0],&ids[0]+ids.size());
-  std::set<int> ssub(sub->getConstPointer(),sub->getConstPointer()+sub->getNumberOfTuples());
-  
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
+  int nbOfNodes=coords->getNumberOfTuples();
+  if(!((DataArrayInt *)_fam_coords))
+    { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
+  //
+  addGroupUnderground(ids,_fam_coords);
+}
+
+void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<int> levs=getNonEmptyLevelsExt();
+  if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
+    { 
+      std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
+      std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(meshDimRelToMaxExt==1)
+    { addNodeGroup(ids); return ; }
+  MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
+  DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
+  addGroupUnderground(ids,fam);
+}
+
+/*!
+ * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
+ * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not NULL (no check of that will be performed)
+ */
+void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
+{
+  if(!ids)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
+  std::string grpName(ids->getName());
+  if(grpName.empty())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
+  ids->checkStrictlyMonotonic(true);
+  famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
+  std::vector<std::string> grpsNames=getGroupsNames();
+  if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
+    {
+      std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
+  allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
+  std::set<int> diffFamIds=famIds->getDifferentValues();
+  std::vector<int> familyIds;
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
+  int maxVal=getTheMaxFamilyId()+1;
+  std::map<std::string,int> families(_families);
+  std::map<std::string, std::vector<std::string> > groups(_groups);
+  std::vector<std::string> fams;
+  bool created(false);
+  for(std::set<int>::const_iterator famId=diffFamIds.begin();famId!=diffFamIds.end();famId++)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
+      if(ret0->empty())
+        {
+          bool isFamPresent=false;
+          for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
+            isFamPresent=(*itl)->presenceOfValue(*famId);
+          if(!isFamPresent)
+            { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
+          else
+            {
+              familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ids2); std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,maxVal,created);
+              fams.push_back(locFamName);
+              if(existsFamily(*famId))
+                {
+                  std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
+                  ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
+                }
+              maxVal++;
+            } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
+        }
+      else
+        {
+          familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
+          familyIds.push_back(maxVal+1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
+          std::string n2(FindOrCreateAndGiveFamilyWithId(families,maxVal+1,created)); fams.push_back(n2);
+          if(existsFamily(*famId))
+            {
+              std::string n1(FindOrCreateAndGiveFamilyWithId(families,maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
+              ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
+            }
+          maxVal+=2;
+        }
+    }
+  for(std::size_t i=0;i<familyIds.size();i++)
+    {
+      DataArrayInt *da=idsPerfamiliyIds[i];
+      famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
+    }
+  _families=families;
+  _groups=groups;
+  _groups[grpName]=fams;
 }
 
 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
@@ -2398,6 +2733,25 @@ void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::
     }
 }
 
+std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
+{
+  std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
+  const DataArrayInt *da(_fam_coords);
+  if(da)
+    { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+    {
+      const MEDFileUMeshSplitL1 *elt(*it);
+      if(elt)
+        {
+          da=elt->getFamilyField();
+          if(da)
+            { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
+        }
+    }
+  return ret;
+}
+
 void MEDFileUMesh::computeRevNum() const
 {
   if((const DataArrayInt *)_num_coords)
@@ -2408,80 +2762,66 @@ void MEDFileUMesh::computeRevNum() const
     }
 }
 
-MEDFileCMesh *MEDFileCMesh::New()
+std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
 {
-  return new MEDFileCMesh;
+  std::size_t ret=MEDFileMesh::getHeapMemorySize();
+  if((const DataArrayInt*)_fam_nodes)
+    ret+=_fam_nodes->getHeapMemorySize();
+  if((const DataArrayInt*)_num_nodes)
+    ret+=_num_nodes->getHeapMemorySize();
+  if((const DataArrayInt*)_fam_cells)
+    ret+=_fam_cells->getHeapMemorySize();
+  if((const DataArrayInt*)_num_cells)
+    ret+=_num_cells->getHeapMemorySize();
+  if((const DataArrayInt*)_rev_num_nodes)
+    ret+=_rev_num_nodes->getHeapMemorySize();
+  if((const DataArrayInt*)_rev_num_cells)
+    ret+=_rev_num_cells->getHeapMemorySize();
+  return ret;
 }
 
-MEDFileCMesh *MEDFileCMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
+int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
 {
-  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
-  if(ms.empty())
+  int ret=-std::numeric_limits<int>::max(),tmp=-1;
+  if((const DataArrayInt *)_fam_nodes)
     {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
+      int val=_fam_nodes->getMaxValue(tmp);
+      ret=std::max(ret,val);
     }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
-  int dt,it;
-  ParaMEDMEM::MEDCouplingMeshType meshType;
-  std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
-  return new MEDFileCMesh(fid,ms.front().c_str(),dt,it);
-}
-
-MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
-{
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
-  return new MEDFileCMesh(fid,mName,dt,it);
-}
-
-int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
-{
-  if(!((const MEDCouplingCMesh*)_cmesh))
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
-  return _cmesh->getMeshDimension();
-}
-
-std::string MEDFileCMesh::simpleRepr() const
-{
-  return MEDFileMesh::simpleRepr();
+  if((const DataArrayInt *)_fam_cells)
+    {
+      int val=_fam_cells->getMaxValue(tmp);
+      ret=std::max(ret,val);
+    }
+  return ret;
 }
 
-std::string MEDFileCMesh::advancedRepr() const
+int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
 {
-  return simpleRepr();
+  int ret=std::numeric_limits<int>::max(),tmp=-1;
+  if((const DataArrayInt *)_fam_nodes)
+    {
+      int val=_fam_nodes->getMinValue(tmp);
+      ret=std::min(ret,val);
+    }
+  if((const DataArrayInt *)_fam_cells)
+    {
+      int val=_fam_cells->getMinValue(tmp);
+      ret=std::min(ret,val);
+    }
+  return ret;
 }
 
-bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
+bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
 {
   if(!MEDFileMesh::isEqual(other,eps,what))
     return false;
-  const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
+  const MEDFileStructuredMesh *otherC=dynamic_cast<const  MEDFileStructuredMesh *>(other);
   if(!otherC)
     {
-      what="Mesh types differ ! This is cartesian and other is NOT !";
-      return false;
-    }
-  clearNonDiscrAttributes();
-  otherC->clearNonDiscrAttributes();
-  const MEDCouplingCMesh *coo1=_cmesh;
-  const MEDCouplingCMesh *coo2=otherC->_cmesh;
-  if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
-    {
-      what="Mismatch of cartesian meshes ! One is defined and not other !";
+      what="Mesh types differ ! This is structured and other is NOT !";
       return false;
     }
-  if(coo1)
-    {
-      bool ret=coo1->isEqual(coo2,eps);
-      if(!ret)
-        {
-          what="cartesian meshes differ !";
-          return false;
-        }
-    }
   const DataArrayInt *famc1=_fam_nodes;
   const DataArrayInt *famc2=otherC->_fam_nodes;
   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
@@ -2549,10 +2889,9 @@ bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh
   return true;
 }
 
-void MEDFileCMesh::clearNonDiscrAttributes() const
+void MEDFileStructuredMesh::clearNonDiscrAttributes() const
 {
   MEDFileMesh::clearNonDiscrAttributes();
-  MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);
   const DataArrayInt *tmp=_fam_nodes;
   if(tmp)
     (const_cast<DataArrayInt *>(tmp))->setName("");
@@ -2567,61 +2906,234 @@ void MEDFileCMesh::clearNonDiscrAttributes() const
     (const_cast<DataArrayInt *>(tmp))->setName("");
 }
 
-MEDFileCMesh::MEDFileCMesh()
-{
-}
-
-MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
-try
-  {
-    loadCMeshFromFile(fid,mName,dt,it);
-  }
-catch(INTERP_KERNEL::Exception& e)
-  {
-    throw e;
-  }
-
-void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
 {
-  MEDFileCMeshL2 loaderl2;
-  ParaMEDMEM::MEDCouplingMeshType meshType;
-  int dummy0,dummy1;
-  std::string dtunit;
-  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
-  if(meshType!=CARTESIAN)
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
+  std::vector<int> famIds=getFamiliesIds(fams);
+  if(meshDimRelToMaxExt==1)
     {
-      std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  loaderl2.loadAll(fid,mid,mName,dt,it);
-  MEDCouplingCMesh *mesh=loaderl2.getMesh();
-  mesh->incrRef();
-  _cmesh=mesh;
-  setName(loaderl2.getName());
-  setDescription(loaderl2.getDescription());
-  setIteration(loaderl2.getIteration());
-  setOrder(loaderl2.getOrder());
-  setTimeValue(loaderl2.getTime());
-  setTimeUnit(loaderl2.getTimeUnit());
-  MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
-  med_bool chgt=MED_FALSE,trsf=MED_FALSE;
-  int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
-  if(nbOfElt>0)
+      if((const DataArrayInt *)_fam_nodes)
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+          if(!famIds.empty())
+            da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+          else
+            da=_fam_nodes->getIdsEqualList(0,0);
+          if(renum)
+            return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
+          else
+            return da.retn();
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
+    }
+  else
     {
-      _fam_nodes=DataArrayInt::New();
-      _fam_nodes->alloc(nbOfElt,1);
-      MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
+      if((const DataArrayInt *)_fam_cells)
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+          if(!famIds.empty())
+            da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+          else
+            da=_fam_cells->getIdsEqualList(0,0);
+          if(renum)
+            return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
+          else
+            return da.retn();
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
     }
-  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
-  if(nbOfElt>0)
+}
+
+void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
+  const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
+  if(meshDimRelToMaxExt==0)
     {
-      _num_nodes=DataArrayInt::New();
-      _num_nodes->alloc(nbOfElt,1);
-      MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
+      int nbCells=mesh->getNumberOfCells();
+      famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
+      _fam_cells=famArr;
     }
-  int spaceDim=mesh->getSpaceDimension();
+  else
+    {
+      int nbNodes=mesh->getNumberOfNodes();
+      famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+      _fam_nodes=famArr;
+    }
+  if(famArr)
+    famArr->incrRef();
+}
+
+void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
+  const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
+  if(meshDimRelToMaxExt==0)
+    {
+      int nbCells=mesh->getNumberOfCells();
+      renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
+      _num_cells=renumArr;
+    }
+  else
+    {
+      int nbNodes=mesh->getNumberOfNodes();
+      renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+      _num_nodes=renumArr;
+    }
+  if(renumArr)
+    renumArr->incrRef();
+}
+
+const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
+  if(meshDimRelToMaxExt==0)
+    return _fam_cells;
+  else
+    return _fam_nodes;
+}
+
+const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
+  if(meshDimRelToMaxExt==0)
+    return _num_cells;
+  else
+    return _num_nodes;
+}
+
+const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
+  if(meshDimRelToMaxExt==0)
+    {
+      if((const DataArrayInt *)_num_cells)
+        {
+          int pos;
+          int maxValue=_num_cells->getMaxValue(pos);
+          _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
+          return _rev_num_cells;
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
+    }
+  else
+    {
+      if((const DataArrayInt *)_num_nodes)
+        {
+          int pos;
+          int maxValue=_num_nodes->getMaxValue(pos);
+          _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
+          return _rev_num_nodes;
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
+    }
+}
+
+std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
+{
+  std::vector<int> ret(1);
+  return ret;
+}
+
+std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
+{
+  std::vector<int> ret(2);
+  ret[0]=1;
+  return ret;
+}
+
+/*!
+ * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
+ */
+bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
+{
+  oldCode.clear(); newCode.clear(); o2nRenumCell=0;
+  return false;
+}
+
+void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
+{
+  DataArrayInt *arr=_fam_nodes;
+  if(arr)
+    arr->changeValue(oldId,newId);
+  arr=_fam_cells;
+  if(arr)
+    arr->changeValue(oldId,newId);
+}
+
+void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
+{
+  if((const DataArrayInt*)_fam_nodes)
+    _fam_nodes=_fam_nodes->deepCpy();
+  if((const DataArrayInt*)_num_nodes)
+    _num_nodes=_num_nodes->deepCpy();
+  if((const DataArrayInt*)_fam_cells)
+    _fam_cells=_fam_cells->deepCpy();
+  if((const DataArrayInt*)_num_cells)
+    _num_cells=_num_cells->deepCpy();
+  if((const DataArrayInt*)_rev_num_nodes)
+    _rev_num_nodes=_rev_num_nodes->deepCpy();
+  if((const DataArrayInt*)_rev_num_cells)
+    _rev_num_cells=_rev_num_cells->deepCpy();
+}
+
+/*!
+ * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
+ * 
+ * \return a pointer to cartesian mesh that need to be managed by the caller.
+ * \warning the returned pointer has to be managed by the caller.
+ */
+MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
+{
+  if(renum)
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
+  if(meshDimRelToMax!=0)
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
+  const MEDCouplingStructuredMesh *m=getStructuredMesh();
+  if(m)
+    m->incrRef();
+  return const_cast<MEDCouplingStructuredMesh *>(m);
+}
+
+int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
+  const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
+  if(!cmesh)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
+  if(meshDimRelToMaxExt==0)
+    return cmesh->getNumberOfCells();
+  else
+    return cmesh->getNumberOfNodes();
+}
+
+int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
+  if(!cmesh)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
+  return cmesh->getNumberOfNodes();
+}
+
+med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
+{
   med_geometry_type geoTypeReq=MED_NONE;
-  switch(spaceDim)
+  switch(meshDim)
     {
     case 3:
       geoTypeReq=MED_HEXA8;
@@ -2636,8 +3148,37 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int
       geoTypeReq=MED_POINT1;
       break;
     default:
-      throw INTERP_KERNEL::Exception("Invalid spacedim detected for cartesian mesh ! Must be in (1,2,3) !");
+      throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
+    }
+  return geoTypeReq;
+}
+
+void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
+{
+  setName(strm->getName());
+  setDescription(strm->getDescription());
+  setIteration(strm->getIteration());
+  setOrder(strm->getOrder());
+  setTimeValue(strm->getTime());
+  setTimeUnit(strm->getTimeUnit());
+  MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
+  med_bool chgt=MED_FALSE,trsf=MED_FALSE;
+  int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
+  if(nbOfElt>0)
+    {
+      _fam_nodes=DataArrayInt::New();
+      _fam_nodes->alloc(nbOfElt,1);
+      MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
+    }
+  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
+  if(nbOfElt>0)
+    {
+      _num_nodes=DataArrayInt::New();
+      _num_nodes->alloc(nbOfElt,1);
+      MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
     }
+  int meshDim=getStructuredMesh()->getMeshDimension();
+  med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
@@ -2654,14 +3195,160 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int
     }
 }
 
-void MEDFileCMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
+{
+  int meshDim=getStructuredMesh()->getMeshDimension();
+  med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
+  //
+  if((const DataArrayInt *)_fam_cells)
+    MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
+  if((const DataArrayInt *)_fam_nodes)
+    MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
+  if((const DataArrayInt *)_num_cells)
+    MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
+  if((const DataArrayInt *)_num_nodes)
+    MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
+  //
+  MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
+}
+
+MEDFileCMesh *MEDFileCMesh::New()
+{
+  return new MEDFileCMesh;
+}
+
+MEDFileCMesh *MEDFileCMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
+  if(ms.empty())
+    {
+      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  int dt,it;
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  std::string dummy2;
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
+  return new MEDFileCMesh(fid,ms.front().c_str(),dt,it);
+}
+
+MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  return new MEDFileCMesh(fid,mName,dt,it);
+}
+
+std::size_t MEDFileCMesh::getHeapMemorySize() const
+{
+  std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
+  if((const MEDCouplingCMesh *)_cmesh)
+    ret+=_cmesh->getHeapMemorySize();
+  return ret;
+}
+
+int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
+{
+  if(!((const MEDCouplingCMesh*)_cmesh))
+    throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
+  return _cmesh->getMeshDimension();
+}
+
+std::string MEDFileCMesh::simpleRepr() const
+{
+  return MEDFileStructuredMesh::simpleRepr();
+}
+
+std::string MEDFileCMesh::advancedRepr() const
+{
+  return simpleRepr();
+}
+
+MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
+  return ret.retn();
+}
+
+MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
+  if((const MEDCouplingCMesh*)_cmesh)
+    ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
+  ret->deepCpyAttributes();
+  return ret.retn();
+}
+
+bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
+{
+  if(!MEDFileStructuredMesh::isEqual(other,eps,what))
+    return false;
+  const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
+  if(!otherC)
+    {
+      what="Mesh types differ ! This is cartesian and other is NOT !";
+      return false;
+    }
+  clearNonDiscrAttributes();
+  otherC->clearNonDiscrAttributes();
+  const MEDCouplingCMesh *coo1=_cmesh;
+  const MEDCouplingCMesh *coo2=otherC->_cmesh;
+  if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
+    {
+      what="Mismatch of cartesian meshes ! One is defined and not other !";
+      return false;
+    }
+  if(coo1)
+    {
+      bool ret=coo1->isEqual(coo2,eps);
+      if(!ret)
+        {
+          what="cartesian meshes differ !";
+          return false;
+        }
+    }
+  return true;
+}
+
+void MEDFileCMesh::clearNonDiscrAttributes() const
+{
+  MEDFileStructuredMesh::clearNonDiscrAttributes();
+  MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
+}
+
+MEDFileCMesh::MEDFileCMesh()
+{
+}
+
+MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
+try
+  {
+    loadCMeshFromFile(fid,mName,dt,it);
+  }
+catch(INTERP_KERNEL::Exception& e)
+  {
+    throw e;
+  }
+
+void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
 {
-  DataArrayInt *arr=_fam_nodes;
-  if(arr)
-    arr->changeValue(oldId,newId);
-  arr=_fam_cells;
-  if(arr)
-    arr->changeValue(oldId,newId);
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  int dummy0,dummy1;
+  std::string dtunit;
+  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
+  if(meshType!=CARTESIAN)
+    {
+      std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDFileCMeshL2 loaderl2;
+  loaderl2.loadAll(fid,mid,mName,dt,it);
+  MEDCouplingCMesh *mesh=loaderl2.getMesh();
+  mesh->incrRef();
+  _cmesh=mesh;
+  loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
 }
 
 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
@@ -2670,16 +3357,10 @@ const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
   return _cmesh;
 }
 
-MEDCouplingMesh *MEDFileCMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
+const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
 {
-  if(renum)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh does not support renumbering ! To do it perform request of renum array directly !");
-  if(meshDimRelToMax!=0)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh does not support multi level for mesh 0 expected as input !");
-  const MEDCouplingCMesh *m=getMesh();
-  if(m)
-    m->incrRef();
-  return const_cast<MEDCouplingCMesh *>(m);
+  synchronizeTinyInfoOnLeaves();
+  return _cmesh;
 }
 
 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
@@ -2699,6 +3380,7 @@ void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
   MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
   int spaceDim=_cmesh->getSpaceDimension();
+  int meshDim=_cmesh->getMeshDimension();
   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   for(int i=0;i<spaceDim;i++)
@@ -2709,7 +3391,7 @@ void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
-  MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
+  MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
   MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
   for(int i=0;i<spaceDim;i++)
     {
@@ -2717,203 +3399,221 @@ void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
       MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
     }
   //
-  med_geometry_type geoTypeReq=MED_NONE;
-  switch(spaceDim)
-    {
-    case 3:
-      geoTypeReq=MED_HEXA8;
-      break;
-    case 2:
-      geoTypeReq=MED_QUAD4;
-      break;
-    case 1:
-      geoTypeReq=MED_SEG2;
-      break;
-    case 0:
-      geoTypeReq=MED_POINT1;
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("Invalid spacedim detected for cartesian mesh ! Must be in (1,2,3) !");
-    }
-  //
-  if((const DataArrayInt *)_fam_cells)
-    MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
-  if((const DataArrayInt *)_fam_nodes)
-    MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
-  //
-  MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
-}
-
-int MEDFileCMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
-{
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
-  if(!((const MEDCouplingCMesh *)_cmesh))
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getSizeAtLevel : No cartesian mesh set !");
-  if(meshDimRelToMaxExt==0)
-    return _cmesh->getNumberOfCells();
-  else
-    return _cmesh->getNumberOfNodes();
+  MEDFileStructuredMesh::writeStructuredLL(fid,maa);
 }
 
 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
 {
   const MEDCouplingCMesh *cmesh=_cmesh;
+  if(!cmesh)
+    return;
   (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
   (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
   (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
   (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
 }
 
-int MEDFileCMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
 {
-  const MEDCouplingCMesh *cmesh(_cmesh);
-  if(!cmesh)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getNumberOfNodes : no cartesian mesh set !");
-  return cmesh->getNumberOfNodes();
+  return new MEDFileCurveLinearMesh;
 }
 
-std::vector<int> MEDFileCMesh::getNonEmptyLevels() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
 {
-  std::vector<int> ret(1);
-  return ret;
+  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
+  if(ms.empty())
+    {
+      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  int dt,it;
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  std::string dummy2;
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
+  return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it);
 }
 
-std::vector<int> MEDFileCMesh::getNonEmptyLevelsExt() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
 {
-  std::vector<int> ret(2);
-  ret[0]=1;
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  return new MEDFileCurveLinearMesh(fid,mName,dt,it);
+}
+
+std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
+{
+  std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
+  if((const MEDCouplingCurveLinearMesh *)_clmesh)
+    ret+=_clmesh->getHeapMemorySize();
   return ret;
 }
 
-DataArrayInt *MEDFileCMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamiliesArr : Only available for levels 0 or 1 !");
-  std::vector<int> famIds=getFamiliesIds(fams);
-  if(meshDimRelToMaxExt==1)
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
+  return ret.retn();
+}
+
+MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
+  if((const MEDCouplingCurveLinearMesh*)_clmesh)
+    ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
+  ret->deepCpyAttributes();
+  return ret.retn();
+}
+
+int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
+{
+  if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
+  return _clmesh->getMeshDimension();
+}
+
+std::string MEDFileCurveLinearMesh::simpleRepr() const
+{
+  return MEDFileStructuredMesh::simpleRepr();
+}
+
+std::string MEDFileCurveLinearMesh::advancedRepr() const
+{
+  return simpleRepr();
+}
+
+bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
+{
+  if(!MEDFileStructuredMesh::isEqual(other,eps,what))
+    return false;
+  const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
+  if(!otherC)
     {
-      if((const DataArrayInt *)_fam_nodes)
-        {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
-          if(!famIds.empty())
-            da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
-          else
-            da=_fam_nodes->getIdsEqualList(0,0);
-          if(renum)
-            return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
-          else
-            {
-              da->incrRef();
-              return da;
-            }
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamiliesArr : no family array specified on nodes !");
+      what="Mesh types differ ! This is curve linear and other is NOT !";
+      return false;
     }
-  else
+  clearNonDiscrAttributes();
+  otherC->clearNonDiscrAttributes();
+  const MEDCouplingCurveLinearMesh *coo1=_clmesh;
+  const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
+  if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
     {
-      if((const DataArrayInt *)_fam_cells)
+      what="Mismatch of curve linear meshes ! One is defined and not other !";
+      return false;
+    }
+  if(coo1)
+    {
+      bool ret=coo1->isEqual(coo2,eps);
+      if(!ret)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
-          if(!famIds.empty())
-            da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
-          else
-            da=_fam_cells->getIdsEqualList(0,0);
-          if(renum)
-            return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
-          else
-            {
-              da->incrRef();
-              return da;
-            }
+          what="curve linear meshes differ !";
+          return false;
         }
-      else
-        throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamiliesArr : no family array specified on cells !");
     }
+  return true;
 }
 
-void MEDFileCMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
+void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
-  if(famArr)
-    famArr->incrRef();
-  if(meshDimRelToMaxExt==0)
-    _fam_cells=famArr;
-  else
-    _fam_nodes=famArr;
+  MEDFileStructuredMesh::clearNonDiscrAttributes();
+  MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
 }
 
-void MEDFileCMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
+void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
-  if(renumArr)
-    renumArr->incrRef();
-  if(meshDimRelToMaxExt==0)
-    _num_cells=renumArr;
-  else
-    _num_nodes=renumArr;
+  const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
+  if(!clmesh)
+    return;
+  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
+  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
+  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
+  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
 }
 
-const DataArrayInt *MEDFileCMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
-  if(meshDimRelToMaxExt==0)
-    return _fam_cells;
-  else
-    return _fam_nodes;
+  synchronizeTinyInfoOnLeaves();
+  return _clmesh;
 }
 
-const DataArrayInt *MEDFileCMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
-  if(meshDimRelToMaxExt==0)
-    return _num_cells;
-  else
-    return _num_nodes;
+  dealWithTinyInfo(m);
+  if(m)
+    m->incrRef();
+  _clmesh=m;
 }
 
-const DataArrayInt *MEDFileCMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
-  if(meshDimRelToMaxExt==0)
-    {
-      if((const DataArrayInt *)_num_cells)
-        {
-          int pos;
-          int maxValue=_num_cells->getMaxValue(pos);
-          _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
-          return _rev_num_cells;
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
-    }
-  else
+  synchronizeTinyInfoOnLeaves();
+  return _clmesh;
+}
+
+MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
+{
+}
+
+MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
+try
+  {
+    loadCLMeshFromFile(fid,mName,dt,it);
+  }
+catch(INTERP_KERNEL::Exception& e)
+  {
+    throw e;
+  }
+
+void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
+{
+  INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+  INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
+  INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
+  MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
+  MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
+  MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
+  int spaceDim=_clmesh->getSpaceDimension();
+  int meshDim=_clmesh->getMeshDimension();
+  INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
+  INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
+  const DataArrayDouble *coords=_clmesh->getCoords();
+  if(!coords)
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
+  for(int i=0;i<spaceDim;i++)
     {
-      if((const DataArrayInt *)_num_nodes)
-        {
-          int pos;
-          int maxValue=_num_nodes->getMaxValue(pos);
-          _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
-          return _rev_num_nodes;
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
+      std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
+      std::string c,u;
+      MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
+      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
+  MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
+  MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
+  std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
+  MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
+  
+  MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
+  //
+  MEDFileStructuredMesh::writeStructuredLL(fid,maa);
 }
 
-/*!
- * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
- */
-bool MEDFileCMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
+void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
 {
-  oldCode.clear(); newCode.clear(); o2nRenumCell=0;
-  return false;
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  int dummy0,dummy1;
+  std::string dtunit;
+  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
+  if(meshType!=CURVE_LINEAR)
+    {
+      std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDFileCLMeshL2 loaderl2;
+  loaderl2.loadAll(fid,mid,mName,dt,it);
+  MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
+  mesh->incrRef();
+  _clmesh=mesh;
+  loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
 }
 
 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
@@ -2931,6 +3631,26 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mN
   return new MEDFileMeshMultiTS(fileName,mName);
 }
 
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
+    if((const MEDFileMesh *)*it)
+      meshOneTs[i]=(*it)->deepCpy();
+  ret->_mesh_one_ts=meshOneTs;
+  return ret.retn();
+}
+
+std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
+{
+  std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    ret+=(*it)->getHeapMemorySize();
+  return ret;
+}
+
 const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
 {
   if(_mesh_one_ts.empty())
@@ -3187,6 +3907,27 @@ catch(INTERP_KERNEL::Exception& e)
   {
   }
 
+MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
+    if((const MEDFileMeshMultiTS *)*it)
+      meshes[i]=(*it)->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
+  ret->_meshes=meshes;
+  return ret.retn();
+}
+
+std::size_t MEDFileMeshes::getHeapMemorySize() const
+{
+  std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
+    if((const MEDFileMeshMultiTS*)*it)
+      ret+=(*it)->getHeapMemorySize();
+  return ret; 
+}
+
 std::string MEDFileMeshes::simpleRepr() const
 {
   std::ostringstream oss;
index 02df40ac61be2ce5e0c468a80d71e83677bc01b8..eb1e5bb3796ca3487dfa357af954420dd5a40877 100644 (file)
@@ -26,6 +26,7 @@
 #include "MEDFileUtilities.hxx"
 
 #include <map>
+#include <list>
 
 namespace ParaMEDMEM
 {
@@ -34,6 +35,9 @@ namespace ParaMEDMEM
   public:
     static MEDFileMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
+    virtual MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception) = 0;
+    virtual MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception) = 0;
     virtual bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
     virtual void clearNonDiscrAttributes() const;
     void setName(const char *name) { _name=name; }
@@ -93,9 +97,14 @@ namespace ParaMEDMEM
     void changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception);
     void changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception);
     void changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception);
+    void changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception);
     int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception);
     int getMaxFamilyId() const throw(INTERP_KERNEL::Exception);
     int getMinFamilyId() const throw(INTERP_KERNEL::Exception);
+    int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception);
+    int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception);
+    virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) = 0;
+    virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) = 0;
     DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception);
     std::vector<int> getFamiliesIds(const std::vector<std::string>& famNames) const throw(INTERP_KERNEL::Exception);
     std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception);
@@ -132,6 +141,8 @@ namespace ParaMEDMEM
     virtual void appendFamilyEntries(const std::set<int>& famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames);
     virtual void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception) = 0;
     static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp);
+    static void ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception);
+    static std::string FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception);
     static std::string CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception);
     static int PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception);
   protected:
@@ -156,10 +167,15 @@ namespace ParaMEDMEM
     static MEDFileUMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception);
     static MEDFileUMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileUMesh *New();
+    std::size_t getHeapMemorySize() const;
+    MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception);
+    MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
     void clearNonDiscrAttributes() const;
     ~MEDFileUMesh();
     //
+    int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception);
+    int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception);
     int getMeshDimension() const throw(INTERP_KERNEL::Exception);
     int getSpaceDimension() const throw(INTERP_KERNEL::Exception);
     std::string simpleRepr() const;
@@ -198,16 +214,18 @@ namespace ParaMEDMEM
     void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception);
     void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception);
     void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception);
-    void addNodeGroup(const std::string& name, const std::vector<int>& ids) throw(INTERP_KERNEL::Exception);
+    void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception);
+    void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception);
     void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception);
     void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception);
     void setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception);
     void setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms) throw(INTERP_KERNEL::Exception);
     void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception);
     void optimizeFamilies() throw(INTERP_KERNEL::Exception);
-    void duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception);
     // tools
+    void duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception);
     bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception);
+    DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception);
   private:
     void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception);
     MEDFileUMesh();
@@ -220,6 +238,8 @@ namespace ParaMEDMEM
     void computeRevNum() const;
     void synchronizeTinyInfoOnLeaves() const;
     void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception);
+    std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > getAllNonNullFamilyIds() const;
+    void addGroupUnderground(const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception);
   private:
     std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> > _ms;
     MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords;
@@ -228,48 +248,98 @@ namespace ParaMEDMEM
     mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_coords;
   };
 
-  class MEDLOADER_EXPORT MEDFileCMesh : public MEDFileMesh
+  class MEDLOADER_EXPORT MEDFileStructuredMesh : public MEDFileMesh
+  {
+    friend class MEDFileMesh;
+  public:
+    std::size_t getHeapMemorySize() const;
+    int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception);
+    int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception);
+    bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
+    void clearNonDiscrAttributes() const;
+    DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception);
+    const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
+    void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception);
+    void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception);
+    const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
+    const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
+    std::vector<int> getNonEmptyLevels() const;
+    std::vector<int> getNonEmptyLevelsExt() const;
+    MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception);
+    int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
+    int getNumberOfNodes() const throw(INTERP_KERNEL::Exception);
+    // tools
+    bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception);
+  protected:
+    void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception);
+    void deepCpyAttributes() throw(INTERP_KERNEL::Exception);
+    void loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception);
+    void writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception);
+    virtual const MEDCouplingStructuredMesh *getStructuredMesh() const = 0;
+    static med_geometry_type GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception);
+  private:
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_nodes;
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_nodes;
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_cells;
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_cells;
+    mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_nodes;
+    mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_cells;
+  };
+
+  class MEDLOADER_EXPORT MEDFileCMesh : public MEDFileStructuredMesh
   {
     friend class MEDFileMesh;
   public:
     static MEDFileCMesh *New();
     static MEDFileCMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileCMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
+    MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception);
+    MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
     int getMeshDimension() const throw(INTERP_KERNEL::Exception);
     std::string simpleRepr() const;
     std::string advancedRepr() const;
     void clearNonDiscrAttributes() const;
     const MEDCouplingCMesh *getMesh() const;
-    MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception);
     void setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception);
-    int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
-    DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception);
-    void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception);
-    void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception);
-    int getNumberOfNodes() const throw(INTERP_KERNEL::Exception);
-    std::vector<int> getNonEmptyLevels() const;
-    std::vector<int> getNonEmptyLevelsExt() const;
-    const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
-    const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
-    const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
-    // tools
-    bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception);
   private:
+    const MEDCouplingStructuredMesh *getStructuredMesh() const;
     void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception);
     MEDFileCMesh();
     void synchronizeTinyInfoOnLeaves() const;
     MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception);
     void loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception);
-    void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception);
   private:
     MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> _cmesh;
-    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_nodes;
-    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_nodes;
-    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_cells;
-    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_cells;
-    mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_nodes;
-    mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_cells;
+  };
+
+  class MEDLOADER_EXPORT MEDFileCurveLinearMesh : public MEDFileStructuredMesh
+  {
+    friend class MEDFileMesh;
+  public:
+    static MEDFileCurveLinearMesh *New();
+    static MEDFileCurveLinearMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception);
+    static MEDFileCurveLinearMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
+    MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception);
+    MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception);
+    bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
+    int getMeshDimension() const throw(INTERP_KERNEL::Exception);
+    std::string simpleRepr() const;
+    std::string advancedRepr() const;
+    void clearNonDiscrAttributes() const;
+    const MEDCouplingCurveLinearMesh *getMesh() const;
+    void setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception);
+  private:
+    MEDFileCurveLinearMesh();
+    MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception);
+    const MEDCouplingStructuredMesh *getStructuredMesh() const;
+    void synchronizeTinyInfoOnLeaves() const;
+    void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception);
+    void loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception);//to imp
+  private:
+    MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> _clmesh;
   };
 
   class MEDLOADER_EXPORT MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable
@@ -278,6 +348,8 @@ namespace ParaMEDMEM
     static MEDFileMeshMultiTS *New();
     static MEDFileMeshMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileMeshMultiTS *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception);
+    MEDFileMeshMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
     const char *getName() const throw(INTERP_KERNEL::Exception);
     void setName(const char *newMeshName) throw(INTERP_KERNEL::Exception);
     bool changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception);
@@ -301,6 +373,8 @@ namespace ParaMEDMEM
   public:
     static MEDFileMeshes *New();
     static MEDFileMeshes *New(const char *fileName) throw(INTERP_KERNEL::Exception);
+    MEDFileMeshes *deepCpy() const throw(INTERP_KERNEL::Exception);
+    std::size_t getHeapMemorySize() const;
     std::string simpleRepr() const;
     void simpleReprWithoutHeader(std::ostream& oss) const;
     void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception);
index e8bda66294729b97484bcbb4d6c93f0f6b62c72b..fcce83e754303ac526a7c5eb5f47652b5d71b3b3 100644 (file)
@@ -37,6 +37,7 @@ namespace ParaMEDMEM
   public:
     static MEDFileUMeshPerType *New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2);
     static bool isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity);
+    std::size_t getHeapMemorySize() const { return 0; }
     int getDim() const;
     const DataArrayInt *getNodal() const { return _conn; }
     const DataArrayInt *getNodalIndex() const { return _conn_index; }
index cfb86ad46dde52f834c11069712e2e8890afcef9..e6851db84dfd25a40f4ae5950971db820b4210d9 100644 (file)
@@ -81,8 +81,22 @@ int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const char *mname, ParaMEDMEM:
       meshType=UNSTRUCTURED;
       break;
     case MED_STRUCTURED_MESH:
-      meshType=CARTESIAN;
-      break;
+      {
+        med_grid_type gt;
+        MEDmeshGridTypeRd(fid,mname,&gt);
+        switch(gt)
+          {
+          case MED_CARTESIAN_GRID:
+            meshType=CARTESIAN;
+            break;
+          case MED_CURVILINEAR_GRID:
+            meshType=CURVE_LINEAR;
+            break;
+          default:
+            throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n");
+          }
+        break;
+      }
     default:
       throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !");
     }
@@ -135,8 +149,22 @@ std::vector<std::string> MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId,
       meshType=UNSTRUCTURED;
       break;
     case MED_STRUCTURED_MESH:
-      meshType=CARTESIAN;
-      break;
+      {
+        med_grid_type gt;
+        MEDmeshGridTypeRd(fid,mName,&gt);
+        switch(gt)
+          {
+          case MED_CARTESIAN_GRID:
+            meshType=CARTESIAN;
+            break;
+          case MED_CURVILINEAR_GRID:
+            meshType=CURVE_LINEAR;
+            break;
+          default:
+            throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getAxisInfoOnMesh : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n");
+          }
+        break;
+      }
     default:
       throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !");
     }
@@ -334,7 +362,7 @@ void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const char *mName, int dt, in
   med_grid_type gridtype;
   MEDmeshGridTypeRd(fid,mName,&gridtype);
   if(gridtype!=MED_CARTESIAN_GRID)
-    throw INTERP_KERNEL::Exception("Invalid cartesion mesh type ! Only Cartesian Grid supported ! Curvilinear grid will come soon !");
+    throw INTERP_KERNEL::Exception("Invalid structured mesh ! Expected cartesian mesh type !");
   _cmesh=MEDCouplingCMesh::New();
   for(int i=0;i<Mdim;i++)
     {
@@ -364,6 +392,36 @@ med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id) throw(IN
     }
 }
 
+MEDFileCLMeshL2::MEDFileCLMeshL2()
+{
+}
+
+void MEDFileCLMeshL2::loadAll(med_idt fid, int mId, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
+{
+  _name.set(mName);
+  int nstep;
+  int Mdim;
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim);
+  if(meshType!=CURVE_LINEAR)
+    throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !");
+  _time=CheckMeshTimeStep(fid,mName,nstep,dt,it);
+  _iteration=dt;
+  _order=it;
+  //
+  _clmesh=MEDCouplingCurveLinearMesh::New();
+  INTERP_KERNEL::AutoPtr<int> stGrid=new int[Mdim];
+  MEDmeshGridStructRd(fid,mName,dt,it,stGrid);
+  _clmesh->setNodeGridStructure(stGrid,((int *)stGrid)+Mdim);
+  med_bool chgt=MED_FALSE,trsf=MED_FALSE;
+  int nbNodes=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&chgt,&trsf);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> da=DataArrayDouble::New();
+  da->alloc(nbNodes,infosOnComp.size());
+  da->setInfoOnComponents(infosOnComp);
+  MEDmeshNodeCoordinateRd(fid,mName,dt,it,MED_FULL_INTERLACE,da->getPointer());
+  _clmesh->setCoords(da);
+}
+
 MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0)
 {
 }
@@ -378,27 +436,20 @@ MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const
   if((MEDCouplingUMesh *)_m==0)
     {
       updateTime();
-      MEDCouplingUMesh *ret=(MEDCouplingUMesh *)_st->_m_by_types->deepCpy();
-      _m=ret;
+      _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types->deepCpy());
       _m->renumberCells(_st->_num->getConstPointer(),true);
-      ret->incrRef();
-      return ret;
+      return _m.retn();
     }
   else
     {
       if(_mpt_time==_st->_m_by_types->getTimeOfThis() && _num_time==_st->_num->getTimeOfThis())
-        {
-          _m->incrRef();
-          return _m;
-        }
+        return _m.retn();
       else
         {
           updateTime();
-          MEDCouplingUMesh *ret=(MEDCouplingUMesh *)_st->_m_by_types->deepCpy();
-          _m=ret;
+          _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types->deepCpy());
           _m->renumberCells(_st->_num->getConstPointer(),true);
-          ret->incrRef();
-          return ret;
+          return _m.retn();
         }
     }
 }
@@ -414,6 +465,10 @@ void MEDFileUMeshPermCompute::updateTime() const
   _num_time=_st->_num->getTimeOfThis();
 }
 
+MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other):_m_by_types(other._m_by_types),_fam(other._fam),_num(other._num),_rev_num(other._rev_num),_m(this)
+{
+}
+
 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const char *mName, int id):_m(this)
 {
   const std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& v=l2.getLev(id);
@@ -463,6 +518,38 @@ MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m(
   assignMesh(m,newOrOld);
 }
 
+std::size_t MEDFileUMeshSplitL1::getHeapMemorySize() const
+{
+  std::size_t ret=0;
+  if((const MEDCouplingUMesh *)_m_by_types)
+    {
+      ret+=_m_by_types->getHeapMemorySize();
+      if((const DataArrayDouble *)_m_by_types->getCoords())
+        ret-=_m_by_types->getCoords()->getHeapMemorySize();
+    }
+  if((const  DataArrayInt*)_fam)
+    ret+=_fam->getHeapMemorySize();
+  if((const  DataArrayInt*)_num)
+    ret+=_num->getHeapMemorySize();
+  if((const  DataArrayInt*)_rev_num)
+    ret+=_rev_num->getHeapMemorySize();
+  return ret;
+}
+
+MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::deepCpy() const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> ret=new MEDFileUMeshSplitL1(*this);
+  if((const MEDCouplingUMesh*)_m_by_types)
+    ret->_m_by_types=static_cast<MEDCouplingUMesh*>(_m_by_types->deepCpy());
+  if((const DataArrayInt *)_fam)
+    ret->_fam=_fam->deepCpy();
+  if((const DataArrayInt *)_num)
+    ret->_num=_num->deepCpy();
+  if((const DataArrayInt *)_rev_num)
+    ret->_rev_num=_rev_num->deepCpy();
+  return ret.retn();
+}
+
 bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const
 {
   const MEDCouplingUMesh *m1=_m_by_types;
@@ -611,8 +698,7 @@ DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const int *idsBg, const int
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=_fam->getIdsEqualList(idsBg,idsEnd);
   if(renum)
     return renumIfNeededArr(da);
-  da->incrRef();
-  return da;
+  return da.retn();
 }
 
 MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const
@@ -622,8 +708,19 @@ MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const
     tmp=_m;
   else
     tmp=_m_by_types;
-  tmp->incrRef();
-  return tmp;
+  return tmp.retn();
+}
+
+DataArrayInt *MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField() throw(INTERP_KERNEL::Exception)
+{
+  if((DataArrayInt *)_fam)
+    return _fam;
+  MEDCouplingUMesh *m(_m_by_types);
+  if(!m)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField : impossible to create a family field array because no mesh specified on this level !");
+  int nbOfTuples=m->getNumberOfCells();
+  _fam=DataArrayInt::New(); _fam->alloc(nbOfTuples,1); _fam->fillWithZero();
+  return _fam;
 }
 
 const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const
@@ -686,6 +783,14 @@ void MEDFileUMeshSplitL1::write(med_idt fid, const char *mName, int mdim) const
     }
 }
 
+void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N) throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingUMesh *m(_m_by_types);
+  if(!m)
+    return;
+  m->renumberNodesInConn(newNodeNumbersO2N);
+}
+
 void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
 {
   DataArrayInt *arr=_fam;
index 263f77d4175017c85817f2f3f47bff824d5033d3..07306af54b851066f0e1e221122cca5d89889f8e 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingCMesh.hxx"
+#include "MEDCouplingCurveLinearMesh.hxx"
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
 #include "med.h"
@@ -38,6 +39,7 @@ namespace ParaMEDMEM
   {
   public:
     MEDFileMeshL2();
+    std::size_t getHeapMemorySize() const { return 0; }
     const char *getName() const { return _name.getReprForWrite(); }
     const char *getDescription() const { return _description.getReprForWrite(); }
     const char *getTimeUnit() const { return _dt_unit.getReprForWrite(); }
@@ -83,7 +85,11 @@ namespace ParaMEDMEM
     MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_coords;
   };
 
-  class MEDFileCMeshL2 : public MEDFileMeshL2
+  class MEDFileStrMeshL2 : public MEDFileMeshL2
+  {
+  };
+
+  class MEDFileCMeshL2 : public MEDFileStrMeshL2
   {
   public:
     MEDFileCMeshL2();
@@ -94,6 +100,16 @@ namespace ParaMEDMEM
   private:
     MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> _cmesh;
   };
+  
+  class MEDFileCLMeshL2 : public MEDFileStrMeshL2
+  {
+  public:
+    MEDFileCLMeshL2();
+    void loadAll(med_idt fid, int mId, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception);
+    MEDCouplingCurveLinearMesh *getMesh() { return _clmesh; }
+  private:
+    MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> _clmesh;
+  };
 
   class MEDFileMesh;
   class MEDFileUMeshSplitL1;
@@ -116,9 +132,12 @@ namespace ParaMEDMEM
   {
     friend class MEDFileUMeshPermCompute;
   public:
+    MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other);
     MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const char *mName, int id);
     MEDFileUMeshSplitL1(MEDCouplingUMesh *m);
     MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld);
+    std::size_t getHeapMemorySize() const;
+    MEDFileUMeshSplitL1 *deepCpy() const;
     bool isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const;
     void clearNonDiscrAttributes() const;
     void synchronizeTinyInfo(const MEDFileMesh& master) const;
@@ -131,6 +150,7 @@ namespace ParaMEDMEM
     MEDCouplingUMesh *getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const;
     DataArrayInt *getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const;
     MEDCouplingUMesh *getWholeMesh(bool renum) const;
+    DataArrayInt *getOrCreateAndGetFamilyField() throw(INTERP_KERNEL::Exception);
     const DataArrayInt *getFamilyField() const;
     const DataArrayInt *getNumberField() const;
     const DataArrayInt *getRevNumberField() const;
@@ -143,6 +163,8 @@ namespace ParaMEDMEM
     void setRenumArr(DataArrayInt *renumArr);
     void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception);
     //
+    void renumberNodesInConn(const int *newNodeNumbersO2N) throw(INTERP_KERNEL::Exception);
+    //
     static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp);
     static std::vector<int> GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families);
     static void TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds,
index 75e1d0c139c8c6776fb45388a0d459ae31ed88df..bf2c9d1d0f994d7ebfbd0a1a7a9bce5ad6b71a0f 100644 (file)
@@ -1118,8 +1118,7 @@ ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS()
   medData->setMeshes( meshes );
   if ( fields ) medData->setFields( fields );
 
-  medData->incrRef();
-  return medData;
+  return medData.retn();
 }
 
 //================================================================================
index 720d34b657309ce845956276b8483f92fee5279d..5b17dcdf7d1c4f4af5e1dabbb31013c92bf08c18 100644 (file)
@@ -55,8 +55,7 @@ SauvReader* SauvReader::New(const char *fileName) throw(INTERP_KERNEL::Exception
   if ( parser->open() )
     {
       SauvReader* reader = new SauvReader;
-      reader->_fileReader = parser;
-      parser->incrRef();
+      reader->_fileReader = parser.retn();
       return reader;
     }
 
@@ -65,8 +64,7 @@ SauvReader* SauvReader::New(const char *fileName) throw(INTERP_KERNEL::Exception
   if ( parser->open() )
     {
       SauvReader* reader = new SauvReader;
-      reader->_fileReader = parser;
-      parser->incrRef();
+      reader->_fileReader = parser.retn();
       return reader;
     }
 
index eaf49c7a1493b8c9aee46e60a846988128a406d4..0b9b6989e5a501827772b1670fbf7cbd80e9e607 100644 (file)
@@ -51,6 +51,7 @@ class MEDLOADER_EXPORT SauvReader : public ParaMEDMEM::RefCountObject
   ~SauvReader();
 
  private:
+  std::size_t getHeapMemorySize() const { return 0; }
 
   void readRecord2();
   void readRecord4();
index 40c36422869dfc7c8f3e78a2013e94cc71dacb91..107552b8f6c3b42eb1a095827fc174fef445f93a 100644 (file)
@@ -109,7 +109,8 @@ namespace SauvUtilities
     virtual float  getFloat() const = 0;
     virtual double getDouble() const = 0;
     virtual std::string getName() const = 0;
-
+  protected:
+    std::size_t getHeapMemorySize() const { return 0; }
   protected:
     std::string _fileName, _curLocale;
     int _iRead, _nbToRead;
index 7ba8a6a76024ca8531dffcfb06d16f7638e71501..e27c54551a418804f0a8c97e4fad18634093c334 100644 (file)
@@ -51,7 +51,7 @@ namespace ParaMEDMEM
     void write(const char* fileName);
 
   private:
-
+    std::size_t getHeapMemorySize() const { return 0; }
     /*!
      * \brief Class representing a GIBI sub-mesh (described in the pile 1 of the SAUVE file).
      * It stands for a named med sub-mesh (family, etc) and contains either cell IDs or other sub-meshes. 
index f99f6635bc14242c1ad22dcb2a702ff4d5083ac8..84736406eca3009836b1f36018ad5f4b876a9ddb 100644 (file)
@@ -55,6 +55,8 @@ using namespace ParaMEDMEM;
 %newobject MEDLoader::ReadFieldGauss;
 %newobject MEDLoader::ReadFieldGaussNE;
 %newobject ParaMEDMEM::MEDFileMesh::New;
+%newobject ParaMEDMEM::MEDFileMesh::deepCpy;
+%newobject ParaMEDMEM::MEDFileMesh::shallowCpy;
 %newobject ParaMEDMEM::MEDFileMesh::getGenMeshAtLevel;
 %newobject ParaMEDMEM::MEDFileMesh::getGroupArr;
 %newobject ParaMEDMEM::MEDFileMesh::getGroupsArr;
@@ -76,21 +78,27 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileUMesh::getLevelM1Mesh;
 %newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh;
 %newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh;
+%newobject ParaMEDMEM::MEDFileUMesh::zipCoords;
 %newobject ParaMEDMEM::MEDFileCMesh::New;
+%newobject ParaMEDMEM::MEDFileCurveLinearMesh::New;
 %newobject ParaMEDMEM::MEDFileMeshMultiTS::New;
+%newobject ParaMEDMEM::MEDFileMeshMultiTS::deepCpy;
 %newobject ParaMEDMEM::MEDFileMeshMultiTS::getOneTimeStep;
 %newobject ParaMEDMEM::MEDFileMeshes::New;
+%newobject ParaMEDMEM::MEDFileMeshes::deepCpy;
 %newobject ParaMEDMEM::MEDFileMeshes::getMeshAtPos;
 %newobject ParaMEDMEM::MEDFileMeshes::getMeshWithName;
 %newobject ParaMEDMEM::MEDFileMeshes::__getitem__;
 %newobject ParaMEDMEM::MEDFileMeshes::__iter__;
 
 %newobject ParaMEDMEM::MEDFileFields::New;
+%newobject ParaMEDMEM::MEDFileFields::deepCpy;
 %newobject ParaMEDMEM::MEDFileFields::getFieldWithName;
 %newobject ParaMEDMEM::MEDFileFields::getFieldAtPos;
 %newobject ParaMEDMEM::MEDFileFields::__getitem__;
 %newobject ParaMEDMEM::MEDFileFields::__iter__;
 %newobject ParaMEDMEM::MEDFileFieldMultiTS::New;
+%newobject ParaMEDMEM::MEDFileFieldMultiTS::deepCpy;
 %newobject ParaMEDMEM::MEDFileFieldMultiTS::getTimeStepAtPos;
 %newobject ParaMEDMEM::MEDFileFieldMultiTS::getTimeStep;
 %newobject ParaMEDMEM::MEDFileFieldMultiTS::getTimeStepGivenTime;
@@ -102,6 +110,7 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevelOld;
 %newobject ParaMEDMEM::MEDFileFieldMultiTS::getUndergroundDataArray;
 %newobject ParaMEDMEM::MEDFileField1TS::New;
+%newobject ParaMEDMEM::MEDFileField1TS::deepCpy;
 %newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevel;
 %newobject ParaMEDMEM::MEDFileField1TS::getFieldAtTopLevel;
 %newobject ParaMEDMEM::MEDFileField1TS::getFieldOnMeshAtLevel;
@@ -109,6 +118,7 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileField1TS::getUndergroundDataArray;
 
 %newobject ParaMEDMEM::MEDFileData::New;
+%newobject ParaMEDMEM::MEDFileData::deepCpy;
 %newobject ParaMEDMEM::MEDFileData::getMeshes;
 %newobject ParaMEDMEM::MEDFileData::getFields;
 
@@ -329,6 +339,8 @@ namespace ParaMEDMEM
   public:
     static MEDFileMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1);
+    virtual MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception);
+    virtual MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception);
     virtual void clearNonDiscrAttributes() const;
     void setName(const char *name);
     const char *getName();
@@ -378,11 +390,16 @@ namespace ParaMEDMEM
     void changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception);
     void changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception);
     void changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception);
+    void changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception);
     void setFamilyInfo(const std::map<std::string,int>& info);
     void setGroupInfo(const std::map<std::string, std::vector<std::string> >&info);
     int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception);
     int getMaxFamilyId() const throw(INTERP_KERNEL::Exception);
     int getMinFamilyId() const throw(INTERP_KERNEL::Exception);
+    int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception);
+    int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception);
+    virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception);
+    virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception);
     std::vector<int> getFamiliesIds(const std::vector<std::string>& famNames) const throw(INTERP_KERNEL::Exception);
     std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception);
@@ -569,13 +586,15 @@ namespace ParaMEDMEM
     void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception);
     void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception);
     void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception);
-    void addNodeGroup(const std::string& name, const std::vector<int>& ids) throw(INTERP_KERNEL::Exception);
+    void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception);
+    void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception);
     void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception);
     void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception);
     void setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception);
     void setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms) throw(INTERP_KERNEL::Exception);
     void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception);
     void optimizeFamilies() throw(INTERP_KERNEL::Exception);
+    DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception);
     %extend
        { 
          MEDFileUMesh(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception)
@@ -629,7 +648,11 @@ namespace ParaMEDMEM
        }
   };
 
-  class MEDFileCMesh : public MEDFileMesh
+  class MEDFileStructuredMesh : public MEDFileMesh
+  {
+  };
+
+  class MEDFileCMesh : public MEDFileStructuredMesh
   {
   public:
     static MEDFileCMesh *New();
@@ -663,12 +686,47 @@ namespace ParaMEDMEM
        }
   };
 
+  class MEDFileCurveLinearMesh : public MEDFileStructuredMesh
+  {
+  public:
+    static MEDFileCurveLinearMesh *New();
+    static MEDFileCurveLinearMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception);
+    static MEDFileCurveLinearMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception);
+    void setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception);
+    %extend
+       {
+         MEDFileCurveLinearMesh()
+         {
+           return MEDFileCurveLinearMesh::New();
+         }
+
+         MEDFileCurveLinearMesh(const char *fileName) throw(INTERP_KERNEL::Exception)
+         {
+           return MEDFileCurveLinearMesh::New(fileName);
+         }
+
+         MEDFileCurveLinearMesh(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception)
+         {
+           return MEDFileCurveLinearMesh::New(fileName,mName,dt,it);
+         }
+         
+         PyObject *getMesh() const throw(INTERP_KERNEL::Exception)
+         {
+           const MEDCouplingCurveLinearMesh *tmp=self->getMesh();
+           if(tmp)
+             tmp->incrRef();
+           return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh, SWIG_POINTER_OWN | 0 );
+         }
+       }
+  };
+
   class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable
   {
   public:
     static MEDFileMeshMultiTS *New();
     static MEDFileMeshMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileMeshMultiTS *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception);
+    MEDFileMeshMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception);
     const char *getName() const throw(INTERP_KERNEL::Exception);
     void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception);
     void setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception);
@@ -726,6 +784,7 @@ namespace ParaMEDMEM
   public:
     static MEDFileMeshes *New();
     static MEDFileMeshes *New(const char *fileName) throw(INTERP_KERNEL::Exception);
+    MEDFileMeshes *deepCpy() const throw(INTERP_KERNEL::Exception);
     void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception);
     int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception);
     std::vector<std::string> getMeshesNames() const throw(INTERP_KERNEL::Exception);
@@ -823,6 +882,7 @@ namespace ParaMEDMEM
   {
   public:
     void shallowCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception);
+    void deepCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception);
     std::vector<std::string> getPfls() const throw(INTERP_KERNEL::Exception);
     std::vector<std::string> getLocs() const throw(INTERP_KERNEL::Exception);
     bool existsPfl(const char *pflName) const throw(INTERP_KERNEL::Exception);
@@ -940,6 +1000,7 @@ namespace ParaMEDMEM
     void setProfileNameOnLeaf(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const char *newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception);
     void setLocNameOnLeaf(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const char *newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception);
     void copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception);
+    MEDFileField1TS *deepCpy() const throw(INTERP_KERNEL::Exception);
     //
     int getDimension() const throw(INTERP_KERNEL::Exception);
     int getIteration() const throw(INTERP_KERNEL::Exception);
@@ -1165,6 +1226,7 @@ namespace ParaMEDMEM
     static MEDFileFieldMultiTS *New() throw(INTERP_KERNEL::Exception);
     static MEDFileFieldMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileFieldMultiTS *New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception);
+    MEDFileFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception);
     //
     MEDFileField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception);
     MEDFileField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception);
@@ -1207,9 +1269,14 @@ namespace ParaMEDMEM
          }
          
          std::string __str__() const throw(INTERP_KERNEL::Exception)
-           {
-             return self->simpleRepr();
-           }
+         {
+           return self->simpleRepr();
+         }
+
+         int __len__() const throw(INTERP_KERNEL::Exception)
+         {
+           return self->getNumberOfTS();
+         }
 
          MEDFileField1TS *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception)
          {
@@ -1545,6 +1612,7 @@ namespace ParaMEDMEM
   public:
     static MEDFileFields *New() throw(INTERP_KERNEL::Exception);
     static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception);
+    MEDFileFields *deepCpy() const throw(INTERP_KERNEL::Exception);
     void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception);
     int getNumberOfFields() const;
     std::vector<std::string> getFieldsNames() const throw(INTERP_KERNEL::Exception);
@@ -1611,6 +1679,7 @@ namespace ParaMEDMEM
   public:
     static MEDFileData *New(const char *fileName) throw(INTERP_KERNEL::Exception);
     static MEDFileData *New();
+    MEDFileData *deepCpy() const throw(INTERP_KERNEL::Exception);
     void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception);
     void setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception);
     int getNumberOfFields() const throw(INTERP_KERNEL::Exception);
index 194def721043b040abc04a537a772aa5bd24945a..3f66653fdcaa24a09d82dfc436b48dd8ee5035ff 100644 (file)
@@ -164,7 +164,9 @@ class MEDLoaderTest(unittest.TestCase):
         t=mm.getGroupArr(0,"GrpOnAllCell")
         self.assertTrue(t.getValues()==range(5))
         #
-        mm.write(outFileName,2);
+        mmCpy=mm.deepCpy()
+        self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) ; del mm
+        mmCpy.write(outFileName,2);
         #
         mm=MEDFileMesh.New(outFileName)
         mbis=mm.getMeshAtLevel(0)
@@ -384,6 +386,7 @@ class MEDLoaderTest(unittest.TestCase):
         mm.write("Pyfile17_bis.med",2)
         ff=MEDFileFieldMultiTS("Pyfile17.med")
         tsExpected=[[1,2],[3,4],[5,6]]
+        self.assertEqual(3,len(ff))
         for pos,f1ts in enumerate(ff):
             self.assertEqual(tsExpected[pos],f1ts.getTime()[:2])
             self.assertEqual(type(f1ts),MEDFileField1TS)
@@ -642,6 +645,7 @@ class MEDLoaderTest(unittest.TestCase):
         #
         ff1.setFieldProfile(f1,mm1,0,da)
         ff1.changePflsNames([(["sup1_NORM_QUAD4"],"ForV650")])
+        ff1=ff1.deepCpy()
         ff1.write(fname,0)
         #
         vals,pfl=ff1.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("")
@@ -649,6 +653,8 @@ class MEDLoaderTest(unittest.TestCase):
         self.assertTrue(vals.isEqual(d,1e-14))
         #
         ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1)
+        ff3=MEDFileField1TS.New(fname,f1.getName(),-1,-1)
+        ff2.deepCpyGlobs(ff3)
         sbt=ff2.getFieldSplitedByType2()
         self.assertEqual(3,sbt[0][0])#TRI3
         self.assertEqual(0,sbt[0][1][0][0])#CELL For TRI3
@@ -679,6 +685,7 @@ class MEDLoaderTest(unittest.TestCase):
         ff1.appendFieldProfile(f1,mm1,0,da)
         f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ;
         ff1.appendFieldProfile(f1,mm1,0,da)
+        ff1=ff1.deepCpy()
         ff1.write(fname,0)
         #
         vals,pfl=ff1.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("")
@@ -912,6 +919,7 @@ class MEDLoaderTest(unittest.TestCase):
         ff1.appendFieldProfile(f1,mm1,0,da)
         ffs.resize(1)
         ffs.setFieldAtPos(0,ff1)
+        ffs=ffs.deepCpy()
         ffs.write(fname,0)
         #
         ffsr=MEDFileFields.New(fname)
@@ -1582,6 +1590,420 @@ class MEDLoaderTest(unittest.TestCase):
         f3_ter.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19])
         self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12))
         pass
+
+    # Testing profile on nodes when the profile is identity but not on all nodes.
+    def testMEDFieldPflOnNode1(self):
+        fname="Pyfile51.med"
+        coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2)
+        m0=MEDCouplingUMesh("Mesh",2)
+        m0.allocateCells(5)
+        m0.insertNextCell(NORM_TRI3,[1,4,2])
+        m0.insertNextCell(NORM_TRI3,[4,5,2])
+        m0.insertNextCell(NORM_QUAD4,[0,3,4,1])
+        m0.insertNextCell(NORM_QUAD4,[3,6,7,4])
+        m0.insertNextCell(NORM_QUAD4,[4,7,8,5])
+        m0.finishInsertingCells()
+        m0.setCoords(coo)
+        m1=MEDCouplingUMesh(m0.getName(),1)
+        m1.allocateCells(9)
+        conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8]
+        for i in xrange(9):
+            m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2])
+            pass
+        m1.finishInsertingCells()
+        m1.setCoords(coo)
+        #
+        m=MEDFileUMesh()
+        m.setMeshAtLevel(0,m0)
+        m.setMeshAtLevel(-1,m1)
+        #
+        dt=3 ; it=2 ; tim=4.5
+        fieldNode0=MEDCouplingFieldDouble(ON_NODES,ONE_TIME)
+        fieldNode0.setName("fieldNode0")
+        fieldNode0.setTime(tim,dt,it)
+        pfl0=DataArrayInt([0,1,2,3,4]) ; pfl0.setName("PflIdentity0") # important to keep like that
+        arr=DataArrayDouble([10,11,12,13,14])
+        fieldNode0.setArray(arr)
+        f0=MEDFileField1TS()
+        f0.setFieldProfile(fieldNode0,m,0,pfl0)
+        m.write(fname,2) ; f0.write(fname,0)
+        fieldNode1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME)
+        fieldNode1.setName("fieldNode1")
+        fieldNode1.setTime(tim,dt,it)
+        pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1")
+        arr1=DataArrayDouble([20,21,22,23,24,25,26])
+        fieldNode1.setArray(arr1)
+        f1=MEDFileField1TS()
+        f1.setFieldProfile(fieldNode1,m,-1,pfl1)
+        f1.write(fname,0)
+        del m,f0,m0,m1,f1
+        ## Reading from file
+        m=MEDFileMesh.New(fname)
+        m0=m.getMeshAtLevel(0)
+        m00=m0.deepCpy() ; m00=m00[[0,2]] ; m00.setName(m.getName()) ; m00.zipCoords()
+        fieldNode0.setMesh(m00)
+        f0=MEDFileField1TS.New(fname,fieldNode0.getName(),dt,it)
+        ff0_1=f0.getFieldOnMeshAtLevel(ON_NODES,m0)
+        ff0_1.checkCoherency()
+        self.assertTrue(ff0_1.isEqual(fieldNode0,1e-12,1e-12))
+        ff0_2=f0.getFieldAtLevel(ON_NODES,0)
+        ff0_2.checkCoherency()
+        self.assertTrue(ff0_2.isEqual(fieldNode0,1e-12,1e-12))
+        ff0_3=f0.getFieldOnMeshAtLevel(ON_NODES,0,m)
+        ff0_3.checkCoherency()
+        self.assertTrue(ff0_3.isEqual(fieldNode0,1e-12,1e-12))
+        ff0_4=MEDLoader.ReadFieldNode(fname,m.getName(),0,fieldNode0.getName(),dt,it)
+        ff0_4.checkCoherency()
+        self.assertTrue(ff0_4.isEqual(fieldNode0,1e-12,1e-12))
+        f1=MEDFileField1TS.New(fname,fieldNode1.getName(),dt,it)
+        m1=m.getMeshAtLevel(-1)
+        m10=m1.deepCpy() ; m10=m10[[0,1,2,3,4,5,6,7]] ; m10.setName(m.getName()) ; m10.zipCoords()
+        fieldNode1.setMesh(m10)
+        ff1_1=f1.getFieldOnMeshAtLevel(ON_NODES,m1)
+        ff1_1.checkCoherency()
+        self.assertTrue(ff1_1.isEqual(fieldNode1,1e-12,1e-12))
+        ff1_2=f1.getFieldAtLevel(ON_NODES,-1)
+        ff1_2.checkCoherency()
+        self.assertTrue(ff1_2.isEqual(fieldNode1,1e-12,1e-12))
+        ff1_3=f1.getFieldOnMeshAtLevel(ON_NODES,-1,m)
+        ff1_3.checkCoherency()
+        self.assertTrue(ff1_3.isEqual(fieldNode1,1e-12,1e-12))
+        ff1_4=MEDLoader.ReadFieldNode(fname,m.getName(),-1,fieldNode1.getName(),dt,it)
+        ff1_4.checkCoherency()
+        self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12))
+        self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,m0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6]
+        self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_NODES,0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6]
+        self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,0,m) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6]
+        arr_r,pfl1_r=f1.getFieldWithProfile(ON_NODES,-1,m)
+        arr_r.setName(fieldNode1.getArray().getName())
+        self.assertTrue(arr_r.isEqual(fieldNode1.getArray(),1e-12))
+        pfl1_r.setName(pfl1.getName())
+        self.assertTrue(pfl1_r.isEqual(pfl1))
+        pass
+    
+        # Testing profile on nodes when the profile is identity but not on all nodes.
+    def testMEDFieldPflOnCell1(self):
+        fname="Pyfile52.med"
+        coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2)
+        m0=MEDCouplingUMesh("Mesh",2)
+        m0.allocateCells(5)
+        m0.insertNextCell(NORM_TRI3,[1,4,2])
+        m0.insertNextCell(NORM_TRI3,[4,5,2])
+        m0.insertNextCell(NORM_QUAD4,[0,3,4,1])
+        m0.insertNextCell(NORM_QUAD4,[3,6,7,4])
+        m0.insertNextCell(NORM_QUAD4,[4,7,8,5])
+        m0.finishInsertingCells()
+        m0.setCoords(coo)
+        m1=MEDCouplingUMesh(m0.getName(),1)
+        m1.allocateCells(9)
+        conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8]
+        for i in xrange(9):
+            m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2])
+            pass
+        m1.finishInsertingCells()
+        m1.setCoords(coo)
+        #
+        m=MEDFileUMesh()
+        m.setMeshAtLevel(0,m0)
+        m.setMeshAtLevel(-1,m1)
+        #
+        dt=3 ; it=2 ; tim=4.5
+        fieldCell0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME)
+        fieldCell0.setName("fieldCell0")
+        fieldCell0.setTime(tim,dt,it)
+        pfl0=DataArrayInt([0,1,2]) ; pfl0.setName("PflIdentity0") # important to keep like that
+        arr=DataArrayDouble([10,11,12])
+        fieldCell0.setArray(arr)
+        f0=MEDFileField1TS()
+        f0.setFieldProfile(fieldCell0,m,0,pfl0)
+        m.write(fname,2) ; f0.write(fname,0)
+        fieldCell1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME)
+        fieldCell1.setName("fieldCell1")
+        fieldCell1.setTime(tim,dt,it)
+        pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1")
+        arr1=DataArrayDouble([20,21,22,23,24,25,26])
+        fieldCell1.setArray(arr1)
+        f1=MEDFileField1TS()
+        f1.setFieldProfile(fieldCell1,m,-1,pfl1)
+        f1.write(fname,0)
+        del m,f0,m0,m1,f1
+        ## Reading from file
+        m=MEDFileMesh.New(fname)
+        m0=m.getMeshAtLevel(0)
+        m00=m0.deepCpy() ; m00=m00[pfl0] ; m00.setName(m.getName())
+        fieldCell0.setMesh(m00)
+        f0=MEDFileField1TS.New(fname,fieldCell0.getName(),dt,it)
+        ff0_1=f0.getFieldOnMeshAtLevel(ON_CELLS,m0)
+        ff0_1.checkCoherency()
+        self.assertTrue(ff0_1.isEqual(fieldCell0,1e-12,1e-12))
+        ff0_2=f0.getFieldAtLevel(ON_CELLS,0)
+        ff0_2.checkCoherency()
+        self.assertTrue(ff0_2.isEqual(fieldCell0,1e-12,1e-12))
+        ff0_3=f0.getFieldOnMeshAtLevel(ON_CELLS,0,m)
+        ff0_3.checkCoherency()
+        self.assertTrue(ff0_3.isEqual(fieldCell0,1e-12,1e-12))
+        ff0_4=MEDLoader.ReadFieldCell(fname,m.getName(),0,fieldCell0.getName(),dt,it)
+        ff0_4.checkCoherency()
+        self.assertTrue(ff0_4.isEqual(fieldCell0,1e-12,1e-12))
+        f1=MEDFileField1TS.New(fname,fieldCell1.getName(),dt,it)
+        m1=m.getMeshAtLevel(-1)
+        m10=m1.deepCpy() ; m10=m10[pfl1] ; m10.setName(m.getName())
+        fieldCell1.setMesh(m10)
+        ff1_1=f1.getFieldOnMeshAtLevel(ON_CELLS,m1)
+        ff1_1.checkCoherency()
+        self.assertTrue(ff1_1.isEqual(fieldCell1,1e-12,1e-12))
+        ff1_2=f1.getFieldAtLevel(ON_CELLS,-1)
+        ff1_2.checkCoherency()
+        self.assertTrue(ff1_2.isEqual(fieldCell1,1e-12,1e-12))
+        ff1_3=f1.getFieldOnMeshAtLevel(ON_CELLS,-1,m)
+        ff1_3.checkCoherency()
+        self.assertTrue(ff1_3.isEqual(fieldCell1,1e-12,1e-12))
+        ff1_4=MEDLoader.ReadFieldCell(fname,m.getName(),-1,fieldCell1.getName(),dt,it)
+        ff1_4.checkCoherency()
+        self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12))
+        self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,m0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6]
+        self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_CELLS,0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6]
+        self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,0,m) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6]
+        arr_r,pfl1_r=f1.getFieldWithProfile(ON_CELLS,-1,m)
+        arr_r.setName(fieldCell1.getArray().getName())
+        self.assertTrue(arr_r.isEqual(fieldCell1.getArray(),1e-12))
+        pfl1_r.setName(pfl1.getName())
+        self.assertTrue(pfl1_r.isEqual(pfl1))
+        pass
+
+    def testMEDFileUMeshZipCoords1(self):
+        m=MEDFileUMesh()
+        coo=DataArrayDouble(30) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"])
+        m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2])
+        m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3])
+        m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8])
+        m0.setCoords(coo) ; m.setMeshAtLevel(0,m0)
+        m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1)
+        m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2)
+        numCoo=DataArrayInt(10) ; numCoo.iota(3) ; m.setRenumFieldArr(1,numCoo)
+        famCoo=DataArrayInt(10) ; famCoo.iota(4) ; m.setFamilyFieldArr(1,famCoo)
+        da=DataArrayInt([20,30,40]) ; m.setRenumFieldArr(0,da) ; da=DataArrayInt([200,300,400]) ; m.setFamilyFieldArr(0,da)
+        da=DataArrayInt([50,60]) ; m.setRenumFieldArr(-1,da) ; da=DataArrayInt([500,600]) ; m.setFamilyFieldArr(-1,da)
+        da=DataArrayInt([70,80,90]) ; m.setRenumFieldArr(-2,da) ; da=DataArrayInt([700,800,900]) ; m.setFamilyFieldArr(-2,da)
+        o2n=m.zipCoords()
+        self.assertTrue(o2n.isEqual(DataArrayInt([-1,0,1,2,3,-1,4,5,6,-1])))
+        self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt([4,5,6,7,9,10,11])))
+        self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([5,6,7,8,10,11,12])))
+        self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,4,1,3,2,3,5,0,4,4,4,1])))
+        self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,9,15])))
+        self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivity().isEqual(DataArrayInt([1,0,4,1,5,2])))
+        self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6])))
+        self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivity().isEqual(DataArrayInt([0,1,0,4,0,6])))
+        self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivityIndex().isEqual(DataArrayInt([0,2,4,6])))
+        pass
+
+    def testMEDUMeshAddNodeGroup1(self):
+        fname="Pyfile53.med"
+        m=MEDFileUMesh()
+        coo=DataArrayDouble(39) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"])
+        m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2])
+        m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3])
+        m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8])
+        m0.setCoords(coo) ; m.setMeshAtLevel(0,m0)
+        m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1)
+        m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2)
+        #
+        mm=m.deepCpy()
+        famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(1,famCoo)
+        da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(0,da0)
+        da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1)
+        da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2)
+        mm.setFamilyId("MyFam",2)
+        mm.setFamilyId("MyOtherFam",3)
+        mm.setFamilyId("MyOther-1",-1)
+        mm.setFamiliesOnGroup("grp0",["MyOtherFam"])
+        mm.setFamiliesOnGroup("grpA",["MyOther-1"])
+        #
+        daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1")
+        mm.addNodeGroup(daTest)
+        self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest))
+        self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8])))
+        for lev,arr in [(0,da0),(-1,da1),(-2,da2)]:
+            self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr))
+            pass
+        self.assertEqual(mm.getFamiliesNames(),('Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam'))
+        self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA'))
+        self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam')
+        self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam')
+        for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]:
+            self.assertEqual(mm.getFamilyNameGivenId(famId),famName)
+            pass
+        self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_8'))
+        da=DataArrayInt([3,12]) ; da.setName("grp0")
+        self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da))
+        da.setValues([1])
+        self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da))
+        mm.write(fname,2)
+        mm=MEDFileMesh.New(fname)
+        self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest))
+        self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8])))
+        for lev,arr in [(0,da0),(-1,da1),(-2,da2)]:
+            self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr))
+            pass
+        self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam'))
+        self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA'))
+        self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam')
+        self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam')
+        for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]:
+            self.assertEqual(mm.getFamilyNameGivenId(famId),famName)
+            pass
+        self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_8','MyOtherFam'))
+        da=DataArrayInt([3,12]) ; da.setName("grp0")
+        self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da))
+        da.setValues([1])
+        self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da))
+        pass
+
+    def testMEDUMeshAddGroup1(self):
+        fname="Pyfile54.med"
+        m=MEDFileUMesh()
+        coo=DataArrayDouble(9) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"])
+        m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0)
+        for i in xrange(7):
+            m0.insertNextCell(NORM_TRI3,[1,2,1])
+            pass
+        for i in xrange(4):
+            m0.insertNextCell(NORM_QUAD4,[1,1,2,0])
+            pass
+        for i in xrange(2):
+            m0.insertNextCell(NORM_POLYGON,[0,0,1,1,2,2])
+            pass
+        m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3])
+        m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8])
+        m0.setCoords(coo) ; m.setMeshAtLevel(0,m0)
+        m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1)
+        m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2)
+        #
+        mm=m.deepCpy()
+        famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(0,famCoo)
+        da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(1,da0)
+        da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1)
+        da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2)
+        mm.setFamilyId("MyFam",2)
+        mm.setFamilyId("MyOtherFam",3)
+        mm.setFamilyId("MyOther-1",-1)
+        mm.setFamiliesOnGroup("grp0",["MyOtherFam"])
+        mm.setFamiliesOnGroup("grpA",["MyOther-1"])
+        #
+        daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1")
+        mm.addGroup(0,daTest)
+        self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest))
+        self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8])))
+        for lev,arr in [(1,da0),(-1,da1),(-2,da2)]:
+            self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr))
+            pass
+        self.assertEqual(mm.getFamiliesNames(),('Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam'))
+        self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA'))
+        self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam')
+        self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam')
+        for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]:
+            self.assertEqual(mm.getFamilyNameGivenId(famId),famName)
+            pass
+        self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_8'))
+        da=DataArrayInt([3,12]) ; da.setName("grp0")
+        self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da))
+        da.setValues([1])
+        self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da))
+        mm.write(fname,2)
+        mm=MEDFileMesh.New(fname)
+        self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest))
+        self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8])))
+        for lev,arr in [(1,da0),(-1,da1),(-2,da2)]:
+            self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr))
+            pass
+        self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam'))
+        self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA'))
+        self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam')
+        self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam')
+        for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]:
+            self.assertEqual(mm.getFamilyNameGivenId(famId),famName)
+            pass
+        self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_8','MyOtherFam'))
+        da=DataArrayInt([3,12]) ; da.setName("grp0")
+        self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da))
+        da.setValues([1])
+        self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da))
+        pass
+
+    def testHeapMem1(self):
+        import platform
+        ver=platform.python_version_tuple()
+        if int(ver[0])!=2 or int(ver[1])<7:
+            return
+        m=MEDCouplingCMesh()
+        arr=DataArrayDouble(10,1) ; arr.iota(0)
+        m.setCoords(arr,arr)
+        m=m.buildUnstructured()
+        m.setName("mm")
+        f=m.getMeasureField(ON_CELLS)
+        self.assertIn(m.getHeapMemorySize(),xrange(3552-100,3552+100))
+        self.assertIn(f.getHeapMemorySize(),xrange(4215-100,4215+100))
+        #
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m)
+        self.assertIn(mm.getHeapMemorySize(),xrange(3889-100,3889+100))
+        ff=MEDFileField1TS()
+        ff.setFieldNoProfileSBT(f)
+        self.assertIn(ff.getHeapMemorySize(),xrange(711-10,711+10))
+        #
+        fff=MEDFileFieldMultiTS()
+        fff.appendFieldNoProfileSBT(f)
+        self.assertIn(fff.getHeapMemorySize(),xrange(743-10,743+10))
+        self.assertIn(fff[-1,-1].getHeapMemorySize(),xrange(711-10,711+10))
+        f.setTime(1.,0,-1)
+        fff.appendFieldNoProfileSBT(f)
+        self.assertIn(fff.getHeapMemorySize(),xrange(1462-10,1462+10))
+        self.assertIn(fff[0,-1].getHeapMemorySize(),xrange(711-10,711+10))
+        f2=f[:50]
+        f2.setTime(2.,1,-1)
+        pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl")
+        fff.appendFieldProfile(f2,mm,0,pfl)
+        self.assertIn(fff.getHeapMemorySize(),xrange(2178-100,2178+100))
+        self.assertIn(fff.getProfile("pfl_NORM_QUAD4").getHeapMemorySize(),xrange(215-10,215+10))
+        self.assertIn(fff[1,-1].getHeapMemorySize(),xrange(700-10,700+10))
+        pass
+
+    def testCurveLinearMesh1(self):
+        fname="Pyfile55.med"
+        mesh=MEDCouplingCurveLinearMesh();
+        mesh.setTime(2.3,4,5);
+        mesh.setTimeUnit("us");
+        mesh.setName("Example of Cuve linear mesh");
+        mesh.setDescription("buildCLMesh");
+        a1=DataArrayDouble(3*20,1);
+        a1.iota(7.) ; a1.rearrange(3);
+        mesh.setCoords(a1);
+        mesh.setNodeGridStructure([4,5]);
+        mesh.checkCoherency();
+        #
+        m=MEDFileCurveLinearMesh()
+        m.setMesh(mesh)
+        d=DataArrayInt(20) ; d.iota(4)
+        m.setFamilyFieldArr(1,d)
+        d3=DataArrayInt(20) ; d3.iota(400)
+        m.setRenumFieldArr(1,d3)
+        d2=DataArrayInt(12) ; d2.iota(40)
+        m.setFamilyFieldArr(0,d2)
+        d4=DataArrayInt(21) ; d4.iota(4000)
+        self.assertRaises(InterpKernelException,m.setRenumFieldArr,1,d4)
+        d4.popBackSilent()
+        m.setRenumFieldArr(1,d4)
+        m.write(fname,2)
+        #
+        m1=MEDFileCurveLinearMesh(fname)
+        mm=m1.getMesh()
+        self.assertTrue(mm.isEqual(mesh,1e-12))
+        #
+        m1=MEDFileMesh.New(fname)
+        self.assertTrue(isinstance(m1,MEDFileCurveLinearMesh))
+        self.assertTrue(m1.getMesh().isEqual(mesh,1e-12))
+        pass
+
     pass
 
 unittest.main()
index 111fd0e2b159d1b04e9ef892514cf175454c4711..cbab3a4d0e60c9bf7466be846d5b7c214fdc5818 100644 (file)
@@ -27,6 +27,8 @@ static PyObject* convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) th
     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileUMesh,owner);
   if(dynamic_cast<ParaMEDMEM::MEDFileCMesh *>(mesh))
     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCMesh,owner);
+  if(dynamic_cast<ParaMEDMEM::MEDFileCurveLinearMesh *>(mesh))
+    ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCurveLinearMesh,owner);
   if(!ret)
     throw INTERP_KERNEL::Exception("Not recognized type of MEDFileMesh on downcast !");
   return ret;
index 726e797800b7b95634acc39b97f1de4d1effd3a0..69c64e11a47149c3be4c57ff453e08f1bdcb77b5 100644 (file)
@@ -69,6 +69,7 @@ SET(medpartitionercpp_SOURCES
   MEDPARTITIONER_ParaDomainSelector.cxx
   MEDPARTITIONER_ConnectZone.cxx
   MEDPARTITIONER_SkyLineArray.cxx
+  MEDPARTITIONER_metis.c
   )
 
 SET(medpartitionercpp_DEFINITIONS "${HDF5_DEFINITIONS} ${MED3_DEFINITIONS} ${LIBXML_DEFINITIONS} ${MPI_DEFINITIONS}")
@@ -83,25 +84,24 @@ SET(medpartitionercpp_LDFLAGS
   medloader
 )
 IF(MED_ENABLE_PARMETIS)
-  SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx)
+  SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ParMetisGraph.hxx)
   SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ParMetisGraph.cxx)
   SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${PARMETIS_DEFINITIONS}")
   SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${PARMETIS_LIBS})
-ELSE(MED_ENABLE_PARMETIS)  
-  IF(MED_ENABLE_METIS)
-    SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx)  
-    SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_MetisGraph.cxx)
-    SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${METIS_DEFINITIONS}")
-    SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${METIS_LIBS})
-  ENDIF(MED_ENABLE_METIS)
-  IF(MED_ENABLE_SCOTCH)
-    SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ScotchGraph.hxx)
-    SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ScotchGraph.cxx)
-    SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${SCOTCH_DEFINITIONS}")
-    SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${SCOTCH_LIBS})
-  ENDIF(MED_ENABLE_SCOTCH)    
-ENDIF(MED_ENABLE_PARMETIS)  
-  
+ENDIF(MED_ENABLE_PARMETIS)
+IF(MED_ENABLE_METIS)
+  SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx)
+  SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_MetisGraph.cxx)
+  SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${METIS_DEFINITIONS}")
+  SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${METIS_LIBS})
+ENDIF(MED_ENABLE_METIS)
+IF(MED_ENABLE_SCOTCH)
+  SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ScotchGraph.hxx)
+  SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ScotchGraph.cxx)
+  SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${SCOTCH_DEFINITIONS}")
+  SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${SCOTCH_LIBS})
+ENDIF(MED_ENABLE_SCOTCH)
+
 IF(MPI_IS_OK)
   SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES}
     MEDPARTITIONER_UtilsPara.cxx
@@ -119,11 +119,11 @@ IF(MED_ENABLE_PARMETIS)
   SET_TARGET_PROPERTIES(medpartitioner_para PROPERTIES COMPILE_FLAGS "${medpartitionercpp_DEFINITIONS}")
   TARGET_LINK_LIBRARIES(medpartitioner_para medpartitionercpp ${medpartitionercpp_LDFLAGS})
   INSTALL(TARGETS medpartitioner_para DESTINATION ${MED_salomebin_BINS})
-ELSE(MED_ENABLE_PARMETIS)
-  ADD_EXECUTABLE(medpartitioner medpartitioner.cxx)
-  SET_TARGET_PROPERTIES(medpartitioner PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS} ${medpartitionercpp_DEFINITIONS}")
-  TARGET_LINK_LIBRARIES(medpartitioner medpartitionercpp ${medpartitionercpp_LDFLAGS})
-  INSTALL(TARGETS medpartitioner DESTINATION ${MED_salomebin_BINS})
 ENDIF(MED_ENABLE_PARMETIS)
 
+ADD_EXECUTABLE(medpartitioner medpartitioner.cxx)
+SET_TARGET_PROPERTIES(medpartitioner PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS} ${medpartitionercpp_DEFINITIONS}")
+TARGET_LINK_LIBRARIES(medpartitioner medpartitionercpp ${medpartitionercpp_LDFLAGS})
+INSTALL(TARGETS medpartitioner DESTINATION ${MED_salomebin_BINS})
+
 INSTALL(FILES ${medpartitionercpp_HEADERS_HXX} DESTINATION ${MED_salomeinclude_HEADERS})
index 87dbc36beb496bdcc63dc62b2b8bf06732c26ea7..bc31670da79c5289587ae0fa7f1b5f4d16e5f454 100644 (file)
@@ -48,13 +48,13 @@ void MEDPARTITIONER::JointFinder::findCommonDistantNodes()
       _node_node[i].resize(nbdomain);
     }
   int nbproc=_domain_selector->nbProcs();
-  std::vector<BBTree<3>* > bbtree(nbdomain,(BBTree<3>*) 0);
+  std::vector<BBTreeOfDim* > bbtree(nbdomain,(BBTreeOfDim*) 0);
   std::vector<double* > bbxi(nbdomain,(double*) 0);
   std::vector<ParaMEDMEM::DataArrayInt*> rev(nbdomain,(ParaMEDMEM::DataArrayInt*) 0);
   std::vector<ParaMEDMEM::DataArrayInt*> revIndx(nbdomain,(ParaMEDMEM::DataArrayInt*) 0);
   int meshDim=-1;
   int spaceDim=-1;
-  
+
   //init rev and revIndx and bbtree for my domain (of me:proc n)
   for (int mydomain=0; mydomain<nbdomain; mydomain++)
     {
@@ -73,12 +73,12 @@ void MEDPARTITIONER::JointFinder::findCommonDistantNodes()
           bbx[2*i]=(coords[i])-1e-12;
           bbx[2*i+1]=bbx[2*i]+2e-12;
         }
-      bbtree[mydomain]=new BBTree<3> (bbx,0,0,myMesh->getNumberOfNodes(),-1e-12);
+      bbtree[mydomain]=new BBTreeOfDim( spaceDim, bbx,0,0,myMesh->getNumberOfNodes(),-1e-12);
       //keep bbx because need it in getIntersectingElems
       //no delete [] bbx yet
       bbxi[mydomain]=bbx;
     }
-  
+
   //send my domains to other proc an receive other domains from other proc
   for (int isource=0; isource<nbdomain; isource++)
     {
@@ -91,11 +91,11 @@ void MEDPARTITIONER::JointFinder::findCommonDistantNodes()
             {
               //preparing data for treatment on target proc
               int targetProc = _domain_selector->getProcessorID(itarget);
-    
+
               std::vector<double> vec(spaceDim*sourceMesh->getNumberOfNodes());
               std::copy(sourceMesh->getCoords()->getConstPointer(),sourceMesh->getCoords()->getConstPointer()+sourceMesh->getNumberOfNodes()*spaceDim,&vec[0]);
               SendDoubleVec(vec,targetProc);
-    
+
               //retrieving target data for storage in commonDistantNodes array
               std::vector<int> localCorrespondency;
               RecvIntVec(localCorrespondency, targetProc);
index 0016d8595af7a4dcba9dcd90dfa1b9f295043779..4fc48e9edf45b71587eec9ff45d3836118a94fb4 100644 (file)
 #include "PointLocator3DIntersectorP0P0.hxx"
 
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
-#include "BBTree.txx"
 
 #ifdef HAVE_MPI2
 #include <mpi.h>
 #endif
 
-#if defined(MED_ENABLE_PARMETIS) || defined(MED_ENABLE_METIS)
+#ifdef MED_ENABLE_PARMETIS
+#include "MEDPARTITIONER_ParMetisGraph.hxx"
+#endif
+#ifdef MED_ENABLE_METIS
 #include "MEDPARTITIONER_MetisGraph.hxx"
 #endif
-
 #ifdef MED_ENABLE_SCOTCH
 #include "MEDPARTITIONER_ScotchGraph.hxx"
 #endif
@@ -70,7 +71,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection()
     _domain_selector( 0 ),
     _i_non_empty_mesh(-1),
     _driver_type(MEDPARTITIONER::MedXml),
-    _subdomain_boundary_creates(false),
+    _subdomain_boundary_creates( MyGlobals::_Creates_Boundary_Faces ),
     _family_splitting(false),
     _create_empty_groups(false),
     _joint_finder(0)
@@ -99,7 +100,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection
     _i_non_empty_mesh(-1),
     _name(initialCollection._name),
     _driver_type(MEDPARTITIONER::MedXml),
-    _subdomain_boundary_creates(false),
+    _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces),
     _family_splitting(family_splitting),
     _create_empty_groups(create_empty_groups),
     _joint_finder(0)
@@ -145,13 +146,13 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection
     std::cout<<"treating cell and face families"<<std::endl;
   
   castIntField(initialCollection.getMesh(),
-                this->getMesh(),
-                initialCollection.getCellFamilyIds(),
-                "cellFamily");
+               this->getMesh(),
+               initialCollection.getCellFamilyIds(),
+               "cellFamily");
   castIntField(initialCollection.getFaceMesh(), 
-                this->getFaceMesh(),
-                initialCollection.getFaceFamilyIds(),
-                "faceFamily");
+               this->getFaceMesh(),
+               initialCollection.getFaceFamilyIds(),
+               "faceFamily");
 
   //treating groups
 #ifdef HAVE_MPI2
@@ -289,13 +290,13 @@ void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialColle
                   array->decrRef(); // array is not used in this case
                 }
               _mesh[inew]->zipCoords();
-                
+
             }
         }
       for (int i=0;i<(int)splitMeshes[inew].size();i++)
         if (splitMeshes[inew][i]!=0)
           splitMeshes[inew][i]->decrRef();
-    }  
+    }
   if (MyGlobals::_Verbose>300)
     std::cout << "proc " << rank << " : castCellMeshes end fusing" << std::endl;
 }
@@ -313,21 +314,23 @@ void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialC
     {
 
       double* bbox;
-      BBTree<3>* tree; 
+      BBTreeOfDim* tree = 0;
+      int dim = 3;
       if (!isParallelMode() || (_domain_selector->isMyDomain(iold)))
         {
           //      std::map<pair<double,pair<double, double> >, int > nodeClassifier;
-          int nvertices=initialCollection.getMesh(iold)->getNumberOfNodes();
-          bbox=new double[nvertices*2*3];
           ParaMEDMEM::DataArrayDouble* coords = initialCollection.getMesh(iold)->getCoords();
           double* coordsPtr=coords->getPointer();
+          dim = coords->getNumberOfComponents();
+          int nvertices=initialCollection.getMesh(iold)->getNumberOfNodes();
+          bbox=new double[nvertices*2*dim];
 
-          for (int i=0; i<nvertices*3;i++)
+          for (int i=0; i<nvertices*dim;i++)
             {
               bbox[i*2]=coordsPtr[i]-1e-8;
               bbox[i*2+1]=coordsPtr[i]+1e-8;
             }
-          tree=new BBTree<3>(bbox,0,0,nvertices,1e-9);
+          tree=new BBTreeOfDim( dim, bbox,0,0,nvertices,1e-9);
         }
 
       for (int inew=0; inew<_topology->nbDomain(); inew++)
@@ -343,7 +346,7 @@ void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialC
               ParaMEDMEM::DataArrayDouble* coords = mesh->getCoords();
               for (int inode=0; inode<mesh->getNumberOfNodes();inode++)
                 {
-                  double* coordsPtr=coords->getPointer()+inode*3;
+                  double* coordsPtr=coords->getPointer()+inode*dim;
                   vector<int> elems;
                   tree->getElementsAroundPoint(coordsPtr,elems);
                   if (elems.size()==0) continue;
@@ -353,52 +356,55 @@ void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialC
             }
           else if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold)))
 #else
-          if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold)))
+            if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold)))
 #endif
-            {
-              ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords();
-              for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++)
-                {
-                  double* coordsPtr=coords->getPointer()+inode*3;
-                  vector<int> elems;
-                  tree->getElementsAroundPoint(coordsPtr,elems);
-                  if (elems.size()==0) continue;
-                  nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode)));
-                }
-            }
+              {
+                ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords();
+                for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++)
+                  {
+                    double* coordsPtr=coords->getPointer()+inode*dim;
+                    vector<int> elems;
+                    tree->getElementsAroundPoint(coordsPtr,elems);
+                    if (elems.size()==0) continue;
+                    nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode)));
+                  }
+              }
         }
       if (!isParallelMode() || (_domain_selector->isMyDomain(iold)))
         {
           delete tree;
           delete[] bbox;
         }
-    } 
+    }
 
 }
 
 void getNodeIds(ParaMEDMEM::MEDCouplingUMesh& meshOne, ParaMEDMEM::MEDCouplingUMesh& meshTwo, std::vector<int>& nodeIds)
 {
   using std::vector;
+  using MEDPARTITIONER::BBTreeOfDim;
   if (!&meshOne || !&meshTwo) return;  //empty or not existing
   double* bbox;
-  BBTree<3>* tree;
+  BBTreeOfDim* tree = 0;
   int nv1=meshOne.getNumberOfNodes();
-  bbox=new double[nv1*6];
   ParaMEDMEM::DataArrayDouble* coords=meshOne.getCoords();
+  int dim = coords->getNumberOfComponents();
+
+  bbox=new double[nv1*2*dim];
   double* coordsPtr=coords->getPointer();
-  for (int i=0; i<nv1*3; i++)
+  for (int i=0; i<nv1*dim; i++)
     {
       bbox[i*2]=coordsPtr[i]-1e-8;
       bbox[i*2+1]=coordsPtr[i]+1e-8;
     }
-  tree=new BBTree<3>(bbox,0,0,nv1,1e-9);
-  
+  tree=new BBTreeOfDim( dim, bbox,0,0,nv1,1e-9);
+
   int nv2=meshTwo.getNumberOfNodes();
   nodeIds.resize(nv2,-1);
   coords=meshTwo.getCoords();
   for (int inode=0; inode<nv2; inode++)
     {
-      double* coordsPtr2=coords->getPointer()+inode*3;
+      double* coordsPtr2=coords->getPointer()+inode*dim;
       vector<int> elems;
       tree->getElementsAroundPoint(coordsPtr2,elems);
       if (elems.size()==0) continue;
@@ -416,31 +422,30 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle
                                                     const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping,
                                                     std::vector<std::vector<std::vector<int> > >& new2oldIds)
 {
-
   //splitMeshes structure will contain the partition of 
   //the old faces on the new ones
   //splitMeshes[4][2] contains the faces from old domain 2
   //that have to be added to domain 4
-  
+
   using std::vector;
   using std::map;
   using std::multimap;
   using std::pair;
   using std::make_pair;
-  
+
   if (MyGlobals::_Verbose>10)
     std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes" << std::endl;
   if (_topology==0)
     throw INTERP_KERNEL::Exception("Topology has not been defined on call to castFaceMeshes");
-  
+
   int nbNewDomain=_topology->nbDomain();
   int nbOldDomain=initialCollection.getTopology()->nbDomain();
-  
+
   vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom=initialCollection.getFaceMesh();
   vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo=this->getFaceMesh();
-  
+
   vector< vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes;
-  
+
   splitMeshes.resize(nbNewDomain);
   for (int inew=0; inew<nbNewDomain; inew++)
     {
@@ -448,7 +453,7 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle
     }
   new2oldIds.resize(nbOldDomain);
   for (int iold=0; iold<nbOldDomain; iold++) new2oldIds[iold].resize(nbNewDomain);
-  
+
   //init null pointer for empty meshes
   for (int inew=0; inew<nbNewDomain; inew++)
     {
@@ -532,7 +537,7 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle
           std::cout<<"proc "<<MyGlobals::_Rank<<" : castFaceMeshes empty mesh from iodDomain "<<iold<<std::endl;
         }
     }
-  
+
 #ifdef HAVE_MPI2
   //send/receive stuff
   if (isParallelMode())
@@ -579,7 +584,18 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle
             if (umesh->getNumberOfCells()>0)
                 myMeshes.push_back(umesh);
         }
-      
+
+      ParaMEDMEM::MEDCouplingUMesh *bndMesh = 0;
+      if ( _subdomain_boundary_creates &&
+           _mesh[inew] &&
+           _mesh[inew]->getNumberOfCells()>0 )
+        {
+          bndMesh =
+            ((ParaMEDMEM::MEDCouplingUMesh *)_mesh[inew]->buildBoundaryMesh(/*keepCoords=*/true));
+          if (bndMesh->getNumberOfCells()>0)
+            myMeshes.push_back( bndMesh );
+        }
+
       if (myMeshes.size()>0)
         {
           meshesCastTo[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(myMeshes);
@@ -592,6 +608,8 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle
       for (int iold=0; iold<nbOldDomain; iold++)
         if (splitMeshes[inew][iold]!=0)
           splitMeshes[inew][iold]->decrRef();
+      if ( bndMesh )
+        bndMesh->decrRef();
     }
   if (MyGlobals::_Verbose>300)
     std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes end fusing" << std::endl;
@@ -600,9 +618,9 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle
 
 
 void MEDPARTITIONER::MeshCollection::castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom,
-                                   std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo,
-                                   std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom,
-                                   std::string nameArrayTo)
+                                                  std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo,
+                                                  std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom,
+                                                  std::string nameArrayTo)
 {
   using std::vector;
   
@@ -613,16 +631,16 @@ void MEDPARTITIONER::MeshCollection::castIntField(std::vector<ParaMEDMEM::MEDCou
   //preparing bounding box trees for accelerating source-target node identifications
   if (MyGlobals::_Verbose>99)
     std::cout<<"making accelerating structures"<<std::endl;
-  std::vector<BBTree<3,int>* > acceleratingStructures(ioldMax);
+  std::vector<BBTreeOfDim* > acceleratingStructures(ioldMax);
   std::vector<ParaMEDMEM::DataArrayDouble*>bbox(ioldMax);
   for (int iold =0; iold< ioldMax; iold++)
     if (isParallelMode() && _domain_selector->isMyDomain(iold))
       {
         ParaMEDMEM::DataArrayDouble* sourceCoords=meshesCastFrom[iold]->getBarycenterAndOwner();
         bbox[iold]=sourceCoords->computeBBoxPerTuple(1.e-6);
-        acceleratingStructures[iold]=new BBTree<3,int> (bbox[iold]->getConstPointer(),0,0,bbox[iold]->getNumberOfTuples());
+        acceleratingStructures[iold]=new BBTreeOfDim( sourceCoords->getNumberOfComponents(), bbox[iold]->getConstPointer(),0,0,bbox[iold]->getNumberOfTuples());
+        sourceCoords->decrRef();
       }
-
   // send-recv operations
 #ifdef HAVE_MPI2
   for (int inew=0; inew<inewMax; inew++)
@@ -689,7 +707,7 @@ void MEDPARTITIONER::MeshCollection::remapIntField(int inew, int iold,
                                                     const ParaMEDMEM::MEDCouplingUMesh& targetMesh,
                                                     const int* fromArray,
                                                     std::string nameArrayTo,
-                                                    const BBTree<3,int>* myTree)
+                                                    const BBTreeOfDim* myTree)
 {
 
   if (sourceMesh.getNumberOfCells()<=0) return; //empty mesh could exist
@@ -697,21 +715,22 @@ void MEDPARTITIONER::MeshCollection::remapIntField(int inew, int iold,
   const double*  tc=targetCoords->getConstPointer();
   int targetSize=targetMesh.getNumberOfCells();
   int sourceSize=sourceMesh.getNumberOfCells();
-if (MyGlobals::_Verbose>200)
-std::cout<<"remap vers target de taille "<<targetSize<<std::endl;
+  if (MyGlobals::_Verbose>200)
+    std::cout<<"remap vers target de taille "<<targetSize<<std::endl;
   std::vector<int> ccI;
   std::string str,cle;
   str=nameArrayTo+"_toArray";
   cle=Cle1ToStr(str,inew);
   int* toArray;
   
-  const BBTree<3>* tree;
+  const BBTreeOfDim* tree;
   bool cleantree=false;
   ParaMEDMEM::DataArrayDouble* sourceBBox=0;
+  int dim = targetCoords->getNumberOfComponents();
   if (myTree==0)
     {
       sourceBBox=sourceMesh.getBarycenterAndOwner()->computeBBoxPerTuple(1e-8);
-      tree=new BBTree<3> (sourceBBox->getConstPointer(),0,0, sourceBBox->getNumberOfTuples(),1e-10);
+      tree=new BBTreeOfDim( dim, sourceBBox->getConstPointer(),0,0, sourceBBox->getNumberOfTuples(),1e-10);
       cleantree=true;
     }
   else tree=myTree;
@@ -730,17 +749,28 @@ std::cout<<"remap vers target de taille "<<targetSize<<std::endl;
     {
       toArray=_map_dataarray_int.find(cle)->second->getPointer();
     }
-  
+
+  std::map< int, int > isource2nb; // count coincident elements
+  std::map<int,int>::iterator i2nb;
+
   for (int itargetnode=0; itargetnode<targetSize; itargetnode++)    
     {
       std::vector<int> intersectingElems;
-      tree->getElementsAroundPoint(tc+itargetnode*3,intersectingElems); // to be changed in 2D
+      tree->getElementsAroundPoint(tc+itargetnode*dim,intersectingElems);
       if (intersectingElems.size()!=0)
         {
           int isourcenode=intersectingElems[0];
-          toArray[itargetnode]=fromArray[isourcenode];
-          ccI.push_back(itargetnode);
-          ccI.push_back(isourcenode);
+          if ( intersectingElems.size() > 1 )
+            {
+              i2nb = isource2nb.insert( std::make_pair( isourcenode, 0 )).first;
+              isourcenode = intersectingElems[ i2nb->second++ ];
+            }
+          if ( isourcenode < sourceSize ) // protection from invalid elements
+            {
+              toArray[itargetnode]=fromArray[isourcenode];
+              ccI.push_back(itargetnode);
+              ccI.push_back(isourcenode);
+            }
         }
     }
   if (MyGlobals::_Verbose>200)
@@ -751,12 +781,11 @@ std::cout<<"remap vers target de taille "<<targetSize<<std::endl;
     std::cout << "proc " << MyGlobals::_Rank << " : map memorize '" << str << "'\n";
 
   _map_dataarray_int[str]=CreateDataArrayIntFromVector(ccI, 2);
-  
+
   targetCoords->decrRef();
   if (cleantree) delete tree;
   if (sourceBBox !=0) sourceBBox->decrRef();
-  
- }
+}
 
 void MEDPARTITIONER::MeshCollection::castAllFields(MeshCollection& initialCollection, std::string nameArrayTo)
 {
@@ -906,6 +935,232 @@ void MEDPARTITIONER::MeshCollection::remapDoubleField(int inew, int iold,
     }
 }
 
+//================================================================================
+/*!
+ * \brief Find faces common with neighbor domains and put them in "JOINT_n_p_Faces"
+ *        group (where "n" and "p" are domain IDs)
+ */
+//================================================================================
+
+void MEDPARTITIONER::MeshCollection::buildConnectZones()
+{
+  if ( getMeshDimension() < 2 )
+    return;
+
+  using ParaMEDMEM::MEDCouplingUMesh;
+  using ParaMEDMEM::DataArrayDouble;
+  using ParaMEDMEM::DataArrayInt;
+
+  std::vector<MEDCouplingUMesh*>& faceMeshes = getFaceMesh();
+  int nbMeshes = faceMeshes.size();
+
+  //preparing bounding box trees for accelerating search of coincident faces
+  std::vector<BBTreeOfDim* >   bbTrees(nbMeshes);
+  std::vector<DataArrayDouble*>bbox   (nbMeshes);
+  for (int inew = 0; inew < nbMeshes-1; inew++)
+    if ( !isParallelMode() || _domain_selector->isMyDomain(inew) )
+      {
+        DataArrayDouble* bcCoords = faceMeshes[inew]->getBarycenterAndOwner();
+        bbox   [inew] = bcCoords->computeBBoxPerTuple(1.e-6);
+        bbTrees[inew] = new BBTreeOfDim( bcCoords->getNumberOfComponents(),
+                                         bbox[inew]->getConstPointer(),0,0,
+                                         bbox[inew]->getNumberOfTuples());
+        bcCoords->decrRef();
+      }
+
+  // loop on domains to find joint faces between them
+  for (int inew1 = 0; inew1 < nbMeshes; inew1++ )
+    {
+      for (int inew2 = inew1+1; inew2 < nbMeshes; inew2++ )
+        {
+          MEDCouplingUMesh* mesh1 = 0;
+          MEDCouplingUMesh* mesh2 = 0;
+          //MEDCouplingUMesh* recvMesh = 0;
+          bool mesh1Here = true, mesh2Here = true;
+          if (isParallelMode())
+            {
+#ifdef HAVE_MPI2
+              mesh1Here = _domain_selector->isMyDomain(inew1);
+              mesh2Here = _domain_selector->isMyDomain(inew2);
+              if ( !mesh1Here && mesh2Here )
+                {
+                  //send mesh2 to domain of mesh1
+                  _domain_selector->sendMesh(*faceMeshes[inew2],
+                                             _domain_selector->getProcessorID(inew1));
+                }
+              else if ( mesh1Here && !mesh2Here )
+                {
+                  //receiving mesh2 from a distant domain
+                  _domain_selector->recvMesh(mesh2,_domain_selector->getProcessorID(inew2));
+                  if ( faceMeshes[ inew2 ] )
+                    faceMeshes[ inew2 ]->decrRef();
+                  faceMeshes[ inew2 ] = mesh2;
+                }
+#endif
+            }
+          if ( mesh1Here && !mesh1 ) mesh1 = faceMeshes[ inew1 ];
+          if ( mesh2Here && !mesh2 ) mesh2 = faceMeshes[ inew2 ];
+
+          // find coincident faces
+          std::vector< int > faces1, faces2;
+          if ( mesh1 && mesh2 )
+            {
+              const DataArrayDouble* coords2 = mesh2->getBarycenterAndOwner();
+              const double*   c2 = coords2->getConstPointer();
+              const int      dim = coords2->getNumberOfComponents();
+              const int nbFaces2 = mesh2->getNumberOfCells();
+              const int nbFaces1 = mesh1->getNumberOfCells();
+
+              for (int i2 = 0; i2 < nbFaces2; i2++)
+                {
+                  std::vector<int> coincFaces;
+                  bbTrees[inew1]->getElementsAroundPoint( c2+i2*dim, coincFaces );
+                  if (coincFaces.size()!=0)
+                    {
+                      int i1 = coincFaces[0];
+                      // if ( coincFaces.size() > 1 )
+                      //   {
+                      //     i2nb = isource2nb.insert( std::make_pair( i1 , 0 )).first;
+                      //     i1  = coincFaces[ i2nb->second++ ];
+                      //   }
+                      if ( i1  < nbFaces1 ) // protection from invalid elements
+                        {
+                          faces1.push_back( i1 );
+                          faces2.push_back( i2 );
+                        }
+                    }
+                }
+              coords2->decrRef();
+            }
+
+          if ( isParallelMode())
+            {
+#ifdef HAVE_MPI2
+              if ( mesh1Here && !mesh2Here )
+                {
+                  //send faces2 to domain of recvMesh
+                  SendIntVec(faces2, _domain_selector->getProcessorID(inew2));
+                }
+              else if ( !mesh1Here && mesh2Here )
+                {
+                  //receiving ids of faces from a domain of mesh1
+                  RecvIntVec(faces2, _domain_selector->getProcessorID(inew1));
+                }
+#endif
+            }
+          // if ( recvMesh )
+          //   recvMesh->decrRef();
+
+          // Create group "JOINT_inew1_inew2_Faces" and corresponding families
+          for ( int is2nd = 0; is2nd < 2; ++is2nd )
+            {
+              createJointGroup( is2nd ? faces2 : faces1,
+                                inew1 , inew2, is2nd );
+            }
+
+        } // loop on the 2nd domains (inew2)
+    } // loop on the 1st domains (inew1)
+
+
+  // delete bounding box trees
+  for (int inew = 0; inew < nbMeshes-1; inew++)
+    if (isParallelMode() && _domain_selector->isMyDomain(inew))
+      {
+        bbox[inew]->decrRef();
+        delete bbTrees[inew];
+      }
+}
+
+//================================================================================
+/*!
+ * \brief Create group "JOINT_inew1_inew2_Faces" and corresponding families
+ *  \param faces - face ids to include into the group
+ *  \param inew1 - index of the 1st domain
+ *  \param inew2 - index of the 2nd domain
+ *  \param is2nd - in which (1st or 2nd) domain to create the group
+ */
+//================================================================================
+
+void MEDPARTITIONER::MeshCollection::createJointGroup( const std::vector< int >& faces,
+                                                       const int                 inew1,
+                                                       const int                 inew2,
+                                                       const bool                is2nd )
+{
+  // get the name of JOINT group
+  std::string groupName;
+  {
+    std::ostringstream oss;
+    oss << "JOINT_"
+        << (is2nd ? inew2 : inew1 ) << "_"
+        << (is2nd ? inew1 : inew2 ) << "_"
+        << ( getMeshDimension()==2 ? "Edge" : "Face" );
+    groupName = oss.str();
+  }
+
+  // remove existing "JOINT_*" group
+  _group_info.erase( groupName );
+
+  // get family IDs array
+  int* famIDs = 0;
+  int inew = (is2nd ? inew2 : inew1 );
+  int totalNbFaces =  _face_mesh[ inew ] ? _face_mesh[ inew ]->getNumberOfCells() : 0;
+  std::string cle = Cle1ToStr( "faceFamily_toArray", inew );
+  if ( !_map_dataarray_int.count(cle) )
+    {
+      if ( totalNbFaces > 0 )
+        {
+          ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New();
+          p->alloc( totalNbFaces, 1 );
+          p->fillWithZero();
+          famIDs = p->getPointer();
+          _map_dataarray_int[cle]=p;
+        }
+    }
+  else
+    {
+      famIDs = _map_dataarray_int.find(cle)->second->getPointer();
+    }
+  // find a family ID of an existing JOINT group
+  int familyID = 0;
+  std::map<std::string, int>::iterator name2id = _family_info.find( groupName );
+  if ( name2id != _family_info.end() )
+    familyID = name2id->second;
+
+  // remove faces from the familyID-the family
+  if ( familyID != 0 && famIDs )
+    for ( size_t i = 0; i < totalNbFaces; ++i )
+      if ( famIDs[i] == familyID )
+        famIDs[i] = 0;
+
+  if ( faces.empty() )
+    return;
+
+  if ( familyID == 0 )  // generate a family ID for JOINT group
+    {
+      std::set< int > familyIDs;
+      for ( name2id = _family_info.begin(); name2id != _family_info.end(); ++name2id )
+        familyIDs.insert( name2id->second );
+      // find the next free family ID
+      int freeIdCount = inew1 * getNbOfGlobalMeshes() + inew2 + is2nd;
+      do
+        {
+          if ( !familyIDs.count( ++familyID ))
+            --freeIdCount;
+        }
+      while ( freeIdCount > 0 );
+    }
+
+  // push faces to familyID-th group
+  if ( faces.back() >= totalNbFaces )
+    throw INTERP_KERNEL::Exception("MeshCollection::createJointGroup(): to high face ID");
+  for ( size_t i = 0; i < faces.size(); ++i )
+    famIDs[ faces[i] ] = familyID;
+
+  // register JOINT group and family
+  _family_info[ groupName ] = familyID; // name of the group and family is same
+  _group_info [ groupName ].push_back( groupName );
+}
+
 /*! constructing the MESH collection from a distributed file
  *
  * \param filename name of the master file containing the list of all the MED files
@@ -917,7 +1172,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename)
     _domain_selector( 0 ),
     _i_non_empty_mesh(-1),
     _driver_type(MEDPARTITIONER::Undefined),
-    _subdomain_boundary_creates(false),
+    _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces),
     _family_splitting(false),
     _create_empty_groups(false),
     _joint_finder(0)
@@ -961,7 +1216,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, Para
     _domain_selector( &domainSelector ),
     _i_non_empty_mesh(-1),
     _driver_type(MEDPARTITIONER::Undefined),
-    _subdomain_boundary_creates(false),
+    _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces),
     _family_splitting(false),
     _create_empty_groups(false),
     _joint_finder(0)
@@ -1121,7 +1376,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, cons
     _i_non_empty_mesh(-1),
     _name(meshname),
     _driver_type(MEDPARTITIONER::MedXml),
-    _subdomain_boundary_creates(false),
+    _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces),
     _family_splitting(false),
     _create_empty_groups(false),
     _joint_finder(0)
@@ -1186,8 +1441,8 @@ MEDPARTITIONER::MeshCollection::~MeshCollection()
 void MEDPARTITIONER::MeshCollection::write(const std::string& filename)
 {
   //building the connect zones necessary for writing joints
-  //   if (_topology->nbDomain()>1)
-  //     buildConnectZones();
+  if (_topology->nbDomain()>1 && _subdomain_boundary_creates )
+    buildConnectZones();
   //suppresses link with driver so that it can be changed for writing
   delete _driver;
   _driver=0;
@@ -1336,10 +1591,12 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray
   if (MyGlobals::_Verbose>50)
     std::cout<<"getting nodal connectivity"<<std::endl;
   //looking for reverse nodal connectivity i global numbering
+  int meshDim = 3;
   for (int idomain=0; idomain<nbdomain; idomain++)
     {
       if (isParallelMode() && !_domain_selector->isMyDomain(idomain))
         continue;
+      meshDim = _mesh[idomain]->getMeshDimension();
     
       ParaMEDMEM::DataArrayInt* index=ParaMEDMEM::DataArrayInt::New();
       ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New();
@@ -1428,9 +1685,9 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray
   for (std::map<pair<int,int>,int>::const_iterator it=cell2cellcounter.begin();
        it!=cell2cellcounter.end();
        it++)
-    if (it->second>=3) 
+    if (it->second>=meshDim)
       {
-        cell2cell.insert(std::make_pair(it->first.first,it->first.second)); //should be adapted for 2D!
+        cell2cell.insert(std::make_pair(it->first.first,it->first.second));
         cell2cell.insert(std::make_pair(it->first.second, it->first.first));
       }
 
@@ -1473,7 +1730,7 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray
           index.push_back(idep);
         }
     }
-  
+
   array=new MEDPARTITIONER::SkyLineArray(index,value);
 
   if (MyGlobals::_Verbose>100)
@@ -1517,18 +1774,30 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nb
   int* edgeweights=0;
   buildCellGraph(array,edgeweights);
   
-  Graph* cellGraph;
+  Graph* cellGraph = 0;
   switch (split)
     {
     case Graph::METIS:
-#if defined(MED_ENABLE_PARMETIS) || defined(MED_ENABLE_METIS)
-      if (MyGlobals::_Verbose>10)
-        std::cout << "METISGraph" << std::endl;
-      cellGraph=new METISGraph(array,edgeweights);
-#else
-      throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please.");
+      if ( isParallelMode() && MyGlobals::_World_Size > 1 )
+      {
+#ifdef MED_ENABLE_PARMETIS
+        if (MyGlobals::_Verbose>10)
+          std::cout << "ParMETISGraph" << std::endl;
+        cellGraph=new ParMETISGraph(array,edgeweights);
 #endif
+      }
+      if ( !cellGraph )
+      {
+#ifdef MED_ENABLE_METIS
+        if (MyGlobals::_Verbose>10)
+          std::cout << "METISGraph" << std::endl;
+        cellGraph=new METISGraph(array,edgeweights);
+#endif
+      }
+      if ( !cellGraph )
+        throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please.");
       break;
+
     case Graph::SCOTCH:
 #ifdef MED_ENABLE_SCOTCH
       if (MyGlobals::_Verbose>10)
@@ -1709,7 +1978,7 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell()
 {
   for (int inew=0; inew<_topology->nbDomain(); inew++)
     {
-      if (isParallelMode() && _domain_selector->isMyDomain(inew))
+      if (!isParallelMode() || _domain_selector->isMyDomain(inew))
         {
           if (MyGlobals::_Verbose>200) 
             std::cout << "proc " << MyGlobals::_Rank << " : filterFaceOnCell on inewDomain " << inew << " nbOfFaces " << _face_mesh[inew]->getNumberOfCells() << std::endl;
@@ -1721,13 +1990,13 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell()
           getNodeIds(*mcel, *mfac, nodeIds);
           if (nodeIds.size()==0)
             continue;  //one empty mesh nothing to do
-      
+
           ParaMEDMEM::DataArrayInt *revNodalCel=ParaMEDMEM::DataArrayInt::New();
           ParaMEDMEM::DataArrayInt *revNodalIndxCel=ParaMEDMEM::DataArrayInt::New();
           mcel->getReverseNodalConnectivity(revNodalCel,revNodalIndxCel);
           int *revC=revNodalCel->getPointer();
           int *revIndxC=revNodalIndxCel->getPointer();
-      
+
           std::vector< int > faceOnCell;
           std::vector< int > faceNotOnCell;
           int nbface=mfac->getNumberOfCells();
@@ -1737,11 +2006,20 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell()
               std::vector< int > inodesFace;
               mfac->getNodeIdsOfCell(iface, inodesFace);
               int nbnodFace=inodesFace.size();
+              if ( nbnodFace != mfac->getNumberOfNodesInCell( iface ))
+                continue; // invalid node ids
               //set inodesFace in mcel
-              for (int i=0; i<nbnodFace; i++) inodesFace[i]=nodeIds[inodesFace[i]];
+              int nbok = 0;
+              for (int i=0; i<nbnodFace; i++)
+                nbok += (( inodesFace[i]=nodeIds[inodesFace[i]] ) >= 0 );
+              if ( nbok != nbnodFace )
+                continue;
               int inod=inodesFace[0];
               if (inod<0)
-                std::cout << "filterFaceOnCell problem 1" << std::endl;
+                {
+                  std::cout << "filterFaceOnCell problem 1" << std::endl;
+                  continue;
+                }
               int nbcell=revIndxC[inod+1]-revIndxC[inod];
               for (int j=0; j<nbcell; j++) //look for each cell with inod
                 {
@@ -1762,15 +2040,38 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell()
                     std::cout << "face NOT on cell " << iface << " " << faceOnCell.size()-1 << std::endl;
                 }
             }
-      
+
           revNodalCel->decrRef();
           revNodalIndxCel->decrRef();
-      
-          std::string keyy;
-          keyy=Cle1ToStr("filterFaceOnCell",inew);
-          _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceOnCell);
-          keyy=Cle1ToStr("filterNotFaceOnCell",inew);
-          _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceNotOnCell);
+
+          // std::string keyy;
+          // keyy=Cle1ToStr("filterFaceOnCell",inew);
+          // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceOnCell);
+          // keyy=Cle1ToStr("filterNotFaceOnCell",inew);
+          // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceNotOnCell);
+
+          // filter the face mesh
+          if ( faceOnCell.empty() )
+            _face_mesh[inew] = CreateEmptyMEDCouplingUMesh();
+          else
+            _face_mesh[inew] = (ParaMEDMEM::MEDCouplingUMesh *)
+              mfac->buildPartOfMySelf( &faceOnCell[0], &faceOnCell[0] + faceOnCell.size(),true);
+          mfac->decrRef();
+
+          // filter the face families
+          std::string key = Cle1ToStr("faceFamily_toArray",inew);
+          if ( getMapDataArrayInt().count( key ))
+            {
+              ParaMEDMEM::DataArrayInt * &     fam = getMapDataArrayInt()[ key ];
+              ParaMEDMEM::DataArrayInt * famFilter = ParaMEDMEM::DataArrayInt::New();
+              famFilter->alloc(faceOnCell.size(),1);
+              int* pfamFilter = famFilter->getPointer();
+              int* pfam       = fam->getPointer();
+              for ( size_t i=0; i<faceOnCell.size(); i++ )
+                pfamFilter[i]=pfam[faceOnCell[i]];
+              fam->decrRef();
+              fam = famFilter;
+            }
         }
     }
 }
index 2e6827a73b47dbd88400b6c0eb98e9369e6ba5d5..622b2a234330c805be68e653308eec09700853f0 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "MEDPARTITIONER.hxx"
 #include "MEDPARTITIONER_Graph.hxx"
+#include "MEDPARTITIONER_Utils.hxx"
 
 #include "MEDCouplingUMesh.hxx"
 
@@ -143,6 +144,9 @@ namespace MEDPARTITIONER
                         const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping,
                         std::vector<std::vector<std::vector<int> > >& new2oldIds);
 
+    //constructing connect zones
+    void buildConnectZones();
+
   private:
     void castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom,
                        std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo,
@@ -156,16 +160,21 @@ namespace MEDPARTITIONER
 
     
     void remapIntField(int inew, int iold, 
-                        const ParaMEDMEM::MEDCouplingUMesh& sourceMesh,
-                        const ParaMEDMEM::MEDCouplingUMesh& targetMesh,
-                        const int* fromArray,
-                        std::string nameArrayTo,
-                       const BBTree<3,int>* tree);
+                       const ParaMEDMEM::MEDCouplingUMesh& sourceMesh,
+                       const ParaMEDMEM::MEDCouplingUMesh& targetMesh,
+                       const int* fromArray,
+                       std::string nameArrayTo,
+                       const BBTreeOfDim* tree);
 
     void remapDoubleField(int inew, int iold,
                            ParaMEDMEM::DataArrayDouble* fromArray,
                            std::string nameArrayTo,
                            std::string descriptionField);
+
+    void createJointGroup( const std::vector< int >& faces,
+                           const int                 inew1,
+                           const int                 inew2,
+                           const bool                is2nd );
   private:
 
     //link to mesh_collection topology
index c2c997d0e060d096b196ddc4ccd7113cd872f0e5..f41349581ebcd9641ca9f5ff31f4ea6932e285aa 100644 (file)
@@ -228,18 +228,18 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile
   std::vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes;
   ParaMEDMEM::MEDCouplingUMesh* cellMesh=_collection->getMesh(idomain);
   ParaMEDMEM::MEDCouplingUMesh* faceMesh=_collection->getFaceMesh(idomain);
-  ParaMEDMEM::MEDCouplingUMesh* faceMeshFilter=0;
+  //ParaMEDMEM::MEDCouplingUMesh* faceMeshFilter=0;
   
   std::string finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName=");
-  std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain);
-  ParaMEDMEM::DataArrayInt* filter=0;
-  if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end())
-    {
-      filter=_collection->getMapDataArrayInt().find(cleFilter)->second;
-      int* index=filter->getPointer();
-      faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true);
-      faceMesh=faceMeshFilter;
-    }
+  // std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain);
+  // ParaMEDMEM::DataArrayInt* filter=0;
+  // if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end())
+  //   {
+  //     filter=_collection->getMapDataArrayInt().find(cleFilter)->second;
+  //     int* index=filter->getPointer();
+  //     faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true);
+  //     faceMesh=faceMeshFilter;
+  //   }
   cellMesh->setName(finalMeshName.c_str());
   meshes.push_back(cellMesh);
   
@@ -250,60 +250,45 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile
       meshes.push_back(faceMesh);
     }
   
-  ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0;
-  if (MyGlobals::_Creates_Boundary_Faces>0)
-    {
-      //try to write Boundary meshes
-      bool keepCoords=false; //TODO or true
-      boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords);
-      boundaryMesh->setName("boundaryMesh");
-    }
-  
+  //ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0;
+  // if (MyGlobals::_Creates_Boundary_Faces>0)
+  //   {
+  //     //try to write Boundary meshes
+  //     bool keepCoords=false; //TODO or true
+  //     boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords);
+  //     boundaryMesh->setName("boundaryMesh");
+  //   }
+
   MEDLoader::WriteUMeshes(distfilename.c_str(), meshes, true);
-  if (faceMeshFilter!=0)
-    faceMeshFilter->decrRef();
-  
-  if (boundaryMesh!=0)
-    {
-      //doing that testMesh becomes second mesh sorted by alphabetical order of name
-      MEDLoader::WriteUMesh(distfilename.c_str(), boundaryMesh, false);
-      boundaryMesh->decrRef();
-    }
+  // if (faceMeshFilter!=0)
+  //   faceMeshFilter->decrRef();
+
+  // if (boundaryMesh!=0)
+  //   {
+  //     //doing that testMesh becomes second mesh sorted by alphabetical order of name
+  //     MEDLoader::WriteUMesh(distfilename.c_str(), boundaryMesh, false);
+  //     boundaryMesh->decrRef();
+  //   }
   ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(distfilename.c_str(), _collection->getMesh(idomain)->getName());
-  
+
   mfm->setFamilyInfo(_collection->getFamilyInfo());
   mfm->setGroupInfo(_collection->getGroupInfo());
-  
+
   std::string key=Cle1ToStr("faceFamily_toArray",idomain);
-  if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end())
+  if ( meshes.size() == 2 &&
+      _collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end())
     {
       ParaMEDMEM::DataArrayInt *fam=_collection->getMapDataArrayInt().find(key)->second;
-      ParaMEDMEM::DataArrayInt *famFilter=0;
-      if (filter!=0)
-        {
-          int* index=filter->getPointer();
-          int nbTuples=filter->getNbOfElems();
-          //not the good one...buildPartOfMySelf do not exist for DataArray 
-          //Filter=fam->renumberAndReduce(index, filter->getNbOfElems());
-          famFilter=ParaMEDMEM::DataArrayInt::New();
-          famFilter->alloc(nbTuples,1);
-          int* pfamFilter=famFilter->getPointer();
-          int* pfam=fam->getPointer();
-          for (int i=0; i<nbTuples; i++)
-            pfamFilter[i]=pfam[index[i]];
-          fam=famFilter;
-          mfm->setFamilyFieldArr(-1,fam);
-          famFilter->decrRef();
-        }
+      mfm->setFamilyFieldArr(-1,fam);
     }
-  
+
   key=Cle1ToStr("cellFamily_toArray",idomain);
   if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end())
     mfm->setFamilyFieldArr(0,_collection->getMapDataArrayInt().find(key)->second);
-  
+
   mfm->write(distfilename.c_str(),0);
   key="/inewFieldDouble="+IntToStr(idomain)+"/";
-    
+
   std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it;
   int nbfFieldFound=0;
   for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++)
index 5f89b9573ba69d1f07ab7803c48f3f26efbd4d4a..05a83a28b1f34f1c67054938aabd20581b1a10dd 100644 (file)
 
 #include <iostream>
 
-#ifdef MED_ENABLE_METIS
 extern "C"
 {
-#include "metis.h"
+#include "MEDPARTITIONER_metis.h"
 }
-#endif
 
 using namespace MEDPARTITIONER;
 
@@ -90,11 +88,11 @@ void METISGraph::partGraph(int ndomain,
       if (MyGlobals::_Verbose>10) 
         std::cout << "METISGraph::partGraph METIS_PartGraph METIS_PartGraph(RecursiveOrKway)" << std::endl;
       if (options_string != "k")
-        METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
-                                  &base, &nparts, options, &edgecut, partition);
+        MEDPARTITIONER_METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
+                                                &base, &nparts, options, &edgecut, partition);
       else
-        METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
-                            &base, &nparts, options, &edgecut, partition);
+        MEDPARTITIONER_METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
+                                           &base, &nparts, options, &edgecut, partition);
     }
   else  //force this case because METIS send all 1 in value
     {
index 5e85a6f94bf59bd07da938dbf5fc63837e359ba9..f042c44bf9ae96d10cdb0d3433090c50a28427aa 100644 (file)
@@ -17,7 +17,7 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#include "MEDPARTITIONER_MetisGraph.hxx"
+#include "MEDPARTITIONER_ParMetisGraph.hxx"
 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
 #include "MEDPARTITIONER_Utils.hxx"
 
 #include <iostream>
 
 #ifdef MED_ENABLE_PARMETIS
-#include <mpi.h>
-#include "parmetis.h"
+#include <parmetis.h>
+// #if PARMETIS_MAJOR_VERSION == 4
+//    #define ParMETIS_PartKway ParMETIS_V3_PartKway
+// #endif
 #endif
 
 using namespace MEDPARTITIONER;
 
-METISGraph::METISGraph():Graph()
+ParMETISGraph::ParMETISGraph():Graph()
 {
 }
 
-METISGraph::METISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight)
+ParMETISGraph::ParMETISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight)
   :Graph(graph,edgeweight)
 {
 }
 
-METISGraph::~METISGraph()
+ParMETISGraph::~ParMETISGraph()
 {
 }
 
-void METISGraph::partGraph(int ndomain,
+void ParMETISGraph::partGraph(int ndomain,
                            const std::string& options_string,
                            ParaDomainSelector *parallelizer)
 {
@@ -53,7 +55,7 @@ void METISGraph::partGraph(int ndomain,
   vector<int> ran,vx,va; //for randomize
   
   if (MyGlobals::_Verbose>10)
-    std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl;
+    std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph" << std::endl;
   
   // number of graph vertices
   int n=_graph->getNumberOf();
@@ -81,12 +83,12 @@ void METISGraph::partGraph(int ndomain,
   // output parameters
   int edgecut;
 #if !defined(MED_ENABLE_PARMETIS)
-  throw INTERP_KERNEL::Exception("METISGraph::partGraph : PARMETIS is not available. Check your products, please.");
+  throw INTERP_KERNEL::Exception("ParMETISGraph::partGraph : PARMETIS is not available. Check your products, please.");
 #else
   int* partition=new int[n];
   
   if (MyGlobals::_Verbose>10) 
-    std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph ParMETIS_PartKway new" << std::endl;
+    std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph ParMETIS_PartKway new" << std::endl;
   int * vtxdist=parallelizer->getProcVtxdist();
   MPI_Comm comm=MPI_COMM_WORLD;
   ParMETIS_PartKway(vtxdist, xadj, adjncy, vwgt, 
diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx
new file mode 100644 (file)
index 0000000..ffc689d
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2007-2012  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 __MEDPARTITIONER_ParMETISGraph_HXX__
+#define __MEDPARTITIONER_ParMETISGraph_HXX__
+
+#include "MEDPARTITIONER_Graph.hxx"
+
+#include <string>
+
+namespace MEDPARTITIONER
+{
+  class MEDPARTITIONER_EXPORT ParMETISGraph : public Graph
+  {
+  public:
+    ParMETISGraph();
+    ParMETISGraph(MEDPARTITIONER::SkyLineArray*, int *edgeweight=0);
+    virtual ~ParMETISGraph();
+    void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0);
+  };
+}
+
+#endif
index 48f7a6ca66eb84dc488d4ce393cffb5c95ec9dbf..0552622749b998991c77759d11b4b0d13a5e7dee 100644 (file)
@@ -100,6 +100,7 @@ bool MEDPARTITIONER::ParaDomainSelector::isOnDifferentHosts() const
   MPI_Allreduce( &same, &sum_same, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
   return (sum_same != nbProcs());
 #endif
+  return false;
 }
 
 /*!
index 6bbe1a86c2b6e3bf54e65dd28de5aebd07bff9a2..64488d052a0170e0207389a2db0e8fb76ed285a0 100644 (file)
@@ -826,3 +826,54 @@ ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::CreateEmptyMEDCouplingUMesh()
   umesh->checkCoherency();
   return umesh;
 }
+
+namespace MEDPARTITIONER
+{
+  BBTreeOfDim::BBTreeOfDim( int           dim,
+                            const double* bbs,
+                            int*          elems,
+                            int           level,
+                            int           nbelems,
+                            double        epsilon)
+  {
+    switch ( dim )
+      {
+      case 3:
+        _tree=new BBTree<3> (bbs,elems,level,nbelems,epsilon);
+        _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 3 >;
+        _PgetIntersectingElems   = & BBTreeOfDim::_getIntersectingElems< 3 >;
+        break;
+      case 2:
+        _tree=new BBTree<2> (bbs,elems,level,nbelems,epsilon);
+        _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 2 >;
+        _PgetIntersectingElems   = & BBTreeOfDim::_getIntersectingElems< 2 >;
+        break;
+      case 1:
+        _tree=new BBTree<1> (bbs,elems,level,nbelems,epsilon);
+        _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 1 >;
+        _PgetIntersectingElems   = & BBTreeOfDim::_getIntersectingElems< 1 >;
+        break;
+      default:
+        _tree=0;
+        throw INTERP_KERNEL::Exception("BBTreeOfDim(): wrong space dimension");
+      }
+  }
+
+  BBTreeOfDim::~BBTreeOfDim()
+  {
+    delete (BBTree<3>*)_tree;
+  }
+
+  void BBTreeOfDim::getElementsAroundPoint( const double* coordsPtr,
+                                            std::vector<int>& elems ) const
+  {
+    BBTreeOfDim* me = (BBTreeOfDim*) this;
+    (me->*_PgetElementsAroundPoint) ( coordsPtr, elems );
+  }
+  void BBTreeOfDim::getIntersectingElems(const double* bb,
+                                         std::vector<int>& elems) const
+  {
+    BBTreeOfDim* me = (BBTreeOfDim*) this;
+    (me->*_PgetIntersectingElems) ( bb, elems );
+  }
+}
index 02b74cf2855573bfb6055a2b0108e6725dea3601..1fcdc33a2a1ca5a26ffdfa7f2795081f71bba812 100644 (file)
@@ -23,6 +23,7 @@
 #include "MEDPARTITIONER.hxx"
 
 #include "MEDCouplingUMesh.hxx"
+#include "BBTree.txx"
 
 #include <string>
 #include <vector>
@@ -133,5 +134,44 @@ namespace MEDPARTITIONER
     /*! used for descriptions of components of fields for example...*/
     static std::vector<std::string> _General_Informations;
   };
+
+
+
+  /*!
+   * \brief Class encapsulating BBTree of dimension given at construction and
+   *        providing all features of BBTree
+   */
+  class BBTreeOfDim
+  {
+    void * _tree;
+    void (BBTreeOfDim::*_PgetElementsAroundPoint)( const double* coordsPtr,
+                                                   std::vector<int>& elems ) const;
+    void (BBTreeOfDim::*_PgetIntersectingElems)( const double* bb,
+                                                 std::vector<int>& elems ) const;
+
+    template< int dim>
+    void _getElementsAroundPoint( const double* coordsPtr,
+                                  std::vector<int>& elems ) const
+    {
+      ((BBTree<dim,int>*)_tree)->getElementsAroundPoint( coordsPtr, elems );
+    }
+    template< int dim>
+    void _getIntersectingElems(const double* bb,
+                               std::vector<int>& elems) const
+    {
+      ((BBTree<dim,int>*)_tree)->getIntersectingElems( bb, elems );
+    }
+  public:
+
+    BBTreeOfDim( int           dim,
+                 const double* bbs,
+                 int*          elems,
+                 int           level,
+                 int           nbelems,
+                 double        epsilon=1e-12);
+    ~BBTreeOfDim();
+    void getElementsAroundPoint(const double* coordsPtr, std::vector<int>& elems ) const;
+    void getIntersectingElems  (const double* bb,        std::vector<int>& elems)  const;
+  };
 }
 #endif
diff --git a/src/MEDPartitioner/MEDPARTITIONER_metis.c b/src/MEDPartitioner/MEDPARTITIONER_metis.c
new file mode 100644 (file)
index 0000000..ec8cde2
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (C) 2007-2012  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
+//
+
+// Creation of this C code is forced by the following.
+//
+// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes
+// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h
+// that breaks compilation. To workaround this problem we create a wrapping C
+// function, inclusion of whose declaration causes no problem.
+
+#include "MEDPARTITIONER_metis.h"
+
+#if defined(MED_ENABLE_METIS)
+  #include <metis.h>
+#else
+  typedef int idxtype;
+#endif
+
+void MEDPARTITIONER_METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                                             idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                                             int *options, int *edgecut, idxtype *part)
+{
+#if defined(MED_ENABLE_METIS)
+  METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, 
+                           adjwgt, wgtflag, numflag, nparts, 
+                           options, edgecut, part);
+#endif
+}
+
+void MEDPARTITIONER_METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                                        idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                                        int *options, int *edgecut, idxtype *part)
+{
+#if defined(MED_ENABLE_METIS)
+  METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, 
+                      adjwgt, wgtflag, numflag, nparts, 
+                      options, edgecut, part);
+#endif
+}
diff --git a/src/MEDPartitioner/MEDPARTITIONER_metis.h b/src/MEDPartitioner/MEDPARTITIONER_metis.h
new file mode 100644 (file)
index 0000000..6b2832d
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (C) 2007-2012  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
+//
+
+// Creation of this C code is forced by the following.
+//
+// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes
+// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h
+// that breaks compilation. To workaround this problem we create a wrapping C
+// function, inclusion of whose declaration causes no problem.
+
+
+void MEDPARTITIONER_METIS_PartGraphRecursive(int *, int  *, int  *, int  *, int  *, int *, int *, int *, int *, int *, int  *);
+
+void MEDPARTITIONER_METIS_PartGraphKway(int *, int  *, int  *, int  *, int  *, int *, int *, int *, int *, int *, int  *); 
index c6039a03070dc2679fcd957a8009ffd8906d44b9..3efca0b19547e37c615227365f74a432dea6a956 100644 (file)
@@ -40,19 +40,19 @@ MEDPARTITIONER.hxx \
 MEDPARTITIONER_ParaDomainSelector.hxx \
 MEDPARTITIONER_ConnectZone.hxx \
 MEDPARTITIONER_SkyLineArray.hxx \
-MEDPARTITIONER_Topology.hxx
+MEDPARTITIONER_Topology.hxx \
+MEDPARTITIONER_metis.h
 
 #compilation of medpartitioner_para OR EXCLUSIVE medpartitioner
 if MED_ENABLE_PARMETIS
-    salomeinclude_HEADERS+= MEDPARTITIONER_MetisGraph.hxx
-else
+    salomeinclude_HEADERS+= MEDPARTITIONER_ParMetisGraph.hxx
+endif
 if MED_ENABLE_METIS
     salomeinclude_HEADERS += MEDPARTITIONER_MetisGraph.hxx
 endif
 if MED_ENABLE_SCOTCH
     salomeinclude_HEADERS += MEDPARTITIONER_ScotchGraph.hxx
 endif
-endif
 
 dist_libmedpartitioner_la_SOURCES= \
 MEDPARTITIONER_MeshCollection.cxx \
@@ -65,7 +65,8 @@ MEDPARTITIONER_UserGraph.cxx\
 MEDPARTITIONER_Utils.cxx \
 MEDPARTITIONER_ParaDomainSelector.cxx \
 MEDPARTITIONER_ConnectZone.cxx \
-MEDPARTITIONER_SkyLineArray.cxx
+MEDPARTITIONER_SkyLineArray.cxx \
+MEDPARTITIONER_metis.c
 
 if MPI_IS_OK
     dist_libmedpartitioner_la_SOURCES+= \
@@ -76,14 +77,13 @@ endif
 if MED_ENABLE_PARMETIS
     dist_libmedpartitioner_la_SOURCES+= \
     MEDPARTITIONER_ParMetisGraph.cxx
-else
+endif
 if MED_ENABLE_METIS
     dist_libmedpartitioner_la_SOURCES += MEDPARTITIONER_MetisGraph.cxx
 endif
 if MED_ENABLE_SCOTCH
     dist_libmedpartitioner_la_SOURCES += MEDPARTITIONER_ScotchGraph.cxx
 endif
-endif
 
 libmedpartitioner_la_CPPFLAGS= $(MPI_INCLUDES) $(MED3_INCLUDES) $(HDF5_INCLUDES) \
   $(LIBXML_INCLUDES) \
@@ -98,7 +98,7 @@ libmedpartitioner_la_LDFLAGS=
 if MED_ENABLE_PARMETIS
   libmedpartitioner_la_CPPFLAGS+= $(PARMETIS_CPPFLAGS)
   libmedpartitioner_la_LDFLAGS+= $(PARMETIS_LIBS)
-else
+endif
 if MED_ENABLE_METIS
   libmedpartitioner_la_CPPFLAGS += $(METIS_CPPFLAGS)
   libmedpartitioner_la_LDFLAGS += $(METIS_LIBS)
@@ -107,25 +107,25 @@ if MED_ENABLE_SCOTCH
   libmedpartitioner_la_CPPFLAGS += $(SCOTCH_CPPFLAGS)
   libmedpartitioner_la_LDFLAGS += $(SCOTCH_LIBS)
 endif
-endif
 
 libmedpartitioner_la_CXXFLAGS = @CXXTMPDPTHFLAGS@
 
 libmedpartitioner_la_LDFLAGS+= $(MED3_LIBS_C_ONLY) $(HDF5_LIBS) $(STDLIB) $(LIBXML_LIBS) $(MPI_LIBS) ../INTERP_KERNEL/libinterpkernel.la ../MEDCoupling/libmedcoupling.la ../MEDLoader/libmedloader.la
 
 # Executables targets
+
+bin_PROGRAMS= medpartitioner
+dist_medpartitioner_SOURCES= medpartitioner.cxx
+medpartitioner_CPPFLAGS= $(libmedpartitioner_la_CPPFLAGS)
+medpartitioner_LDADD= $(libmedpartitioner_la_LDFLAGS) -lm libmedpartitioner.la
+medpartitioner_CXXFLAGS = @CXXTMPDPTHFLAGS@
+
 if MED_ENABLE_PARMETIS
   bin_PROGRAMS=medpartitioner_para
   dist_medpartitioner_para_SOURCES= medpartitioner_para.cxx
   medpartitioner_para_CPPFLAGS= $(libmedpartitioner_la_CPPFLAGS)
   medpartitioner_para_LDADD= $(libmedpartitioner_la_LDFLAGS) -lm libmedpartitioner.la
   medpartitioner_para_CXXFLAGS=@CXXTMPDPTHFLAGS@
-else
-  bin_PROGRAMS= medpartitioner
-  dist_medpartitioner_SOURCES= medpartitioner.cxx
-  medpartitioner_CPPFLAGS= $(libmedpartitioner_la_CPPFLAGS)
-  medpartitioner_LDADD= $(libmedpartitioner_la_LDFLAGS) -lm libmedpartitioner.la
-  medpartitioner_CXXFLAGS = @CXXTMPDPTHFLAGS@
 endif
 
 
index ee2bc2143d209fd5311c44d9825dee8cae0f4577..d58c6828ae5c5a951a1131e2a5287b36b8561686 100644 (file)
@@ -58,12 +58,12 @@ IF(MPI_IS_OK)
     SET(MEDPARTITIONERTest_SOURCES ${MEDPARTITIONERTest_SOURCES} MEDPARTITIONERTestPara.cxx)
     SET(MEDPARTITIONERTest_DEFINITIONS "${MEDPARTITIONERTest_DEFINITIONS} ${MPI_DEFINITIONS} ${PARMETIS_DEFINITIONS}")
   ENDIF(MED_ENABLE_PARMETIS)
-ELSE(MPI_IS_OK)
-  IF(MED_ENABLE_METIS)
-    SET(MEDPARTITIONERTest_DEFINITIONS "${MEDPARTITIONERTest_DEFINITIONS} ${METIS_DEFINITIONS}")
-  ENDIF(MED_ENABLE_METIS)
 ENDIF(MPI_IS_OK)
 
+IF(MED_ENABLE_METIS)
+  SET(MEDPARTITIONERTest_DEFINITIONS "${MEDPARTITIONERTest_DEFINITIONS} ${METIS_DEFINITIONS}")
+ENDIF(MED_ENABLE_METIS)
+
 ADD_LIBRARY(MEDPARTITIONERTest SHARED ${MEDPARTITIONERTest_SOURCES})
 SET_TARGET_PROPERTIES(MEDPARTITIONERTest PROPERTIES COMPILE_FLAGS "${MEDPARTITIONERTest_DEFINITIONS}")
 TARGET_LINK_LIBRARIES(MEDPARTITIONERTest ${MEDPARTITIONERTest_LDFLAGS})
index 1a377236333fa069aaaafc4779fb85d3bc5f99e8..86bf5e3255e7efed8833fe1bc82073448e660558 100644 (file)
@@ -506,6 +506,7 @@ void MEDPARTITIONERTest::createTestMeshWithoutField()
       }
     mesh1->decrRef();
     mesh2->decrRef();
+    mfm->decrRef();
   }
    
   {
@@ -627,6 +628,7 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
   //cout<<"\n"<<tagXml<<endl;
   if (_verbose) 
     cout<<endl<<nameFileXml<<" created"<<endl;
+  mesh->decrRef();
 }
 
 void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells()
@@ -891,7 +893,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis()
 
 void MEDPARTITIONERTest::testMetisSmallSize()
 {
-#if !defined(HAVE_MPI2)
+  //#if !defined(HAVE_MPI2)
   setSmallSize();
   createTestMeshes();
   std::string MetisOrScotch("metis");
@@ -899,7 +901,7 @@ void MEDPARTITIONERTest::testMetisSmallSize()
   verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch);
-#endif
+  //#endif
 }
 #endif
 
@@ -973,7 +975,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch()
 
 void MEDPARTITIONERTest::testScotchSmallSize()
 {
-#if !defined(HAVE_MPI2)
+  //#if !defined(HAVE_MPI2)
   setSmallSize();
   createTestMeshes();
   std::string MetisOrScotch("scotch");
@@ -981,7 +983,7 @@ void MEDPARTITIONERTest::testScotchSmallSize()
   verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch);
-#endif
+  //#endif
 }
 #endif
 
@@ -1124,7 +1126,9 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   faceMesh->decrRef();
   fusedCell->decrRef();
   refusedCellMesh->decrRef();
+  refusedMesh->decrRef();
   cellMesh->decrRef();
+  initialMesh->decrRef();
   //done in ~collection
   //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef();
   //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef();
@@ -1213,8 +1217,10 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnC
   field1->decrRef();
   field2->decrRef();
   fusedCell->decrRef();
+  refusedMesh->decrRef();
   refusedCellMesh->decrRef();
   cellMesh->decrRef();
+  initialMesh->decrRef();
 }
 
 void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch)
@@ -1301,6 +1307,200 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnG
   field1->decrRef();
   field2->decrRef();
   fusedCell->decrRef();
+  refusedMesh->decrRef();
   refusedCellMesh->decrRef();
   cellMesh->decrRef();
+  initialMesh->decrRef();
+}
+
+//================================================================================
+/*!
+ * \brief Test for 0021756: [CEA 602] MEDPartitioner improvements
+ */
+//================================================================================
+
+void MEDPARTITIONERTest::testCreateBoundaryFaces2D()
+{
+  // Fixed complains are:
+  // - 2D is not available
+  // - groups and family handling is bugged (probably due to bug in the handling
+  //   of arrayTo in castIntField())
+  // - creates boundary faces option is not handled
+
+  // Create a 2D mesh in a file
+
+  const char fileName[] = "tmp_testCreateBoundaryFaces2D.med";
+
+  const int idFam1 = 3, idFam2 = 2;
+  int nbFam1, nbFam2, nbc;
+  {
+    const int nbX = 20, nbY = 15;
+    vector<int> conn;
+    vector<double> coor;
+    for (int j=0; j<=nbY; j++)
+      for (int i=0; i<=nbX; i++)
+        {
+          coor.push_back(i+.1);
+          coor.push_back(j+.2);
+        }
+    int ii;
+    for (int j=0; j<nbY; j++)
+      for (int i=0; i<nbX; i++)
+        {
+          ii=i + j*(nbX+1);
+          conn.push_back(ii);
+          conn.push_back(ii+1);
+          ii=ii + nbX + 2 ;
+          conn.push_back(ii);
+          conn.push_back(ii-1);
+        }
+    MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
+    mesh->setMeshDimension(2);
+
+    nbc=conn.size()/4; //nb of cells
+    mesh->allocateCells(nbc);
+    int* pConn = &conn[0];
+    for(int i=0; i<nbc; i++, pConn+=4)
+      mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,pConn);
+    mesh->finishInsertingCells();
+
+    int nbv=coor.size()/2; //nb of vertices
+    DataArrayDouble *myCoords=DataArrayDouble::New();
+    myCoords->useArray( &coor[0], /*ownership=*/false, CPP_DEALLOC, nbv, 2 );
+    mesh->setCoords(myCoords);
+    mesh->setName("FacesIn2D");
+    myCoords->decrRef();
+    mesh->checkCoherency();
+
+    // groups of cells
+    DataArrayInt* cellsFam=DataArrayInt::New();
+    cellsFam->alloc(nbc,1);
+    nbFam1 = nbc/3, nbFam2 = nbc/2;
+    int iE = 0;
+    for ( int i = 0; i < nbFam1; ++i ) cellsFam->getPointer()[ iE++ ] = idFam1;
+    for ( int i = 0; i < nbFam2; ++i ) cellsFam->getPointer()[ iE++ ] = idFam2;
+    for (            ; iE < nbc;     ) cellsFam->getPointer()[ iE++ ] = 0;
+    map<string,int> theFamilies;
+    theFamilies["FAMILLE_ZERO"]=0;
+    theFamilies["Family1"     ]=idFam1;
+    theFamilies["Family2"     ]=idFam2;
+    map<string, vector<string> > theGroups;
+    theGroups["Group1"].push_back("Family1");
+    theGroups["Group2"].push_back("Family2");
+
+    // write mesh
+    MEDFileUMesh * fileMesh = MEDFileUMesh::New();
+    fileMesh->setMeshAtLevel(0, mesh);
+    fileMesh->setFamilyInfo(theFamilies);
+    fileMesh->setGroupInfo(theGroups);
+    fileMesh->setFamilyFieldArr(0, cellsFam);
+    fileMesh->write(fileName,2);
+
+    cellsFam->decrRef();
+    mesh    ->decrRef();
+    fileMesh->decrRef();
+
+  } // mesh creation
+
+  // Partition the mesh into 4 parts
+
+  const int ndomains = 4;
+  ParaDomainSelector parallelizer(false);
+  MeshCollection collection(fileName,parallelizer);
+  ParallelTopology* aPT = (ParallelTopology*) collection.getTopology();
+  aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
+
+  std::auto_ptr< Topology > new_topo;
+#if defined(MED_ENABLE_METIS) || defined(MED_ENABLE_PARMETIS)
+  new_topo.reset( collection.createPartition(ndomains,Graph::METIS) );
+#endif
+#if defined(MED_ENABLE_SCOTCH)
+  if ( !new_topo.get() )
+    new_topo.reset( collection.createPartition(ndomains,Graph::SCOTCH) );
+#endif
+  if ( !new_topo.get() )
+    return;
+
+  // Check that "2D is available"
+
+  const char xmlName[] = "tmp_testCreateBoundaryFaces2D";
+  {
+    MyGlobals::_Creates_Boundary_Faces = true;
+    MeshCollection new_collection(collection,new_topo.get());
+
+    CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
+    CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
+    CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
+    CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces());
+    CPPUNIT_ASSERT      (new_collection.getNbOfLocalFaces() > 0 );
+
+    MyGlobals::_General_Informations.clear();
+    MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=2D"));
+    new_collection.write( xmlName );
+  }
+
+  // Check that "groups and family handling is NOT bugged"
+
+  MeshCollection new_collection(std::string(xmlName)+".xml");
+  std::map< int, int > famId2nb; // count total nb of cells in divided families
+  std::map< int, int >::iterator id2nn;
+  {
+    const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getCellFamilyIds();
+    for ( size_t i = 0; i < famIdsVec.size(); ++i )
+      {
+        ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i];
+        for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j )
+          {
+            id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first;
+            id2nn->second++;
+          }
+      }
+  }
+  CPPUNIT_ASSERT_EQUAL( 3, (int) famId2nb.size() ); // 3 fams/groups in all
+  CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( 0      ));
+  CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam1 ));
+  CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam2 ));
+  CPPUNIT_ASSERT_EQUAL( nbFam1, famId2nb[ idFam1 ]);
+  CPPUNIT_ASSERT_EQUAL( nbFam2, famId2nb[ idFam2 ]);
+  CPPUNIT_ASSERT_EQUAL( nbc - nbFam1 - nbFam2, famId2nb[ 0 ]);
+
+  // Check that "creates boundary faces option is handled"
+
+  famId2nb.clear();
+  const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getFaceFamilyIds();
+  for ( size_t i = 0; i < famIdsVec.size(); ++i )
+    {
+      ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i];
+      for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j )
+        {
+          id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first;
+          id2nn->second++;
+        }
+    }
+
+  CPPUNIT_ASSERT( !famId2nb.empty() );
+
+  // for each "JOINT_n_p_..." group there must be "JOINT_p_n_..." group
+  // of the same size
+  std::map<std::string,int>& famName2id = new_collection.getFamilyInfo();
+  std::map<std::string,int>::iterator na2id = famName2id.begin(), na2id2;
+  std::set< int > okFamIds;
+  okFamIds.insert(0);
+  for ( ; na2id != famName2id.end(); ++na2id )
+    {
+      if ( okFamIds.count( na2id->second ) || na2id->first[0] != 'J')
+        continue;
+      na2id2 = na2id;
+      bool groupOK = false;
+      while ( !groupOK && ++na2id2 != famName2id.end() )
+        groupOK = ( na2id2->first.find_first_not_of( na2id->first ) == std::string::npos );
+
+      CPPUNIT_ASSERT( groupOK );
+      CPPUNIT_ASSERT( na2id->second != na2id2->second);
+      CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id2->second ));
+      CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id->second ));
+      CPPUNIT_ASSERT_EQUAL( (int) famId2nb[ na2id2->second ],
+                            (int) famId2nb[ na2id->second ]);
+      okFamIds.insert( na2id2->second );
+    }
 }
index 5d1445ec8c65f2a8974a91ea86cb631f83c20b0e..d95ee9434b927331f8741dd48276d692dcba06b8 100644 (file)
@@ -66,6 +66,8 @@ class MEDPARTITIONERTEST_EXPORT MEDPARTITIONERTest : public CppUnit::TestFixture
 #endif
 #endif
 
+  CPPUNIT_TEST( testCreateBoundaryFaces2D ); // imp 0021756
+
   //CPPUNIT_TEST( deleteTestMeshes );
   CPPUNIT_TEST_SUITE_END();
 
@@ -133,6 +135,8 @@ public:
   void testMpirunMedianSize();
   void testMpirunHugeSize();
 #endif
+
+  void testCreateBoundaryFaces2D();
 };
 
 #endif
index 19dcc228349d2f92c4625d0351d3b12a34a040c8..b2a9420af7b06f82e9586f4f6d48efc6dbc097ed 100644 (file)
@@ -49,7 +49,7 @@ libMEDPARTITIONERTest_la_LDFLAGS=
 if MED_ENABLE_PARMETIS
   libMEDPARTITIONERTest_la_CPPFLAGS+= $(PARMETIS_CPPFLAGS)
   libMEDPARTITIONERTest_la_LDFLAGS+= $(PARMETIS_LIBS)
-else
+endif
 if MED_ENABLE_METIS
   libMEDPARTITIONERTest_la_CPPFLAGS += $(METIS_CPPFLAGS)
   libMEDPARTITIONERTest_la_LDFLAGS += $(METIS_LIBS)
@@ -58,7 +58,6 @@ if MED_ENABLE_SCOTCH
   libMEDPARTITIONERTest_la_CPPFLAGS += $(SCOTCH_CPPFLAGS)
   libMEDPARTITIONERTest_la_LDFLAGS += $(SCOTCH_LIBS)
 endif
-endif
 
 libMEDPARTITIONERTest_la_LDFLAGS += \
        $(MED3_LIBS_C_ONLY) \
@@ -80,14 +79,13 @@ TestMEDPARTITIONER_CPPFLAGS = $(libMEDPARTITIONERTest_la_CPPFLAGS) \
 
 if MPI_IS_OK
   TestMEDPARTITIONER_CPPFLAGS +=$(MPI_INCLUDES) $(PARMETIS_CPPFLAGS)
-else
+endif
 if MED_ENABLE_METIS
   TestMEDPARTITIONER_CPPFLAGS += $(METIS_CPPFLAGS)
 endif
 if MED_ENABLE_SCOTCH
   TestMEDPARTITIONER_CPPFLAGS += $(SCOTCH_CPPFLAGS)
 endif
-endif
 
 TestMEDPARTITIONER_LDADD = \
        $(libMEDPARTITIONERTest_la_LDFLAGS) -lm \
index 29073b76e9db96242c6f87dbe642f71b843166c6..9dc2aad62ea71cd21e6ebb1cae6c64f423c40942 100644 (file)
@@ -72,6 +72,7 @@ int main(int argc, char** argv)
   //sequential : no MPI
   MyGlobals::_World_Size=1;
   MyGlobals::_Rank=0;
+  MyGlobals::_Creates_Boundary_Faces=0;
 
   // Primitive parsing of command-line options
   string desc ("Available options of medpartitioner V1.0:\n"
@@ -84,7 +85,7 @@ int main(int argc, char** argv)
   //user can choose!
                "\t--split-method=<string>  : name of the splitting library (metis/scotch), default is metis\n"
 #endif
-//               "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n"
+               "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n"
                "\t--dump-cpu-memory        : dumps passed CPU time and maximal increase of used memory\n"
                );
 
@@ -109,7 +110,7 @@ int main(int argc, char** argv)
       else if (TestArg(argv[i],"--output-file",value)) output=value;
       else if (TestArg(argv[i],"--split-method",value)) library=value;
       else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str());
-//      else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1;
+      else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1;
       else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true;
       else 
         {
@@ -149,7 +150,7 @@ int main(int argc, char** argv)
       cout << "  output-file = " << output << endl;
       cout << "  split-method = " << library << endl;
       cout << "  ndomains = " << ndomains << endl;
-//      cout << "  creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl;
+      cout << "  creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl;
       cout << "  dump-cpu-memory = " << mesure_memory<< endl;
       cout << "  verbose = " << MyGlobals::_Verbose << endl;
     }
index 8e15db02ddf46aa3c13fe9f0e54c15fcada8ce88..9709745d20646402c53f96ee6086997871d836f5 100644 (file)
@@ -88,19 +88,19 @@ namespace ParaMEDMEM
     if (find(_distant_proc_ids.begin(), _distant_proc_ids.end(),rank)==_distant_proc_ids.end())
       return;
    
-    vector<int> elems;
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems;
 #ifdef USE_DIRECTED_BB
     INTERP_KERNEL::DirectedBoundingBox dbb;
     double* distant_bb = _domain_bounding_boxes+rank*dbb.dataSize(_local_cell_mesh_space_dim);
     dbb.setData(distant_bb);
-    _local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment(),elems);
+    elems=_local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment());
 #else
     double* distant_bb = _domain_bounding_boxes+rank*2*_local_cell_mesh_space_dim;
-    _local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems);
+    elems=_local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment());
 #endif
     
     DataArrayInt *distant_ids_send;
-    MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(&elems[0],&elems[elems.size()],distant_ids_send);
+    MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(elems->begin(),elems->end(),distant_ids_send);
     _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids);
     distant_ids_send->decrRef();
     
index 417c50e0fa4376ce873d926404eb9d2a63a300fb..ab27b9273305dc9812c730c3857ccf659bb5f80d 100644 (file)
@@ -270,7 +270,6 @@ namespace ParaMEDMEM
    */
   void OverlapElementLocator::sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const
   {
-   vector<int> elems;
    //int myProcId=_group.myRank();
    const double *distant_bb=0;
    MEDCouplingPointSet *local_mesh=0;
@@ -287,9 +286,9 @@ namespace ParaMEDMEM
        local_mesh=_local_target_mesh;
        field=_local_target_field;
      }
-   local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems);
+   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment());
    DataArrayInt *idsToSend;
-   MEDCouplingPointSet *send_mesh=static_cast<MEDCouplingPointSet *>(field->getField()->buildSubMeshData(&elems[0],&elems[elems.size()],idsToSend));
+   MEDCouplingPointSet *send_mesh=static_cast<MEDCouplingPointSet *>(field->getField()->buildSubMeshData(elems->begin(),elems->end(),idsToSend));
    if(sourceOrTarget)
      matrix.keepTracksOfSourceIds(procId,idsToSend);//Case#1 in Step2 of main algorithm.
    else