]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Merge from V5_1_main branch 24/11/2010
authorvsr <vsr@opencascade.com>
Thu, 25 Nov 2010 12:33:05 +0000 (12:33 +0000)
committervsr <vsr@opencascade.com>
Thu, 25 Nov 2010 12:33:05 +0000 (12:33 +0000)
120 files changed:
doc/doxygen/Doxyfile_med_user.in
doc/doxygen/Makefile.am
doc/doxygen/interpkernel.dox
doc/doxygen/main.dox
doc/doxygen/medloader.dox [new file with mode: 0644]
src/INTERP_KERNEL/CellModel.cxx
src/INTERP_KERNEL/CellModel.hxx
src/INTERP_KERNEL/CurveIntersectorP0P1.txx
src/INTERP_KERNEL/CurveIntersectorP1P0.txx
src/INTERP_KERNEL/CurveIntersectorP1P1.txx
src/INTERP_KERNEL/DirectedBoundingBox.cxx
src/INTERP_KERNEL/DirectedBoundingBox.hxx
src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx
src/INTERP_KERNEL/ExprEval/Makefile.am
src/INTERP_KERNEL/GenMathFormulae.hxx [new file with mode: 0644]
src/INTERP_KERNEL/InterpKernelMeshQuality.cxx [new file with mode: 0644]
src/INTERP_KERNEL/InterpKernelMeshQuality.hxx [new file with mode: 0644]
src/INTERP_KERNEL/InterpolationOptions.cxx
src/INTERP_KERNEL/InterpolationOptions.hxx
src/INTERP_KERNEL/InterpolationUtils.hxx
src/INTERP_KERNEL/Makefile.am
src/INTERP_KERNEL/TranslationRotationMatrix.cxx [new file with mode: 0644]
src/INTERP_KERNEL/TranslationRotationMatrix.hxx
src/INTERP_KERNEL/VolSurfFormulae.hxx
src/INTERP_KERNEL/VolSurfUser.hxx
src/INTERP_KERNEL/VolSurfUser.txx
src/INTERP_KERNELTest/ExprEvalInterpTest.cxx
src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingCMesh.cxx
src/MEDCoupling/MEDCouplingCMesh.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 [new file with mode: 0644]
src/MEDCoupling/MEDCouplingGaussLocalization.hxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMemArray.txx
src/MEDCoupling/MEDCouplingMesh.cxx
src/MEDCoupling/MEDCouplingMesh.hxx
src/MEDCoupling/MEDCouplingNatureOfField.cxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingNatureOfField.hxx
src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx
src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingPointSet.txx
src/MEDCoupling/MEDCouplingRefCountObject.hxx
src/MEDCoupling/MEDCouplingRemapper.cxx
src/MEDCoupling/MEDCouplingRemapper.hxx
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/MEDCouplingBasicsTest.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx [new file with mode: 0644]
src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx
src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx
src/MEDCoupling/Test/Makefile.am
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingDataForTest.py [new file with mode: 0644]
src/MEDCoupling_Swig/MEDCouplingTypemaps.i
src/MEDCoupling_Swig/Makefile.am
src/MEDCoupling_Swig/libMEDCoupling_Swig.i
src/MEDLoader/MEDLoader.cxx
src/MEDLoader/MEDLoader.hxx
src/MEDLoader/MEDLoaderBase.cxx
src/MEDLoader/MEDLoaderBase.hxx
src/MEDLoader/MEDLoaderDefines.hxx [new file with mode: 0644]
src/MEDLoader/Makefile.am
src/MEDLoader/Swig/MEDLoaderDataForTest.py [new file with mode: 0644]
src/MEDLoader/Swig/MEDLoaderTest.py [new file with mode: 0644]
src/MEDLoader/Swig/MEDLoaderTest2.py [new file with mode: 0644]
src/MEDLoader/Swig/MEDLoaderTypemaps.i [new file with mode: 0644]
src/MEDLoader/Swig/Makefile.am
src/MEDLoader/Swig/libMEDLoader_Swig.i
src/MEDLoader/Test/MEDLoaderTest.cxx [new file with mode: 0644]
src/MEDLoader/Test/MEDLoaderTest.hxx [new file with mode: 0644]
src/MEDLoader/Test/Makefile.am [new file with mode: 0755]
src/MEDLoader/Test/TestMEDLoader.cxx [new file with mode: 0644]
src/ParaMEDMEM/DEC.cxx
src/ParaMEDMEM/DEC.hxx
src/ParaMEDMEM/ElementLocator.cxx
src/ParaMEDMEM/ExplicitCoincidentDEC.cxx
src/ParaMEDMEM/ICoCoField.cxx
src/ParaMEDMEM/ICoCoField.hxx
src/ParaMEDMEM/ICoCoTrioField.cxx
src/ParaMEDMEM/ICoCoTrioField.hxx
src/ParaMEDMEM/InterpKernelDEC.cxx
src/ParaMEDMEM/InterpKernelDEC.hxx
src/ParaMEDMEM/InterpolationMatrix.cxx
src/ParaMEDMEM/ParaFIELD.cxx
src/ParaMEDMEMTest/MPI2Connector.cxx [new file with mode: 0644]
src/ParaMEDMEMTest/MPI2Connector.hxx [new file with mode: 0644]
src/ParaMEDMEMTest/Makefile.am
src/ParaMEDMEMTest/ParaMEDMEMTest.hxx
src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx [new file with mode: 0644]
src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx [new file with mode: 0644]
src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx
src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx
src/ParaMEDMEMTest/ParaMEDMEMTest_ICocoTrio.cxx
src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx
src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx
src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx
src/ParaMEDMEM_Swig/Makefile.am

index 95bbc0d62d4679b52e7f76bca5b9ebc9758c0f81..ef07e414c2b7bc0d73f771a7e913f373630bf637 100644 (file)
@@ -73,6 +73,7 @@ INPUT                  = @srcdir@ \
                          @srcdir@/../../src/INTERP_KERNEL \
                          @srcdir@/../../src/INTERP_KERNEL/Geometric2D \
                          @srcdir@/../../src/MEDCoupling \
+                        @srcdir@/../../src/MEDLoader \
                          @srcdir@/../../src/MEDMEM
 
 FILE_PATTERNS          = MEDMEM_Mesh.* \
@@ -95,6 +96,7 @@ FILE_PATTERNS          = MEDMEM_Mesh.* \
                          PlanarIntersector.* \
                          TargetIntersector.* \
                          Interpolation.* \
+                        InterpolationOptions.* \
                          InterpKernelGeo2DAbstractEdge.* \
                          InterpKernelGeo2DEdge.* \
                          InterpKernelGeo2DEdgeArcCircle.* \
@@ -111,8 +113,14 @@ FILE_PATTERNS          = MEDMEM_Mesh.* \
                         MEDCouplingCMesh.* \
                         MEDCouplingExtrudedMesh.* \
                         MEDCouplingFieldDouble.* \
+                        MEDCouplingField.* \
                         MEDCouplingFieldDiscretization.* \
                         MEDCouplingTimeDiscretization.* \
+                        MEDCouplingTimeLabel.* \
+                        MEDCouplingRefCountObject.* \
+                        MEDCouplingMemArray.* \
+                        MEDCouplingRemapper.* \
+                        MEDLoader.* \
                          *.dox
 RECURSIVE              = NO
 EXCLUDE                = CVS
index 0e2909df1c91dd227f27420c1f8df68df26ea26e..178b3c6885e1df5de1fb1b8e401de856f8b12649 100644 (file)
@@ -28,7 +28,12 @@ guidoc_DATA = images/head.png
 
 install-data-local : html-local
        $(INSTALL) -d $(DESTDIR)$(docdir)/gui/MED
-       cp -rp doc_ref_user/html/*.* $(DESTDIR)$(docdir)/gui/MED
+       @if test -d doc_ref_user/html ; then                            \
+         for filen in `find doc_ref_user/html -maxdepth 1 -type f` ; do\
+           echo "Installing $${filen}" ;                               \
+           cp -rp $${filen} $(DESTDIR)$(docdir)/gui/MED ;              \
+         done ;                                                        \
+       fi ;
 
 uninstall-local:
        rm -rf $(DESTDIR)$(docdir)/gui/MED
index afe4b70c3cba86a07ed23cf4668df781ed2af353..bfed9661fed5c1c67e530933c4818a9cbd156151 100644 (file)
@@ -214,10 +214,33 @@ interpolation. To be able to be filled by the interpolator the \c MatrixType cla
 
 \subsection InterpKerHighLevUsage high-level usage
 
-This the simplest mode of usage of interpolator. This way is strongly
-linked with MED data-structure. All interpolators is completely hidden
-to you. Even sparse interpolation matrix is hidden. An exemple of
-usage :
+The simplest mode of usage of interpolator in sequential mode is to use REMAPPER classes. These classes fulfill HXX2SALOME rules to allow the user to use it 
+in coupling graphs. 2 REMAPPERS exist, ParaMEDMEM::MEDCouplingRemapper and Remapper. These classes are strongly linked to their corresponding data structure, respectively
+MEDCoupling and MEDMEM. In return, all interpolation request and spare interpolation matrix are hidden from you. Here two examples of REMAPPER classes :
+
+- If you intend to use MEDCoupling data struture, ParaMEDMEM::MEDCouplingRemapper class should be used :
+
+\code
+...
+const char sourceFileName[]="source.med";
+MEDCouplingFieldDouble *sourceField=MEDLoader::ReadFieldCell(sourceFileName,"Source_Mesh",0,"Density",/*iteration*/0,/*order*/0);
+const char targetFileName[]="target.med";
+MEDCouplingUMesh *med_target_mesh=MEDLoader::ReadUMeshFromFile(targetFileName,"Target_Mesh",0);
+//
+sourceField->setNature(ConservativeVolumic);//Specify nature is needed to allow remapper object to apply correct policy for denominator computation !
+MEDCouplingRemapper remapper;
+remapper.setPrecision(1e-12);
+remapper.setIntersectionType(INTERP_KERNEL::Triangulation);
+remapper.prepare(sourceField->getMesh(),med_target_mesh,"P0P0");
+MEDCouplingFieldDouble *targetField=remapper.transferField(sourceField,/*default_value*/4.57);//Any target cell not intercepted by any source cell will have value set to 4.57.
+...
+// clean-up
+targetField->decrRef();
+sourceField->decrRef();
+med_target_mesh->decrRef();
+\endcode
+
+- If you intend to use MEDMEM data structure, Remapper class should be used :
 
 \code
 ...
@@ -244,7 +267,29 @@ As consequence of genericity of interpolators,  they are usable only by
 instanciating an underneath mesh data structure. The two following
 examples show how to use interpolator at this level.
 
-- The simplest way to use the interpolator with MED datastructure is :
+- The simplest way to use interpolator with MEDCoupling datastruture is put in the following example. Note that this code is close to those used by ParaMEDMEM
+to perform synchronization of meshes between processes of a MPI communicator :
+
+\code
+...
+MEDCouplingUMesh *med_source_mesh=MEDLoader::ReadUMeshFromFile("source.med","Source_mesh",0);
+MEDCouplingUMesh *med_target_mesh=MEDLoader::ReadUMeshFromFile("target.med","Target_mesh",0);
+MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_source_mesh(med_source_mesh);
+MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_target_mesh(med_target_mesh);
+// Go for interpolation...
+INTERP_KERNEL::Interpolation2D myInterpolator;
+myInterpolator.setPrecision(1e-7);
+myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D);
+std::vector<std::map<int,double> > resultMatrix;
+INTERP_KERNEL::Matrix<double,ALL_C_MODE> resultMatrix2;
+// here the interpolation is performed twice for this code to show the capability of storing data of out matrix in 2 different data structures.
+myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix,"P0P0");
+myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix2,"P0P0");
+//Ok resultMatrix and resultMatrix2 contain matrix now
+...
+\endcode
+
+- An another way to use the interpolator with MEDMEM datastructure is :
 
 \code
 ...
index 69d054975e31bff9de614741856afe7b3826e778..d7e4c38939ef1b4a1261f0cdc235b7c22c336305 100644 (file)
@@ -19,6 +19,8 @@ localization library.
 - Chapter \ref medcoupling describes DataStructures used for cross
 process exchange of meshes and fields.
 - Chapter \ref paramedmem describes its MPI implementation, which is called %ParaMEDMEM.
+- Chapter \ref medloader describes API for I/O from or to a MED file
+coming from a \ref medcoupling data structure.
 - Chapter \ref tools describes various tools based on MEDMEM  that can
 be helpful for handling MED files (conversion tools and splitting tools). 
 
diff --git a/doc/doxygen/medloader.dox b/doc/doxygen/medloader.dox
new file mode 100644 (file)
index 0000000..9cb490e
--- /dev/null
@@ -0,0 +1,357 @@
+/*!
+\page medloader MEDLoader
+
+\section MEDLoaderIntro Introduction
+
+MEDLoader is a package in charge of loading from a file or write to a file
+in MED format a \ref medcoupling data structure. The fact that these
+functionalities are not merged in \ref medcoupling is explained by a
+willingness of reducing as much as possible the dependancies of \ref medcoupling libraries.
+
+As a MED file can combine several \ref medcoupling aspects in one (for exemple meshes in
+MED file on different mesh dimension with families and groups) the API of MEDLoader is much more rich than simply read and write.
+
+MEDLoader offers \b static methods whose method names have the first
+character in capital. You are intended to use these methods. The following
+chapters will try to describe in details some of important ones.
+
+The basic idea of MEDLoader is to exploite as much as possible MED
+file capabilities to store MEDCoupling data file in a MED file and 
+reversely to load from a MED file into a MEDCoupling data structure.
+Basically, the info on components of ParaMEDMEM::DataArrayDouble
+instances are stores into components and units into MED files. The
+name of meshes and fields are used by MEDLoader to use it as this into
+MED file. A field f with \ref ParaMEDMEM::MEDCouplingTimeDiscretization
+"time discretization" set to ONE_TIME, the value of
+\c f->getTime(time,iteration,order) are used by MEDLoader to store
+identifies the field into MED file. All strings used by MEDLoader to
+use it into MED file should fulfill the rules of MED file where length
+are limited. 
+That's why the user should be aware of these constaints when trying to read/write a MED file using MEDLoader. 
+MEDLoader tries to manage that by protecting the user by throwing exceptions when the rules are not followed.
+
+\section MEDLoaderMainC Main concepts of MED files
+
+Here we will describes some of basic concepts of MED files in order to
+use the best methods proposed by MEDLoader API.
+
+\subsection MEDLoaderMEDFileGen Basics in MED files
+
+First of all MEDLoader \b will \b not read MED files whose version is
+\b lower \b than \b 2.2. The MEDLoader::CheckFileForRead will perform
+the check of that before any attempt of read.
+
+
+For new comers in MED file world some of basics principles are
+recalled here. Let's recall basic principles that explains some of the aspect of MEDLoade API.
+\anchor MEDLoaderMeshNameConstraint MED file can contain several meshes. These meshes are
+discriminated by their names (two meshes could not have the same
+names). By the same way a MED file can contain several fields in MED.
+So MEDLoader propose to you the MEDLoader::GetMeshNames method to
+discover all the mesh names contained in your file.
+
+A field is also discriminated by its name. The method MEDLoader::GetCellFieldNamesOnMesh and MEDLoader::GetNodeFieldNamesOnMesh are available to know all fields
+respectively on cells and on nodes lying on a specified mesh.
+
+ A field is defined by several time steps discriminated by a pair of int
+(iteration,order). It is \b not possible to store 2 time steps of a same
+field having the same iteration and order
+number. The floatting point value attached on this couple of ids (iteration,order) is only present for information.
+Static methods MEDLoader::GetCellFieldIterations and
+MEDLoader::GetNodeFieldIterations return a vector of pair containing
+each respectively iteration and order.
+
+A time step of a field lyies on one \b or \b more mesh(es) specified by its \b or \b their name. A time step of a field in
+MED file could be defined on point \b and on cell \b and, \b or on gauss points \b and, \b or on point per element.
+
+This recalled specificities of MED file explains that it is necessary to specify
+each time, at field-read time, the type of field, the iteration and order
+number the mesh you are interested in.  
+
+\subsection MEDLoaderMEDFileMesh Meshes in MED files
+
+In MED file meshes could combine in one unstructured mesh cells that
+have different dimension. For example it is possible to mix
+MED_TETRA4, MED_TRIA6, MED_SEG2, MED_POINT0, MED_POLYGON,
+MED_POLYHEDRA in a same mesh. In MEDCouplingUMesh such a mix is not
+allowed as described \ref MEDCouplingUMeshes "here". So to \b read such mesh it
+is important to know which meshdimension you are interested to. In API
+the parameter \b meshDimRelToMax discreminates the meshdim you are
+interested to relatively to the maximal dimension of cells contained
+in the mesh in file.
+
+Let's take 2 examples :
+
+- If you have a mesh called "MyMesh" in file "file1.med" with
+MED_POLYGON, MED_TRI3, MED_SEG2 and MED_SEG3 : The max dimension of
+cells is 2 (for MED_POLYGON and MED_TRI3). So if you want exclusively
+cells with type MED_POLYGON and MED_TRI3 you should use :
+
+\code
+MEDCouplingUMesh *m2D=MEDLoader::ReadUMeshFromFile("file1.med","MyMesh",0);
+\endcode
+
+If you are interested in MED_SEG2 and MED_SEG3 you should use :
+
+\code
+MEDCouplingUMesh *m1D=MEDLoader::ReadUMeshFromFile("file1.med","MyMesh",-1);
+\endcode
+
+The method MEDLoader::ReadUMeshDimFromFile could
+help you to have this mesh dimension.
+\anchor MEDLoaderExample2
+- Consider an another mesh called "Example2" in file "file2.med"
+containing MED_POLYHEDRA, MED_TETRA4, MED_QUAD8, MED_TRI6, MED_SEG2
+and MED_POINT0. In this case you will have :
+
+\code
+assert(3==MEDLoader::ReadUMeshDimFromFile("file2.med","Example2"));
+\endcode
+
+To get 3D cells (MED_POLYHEDRA and MED_TETRA4) you should type :
+\code
+MEDCouplingUMesh *m3D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",0);
+\endcode
+
+To get 2D cells (MED_TRI6 and MED_QUAD8) you should type :
+
+\code
+MEDCouplingUMesh *m2D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",-1);
+\endcode
+
+To get 1D cells (MED_SEG2) you should type :
+
+\code
+MEDCouplingUMesh *m1D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",-2);
+\endcode
+
+And finally for 0D cells (MED_POINT0) you will write :
+
+\code
+MEDCouplingUMesh *m0D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",-3);
+\endcode
+
+To finish this subsection, it is important to know that MEDLoader
+takes into account of the cell numbers stored in a mesh of a med
+file. This renumbering allows MEDLoader to conserve the order of
+MEDCoupling cells into the file. So if the renumbering of cells in MED
+file is not correct an exception will be thrown.
+
+\subsection MEDLoaderMEDFilePoMesh Part of meshes in MED files
+
+A mesh contains one or more families on nodes and/or on cells. A family is a partition
+(mathematical sense) of the mesh it lies to. A family can be described
+by an integer field on \b all nodes and on \b all cells of a same mesh.
+All cells and nodes having the same ids defines this family. This id
+is called the familyId. A family is discriminated by its id. MED file
+attach a name to its id to be more userfriendly. So by construction, 2 different
+families could not share anything. The user can retrieve all the
+families names available on a mesh with the static method MEDLoader::GetMeshFamiliesNames.
+
+A group is a set of families. So groups can overlap each other,
+contrary to families. Groups are also discriminated by a name. As for
+families the static method to retrieves the groups of a specified mesh is MEDLoader::GetMeshGroupsNames.
+
+MEDLoader allows you to retrieve the
+corresponding "part of meshes" thanks to static methods
+MEDLoader::ReadUMeshFromFamilies and MEDLoader::ReadUMeshFromGroups.
+This method allows you to combine several families and groups in the
+same returned mesh.
+
+\subsection MEDLoaderMEDFileField Reading a field at one time step in MED files
+
+A field at one time step on one mesh, with one entity (cell, node)
+lies on all mesh on on a part of it. In this last case a definition of
+a profile is needed. Even if the notions of profile on mesh and group
+on mesh could appear close, these two concepts are totally
+disconnected in MED file.
+The aspect of profile is managed by MEDLoader, thats why this
+aspect does not appear in the MEDLoader API.
+So to retrieve a field on 3D cell called "F1Cell" in example file
+\ref MEDLoaderExample2 "file2.med (seen in meshes section)" on a mesh "Example2" on time
+step defined by iteration number 2 and iteration 3 the request will be :
+
+\code
+MEDCouplingFieldDouble *f1Cell_3D=MEDLoader::ReadFieldCell("file2.med","Example2",0,"F1Cell",2,3);
+\endcode
+
+To retrive the same field (same iteration) on 2D cells only the call will be : 
+
+\code
+MEDCouplingFieldDouble *f1Cell_2D=MEDLoader::ReadFieldCell("file2.med","Example2",-1,"F1Cell",2,3);
+\endcode
+
+\subsection MEDLoaderMEDFieldsRead Reading several field time steps at a time in MED files
+
+It is possible with MEDLoader to read several time steps of a field at
+a time.
+The advantage with this approach is to avoid to read and load several
+time a same mesh. This is typically recommanded to use the following
+code when you desire to load all time steps of a field on cell "myField" lying on
+same mesh "mesh1" in one shot :
+
+\code
+
+std::vector<std::pair<int,int> > timeStepsIds=MEDLoader::GetCellFieldIterations("file4.med");
+std::vector<MEDCouplingFieldDouble *> fs=MEDLoader::ReadFieldsCellOnSameMesh("file4.med","mesh1",0,"myField",timeStepsIds);
+
+\endcode
+
+\section MEDLoaderWriteMain Writing a MED file with MEDLoader
+
+As MEDMEM and MED file do, MEDLoader write process separates clearly
+meshes from fields. The reason is that a common use case in write mode
+is to write in a first time a mesh and then writes several time steps
+of a same field in appended mode.
+
+The fact that the write process is rarely in a one shot put a
+constraint on API (as MEDMEM does) to precise to MEDLoader if you intend
+to append data to an existing file, or if you want to create a new
+file from scratch. This explains the presence of boolean parameter \b
+writeFromScratch in API of MEDLoader starting with \b
+MEDLoader::Write* .
+
+If \b writeFromScratch parameter is set to \b true and if the file
+already exists the file will be crashed and replaced by the new
+corresponding data. If \b writeFromScratch parameter is set to \b false and if the
+file does \b not \b exist the new file is created, but if the file
+exists MEDLoader will enter in appended mode.
+
+Two classes of MEDLoader write methods exists when \b writeFromScratch
+is set to \b false :
+
+-  Methods \b MEDLoader::Write*Dep : The behaviour is as MEDMEM, that
+   is to say, the write is done without any question in file. The
+   responsability is let to the user because the MED file could be
+   corrupted. The advantage of this method is that it is faster
+   because no check is done.
+- Methods \b MEDLoader::Write* : MEDLoader will not corrupt your file
+   by always trying to append data. The consequence of that is that a
+   read of part (and data processing) of MED file could be needed before any attempt of
+   writing. So these methods could be in some cases much time and memory consuming.
+
+The behaviour of MEDLoader when \b writeFromScratch is set to false will be precised
+for each \b MEDLoader::Write* methods is the next subsections.
+
+\subsection MEDLoaderWriteMesh Writing one mesh in a MED file with MEDLoader
+
+The first think to know is that MEDLoader is using the \b meshName in
+ParaMEDMEM::MEDCouplingMesh instance to put it in MED file.
+
+As explained in previous section \ref MEDLoaderMeshNameConstraint "here",
+a mesh in MED file is discriminated by a name, so the \b meshName
+\b should \b be \b non \b empty. If it is the case an
+INTERP_KERNEL::Exception will be thrown.
+
+To write one mesh \b myMesh with name \b "myMeshName" in a MED file \b "wfile1.med" the following code should be typed :
+
+\code
+
+MEDCouplingUMesh *myMesh=...;
+myMesh->setName("myMeshName");
+MEDLoader::WriteUMesh("wFile1.med",myMesh,true);
+
+\endcode
+
+With the previous code, if "wFile1.med" file existed the file is
+crashed and will contain after the call only the content of myMesh
+instance.
+
+If you desire to append a mesh in "wFile1.med" you should type :
+
+\code
+
+MEDCouplingUMesh *myMesh=...;
+myMesh->setName("myMeshName");
+MEDLoader::WriteUMesh("wFile1.med",myMesh,false);
+
+\endcode
+
+With the previous code, if the "wFile1.med" had already a mesh called "myMeshName" an
+INTERP_KERNEL::Exception will be thrown.
+
+\subsection MEDLoaderWriteMeshes Writing several meshes in a MED file with MEDLoader
+
+It could be interesting to write several meshes in one shot. Two
+possiblities are possible :
+
+- Write several instances of ParaMEDMEM::MEDCouplingUMesh
+  lying \b on \b same \b coords \b with \b different \b mesh \b dimension. In this case the
+  use of MEDLoader::WriteUMeshes is the method you should
+  use. Typically this method should be used to write such of file
+  defined \ref MEDLoaderExample2 "here".
+  This method first checks that all instances share the same
+  ParaMEDMEM::DataArrayDouble instance as coords. If not an
+  INTERP_KERNEL::Exception will be thrown and an invocation on
+  ParaMEDMEM::MEDCouplingPointSet::tryToShareSameCoords will be necessary.
+
+- Write a partition of meshes having \b same \b mesh \b dimension, that is to say a set of
+  groups and families from given meshes. As in the previous case the
+  check of same coords will be done (if not an INTERP_KERNEL::Exception is
+  thrown). After this step this method will
+  merge (by concerving the order in input) and will simplify the
+  merged mesh. After this operation, the groups will be constituted by
+  assigning the groups names with the conresponding names of
+  instance. That's why all meshes have to have a not empty name and
+  different each other. The method to use in this case is
+  MEDLoader::WriteUMeshesPartition.
+
+For these 2 described methods the semantic of \b writeFromScratch when
+\b false is the same, that is to say : no writing
+(INTERP_KERNEL::Exception thrown) will be done if the
+file already exists and contains already a mesh with name 'meshName'
+for MEDLoader::WriteUMeshesPartition method and the name of the first
+of the vector of unstructured meshes passed as first parameter of
+MEDLoader::WriteUMeshes.
+
+\subsection MEDLoaderWriteField Writing one time step of a field in a MED file with MEDLoader
+
+To write \b one \b time \b step of a field from scratch with MEDLoader is to
+use MEDLoader::WriteField method. The behviour of this method depends
+on the value of the \b writeFromScratch paramter :
+
+- When \b writeFromScratch equals to \b true, this method performs two things, it
+writes the underlying mesh and write the specified time step on it.
+
+- When \b writeFromScatch equals to \b false, this method looks that
+  the underlying mesh exists (by looking the content of \c field->getMesh()->getName() ) in file. If not, the behaviour is the
+  same that previous case with \b writeFromScratch parameter set to
+  \b true. If the mesh already exists, MEDLoader reads the field and
+  tries to apply field on it. This operation could be rather time
+  consuming because a read operation is performed and a reorder
+  operation too. If the file already contains the same field at the
+  same time step (iteration and order ids) the corresponding time step
+  will be replaced by the field passed in parameter.
+
+\subsection MEDLoaderWriteFields Writing several time steps of a field in a MED file with MEDLoader
+
+To write a serie of time steps in a "file3.med" file lying on the same
+unstructured mesh the typical code
+to write is the following :
+
+\code
+
+MEDCouplingFieldDouble *f=...;
+MEDLoader::WriteUMesh("file3.med",static_cast<MEDCouplingUMesh*>f->getMesh(),true);
+f->setTime(1.2,1,0);
+//Writing first time step with iteration==1 and order==0
+MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file3.med",f);
+f->setTime(1.3,2,0);
+f->applyFunc("sqrt(x)");
+//Writing second time step with iteration==2 and order==0
+MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file3.med",f);
+
+\endcode 
+
+In the previous code, it is important to note that the values of pair
+(iteration,order) should be different between two calls to avoid that
+a call to MEDLoader::WriteFieldUsingAlreadyWrittenMesh overwrites a
+previous call.
+An another important thing is the fact that \c f->getMesh() does not be
+modified.
+This method of writing presents the big advantage to be fast, because
+no check neither read is performed by this method. That's why contrary
+to other MEDLoader::Write* method the parameter of \b writeFromScratch
+is not needed here.
+
+*/
index af6dac5ad779cf0f18bc0ba782d8e874433734ee..88bc7a820cee19dca29bf05748b40f6e1e99a656 100644 (file)
 
 namespace INTERP_KERNEL
 {
+  const char *CellModel::CELL_TYPES_REPR[]={"NORM_POINT0", "NORM_SEG2", "NORM_SEG3", "NORM_TRI3", "NORM_QUAD4",// 0->4
+                                            "NORM_POLYGON", "NORM_TRI6", "" , "NORM_QUAD8", "",//5->9
+                                            "", "", "", "", "NORM_TETRA4",//10->14
+                                            "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19
+                                            "NORM_TETRA10", "", "", "NORM_PYRA13", "",//20->24
+                                            "NORM_PENTA15", "", "", "", "",//25->29
+                                            "NORM_HEXA20", "NORM_POLYHED", "", "", "",//30->34
+                                            "", "", "", "", "",//35->39
+                                            "NORM_ERROR"};
+
   std::map<NormalizedCellType,CellModel> CellModel::_map_of_unique_instance;
 
   const CellModel& CellModel::getCellModel(NormalizedCellType type)
@@ -42,6 +52,11 @@ namespace INTERP_KERNEL
     return (*iter).second;
   }
 
+  const char *CellModel::getRepr() const
+  {
+    return CELL_TYPES_REPR[(int)_type];
+  }
+
   /*!
    * This method is compatible with all types including dynamic one.
    */
@@ -87,6 +102,8 @@ namespace INTERP_KERNEL
     _quadratic=false;
     _dyn=false;
     _extruded_type=NORM_ERROR;
+    _linear_type=NORM_ERROR;
+    _quadratic_type=NORM_ERROR;
     switch(type)
       {
       case NORM_POINT0:
@@ -96,17 +113,17 @@ namespace INTERP_KERNEL
         break;
       case NORM_SEG2:
         {
-          _nb_of_pts=2; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD4;
+          _nb_of_pts=2; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3;
         }
         break;
       case NORM_SEG3:
         {
-          _nb_of_pts=3; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD8;
+          _nb_of_pts=3; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD8; _linear_type=NORM_SEG2;
         }
         break;
       case NORM_TETRA4:
         {
-          _nb_of_pts=4; _nb_of_sons=4; _dim=3;
+          _nb_of_pts=4; _nb_of_sons=4; _dim=3; _quadratic_type=NORM_TETRA10;
           _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3;
           _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _nb_of_sons_con[1]=3;
@@ -116,7 +133,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_HEXA8:
         {
-          _nb_of_pts=8; _nb_of_sons=6; _dim=3;
+          _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20;
           _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_QUAD4; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4;
           _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _nb_of_sons_con[1]=4;
@@ -128,7 +145,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_QUAD4:
         {
-          _nb_of_pts=4; _nb_of_sons=4; _dim=2;
+          _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8;
           _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_type[3]=NORM_SEG2;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2;
           _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2;
@@ -138,7 +155,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_TRI3:
         {
-          _nb_of_pts=3; _nb_of_sons=3; _dim=2;
+          _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6;
           _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2;
           _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2;
@@ -147,7 +164,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_TRI6:
         {
-          _nb_of_pts=6; _nb_of_sons=3; _dim=2;
+          _nb_of_pts=6; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3;
           _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3;
           _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3;
@@ -156,7 +173,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_QUAD8:
         {
-          _nb_of_pts=8; _nb_of_sons=4; _dim=2;
+          _nb_of_pts=8; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4;
           _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3;
           _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3;
@@ -166,7 +183,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_PYRA5:
         {
-          _nb_of_pts=5; _nb_of_sons=5; _dim=3;
+          _nb_of_pts=5; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PYRA13;
           _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_type[4]=NORM_TRI3;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4;
           _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _nb_of_sons_con[1]=3;
@@ -177,7 +194,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_PENTA6:
         {
-          _nb_of_pts=6; _nb_of_sons=5; _dim=3;
+          _nb_of_pts=6; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PENTA15;
           _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3;
           _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _nb_of_sons_con[1]=3;
@@ -188,7 +205,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_TETRA10:
         {
-          _nb_of_pts=10; _nb_of_sons=4; _dim=3;
+          _nb_of_pts=10; _nb_of_sons=4; _dim=3; _linear_type=NORM_TETRA4;
           _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=4; _sons_con[0][4]=5; _sons_con[0][5]=6; _nb_of_sons_con[0]=6;
           _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _sons_con[1][3]=7; _sons_con[1][4]=8; _sons_con[1][5]=4; _nb_of_sons_con[1]=6;
@@ -198,7 +215,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_PYRA13:
         {
-          _nb_of_pts=13; _nb_of_sons=5; _dim=3;
+          _nb_of_pts=13; _nb_of_sons=5; _dim=3; _linear_type=NORM_PYRA5;
           _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_type[4]=NORM_TRI6;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=5; _sons_con[0][5]=6; _sons_con[0][6]=7; _sons_con[0][7]=8; _nb_of_sons_con[0]=8;
           _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _sons_con[1][3]=9; _sons_con[1][4]=10; _sons_con[1][5]=5; _nb_of_sons_con[1]=6;
@@ -209,7 +226,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_PENTA15:
         {
-          _nb_of_pts=15; _nb_of_sons=5; _dim=3;
+          _nb_of_pts=15; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6;
           _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6;
           _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6;
@@ -220,7 +237,7 @@ namespace INTERP_KERNEL
         break;
       case NORM_HEXA20:
         {
-          _nb_of_pts=20; _nb_of_sons=6; _dim=3;
+          _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8;
           _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_QUAD8; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_type[5]=NORM_QUAD8;
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _nb_of_sons_con[0]=8;
           _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _nb_of_sons_con[1]=8;
index 393fea0eb723d9eba2c8f864968752d34bff3009..23b7355127c89ad32b991904f024104f0b9fd5d4 100644 (file)
@@ -41,6 +41,7 @@ namespace INTERP_KERNEL
     static void buildUniqueInstance();
   public:
     INTERPKERNEL_EXPORT static const CellModel& getCellModel(NormalizedCellType type);
+    INTERPKERNEL_EXPORT const char *getRepr() const;
     INTERPKERNEL_EXPORT bool isDynamic() const { return _dyn; }
     INTERPKERNEL_EXPORT bool isQuadratic() const { return _quadratic; }
     INTERPKERNEL_EXPORT unsigned getDimension() const { return _dim; }
@@ -53,6 +54,8 @@ namespace INTERP_KERNEL
     INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon(unsigned sonId) const { return _nb_of_sons_con[sonId]; }
     INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const;
     INTERPKERNEL_EXPORT NormalizedCellType getExtrudedType() const { return _extruded_type; }
+    INTERPKERNEL_EXPORT NormalizedCellType getLinearType() const { return _linear_type; }
+    INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType() const { return _quadratic_type; }
     INTERPKERNEL_EXPORT NormalizedCellType getSonType(unsigned sonId) const { return _sons_type[sonId]; }
     INTERPKERNEL_EXPORT NormalizedCellType getSonType2(unsigned sonId) const;
     INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const;
@@ -65,10 +68,13 @@ namespace INTERP_KERNEL
     unsigned _nb_of_sons;
     NormalizedCellType _type;
     NormalizedCellType _extruded_type;
+    NormalizedCellType _linear_type;
+    NormalizedCellType _quadratic_type;
     unsigned _sons_con[MAX_NB_OF_SONS][MAX_NB_OF_NODES_PER_ELEM];
     unsigned _nb_of_sons_con[MAX_NB_OF_SONS];
     NormalizedCellType _sons_type[MAX_NB_OF_SONS];
     static std::map<NormalizedCellType,CellModel> _map_of_unique_instance;
+    static const char *CELL_TYPES_REPR[];
   };
 }
 
index c25136b5d4608eeae0a86bbecdddb57e580ada2a..1947a9f5bfb23ba66d5bc472fc8ea78ce616b406 100644 (file)
@@ -60,7 +60,7 @@ namespace INTERP_KERNEL
   {
     std::vector<typename BASE_INTERSECTOR::TDualSegment> segmentsT;
     BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT);
-    for ( int t = 0; t < segmentsT.size(); ++t )
+    for ( int t = 0; t < (int)segmentsT.size(); ++t )
       {
         typename MyMatrix::value_type& resRow = res[ OTT<ConnType,numPol>::ind2C( segmentsT[t]._nodeId )];
         for(typename std::vector<ConnType>::const_iterator
index bafd3ad9ed4b116c324f41eb1ef93e988ea607a9..f4e136dd301bc03898c7faeb97e0e4e6329b82e0 100644 (file)
@@ -69,7 +69,7 @@ namespace INTERP_KERNEL
           int iS = *iter;
           BASE_INTERSECTOR::getDualSegments( OTT<ConnType,numPol>::ind2C(iS),
                                              BASE_INTERSECTOR::_meshS, segmentsS);
-          for ( int s = 0; s < segmentsS.size(); ++s )
+          for ( int s = 0; s < (int)segmentsS.size(); ++s )
             {
               double surf = BASE_INTERSECTOR::intersectSegments(&segmentsS[s]._coords[0],
                                                                 &coordsT[0] + t*SPACEDIM);
index fd43fe7fc6f635a490e677c8f0cd458547768002..7be7429bb21049ce78aae4447918cc7a85863682 100644 (file)
@@ -54,7 +54,7 @@ namespace INTERP_KERNEL
   {
     std::vector<typename BASE_INTERSECTOR::TDualSegment> segmentsT, segmentsS;
     BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT);
-    for ( int t = 0; t < segmentsT.size(); ++t )
+    for ( int t = 0; t < (int)segmentsT.size(); ++t )
       {
         typename MyMatrix::value_type& resRow = res[ OTT<ConnType,numPol>::ind2C( segmentsT[t]._nodeId )];
         for(typename std::vector<ConnType>::const_iterator
@@ -63,7 +63,7 @@ namespace INTERP_KERNEL
             int iS = *iter;
             BASE_INTERSECTOR::getDualSegments( OTT<ConnType,numPol>::ind2C(iS),
                                                BASE_INTERSECTOR::_meshS, segmentsS);
-            for ( int s = 0; s < segmentsS.size(); ++s )
+            for ( int s = 0; s < (int)segmentsS.size(); ++s )
               {
                 double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0],
                                                                   &segmentsS[s]._coords[0]);
index 72b5c51016b38f4a15e85c6ca3f941a1d2b3bca9..b59f78db6b0b8f48e8e3f1aaba8cb5221590f55b 100644 (file)
@@ -20,7 +20,6 @@
 // Created   : Mon Apr 12 14:41:22 2010
 // Author    : Edward AGAPOV (eap)
 
-
 #include "DirectedBoundingBox.hxx"
 
 #include "InterpolationUtils.hxx"
@@ -31,7 +30,7 @@
 #define __MAX(i)      _minmax[i*2+1]
 #define __MYID        (long(this)%10000)
 #define __DMP(msg) \
-   //cout << msg << endl
+  //  cout << msg << endl
 
 using namespace std;
 
@@ -237,9 +236,9 @@ namespace INTERP_KERNEL
     if ( dim > 1 )
       {
         for ( coord = pts; coord < coordEnd; )
-          for ( int i = 0; i < dim; ++i )
+          for ( int i = 0; i < (int)dim; ++i )
             gc[i] += *coord++;
-        for ( int j = 0; j < dim; ++j )
+        for ( int j = 0; j < (int)dim; ++j )
           gc[j] /= numPts;
 
       }
@@ -309,9 +308,9 @@ namespace INTERP_KERNEL
     if ( dim > 1 )
       {
         for ( unsigned i = 0; i < numPts; ++i )
-          for ( int j = 0; j < dim; ++j )
+          for ( int j = 0; j < (int)dim; ++j )
             gc[j] += pts[i][j];
-        for ( int j = 0; j < dim; ++j )
+        for ( int j = 0; j < (int)dim; ++j )
           gc[j] /= numPts;
       }
 
@@ -347,6 +346,7 @@ namespace INTERP_KERNEL
             if ( pts[i][0] < _minmax[0] ) _minmax[0] = pts[i][0];
             if ( pts[i][0] > _minmax[1] ) _minmax[1] = pts[i][0];
           }
+        _axes[0] = 1.0;
       }
   }
 
@@ -568,7 +568,7 @@ namespace INTERP_KERNEL
                                        const double*        minmax) const
   {
     int iC, nbCorners = 1;
-    for ( int i=0;i<_dim;++i ) nbCorners *= 2;
+    for ( int i=0;i<(int)_dim;++i ) nbCorners *= 2;
     corners.resize( nbCorners * _dim );
     // each coordinate is filled with either min or max, nbSwap is number of corners
     // after which min and max swap
@@ -595,6 +595,8 @@ namespace INTERP_KERNEL
   bool DirectedBoundingBox::isDisjointWith(const DirectedBoundingBox& box) const
   {
     if ( _dim < 1 || box._dim < 1 ) return false; // empty box includes all
+    if ( _dim == 1 )
+      return isMinMaxOut( &box._minmax[0], &this->_minmax[0], _dim );
 
     // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect
     for ( int isThisCS = 0; isThisCS < 2; ++isThisCS )
@@ -632,6 +634,8 @@ namespace INTERP_KERNEL
   bool DirectedBoundingBox::isDisjointWith(const double* box) const
   {
     if ( _dim < 1 ) return false; // empty box includes all
+    if ( _dim == 1 )
+      return isMinMaxOut( &_minmax[0], box, _dim );
 
     // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect
 
@@ -657,7 +661,7 @@ namespace INTERP_KERNEL
       for ( int iC = 0, nC = cornersThis.size()/_dim; iC < nC; ++iC)
         {
           fromLocalCS( &cornersThis[iC*_dim], globCorner );
-          for ( int i = 0; i < _dim; ++i )
+          for ( int i = 0; i < (int)_dim; ++i )
             {
               if ( globCorner[i] < mmBox._minmax[i*2] )   mmBox._minmax[i*2] = globCorner[i];
               if ( globCorner[i] > mmBox._minmax[i*2+1] ) mmBox._minmax[i*2+1] = globCorner[i];
@@ -710,7 +714,7 @@ namespace INTERP_KERNEL
       data.insert( data.end(), &_axes[0], &_axes[0] + _axes.size());
       data.insert( data.end(), &_minmax[0], &_minmax[0] + _minmax.size());
     }
-    if ( data.size() < dataSize( _dim ))
+    if ( data.size() < (unsigned)dataSize( _dim ))
       data.resize( dataSize( _dim ), 0 );
     return data;
   }
index 93874acdb8fddda234f98d28e9b4ce0439f09f78..344f659090f767cd377c57ee04037db896775fb9 100644 (file)
@@ -16,8 +16,9 @@
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-#ifndef __DirectedBoundingBox_HXX__
-#define __DirectedBoundingBox_HXX__
+
+#ifndef __DIRECTEDBOUNDINGBOX_HXX__
+#define __DIRECTEDBOUNDINGBOX_HXX__
 
 #include "INTERPKERNELDefines.hxx"
 
@@ -92,7 +93,7 @@ namespace INTERP_KERNEL
 
   inline bool DirectedBoundingBox::isLocalOut(const double* pLoc) const
     {
-      for ( int i = 0; i < _dim; ++i )
+      for ( int i = 0; i < (int)_dim; ++i )
         if ( pLoc[i] < _minmax[i*2] || pLoc[i] > _minmax[i*2+1] )
           return true;
       return false;
@@ -106,10 +107,10 @@ namespace INTERP_KERNEL
 
   inline void DirectedBoundingBox::addPointToBox(const double* coord)
   {
-    for ( int i = 0; i < _dim; ++i )
+    for ( int i = 0; i < (int)_dim; ++i )
       {
         double c = 0;
-        for ( int j = 0; j < _dim; ++j ) c += coord[j]*_axes[i*_dim+j];
+        for ( int j = 0; j < (int)_dim; ++j ) c += coord[j]*_axes[i*_dim+j];
         if ( c < _minmax[i*2] )   _minmax[i*2] = c;
         if ( c > _minmax[i*2+1] ) _minmax[i*2+1] = c;
       }
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx
new file mode 100644 (file)
index 0000000..ee7116f
--- /dev/null
@@ -0,0 +1,477 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "InterpKernelAsmX86.hxx"
+
+#include <cstring>
+#include <sstream>
+#include <algorithm>
+
+const char *INTERP_KERNEL::AsmX86::OPS[NB_OF_OPS]={"mov","push","pop","fld","faddp","fsubp","fmulp","fdivp","fcos","fsin","fabs","fchs","fsqrt","sub","add","ret","leave","movsd","fst"};
+
+std::vector<char> INTERP_KERNEL::AsmX86::convertIntoMachineLangage(const std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<char> ret;
+  for(std::vector<std::string>::const_iterator iter=asmb.begin();iter!=asmb.end();iter++)
+    convertOneInstructionInML(*iter,ret);
+  return ret;
+}
+
+char *INTERP_KERNEL::AsmX86::convertMachineLangageInBasic(const std::vector<char>& ml, int& lgth) const
+{
+  lgth=ml.size();
+  char *ret=new char[lgth];
+  std::copy(ml.begin(),ml.end(),ret);
+  return ret;
+}
+
+void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector<char>& ml) const throw(INTERP_KERNEL::Exception)
+{
+  std::string::size_type pos=inst.find_first_of(' ');
+  std::string op;
+  std::string param;
+  if(pos!=std::string::npos)
+    {
+      op=inst.substr(0,pos);
+      param=inst.substr(pos+1);
+    }
+  else
+    op=inst;
+  int id=0;
+  for(const char **it=OPS;it!=OPS+NB_OF_OPS;it++,id++)
+    {
+      std::string tmp(*it);
+      if(op==tmp)
+        break;
+    }
+  switch(id)
+    {
+    case 0:
+      convertMov(param,ml);
+      break;
+    case 1:
+      convertPush(param,ml);
+      break;
+    case 2:
+      convertPop(param,ml);
+      break;
+    case 3:
+      convertFld(param,ml);
+      break;
+    case 4:
+      convertFaddp(param,ml);
+      break;
+    case 5:
+      convertFsubp(param,ml);
+      break;
+    case 6:
+      convertFmulp(param,ml);
+      break;
+    case 7:
+      convertFdivp(param,ml);
+      break;
+    case 8:
+      convertFcos(param,ml);
+      break;
+    case 9:
+      convertFsin(param,ml);
+      break;
+    case 10:
+      convertFabs(param,ml);
+      break;
+    case 11:
+      convertFchs(param,ml);
+      break;
+    case 12:
+      convertFsqrt(param,ml);
+      break;
+    case 13:
+      convertSub(param,ml);
+      break;
+    case 14:
+      convertAdd(param,ml);
+      break;
+    case 15:
+      convertRet(param,ml);
+      break;
+    case 16:
+      convertLeave(param,ml);
+      break;
+    case 17:
+      convertMovsd(param,ml);
+      break;
+    case 18:
+      convertFst(param,ml);
+      break;
+    default:
+      {
+        std::ostringstream oss; oss << "Unrecognized op : " << op << " in assembly line : " << inst;
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    }
+}
+
+#include <iostream>
+
+void INTERP_KERNEL::AsmX86::convertMov(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ASM1[]="ebp,esp";
+  const char ML1[2]={0x89,0xe5};
+  if(inst==ASM1)
+    {
+      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+      return ;
+    }
+  const char ASM2[]="rbp,rsp";
+  const char ML2[3]={0x48,0x89,0xe5};
+  if(inst==ASM2)
+    {
+      ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+      return ;
+    }
+  std::string::size_type pos=inst.find_first_of(' ');
+  if(pos==std::string::npos)
+    {
+      std::ostringstream oss; oss << "not recognized instruction mov : " << inst;
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  std::string inst2=inst.substr(pos+1);
+  pos=inst2.find_first_of(',');
+  if(pos==std::string::npos)
+    {
+      std::ostringstream oss; oss << "not recognized instruction mov : " << inst;
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  std::string inst3=inst2.substr(0,pos);
+  std::string inst4=inst2.substr(pos+1);
+  convertMovToEsp(inst3,inst4,ml);
+}
+
+void INTERP_KERNEL::AsmX86::convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  if(inst1[0]!='[' || inst1[inst1.length()-1]!=']')
+    throw INTERP_KERNEL::Exception("not recognized convertMovToEsp exp !");
+  std::string inst1bis=inst1.substr(1,inst1.length()-2);
+  const char ASM1[]="esp";
+  const char ML1[3]={0xc7,0x04,0x24};
+  if(inst1bis==ASM1)
+    {//mov dword [esp],0x3ff3c0ca
+      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+      appendAddress(inst2,4,ml);
+      return ;
+    }
+  if(inst1bis.substr(0,3)==ASM1)
+    {
+      if(inst1bis[3]=='+')
+        {//mov dword [esp+4],0x3ff3c0ca
+          const char ML2[3]={0xc7,0x44,0x24};
+          ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+          std::string::size_type pos=inst1bis.find_first_of(']');
+          std::string inst1_1=inst1bis.substr(4,pos-4-1);
+          appendAddress(inst1_1,1,ml);
+          appendAddress(inst2,4,ml);
+          return;
+        }
+      else
+        throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],...");
+    }
+  const char ASM3[]="rsp";
+  const char ML3[3]={0xc7,0x04,0x24};
+  if(inst1bis==ASM3)
+    {//mov dword [rsp],0x3ff3c0ca
+      ml.insert(ml.end(),ML3,ML3+sizeof(ML3));
+      appendAddress(inst2,4,ml);
+      return ;
+    }
+  if(inst1bis.substr(0,3)==ASM3)
+    {
+      if(inst1bis[3]=='+')
+        {//mov dword [rsp+4],0x3ff3c0ca
+          const char ML2[3]={0xc7,0x44,0x24};
+          ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+          std::string::size_type pos=inst1bis.find_first_of(']');
+          std::string inst1_1=inst1bis.substr(4,pos-4-1);
+          appendAddress(inst1_1,1,ml);
+          appendAddress(inst2,4,ml);
+          return;
+        }
+      else
+        throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],...");
+    }
+  throw INTERP_KERNEL::Exception("Not recognized exp : mov");
+}
+
+void INTERP_KERNEL::AsmX86::convertPush(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  std::string::size_type pos=inst.find_first_of(' ');
+  std::string inst2=inst.substr(pos+1);
+  const char ASM1[]="ebp";
+  const char ML1[1]={0x55};
+  if(inst2==ASM1)
+    {//push ebp
+      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+      return ;
+    }
+  const char ASM2[]="ebx";
+  const char ML2[1]={0x53};
+  if(inst2==ASM2)
+    {//push ebx
+      ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+      return ;
+    }
+  const char ASM3[]="rbp";
+  const char ML3[1]={0x55};
+  if(inst2==ASM3)
+    {//push rbp
+      ml.insert(ml.end(),ML3,ML3+sizeof(ML3));
+      return ;
+    }
+  throw INTERP_KERNEL::Exception("Unrecognized push instruction");
+}
+
+void INTERP_KERNEL::AsmX86::convertPop(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  std::string::size_type pos=inst.find_first_of(' ');
+  std::string inst2=inst.substr(pos+1);
+  const char ASM1[]="ebp";
+  const char ML1[1]={0x5d};
+  if(inst2==ASM1)
+    {//push ebp
+      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+      return ;
+    }
+  const char ASM2[]="ebx";
+  const char ML2[1]={0x5b};
+  if(inst2==ASM2)
+    {//push ebx
+      ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+      return ;
+    }
+  throw INTERP_KERNEL::Exception("Unrecognized pop instruction");
+}
+
+void INTERP_KERNEL::AsmX86::convertFld(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  std::string::size_type pos=inst.find_first_of(' ');
+  std::string params=inst.substr(pos+1);
+  std::string params2=params.substr(1,params.length()-2);
+  if(params2.substr(0,3)=="esp")
+    {
+      const char ML1[3]={0xdd,0x04,0x24};
+      if(params2.length()==3)
+        {//fld qword [esp]
+          ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+          return ;
+        }
+      pos=params2.find_first_of('+');
+      if(pos!=std::string::npos)
+        {//fld qword [esp+@]
+          ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+          std::string params3=params2.substr(pos+1);
+          appendAddress(params3,1,ml);
+          return ;
+        }
+      throw INTERP_KERNEL::Exception("Unrecognized fld esp...");
+    }
+  if(params2.substr(0,3)=="ebp")
+    {
+      const char ML2[2]={0xdd,0x45};
+      if(params2.length()==3)
+        {//fld qword [ebp]
+          ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+          ml.push_back(0);
+          return ;
+        }
+      pos=params2.find_first_of('+');
+      if(pos!=std::string::npos)
+        {//fld qword [esp+@]
+          ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+          std::string params3=params2.substr(pos+1);
+          appendAddress(params3,1,ml);
+          return ;
+        }
+      throw INTERP_KERNEL::Exception("Unrecognized fld ebp...");
+    }
+  if(params2.substr(0,3)=="rsp")
+    {
+      const char ML2[3]={0xdd,0x04,0x24};
+      ml.insert(ml.end(),ML2,ML2+sizeof(ML2));// to improve ! no fully managed !
+      return ;
+    }
+  throw INTERP_KERNEL::Exception("Unrecognized fld instruction");
+}
+
+void INTERP_KERNEL::AsmX86::convertFaddp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML1[2]={0xde,0xc1};
+  ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+}
+
+void INTERP_KERNEL::AsmX86::convertFsubp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML1[2]={0xde,0xe9};
+  ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+}
+
+void INTERP_KERNEL::AsmX86::convertFmulp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML1[2]={0xde,0xc9};
+  ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+}
+
+void INTERP_KERNEL::AsmX86::convertFdivp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML1[2]={0xde,0xf9};
+  ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+}
+
+void INTERP_KERNEL::AsmX86::convertFcos(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML[2]={0xd9,0xff};
+  ml.insert(ml.end(),ML,ML+sizeof(ML));
+}
+
+void INTERP_KERNEL::AsmX86::convertFsin(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML[2]={0xd9,0xfe};
+  ml.insert(ml.end(),ML,ML+sizeof(ML));
+}
+
+void INTERP_KERNEL::AsmX86::convertFabs(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML[2]={0xd9,0xe1};
+  ml.insert(ml.end(),ML,ML+sizeof(ML));
+}
+
+void INTERP_KERNEL::AsmX86::convertFchs(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML[2]={0xd9,0xe0};
+  ml.insert(ml.end(),ML,ML+sizeof(ML));
+}
+
+void INTERP_KERNEL::AsmX86::convertFsqrt(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML[2]={0xd9,0xfa};
+  ml.insert(ml.end(),ML,ML+sizeof(ML));
+}
+
+void INTERP_KERNEL::AsmX86::convertSub(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  if(inst.substr(0,4)=="esp,")
+    {
+      const char ML[2]={0x81,0xec};
+      ml.insert(ml.end(),ML,ML+sizeof(ML));
+      std::string inst2=inst.substr(4);
+      appendAddress(inst2,4,ml);
+      return;
+    }
+  if(inst.substr(0,4)=="rsp,")
+    {
+      const char ML[4]={0x48,0x83,0xec,0x08};
+      ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!!
+      return;
+    }
+  throw INTERP_KERNEL::Exception("Not recognized sub instruction.");
+}
+
+void INTERP_KERNEL::AsmX86::convertAdd(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  if(inst.substr(0,4)=="esp,")
+    {
+      const char ML[2]={0x81,0xc4};
+      ml.insert(ml.end(),ML,ML+sizeof(ML));
+      std::string inst2=inst.substr(4);
+      appendAddress(inst2,4,ml);
+      return;
+    }
+  if(inst.substr(0,4)=="rsp,")
+    {
+      const char ML[4]={0x48,0x83,0xc4,0x08};
+      ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!!
+      return;
+    }
+  throw INTERP_KERNEL::Exception("Not recognized add instruction.");
+}
+
+void INTERP_KERNEL::AsmX86::convertRet(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML[1]={0xc3};
+  ml.insert(ml.end(),ML,ML+sizeof(ML));
+}
+
+void INTERP_KERNEL::AsmX86::convertLeave(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ML[1]={0xc9};
+  ml.insert(ml.end(),ML,ML+sizeof(ML));
+}
+
+void INTERP_KERNEL::AsmX86::convertMovsd(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ASM1[]="[rsp],xmm0";
+  const char ML1[5]={0xf2,0x0f,0x11,0x04,0x24};
+  if(inst==ASM1)
+    {
+      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+      return ;
+    }
+  const char ASM2[]="xmm0,[rsp]";
+  const char ML2[5]={0xf2,0x0f,0x10,0x04,0x24};
+  if(inst==ASM2)
+    {
+      ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
+      return ;
+    }
+  std::ostringstream oss; oss << "not recognized instruction movsd : " << inst;
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+void INTERP_KERNEL::AsmX86::convertFst(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  const char ASM1[]="qword [rsp]";
+  const char ML1[3]={0xdd,0x14,0x24};
+  if(inst==ASM1)
+    {
+      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
+      return ;
+    }
+  std::ostringstream oss; oss << "not recognized instruction fst : " << inst;
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+  //tony
+}
+
+
+void INTERP_KERNEL::AsmX86::appendAddress(const std::string& addr, int nbOfByte, std::vector<char>& ml) throw(INTERP_KERNEL::Exception)
+{
+  int i,j;
+  char v;
+  std::istringstream iss(addr);
+  if(addr.length()>2)
+    {
+      if(addr[0]=='0' && addr[1]=='x')
+        iss >> std::hex;
+    }
+  iss >> i;
+  for(int k=0;k<nbOfByte;k++)
+    {
+      j=i&255;
+      v=j;
+      ml.push_back(v);
+      i>>=8;
+    }
+}
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx
new file mode 100644 (file)
index 0000000..11b8733
--- /dev/null
@@ -0,0 +1,67 @@
+//  Copyright (C) 2007-2010  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 __INTERPKERNELASMX86_HXX__
+#define __INTERPKERNELASMX86_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelException.hxx"
+
+#include <vector>
+#include <string>
+
+namespace INTERP_KERNEL
+{
+  class AsmX86
+  {
+  public:
+    std::vector<char> convertIntoMachineLangage(const std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    char *convertMachineLangageInBasic(const std::vector<char>& ml, int& lgth) const;
+  private:
+    void convertOneInstructionInML(const std::string& inst, std::vector<char>& ml) const throw(INTERP_KERNEL::Exception);
+  private:
+    static void convertMov(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertPush(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertPop(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFld(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFaddp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFsubp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFmulp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFdivp(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFcos(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFsin(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFabs(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFchs(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFsqrt(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertSub(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertAdd(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertRet(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertLeave(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertMovsd(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void convertFst(const std::string& inst, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    //
+    static void convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+    static void appendAddress(const std::string& addr, int nbOfByte, std::vector<char>& ml) throw(INTERP_KERNEL::Exception);
+  private:
+    static const int NB_OF_OPS=19;
+    static const char *OPS[NB_OF_OPS];
+  };
+}
+
+#endif
index 5dde84961d5cebec8b5d5743b489a79010340ef6..585fac2f832a1ff3d6c4162e90854de62a304efb 100644 (file)
 
 #include "InterpKernelExprParser.hxx"
 #include "InterpKernelValue.hxx"
+#include "InterpKernelAsmX86.hxx"
 
 #include <cctype>
 #include <sstream>
 #include <vector>
 #include <iterator>
+#include <iostream>
 #include <algorithm>
 
+#ifdef _POSIX_MAPPED_FILES
+#include <sys/mman.h>
+#else
+#ifdef WNT
+#include <windows.h>
+#endif
+#endif
+
 using namespace INTERP_KERNEL;
 
 const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
@@ -120,12 +130,12 @@ LeafExprVar::~LeafExprVar()
 {
 }
 
-ExprParser::ExprParser(const char *expr):_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
+ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
 {
 }
 
 //! For \b NOT null terminated strings coming from FORTRAN.
-ExprParser::ExprParser(const char *expr, int lgth):_is_parsed(false),_leaf(0),_is_parsing_ok(false)
+ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false)
 {
   _expr=buildStringFromFortran(expr,lgth);
 }
@@ -228,7 +238,7 @@ DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Ex
   return ret;
 }
 
-void ExprParser::evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception)
+void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception)
 {
   Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
   ValueDoubleExpr *res=0;
@@ -404,7 +414,7 @@ void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
       if(pos5!=std::string::npos)
         len=pos5-pos6;
       std::string newExp3=newExp2.substr(pos6,len);
-      _sub_expr.push_back(ExprParser(newExp3.c_str()));
+      _sub_expr.push_back(ExprParser(newExp3.c_str(),this));
       pos6=pos5+1;
     }
   _is_parsing_ok=true;
@@ -456,7 +466,7 @@ void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
                   if(*accessor!='*' && *accessor!='/' && *accessor!='^')
                     {
                       isParsingSucceed=true;
-                      _sub_expr.push_back(ExprParser(curPart.c_str()));
+                      _sub_expr.push_back(ExprParser(curPart.c_str(),this));
                       curPart.clear();
                       _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
                     }
@@ -483,7 +493,7 @@ void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
     {
       if(!curPart.empty())
         {
-          _sub_expr.push_back(ExprParser(curPart.c_str()));
+          _sub_expr.push_back(ExprParser(curPart.c_str(),this));
           _is_parsing_ok=true;
         }
       else
@@ -515,7 +525,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
               isParsingSucceed=true;
               if(!curPart.empty())
                 {
-                  _sub_expr.push_back(ExprParser(curPart.c_str()));
+                  _sub_expr.push_back(ExprParser(curPart.c_str(),this));
                   curPart.clear();
                   _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
                 }
@@ -546,7 +556,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
     {
       if(!curPart.empty())
         {
-          _sub_expr.push_back(ExprParser(curPart.c_str()));
+          _sub_expr.push_back(ExprParser(curPart.c_str(),this));
           _is_parsing_ok=true;
         }
       else
@@ -576,7 +586,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
             if(!curPart.empty())
               {
                 isParsingSucceed=true;
-                _sub_expr.push_back(ExprParser(curPart.c_str()));
+                _sub_expr.push_back(ExprParser(curPart.c_str(),this));
                 curPart.clear();
                 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
               }
@@ -606,7 +616,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
     {
       if(!curPart.empty())
         {
-          _sub_expr.push_back(ExprParser(curPart.c_str()));
+          _sub_expr.push_back(ExprParser(curPart.c_str(),this));
           _is_parsing_ok=true;
         }
       else
@@ -691,3 +701,169 @@ void ExprParser::locateError(std::ostream& stringToDisp, const std::string& srcO
 {
   stringToDisp << "Position is " << posOfErr << " of string : \"" <<  srcOfErr << "\"" << std::endl;
 }
+
+char *ExprParser::compileX86() const
+{
+  std::vector<std::string> ass;
+  //need in stack
+  ass.push_back("push ebp");
+  ass.push_back("mov ebp,esp");
+  compileX86LowLev(ass);
+  ass.push_back("pop ebp");
+  ass.push_back("ret");
+  std::cout << std::endl;
+  for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
+    std::cout << "        " << *iter << std::endl;
+  AsmX86 asmb;
+  std::vector<char> output=asmb.convertIntoMachineLangage(ass);
+  for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
+    std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
+  std::cout << std::endl;
+  int lgth;
+  char *lm=asmb.convertMachineLangageInBasic(output,lgth);
+  char *ret=0;
+#ifdef _POSIX_MAPPED_FILES
+  ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0);
+#else
+#ifdef WNT
+  HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL);
+  ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth);
+#endif
+#endif
+  if(ret)
+    std::copy(lm,lm+lgth,ret);
+  delete [] lm;
+  return ret;
+}
+
+char *ExprParser::compileX86_64() const
+{
+  std::vector<std::string> ass;
+  //need in stack
+  ass.push_back("push rbp");
+  ass.push_back("mov rbp,rsp");
+  compileX86_64LowLev(ass);
+  ass.push_back("sub rsp,8");
+  ass.push_back("fst qword [rsp]");
+  ass.push_back("movsd xmm0,[rsp]");
+  ass.push_back("add rsp,8");
+  ass.push_back("leave");
+  ass.push_back("ret");
+  std::cout << std::endl;
+  for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
+    std::cout << "        " << *iter << std::endl;
+  AsmX86 asmb;
+  std::vector<char> output=asmb.convertIntoMachineLangage(ass);
+  for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
+    std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
+  std::cout << std::endl;
+  int lgth;
+  char *lm=asmb.convertMachineLangageInBasic(output,lgth);
+  char *ret=0;
+#ifdef _POSIX_MAPPED_FILES
+  ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0);
+#else
+#ifdef WNT
+  HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL);
+  ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth);
+#endif
+#endif
+  if(ret)
+    std::copy(lm,lm+lgth,ret);
+  delete [] lm;
+  return ret;
+}
+
+void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const
+{
+  if(_leaf)
+    _leaf->compileX86(ass);
+  else
+    {
+      for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+        (*iter).compileX86LowLev(ass);
+      for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
+        (*iter2)->operateX86(ass);
+    }
+}
+
+void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
+{
+  if(_leaf)
+    _leaf->compileX86_64(ass);
+  else
+    {
+      for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+        (*iter).compileX86_64LowLev(ass);
+      for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
+        (*iter2)->operateX86(ass);
+    }
+}
+
+void LeafExprVal::compileX86(std::vector<std::string>& ass) const
+{
+  ass.push_back("sub esp,8");
+  int *b=(int *)&_value,*c=(int *)&_value;
+  c++;
+  std::ostringstream oss;
+  oss << std::hex;
+  oss << "mov dword [esp+4],0x" << *c;
+  ass.push_back(oss.str());
+  oss.str("");
+  oss << "mov dword [esp],0x" << *b;
+  ass.push_back(oss.str());
+  ass.push_back("fld qword [esp]");
+  ass.push_back("add esp,8");
+}
+
+void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
+{
+  ass.push_back("sub rsp,8");
+  int *b=(int *)&_value,*c=(int *)&_value;
+  c++;
+  std::ostringstream oss;
+  oss << std::hex;
+  oss << "mov dword [rsp+4],0x" << *c;
+  ass.push_back(oss.str());
+  oss.str("");
+  oss << "mov dword [rsp],0x" << *b;
+  ass.push_back(oss.str());
+  ass.push_back("fld qword [rsp]");
+  ass.push_back("add rsp,8");
+}
+
+void LeafExprVar::compileX86(std::vector<std::string>& ass) const
+{
+  ass.push_back("fld qword [ebp+8]");
+}
+
+void LeafExprVar::compileX86_64(std::vector<std::string>& ass) const
+{
+  ass.push_back("sub rsp,8");
+  ass.push_back("movsd [rsp],xmm0");
+  ass.push_back("fld qword [rsp]");
+  ass.push_back("add rsp,8");
+}
+
+int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const
+{
+  if(asker)
+    {
+      int sz=_father->getStackSizeToPlayX86(this);
+      int i=0;
+      for(std::list<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
+        {
+          const ExprParser& obj=(*iter);
+          const ExprParser *pt=&obj;
+          if(pt==asker)
+            return sz-i;
+        }
+      throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !");
+    }
+  else
+    {
+      if(!_father)
+        return MAX_X86_FP_ST;
+      return _father->getStackSizeToPlayX86(this);
+    }
+}
index 032f7070afe8175b9d569eaab8aabd332d3e7835..7ff8babb57eb193d2983fb4540041f375a78f3c7 100644 (file)
@@ -39,6 +39,8 @@ namespace INTERP_KERNEL
   public:
     virtual ~LeafExpr();
     virtual void fillValue(Value *val) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual void compileX86(std::vector<std::string>& ass) const = 0;
+    virtual void compileX86_64(std::vector<std::string>& ass) const = 0;
     static LeafExpr *buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception);
   };
 
@@ -47,6 +49,8 @@ namespace INTERP_KERNEL
   public:
     LeafExprVal(double value);
     ~LeafExprVal();
+    void compileX86(std::vector<std::string>& ass) const;
+    void compileX86_64(std::vector<std::string>& ass) const;
     void fillValue(Value *val) const throw(INTERP_KERNEL::Exception);
   private:
     double _value;
@@ -57,6 +61,8 @@ namespace INTERP_KERNEL
   public:
     LeafExprVar(const std::string& var);
     ~LeafExprVar();
+    void compileX86(std::vector<std::string>& ass) const;
+    void compileX86_64(std::vector<std::string>& ass) const;
     void fillValue(Value *val) const throw(INTERP_KERNEL::Exception);
     std::string getVar() const { return _var_name; }
     void prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception);
@@ -72,18 +78,25 @@ namespace INTERP_KERNEL
   class INTERPKERNELEXPREVAL_EXPORT ExprParser
   {
   public:
-    ExprParser(const char *expr);
-    ExprParser(const char *expr, int lgth);
+    ExprParser(const char *expr, ExprParser *father=0);
+    ExprParser(const char *expr, int lgth, ExprParser *father=0);
     ~ExprParser();
     void parse() throw(INTERP_KERNEL::Exception);
     bool isParsingSuccessfull() const { return _is_parsing_ok; }
     double evaluate() const throw(INTERP_KERNEL::Exception);
     DecompositionInUnitBase evaluateUnit() const throw(INTERP_KERNEL::Exception);
     void prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception);
-    void evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception);
+    void evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception);
     void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception);
     void getSetOfVars(std::set<std::string>& vars) const;
     void getTrueSetOfVars(std::set<std::string>& vars) const;
+    //
+    char *compileX86() const;
+    char *compileX86_64() const;
+    void compileX86LowLev(std::vector<std::string>& ass) const;
+    void compileX86_64LowLev(std::vector<std::string>& ass) const;
+    int getStackSizeToPlayX86(const ExprParser *asker) const;
+    //
     static std::string buildStringFromFortran(const char *expr, int lgth);
     static std::string deleteWhiteSpaces(const std::string& expr);
   private:
@@ -102,6 +115,7 @@ namespace INTERP_KERNEL
     static std::size_t findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket);
     static void locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr);
   private:
+    ExprParser *_father;
     bool _is_parsed;
     LeafExpr *_leaf;
     bool _is_parsing_ok;
@@ -109,6 +123,7 @@ namespace INTERP_KERNEL
     std::list<ExprParser> _sub_expr;
     std::list<Function *> _func_btw_sub_expr;
   private:
+    static const int MAX_X86_FP_ST=8;
     static const char WHITE_SPACES[];
     static const char EXPR_PARSE_ERR_MSG[];
   };
index 6e8316526a41e0dd4c949b00d6ee04604f21cfbf..dd16329f6d43afacacdb496ecb4b973be26458b2 100644 (file)
@@ -140,6 +140,10 @@ void IdentityFunction::operate(std::vector<Value *>& stack) const throw(INTERP_K
 {
 }
 
+void IdentityFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+}
+
 const char *IdentityFunction::getRepr() const
 {
   return REPR;
@@ -163,6 +167,10 @@ void PositiveFunction::operate(std::vector<Value *>& stack) const throw(INTERP_K
 {
 }
 
+void PositiveFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+}
+
 const char *PositiveFunction::getRepr() const
 {
   return REPR;
@@ -183,6 +191,11 @@ void NegateFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KER
   val->negate();
 }
 
+void NegateFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fchs");
+}
+
 const char *NegateFunction::getRepr() const
 {
   return REPR;
@@ -203,6 +216,11 @@ void CosFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val->cos();
 }
 
+void CosFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fcos");
+}
+
 const char *CosFunction::getRepr() const
 {
   return REPR;
@@ -223,6 +241,11 @@ void SinFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val->sin();
 }
 
+void SinFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fsin");
+}
+
 const char *SinFunction::getRepr() const
 {
   return REPR;
@@ -243,6 +266,11 @@ void TanFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val->tan();
 }
 
+void TanFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
 const char *TanFunction::getRepr() const
 {
   return REPR;
@@ -263,6 +291,11 @@ void SqrtFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNE
   val->sqrt();
 }
 
+void SqrtFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fsqrt");
+}
+
 const char *SqrtFunction::getRepr() const
 {
   return REPR;
@@ -283,6 +316,11 @@ void AbsFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val->abs();
 }
 
+void AbsFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fabs");
+}
+
 const char *AbsFunction::getRepr() const
 {
   return REPR;
@@ -298,7 +336,12 @@ void ExpFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   Value *val=stack.back();
   val->exp();
 }
+
+void ExpFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
 const char *ExpFunction::getRepr() const
 {
   return REPR;
@@ -319,6 +362,11 @@ void LnFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL:
   val->ln();
 }
 
+void LnFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
 const char *LnFunction::getRepr() const
 {
   return REPR;
@@ -358,6 +406,11 @@ void PlusFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNE
   val2=val3;
 }
 
+void PlusFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("faddp st1");
+}
+
 const char *PlusFunction::getRepr() const
 {
   return REPR;
@@ -392,6 +445,11 @@ void MinusFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERN
   val2=val3;
 }
 
+void MinusFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fsubp st1");
+}
+
 const char *MinusFunction::getRepr() const
 {
   return REPR;
@@ -417,6 +475,11 @@ void MultFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNE
   val2=val3;
 }
 
+void MultFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fmulp st1");
+}
+
 const char *MultFunction::getRepr() const
 {
   return REPR;
@@ -451,6 +514,11 @@ void DivFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val2=val3;
 }
 
+void DivFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  asmb.push_back("fdivp st1");
+}
+
 const char *DivFunction::getRepr() const
 {
   return REPR;
@@ -485,6 +553,11 @@ void PowFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val2=val3;
 }
 
+void PowFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
 const char *PowFunction::getRepr() const
 {
   return REPR;
@@ -523,6 +596,11 @@ void MaxFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val2=val3;
 }
 
+void MaxFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
 const char *MaxFunction::getRepr() const
 {
   return REPR;
@@ -557,6 +635,11 @@ void MinFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL
   val2=val3;
 }
 
+void MinFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
 const char *MinFunction::getRepr() const
 {
   return REPR;
index 548a09f1edf68afc050d0bb825150c60029c438d..160e15ba92031c0d880a4d62d5cb074277114485 100644 (file)
@@ -46,6 +46,7 @@ namespace INTERP_KERNEL
     virtual ~Function();
     virtual int getNbInputParams() const = 0;
     virtual void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception) = 0;
     virtual const char *getRepr() const = 0;
     virtual bool isACall() const = 0;
   };
@@ -61,6 +62,7 @@ namespace INTERP_KERNEL
   public:
     ~IdentityFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -72,6 +74,7 @@ namespace INTERP_KERNEL
   public:
     ~PositiveFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -83,6 +86,7 @@ namespace INTERP_KERNEL
   public:
     ~NegateFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -94,6 +98,7 @@ namespace INTERP_KERNEL
   public:
     ~CosFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -105,6 +110,7 @@ namespace INTERP_KERNEL
   public:
     ~SinFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -116,6 +122,7 @@ namespace INTERP_KERNEL
   public:
     ~TanFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -127,6 +134,7 @@ namespace INTERP_KERNEL
   public:
     ~SqrtFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -138,6 +146,7 @@ namespace INTERP_KERNEL
   public:
     ~AbsFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -149,6 +158,7 @@ namespace INTERP_KERNEL
   public:
     ~ExpFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -160,6 +170,7 @@ namespace INTERP_KERNEL
   public:
     ~LnFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -177,6 +188,7 @@ namespace INTERP_KERNEL
   public:
     ~PlusFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -188,6 +200,7 @@ namespace INTERP_KERNEL
   public:
     ~MinusFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -199,6 +212,7 @@ namespace INTERP_KERNEL
   public:
     ~MultFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -210,6 +224,7 @@ namespace INTERP_KERNEL
   public:
     ~DivFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -221,6 +236,7 @@ namespace INTERP_KERNEL
   public:
     ~PowFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -232,6 +248,7 @@ namespace INTERP_KERNEL
   public:
     ~MaxFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
@@ -243,6 +260,7 @@ namespace INTERP_KERNEL
   public:
     ~MinFunction();
     void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
     const char *getRepr() const;
     bool isACall() const;
   public:
index 4a67afba5125fb69a5d8a1c4a2afa9ab1d092fca..28f5e91242b8e6b8e6c57b9bd1b1f6ead2e99f94 100644 (file)
@@ -30,8 +30,8 @@ INTERPKERNELEXPREVALDefines.hxx         \
 InterpKernelExprParser.hxx              \
 InterpKernelFunction.hxx                \
 InterpKernelUnit.hxx                    \
-InterpKernelValue.hxx
-
+InterpKernelValue.hxx                   \
+InterpKernelAsmX86.hxx
 
 EXTRA_DIST +=                          \
 INTERPKERNELEXPREVALDefines.hxx         \
@@ -44,7 +44,8 @@ dist_libinterpkernelexpreval_la_SOURCES = \
        InterpKernelExprParser.cxx        \
        InterpKernelFunction.cxx          \
        InterpKernelUnit.cxx              \
-       InterpKernelValue.cxx
+       InterpKernelValue.cxx             \
+       InterpKernelAsmX86.cxx
 
 libinterpkernelexpreval_la_CPPFLAGS=-I$(srcdir)/../Bases
 
diff --git a/src/INTERP_KERNEL/GenMathFormulae.hxx b/src/INTERP_KERNEL/GenMathFormulae.hxx
new file mode 100644 (file)
index 0000000..42ce4f4
--- /dev/null
@@ -0,0 +1,95 @@
+//  Copyright (C) 2007-2010  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 __GENMATHFORMULAE_HXX__
+#define __GENMATHFORMULAE_HXX__
+
+#include "InterpKernelException.hxx"
+
+#include <cmath>
+
+namespace INTERP_KERNEL
+{
+  /*!
+   * This method computes eigenvalues of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here:
+   * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz,
+   * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz
+   * This method returns the 3 eigenvalues in 'eigenVals'.
+   */
+  void computeEigenValues6(const double *matrix, double *eigenVals)
+  {
+    double tr=(matrix[0]+matrix[1]+matrix[2])/3.;
+    double K[6]={matrix[0]-tr,matrix[1]-tr,matrix[2]-tr,matrix[3],matrix[4],matrix[5]};
+    double q=(K[0]*K[1]*K[2]+2.*K[4]*K[5]*K[3]-K[0]*K[4]*K[4]-K[2]*K[3]*K[3]-K[1]*K[5]*K[5])/2.;
+    double p=K[0]*K[0]+K[1]*K[1]+K[2]*K[2]+2*(K[3]*K[3]+K[4]*K[4]+K[5]*K[5]);
+    p/=6.;
+    double sqp=sqrt(p);
+    double tmp=p*sqp;
+    double phi;
+    if(fabs(q)<=fabs(tmp))
+      phi=1./3.*acos(q/tmp);
+    else
+      phi=0.;
+    if(phi<0.)
+      phi+=M_PI/3.;
+    eigenVals[0]=tr+2.*sqp*cos(phi);
+    eigenVals[1]=tr-sqp*(cos(phi)+sqrt(3.)*sin(phi));
+    eigenVals[2]=tr-sqp*(cos(phi)-sqrt(3.)*sin(phi));
+  }
+  
+  /*!
+   * This method computes one eigenvector of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here:
+   * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz,
+   * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz
+   * This method returns the eigenvector of the corresponding eigenvalue in 'eigenVal'. The returned eigenValue is normalized.
+   */
+  void computeEigenVectorForEigenValue6(const double *matrix, double eigenVal, double eps, double *eigenVector) throw(INTERP_KERNEL::Exception)
+  {
+    //if(fabs(eigenVal)>eps)
+      {
+        const double m9[9]={matrix[0]-eigenVal,matrix[3],matrix[5],matrix[3],matrix[1]-eigenVal,matrix[4],matrix[5],matrix[4],matrix[2]-eigenVal};
+        for(int i=0;i<3;i++)
+          {
+            double w[9]={m9[0+3*i],m9[1+3*i],m9[2+3*i],m9[0+(3*(i+1))%6],m9[1+(3*(i+1))%6],m9[2+(3*(i+1))%6],1.,1.,1.};
+            double det=w[0]*w[4]*w[8]+w[1]*w[5]*w[6]+w[2]*w[3]*w[7]-w[0]*w[5]*w[7]-w[1]*w[3]*w[8]-w[2]*w[4]*w[6];
+            if(fabs(det)>eps)
+              {
+                eigenVector[0]=(w[1]*w[5]-w[4]*w[2])/det;
+                eigenVector[1]=(w[2]*w[3]-w[0]*w[5])/det;
+                eigenVector[2]=(w[0]*w[4]-w[1]*w[3])/det;
+                double norm=sqrt(eigenVector[0]*eigenVector[0]+eigenVector[1]*eigenVector[1]+eigenVector[2]*eigenVector[2]);
+                eigenVector[0]/=norm;
+                eigenVector[1]/=norm;
+                eigenVector[2]/=norm;
+                return;
+              }
+          }
+      }
+      //else
+      {
+        eigenVector[0]=0.;
+        eigenVector[1]=0.;
+        eigenVector[2]=0.;
+        return;
+      }
+      //throw INTERP_KERNEL::Exception("computeEigenVector : Do not succed in finding eigen vector !");
+  }
+}
+
+#endif
diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx
new file mode 100644 (file)
index 0000000..271771e
--- /dev/null
@@ -0,0 +1,209 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "InterpKernelMeshQuality.hxx"
+
+#include <cmath>
+#include <limits>
+#include <numeric>
+#include <algorithm>
+
+double INTERP_KERNEL::quadSkew(const double *coo)
+{
+  double pa0[3]={
+    coo[3]+coo[6]-coo[0]-coo[9],
+    coo[4]+coo[7]-coo[1]-coo[10],
+    coo[5]+coo[8]-coo[2]-coo[11]
+  };
+  double pa1[3]={
+    coo[6]+coo[9]-coo[0]-coo[3],
+    coo[7]+coo[10]-coo[1]-coo[4],
+    coo[8]+coo[11]-coo[2]-coo[5],
+  };
+  double l0=sqrt(pa0[0]*pa0[0]+pa0[1]*pa0[1]+pa0[2]*pa0[2]);
+  double l1=sqrt(pa1[0]*pa1[0]+pa1[1]*pa1[1]+pa1[2]*pa1[2]);
+  if(l0<1.e-15)
+    return 0.;
+  if(l1<1.e-15)
+    return 0.;
+  pa0[0]/=l0; pa0[1]/=l0; pa0[2]/=l0;
+  pa1[0]/=l1; pa1[1]/=l1; pa1[2]/=l1;
+  return pa0[0]*pa1[0]+pa0[1]*pa1[1]+pa0[2]*pa1[2];
+}
+
+double INTERP_KERNEL::quadEdgeRatio(const double *coo)
+{
+  double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]);
+  double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]);
+  double c2=(coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8]);
+  double d2=(coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11]);
+  double mab=a2<b2?a2:b2;
+  double Mab=a2<b2?b2:a2;
+  double mcd=c2<d2?c2:d2;
+  double Mcd=c2<d2?d2:c2;
+  double m2=mab<mcd?mab:mcd;
+  double M2=Mab>Mcd?Mab:Mcd;
+  if(m2>1.e-15)
+    return sqrt(M2/m2);
+  else
+    return std::numeric_limits<double>::max();
+}
+
+double INTERP_KERNEL::quadAspectRatio(const double *coo)
+{
+  double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]));
+  double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]));
+  double c=sqrt((coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8]));
+  double d=sqrt((coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11]));
+  double ma=a>b?a:b;
+  double mb=c>d?c:d;
+  double hm=ma>mb?ma:mb;
+  double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]),
+                (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]),
+                (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])};
+  double cd[3]={(coo[10]-coo[7])*(coo[2]-coo[11])-(coo[1]-coo[10])*(coo[11]-coo[8]),
+                (coo[11]-coo[8])*(coo[0]-coo[9])-(coo[9]-coo[6])*(coo[2]-coo[11]),
+                (coo[9]-coo[6])*(coo[1]-coo[10])-(coo[10]-coo[7])*(coo[0]-coo[9])};
+  double e=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2])+sqrt(cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]);
+  if(d>1e-15)
+    return 0.5*(a+b+c+d)*hm/e;
+  else
+    return std::numeric_limits<double>::max();
+}
+
+double INTERP_KERNEL::quadWarp(const double *coo)
+{
+  double e0[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]};
+  double e1[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]};
+  double e2[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]};
+  double e3[3]={coo[0]-coo[9],coo[1]-coo[10],coo[2]-coo[11]};
+  
+  double n0[3]={e3[1]*e0[2]-e3[2]*e0[1],e3[2]*e0[0]-e3[0]*e0[2],e3[0]*e0[1]-e3[1]*e0[0]};
+  double n1[3]={e0[1]*e1[2]-e0[2]*e1[1],e0[2]*e1[0]-e0[0]*e1[2],e0[0]*e1[1]-e0[1]*e1[0]};
+  double n2[3]={e1[1]*e2[2]-e1[2]*e2[1],e1[2]*e2[0]-e1[0]*e2[2],e1[0]*e2[1]-e1[1]*e2[0]};
+  double n3[3]={e2[1]*e3[2]-e2[2]*e3[1],e2[2]*e3[0]-e2[0]*e3[2],e2[0]*e3[1]-e2[1]*e3[0]};
+
+  double l0=sqrt(n0[0]*n0[0]+n0[1]*n0[1]+n0[2]*n0[2]);
+  double l1=sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]);
+  double l2=sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]);
+  double l3=sqrt(n3[0]*n3[0]+n3[1]*n3[1]+n3[2]*n3[2]);
+
+  if(l0<1.e-15 || l1<1.e-15 || l2<1.e-15 || l3<1e-15)
+    return std::numeric_limits<double>::min();
+
+  double warp=std::min(n0[0]/l0*n2[0]/l2+n0[1]/l0*n2[1]/l2+n0[2]/l0*n2[2]/l2,n1[0]/l1*n3[0]/l3+n1[1]/l1*n3[1]/l3+n1[2]/l1*n3[2]/l3);
+  return warp*warp*warp;
+}
+
+double INTERP_KERNEL::triEdgeRatio(const double *coo)
+{
+  double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]);
+  double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]);
+  double c2=(coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8]);
+  double mab=a2<b2?a2:b2;
+  double Mab=a2<b2?b2:a2;
+  double m2=c2>mab?mab:c2;
+  double M2=c2>Mab?c2:Mab;
+  if(m2>1.e-15)
+    return sqrt(M2/m2);
+  else
+    return std::numeric_limits<double>::max();
+}
+
+double INTERP_KERNEL::triAspectRatio(const double *coo)
+{
+  double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]));
+  double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]));
+  double c=sqrt((coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8]));
+  double hm=a>b?a:b;
+  hm=hm>c?hm:c;
+
+  double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]),
+                (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]),
+                (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])};
+  double d=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]);
+  static const double normalizeCoeff=sqrt(3.)/6.;
+  if(d>1.e-15) 
+    return normalizeCoeff*hm*(a+b+c)/d;
+  else
+    return std::numeric_limits<double>::max();
+}
+
+double INTERP_KERNEL::tetraEdgeRatio(const double *coo)
+{
+  double a[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]};
+  double b[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]};
+  double c[3]={coo[0]-coo[6],coo[1]-coo[7],coo[2]-coo[8]};
+  double d[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]};
+  double e[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]};
+  double f[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]};
+  
+  double l2[6]=
+    {a[0]*a[0]+a[1]*a[1]+a[2]*a[2],
+     b[0]*b[0]+b[1]*b[1]+b[2]*b[2],
+     c[0]*c[0]+c[1]*c[1]+c[2]*c[2],
+     d[0]*d[0]+d[1]*d[1]+d[2]*d[2],
+     e[0]*e[0]+e[1]*e[1]+e[2]*e[2],
+     f[0]*f[0]+f[1]*f[1]+f[2]*f[2]};
+
+  double M2=*std::max_element(l2,l2+6);
+  double m2=*std::min_element(l2,l2+6);
+  if(m2>1e-15)
+    return sqrt(M2/m2);
+  else
+    return std::numeric_limits<double>::max();
+}
+
+double INTERP_KERNEL::tetraAspectRatio(const double *coo)
+{
+  static const double normalizeCoeff=sqrt(6.)/12.;
+  double ab[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]};
+  double ac[3]={coo[6]-coo[0],coo[7]-coo[1],coo[8]-coo[2]};
+  double ad[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]};
+  double detTet=(ab[0]*(ac[1]*ad[2]-ac[2]*ad[1]))+(ab[1]*(ac[2]*ad[0]-ac[0]*ad[2]))+(ab[2]*(ac[0]*ad[1]-ac[1]*ad[0]));
+  //if(detTet<1.e-15)
+  //  return std::numeric_limits<double>::max();
+  double bc[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]};
+  double bd[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]};
+  double cd[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]};
+
+  double ab2=ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2];
+  double bc2=bc[0]*bc[0]+bc[1]*bc[1]+bc[2]*bc[2];
+  double ac2=ac[0]*ac[0]+ac[1]*ac[1]+ac[2]*ac[2];
+  double ad2=ad[0]*ad[0]+ad[1]*ad[1]+ad[2]*ad[2];
+  double bd2=bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2];
+  double cd2=cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2];
+
+  double A=ab2>bc2?ab2:bc2;
+  double B=ac2>ad2?ac2:ad2;
+  double C=bd2>cd2?bd2:cd2;
+  double D=A>B?A:B;
+  double hm=D>C?sqrt(D):sqrt(C);
+
+  bd[0]=ab[1]*bc[2]-ab[2]*bc[1]; bd[1]=ab[2]*bc[0]-ab[0]*bc[2]; bd[2]=ab[0]*bc[1]-ab[1]*bc[0];
+  A=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]);
+  bd[0]=ab[1]*ad[2]-ab[2]*ad[1]; bd[1]=ab[2]*ad[0]-ab[0]*ad[2]; bd[2]=ab[0]*ad[1]-ab[1]*ad[0];
+  B=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]);
+  bd[0]=ac[1]*ad[2]-ac[2]*ad[1]; bd[1]=ac[2]*ad[0]-ac[0]*ad[2]; bd[2]=ac[0]*ad[1]-ac[1]*ad[0];
+  C=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]);
+  bd[0]=bc[1]*cd[2]-bc[2]*cd[1]; bd[1]=bc[2]*cd[0]-bc[0]*cd[2]; bd[2]=bc[0]*cd[1]-bc[1]*cd[0];
+  D=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]);
+  return normalizeCoeff*hm*(A+B+C+D)/fabs(detTet);
+}
diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx
new file mode 100644 (file)
index 0000000..2f11bb4
--- /dev/null
@@ -0,0 +1,37 @@
+//  Copyright (C) 2007-2010  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 __INTERPKERNELMESHQUALITY_HXX_
+#define __INTERPKERNELMESHQUALITY_HXX__
+
+#include "INTERPKERNELDefines.hxx"
+
+namespace INTERP_KERNEL
+{
+  INTERPKERNEL_EXPORT double quadSkew(const double *coo);
+  INTERPKERNEL_EXPORT double quadEdgeRatio(const double *coo);
+  INTERPKERNEL_EXPORT double quadAspectRatio(const double *coo);
+  INTERPKERNEL_EXPORT double quadWarp(const double *coo);
+  INTERPKERNEL_EXPORT double triEdgeRatio(const double *coo);
+  INTERPKERNEL_EXPORT double triAspectRatio(const double *coo);
+  INTERPKERNEL_EXPORT double tetraEdgeRatio(const double *coo);
+  INTERPKERNEL_EXPORT double tetraAspectRatio(const double *coo);
+}
+
+#endif
index 6eb93e9aa25a2a2deaed0bb83f388eb8c23c75d4..6069bf22df01a275b65c29fffa1e23a666d04cbb 100644 (file)
@@ -121,7 +121,7 @@ bool INTERP_KERNEL::InterpolationOptions::setOptionInt(const std::string& key, i
       return false;
 }
 
-bool INTERP_KERNEL::InterpolationOptions::setOptionString(const std::string& key, std::string& value)
+bool INTERP_KERNEL::InterpolationOptions::setOptionString(const std::string& key, const std::string& value)
 {
   if(key==INTERSEC_TYPE_STR) 
     {
index 49068a01a9c5c55fc1b9df1615b49b9be5270228..667e320b69da80251b82cd285820daca285d952d 100644 (file)
@@ -118,10 +118,10 @@ namespace INTERP_KERNEL
                                  bool measure_abs,
                                  std::string splitting_policy,
                                  bool P1P0_bary_method );
-    void copyOptions(InterpolationOptions & other) { *this = other; }
+    void copyOptions(const InterpolationOptions & other) { *this = other; }
     bool setOptionDouble(const std::string& key, double value);
     bool setOptionInt(const std::string& key, int value);
-    bool setOptionString(const std::string& key, std::string& value);
+    bool setOptionString(const std::string& key, const std::string& value);
   private:
     static const double DFT_MEDIAN_PLANE;
     static const double DFT_SURF3D_ADJ_EPS;
index 2d5ca00df45742707df0a320556ab740089b97e3..e96f3fc1bd555779db0e97473e6a1c30a01bf76a 100644 (file)
@@ -221,13 +221,13 @@ namespace INTERP_KERNEL
     // make upper triangular matrix (forward elimination)
 
     int iR[nbRow];// = { 0, 1, 2 };
-    for ( int i = 0; i < nbRow; ++i ) iR[i] = i;
+    for ( int i = 0; i < (int) nbRow; ++i ) iR[i] = i;
 
-    for ( int i = 0; i < nbRow-1; ++i ) // nullify nbRow-1 rows
+    for ( int i = 0; i < (int)(nbRow-1); ++i ) // nullify nbRow-1 rows
       {
         // swap rows to have max value of i-th column in i-th row
         double max = std::fabs( M[ iR[i] ][i] );
-        for ( int r = i+1; r < nbRow; ++r ) {
+        for ( int r = i+1; r < (int)nbRow; ++r ) {
           double m = std::fabs( M[ iR[r] ][i] );
           if ( m > max ) {
             max = m;
@@ -240,7 +240,7 @@ namespace INTERP_KERNEL
         }
         // make 0 below M[i][i] (actually we do not modify i-th column)
         double* tUpRow = M[ iR[i] ];
-        for ( int r = i+1; r < nbRow; ++r ) {
+        for ( int r = i+1; r < (int)nbRow; ++r ) {
           double* mRow = M[ iR[r] ];
           double coef = mRow[ i ] / tUpRow[ i ];
           for ( int c = i+1; c < nbCol; ++c )
index a125070120d5435e9922194a96ad1ba293a2150e..e3dfc56cb54882326f7ee567215cff6dc71bd622 100644 (file)
@@ -43,6 +43,7 @@ PointLocator2DIntersector.hxx           \
 PointLocator2DIntersector.txx           \
 INTERPKERNELDefines.hxx                        \
 InterpKernelMatrix.hxx                 \
+InterpKernelMeshQuality.hxx             \
 Interpolation.hxx                      \
 Interpolation.txx                       \
 Interpolation2D.hxx                    \
@@ -141,6 +142,7 @@ VTKNormalizedUnstructuredMesh.hxx   \
 VTKNormalizedUnstructuredMesh.txx      \
 VectorUtils.hxx                         \
 VolSurfFormulae.hxx                     \
+GenMathFormulae.hxx                     \
 VolSurfUser.hxx                         \
 VolSurfUser.txx                         \
 CurveIntersector.hxx                    \
@@ -177,15 +179,17 @@ VolSurfUser.txx
 # Libraries targets
 
 dist_libinterpkernel_la_SOURCES = \
-       TransformedTriangle.cxx\
-       TransformedTriangleIntersect.cxx\
-       TransformedTriangleMath.cxx\
+       TransformedTriangle.cxx \
+       TransformedTriangleIntersect.cxx \
+       TransformedTriangleMath.cxx \
        BoundingBox.cxx \
-       TetraAffineTransform.cxx\
-       CellModel.cxx\
+       TranslationRotationMatrix.cxx \
+       TetraAffineTransform.cxx \
+       CellModel.cxx \
        UnitTetraIntersectionBary.cxx \
        InterpolationOptions.cxx \
-       DirectedBoundingBox.cxx
+       DirectedBoundingBox.cxx \
+       InterpKernelMeshQuality.cxx
 
 libinterpkernel_la_CPPFLAGS=-I$(srcdir)/Geometric2D -I$(srcdir)/Bases
 
diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.cxx b/src/INTERP_KERNEL/TranslationRotationMatrix.cxx
new file mode 100644 (file)
index 0000000..0e31b21
--- /dev/null
@@ -0,0 +1,22 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "TranslationRotationMatrix.hxx"
+
+const double INTERP_KERNEL::TranslationRotationMatrix::EPS=1e-12;
index 8258cf18e28412661b58be0c875b4af34740a31b..e1108573b41ba71fca8e0bd0ae0e37119ca5c936 100644 (file)
 #ifndef __TRANSLATIONROTATIONMATRIX_HXX__
 #define __TRANSLATIONROTATIONMATRIX_HXX__
 
+#include "INTERPKERNELDefines.hxx"
+
 #include <cmath>
 
 namespace INTERP_KERNEL
 {
-  class TranslationRotationMatrix
+  class INTERPKERNEL_EXPORT TranslationRotationMatrix
   {
 
   public:
@@ -125,7 +127,6 @@ namespace INTERP_KERNEL
     double _rotation_coeffs[ROT_SIZE];
     double _translation_coeffs[TRANSL_SIZE];
   };
-  const double TranslationRotationMatrix::EPS=1e-12;
 }
 
 #endif
index e62956e2935ec6a032981ecffd8583e21705a89f..e9bdd855d6d4387b0e9a9309e3332eee70a71a85 100644 (file)
@@ -20,7 +20,9 @@
 #ifndef __VOLSURFFORMULAE_HXX__
 #define __VOLSURFFORMULAE_HXX__
 
-#include <math.h>
+#include "InterpolationUtils.hxx"
+
+#include <cmath>
 
 namespace INTERP_KERNEL
 {
@@ -31,6 +33,19 @@ namespace INTERP_KERNEL
                                       int spaceDim);
 
 
+  inline double calculateLgthForSeg2(const double *p1, const double *p2, int spaceDim)
+  {
+    if(spaceDim==1)
+      return *p2-*p1;
+    else
+      {
+        double ret=0;
+        for(int i=0;i<spaceDim;i++)
+          ret+=(p2[i]-p1[i])*(p2[i]-p1[i]);
+        return sqrt(ret);
+      }
+  }
+
   // ===========================
   // Calculate Area for triangle
   // ===========================
@@ -398,6 +413,125 @@ namespace INTERP_KERNEL
     return -volume/3.;
   }
 
+  /*!
+   * Calculate Volume for Generic Polyedron, even not convex one, WARNING !!! The polyedron's faces must be correctly ordered.
+   * 2nd API avoiding to create double** arrays. The returned value could be negative if polyhedrons faces are not oriented with normal outside of the
+   * polyhedron
+   */
+  template<class ConnType, NumberingPolicy numPol>
+  inline double calculateVolumeForPolyh2(const ConnType *connec, int lgth, const double *coords)
+  {
+    int nbOfFaces=std::count(connec,connec+lgth,-1)+1;
+    double volume=0.;
+    const int *work=connec;
+    for(int iFace=0;iFace<nbOfFaces;iFace++)
+      {
+        const int *work2=std::find(work+1,connec+lgth,-1);
+        int nbOfNodesOfCurFace=std::distance(work,work2);
+        double areaVector[3]={0.,0.,0.};
+        for(int ptId=0;ptId<nbOfNodesOfCurFace;ptId++)
+          {
+            const double *pti=coords+3*OTT<ConnType,numPol>::coo2C(work[ptId]);
+            const double *pti1=coords+3*OTT<ConnType,numPol>::coo2C(work[(ptId+1)%nbOfNodesOfCurFace]);
+            areaVector[0]+=pti[1]*pti1[2]-pti[2]*pti1[1];
+            areaVector[1]+=pti[2]*pti1[0]-pti[0]*pti1[2];
+            areaVector[2]+=pti[0]*pti1[1]-pti[1]*pti1[0];
+          }
+        const double *pt=coords+3*work[0];
+        volume+=pt[0]*areaVector[0]+pt[1]*areaVector[1]+pt[2]*areaVector[2];
+        work=work2+1;
+      }
+    return volume/6.;
+  }
+
+  /*!
+   * This method returns the area oriented vector of a polygon. This method is useful for normal computation without
+   * any troubles if several edges are colinears.
+   * @param res must be of size at least 3 to store the result.
+   */
+  template<class ConnType, NumberingPolicy numPol>
+  inline void areaVectorOfPolygon(const ConnType *connec, int lgth, const double *coords, double *res)
+  {
+    res[0]=0.; res[1]=0.; res[2]=0.;
+    for(int ptId=0;ptId<lgth;ptId++)
+      {
+        const double *pti=coords+3*OTT<ConnType,numPol>::coo2C(connec[ptId]);
+        const double *pti1=coords+3*OTT<ConnType,numPol>::coo2C(connec[(ptId+1)%lgth]);
+        res[0]+=pti[1]*pti1[2]-pti[2]*pti1[1];
+        res[1]+=pti[2]*pti1[0]-pti[0]*pti1[2];
+        res[2]+=pti[0]*pti1[1]-pti[1]*pti1[0];
+      }
+  }
+
+  inline double integrationOverA3DLine(double u1, double v1, double u2, double v2, double A, double B, double C)
+  {
+    return (u1-u2)*(6.*C*C*(v1+v2)+B*B*(v1*v1*v1+v1*v1*v2+v1*v2*v2+v2*v2*v2)+A*A*(2.*u1*u2*(v1+v2)+u1*u1*(3.*v1+v2)+u2*u2*(v1+3.*v2))+ 
+                    4.*C*(A*(2*u1*v1+u2*v1+u1*v2+2.*u2*v2)+B*(v1*v1+v1*v2+v2*v2))+A*B*(u1*(3.*v1*v1+2.*v1*v2+v2*v2)+u2*(v1*v1+2.*v1*v2+3.*v2*v2)))/24.;
+  }
+
+  template<class ConnType, NumberingPolicy numPol>
+  inline void barycenterOfPolyhedron(const ConnType *connec, int lgth, const double *coords, double *res)
+  {
+    int nbOfFaces=std::count(connec,connec+lgth,-1)+1;
+    res[0]=0.; res[1]=0.; res[2]=0.;
+    const int *work=connec;
+    for(int i=0;i<nbOfFaces;i++)
+      {
+        const int *work2=std::find(work+1,connec+lgth,-1);
+        int nbOfNodesOfCurFace=std::distance(work,work2);
+        // projection to (u,v) of each faces of polyh to compute integral(x^2/2) on each faces.
+        double normal[3];
+        areaVectorOfPolygon<ConnType,numPol>(work,nbOfNodesOfCurFace,coords,normal);
+        double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
+        normal[0]/=normOfNormal; normal[1]/=normOfNormal; normal[2]/=normOfNormal;
+        double u[2]={normal[1],-normal[0]};
+        double s=sqrt(u[0]*u[0]+u[1]*u[1]);
+        double c=normal[2];
+        if(fabs(s)>1e-12)
+          {
+            u[0]/=std::abs(s); u[1]/=std::abs(s);
+          }
+        else
+          { u[0]=1.; u[1]=0.; }
+        //C : high in plane of polyhedron face : always constant
+        double w=normal[0]*coords[3*OTT<ConnType,numPol>::coo2C(work[0])]+
+          normal[1]*coords[3*OTT<ConnType,numPol>::coo2C(work[0])+1]+
+          normal[2]*coords[3*OTT<ConnType,numPol>::coo2C(work[0])+2];
+        // A,B,D,F,G,H,L,M,N coeffs of rotation matrix defined by (u,c,s)
+        double A=u[0]*u[0]*(1-c)+c;
+        double B=u[0]*u[1]*(1-c);
+        double D=u[1]*s;
+        double F=B;
+        double G=u[1]*u[1]*(1-c)+c;
+        double H=-u[0]*s;
+        double L=-u[1]*s;
+        double M=u[0]*s;
+        double N=c;
+        double CX=-w*D;
+        double CY=-w*H;
+        double CZ=-w*N;
+        for(int j=0;j<nbOfNodesOfCurFace;j++)
+          {
+            const double *p1=coords+3*OTT<ConnType,numPol>::coo2C(work[j]);
+            const double *p2=coords+3*OTT<ConnType,numPol>::coo2C(work[(j+1)%nbOfNodesOfCurFace]);
+            double u1=A*p1[0]+B*p1[1]+D*p1[2];
+            double u2=A*p2[0]+B*p2[1]+D*p2[2];
+            double v1=F*p1[0]+G*p1[1]+H*p1[2];
+            double v2=F*p2[0]+G*p2[1]+H*p2[2];
+            //
+            double gx=integrationOverA3DLine(u1,v1,u2,v2,A,B,CX);
+            double gy=integrationOverA3DLine(u1,v1,u2,v2,F,G,CY);
+            double gz=integrationOverA3DLine(u1,v1,u2,v2,L,M,CZ);
+            res[0]+=gx*normal[0];
+            res[1]+=gy*normal[1];
+            res[2]+=gz*normal[2];
+          }
+        work=work2+1;
+      }
+    double vol=calculateVolumeForPolyh2<ConnType,numPol>(connec,lgth,coords);
+    res[0]/=vol; res[1]/=vol; res[2]/=vol;
+  }
+
   // ============================================================================================================================================
   // Calculate Volume for NON Generic Polyedron. Only polydrons with bary included in pts is supported by this method. Result is always positive.
   // ============================================================================================================================================
@@ -503,6 +637,56 @@ namespace INTERP_KERNEL
         bary[i]=temp/nbPts;
       }
   }
+  
+  template<class ConnType, NumberingPolicy numPol>
+  inline void computePolygonBarycenter2D(const ConnType *connec, int lgth, const double *coords, double *res)
+  {
+    double area=0.;
+    res[0]=0.; res[1]=0.;
+    for(int i=0;i<lgth;i++)
+      {
+        double cp=coords[2*OTT<ConnType,numPol>::coo2C(connec[i])]*coords[2*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])+1]-
+          coords[2*OTT<ConnType,numPol>::coo2C(connec[i])+1]*coords[2*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])];
+        area+=cp;
+        res[0]+=cp*(coords[2*OTT<ConnType,numPol>::coo2C(connec[i])]+coords[2*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])]);
+        res[1]+=cp*(coords[2*OTT<ConnType,numPol>::coo2C(connec[i])+1]+coords[2*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])+1]);
+      }
+    res[0]/=3.*area;
+    res[1]/=3.*area;
+  }
+
+  template<class ConnType, NumberingPolicy numPol>
+  inline void computePolygonBarycenter3D(const ConnType *connec, int lgth, const double *coords, double *res)
+  {
+    double area[3];
+    areaVectorOfPolygon<ConnType,numPol>(connec,lgth,coords,area);
+    double norm=sqrt(area[0]*area[0]+area[1]*area[1]+area[2]*area[2]);
+    area[0]/=norm; area[1]/=norm; area[2]/=norm;
+    res[0]=0.; res[1]=0.; res[2]=0.;
+    for(int i=1;i<lgth-1;i++)
+      {
+        double v[3];
+        double tmpArea[3];
+        v[0]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[0])]+
+              coords[3*OTT<ConnType,numPol>::coo2C(connec[i])]+
+              coords[3*OTT<ConnType,numPol>::coo2C(connec[i+1])])/3.;
+        v[1]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+1]+
+              coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+1]+
+              coords[3*OTT<ConnType,numPol>::coo2C(connec[i+1])+1])/3.;
+        v[2]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+2]+
+              coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+2]+
+              coords[3*OTT<ConnType,numPol>::coo2C(connec[i+1])+2])/3.;
+        ConnType tmpConn[3]={connec[0],connec[i],connec[i+1]};
+        areaVectorOfPolygon<ConnType,numPol>(tmpConn,3,coords,tmpArea);
+        double norm2=sqrt(tmpArea[0]*tmpArea[0]+tmpArea[1]*tmpArea[1]+tmpArea[2]*tmpArea[2]);
+        if(norm2>1e-12)
+          {
+            tmpArea[0]/=norm2; tmpArea[1]/=norm2; tmpArea[2]/=norm2;
+            double signOfArea=area[0]*tmpArea[0]+area[1]*tmpArea[1]+area[2]*tmpArea[2];
+            res[0]+=signOfArea*norm2*v[0]/norm; res[1]+=signOfArea*norm2*v[1]/norm; res[2]+=signOfArea*norm2*v[2]/norm;
+          }
+      }   
+  }
 }
 
 #endif
index a0eafd221234138e38bdb347320309cea880dc61..99083c319dff1a4b62be84b8034529cc28a5f610 100644 (file)
@@ -29,6 +29,12 @@ namespace INTERP_KERNEL
 
   template<class ConnType, NumberingPolicy numPolConn>
   double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim);
+
+  template<class ConnType, NumberingPolicy numPolConn, int SPACEDIM>
+  void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res);
+
+  template<class ConnType, NumberingPolicy numPolConn>
+  void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res);
 }
 
 #endif
index d6fcd11bf1974298f8569ec3a8a6c55ca2f68119..f14ba420adbd925273c868cd9b7536ee10e4962c 100644 (file)
@@ -23,6 +23,8 @@
 #include "VolSurfFormulae.hxx"
 #include "InterpolationUtils.hxx"
 
+#include <algorithm>
+
 namespace INTERP_KERNEL
 {
   template<class ConnType, NumberingPolicy numPol, int SPACEDIM>
@@ -30,6 +32,13 @@ namespace INTERP_KERNEL
   {
     switch(type)
       {
+      case INTERP_KERNEL::NORM_SEG2 :
+      case INTERP_KERNEL::NORM_SEG3 :
+        {
+          int N1 = OTT<ConnType,numPol>::coo2C(connec[0]);
+          int N2 = OTT<ConnType,numPol>::coo2C(connec[1]);
+          return INTERP_KERNEL::calculateLgthForSeg2(coords+(SPACEDIM*N1),coords+(SPACEDIM*N2),SPACEDIM);
+        }
       case INTERP_KERNEL::NORM_TRI3 :
       case INTERP_KERNEL::NORM_TRI6 :
         {
@@ -64,7 +73,7 @@ namespace INTERP_KERNEL
         {          
           const double **pts=new const double *[lgth];
           for(int inod=0;inod<lgth;inod++)
-            pts[inod] = coords+3*OTT<ConnType,numPol>::coo2C(connec[inod]);
+            pts[inod] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[inod]);
           double val=INTERP_KERNEL::calculateAreaForPolyg(pts,lgth,SPACEDIM);
           delete [] pts;
           return val;
@@ -146,11 +155,11 @@ namespace INTERP_KERNEL
             
       case INTERP_KERNEL::NORM_POLYHED :
         {
-          throw INTERP_KERNEL::Exception("Polyedra Not yet implemented !");
+          return calculateVolumeForPolyh2<ConnType,numPol>(connec,lgth,coords);
         }
         break;
       default:
-        throw INTERP_KERNEL::Exception("Not recognized cell type to get Area/Volume on it !");
+        throw INTERP_KERNEL::Exception("Not recognized cell type to get Length/Area/Volume on it !");
       }
   }
 
@@ -161,7 +170,127 @@ namespace INTERP_KERNEL
       return computeVolSurfOfCell<ConnType,numPolConn,3>(type,connec,lgth,coords);
     if(spaceDim==2)
       return computeVolSurfOfCell<ConnType,numPolConn,2>(type,connec,lgth,coords);
-    throw INTERP_KERNEL::Exception("Invalid spaceDim specified : must be 2 or 3");
+    if(spaceDim==1)
+      return computeVolSurfOfCell<ConnType,numPolConn,1>(type,connec,lgth,coords);
+    throw INTERP_KERNEL::Exception("Invalid spaceDim specified : must be 1, 2 or 3");
+  }
+
+  template<class ConnType, NumberingPolicy numPol,int SPACEDIM>
+  void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res)
+  {
+    switch(type)
+      {
+      case NORM_SEG3:
+      case NORM_SEG2:
+        {
+          std::copy(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]),
+                    coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]+1),res);
+          std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]),res,std::plus<double>());
+          std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies<double>(),0.5));
+          break;
+        }
+      case NORM_TRI3:
+      case NORM_TRI6:
+        {
+          std::copy(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]),
+                    coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]+1),res);
+          std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]),res,std::plus<double>());
+          std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2]),res,std::plus<double>());
+          std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies<double>(),1./3.));
+          break;
+        }
+      case NORM_QUAD4:
+      case NORM_POLYGON:
+        {
+          if(SPACEDIM==2)
+            computePolygonBarycenter2D<ConnType,numPol>(connec,lgth,coords,res);
+          else if(SPACEDIM==3)
+            computePolygonBarycenter3D<ConnType,numPol>(connec,lgth,coords,res);
+          else
+            throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !");
+          break;
+        }
+      case NORM_QUAD8:
+        {
+          if(SPACEDIM==2)
+            computePolygonBarycenter2D<ConnType,numPol>(connec,lgth/2,coords,res);
+          else if(SPACEDIM==3)
+            computePolygonBarycenter3D<ConnType,numPol>(connec,lgth/2,coords,res);
+          else
+            throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !");
+          break;
+        }
+      case NORM_TETRA4:
+        {
+          res[0]=coords[3*OTT<ConnType,numPol>::coo2C(connec[0])]; 
+          res[1]=coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+1];
+          res[2]=coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+2];
+          res[0]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[1])]; 
+          res[1]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[1])+1];
+          res[2]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[1])+2];
+          res[0]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[2])]; 
+          res[1]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[2])+1];
+          res[2]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[2])+2];
+          res[0]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[3])]; 
+          res[1]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[3])+1];
+          res[2]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[3])+2];
+          res[0]/=4.; res[1]/=4.; res[2]/=4.;
+          break;
+        }
+      case NORM_PYRA5:
+        {
+          double tmp[3];
+          computePolygonBarycenter3D<ConnType,numPol>(connec,lgth-1,coords,tmp);
+          res[0]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[4])]+3.*tmp[0])/4.;
+          res[1]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[4])+1]+3.*tmp[1])/4.;
+          res[2]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[4])+2]+3.*tmp[2])/4.;
+          break;
+        }
+      case NORM_HEXA8:
+        {
+          const int conn[29]={
+            OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[3]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[5]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[4]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[7]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[6]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[1]),
+            };
+          barycenterOfPolyhedron<ConnType,numPol>(conn,29,coords,res);
+          break;
+        }
+      case NORM_PENTA6:
+        {
+          const int conn[22]={
+            OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[2]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[4]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[3]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[5]),-1,
+            OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[4])
+          };
+          barycenterOfPolyhedron<ConnType,numPol>(conn,22,coords,res);
+          break;
+        }
+      case NORM_POLYHED:
+        {
+          barycenterOfPolyhedron<ConnType,numPol>(connec,lgth,coords,res);
+          break;
+        }
+      default:
+        throw INTERP_KERNEL::Exception("Not recognized cell type to get Barycenter on it !");
+      }
+  }
+
+  template<class ConnType, NumberingPolicy numPolConn>
+  void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res)
+  {
+    if(spaceDim==3)
+      return computeBarycenter<ConnType,numPolConn,3>(type,connec,lgth,coords,res);
+    if(spaceDim==2)
+      return computeBarycenter<ConnType,numPolConn,2>(type,connec,lgth,coords,res);
+    if(spaceDim==1)
+      return computeBarycenter<ConnType,numPolConn,1>(type,connec,lgth,coords,res);
+    throw INTERP_KERNEL::Exception("Invalid spaceDim specified for compute barycenter : must be 1, 2 or 3");
   }
 }
 
index 947f8fa5c9a49f89fd99700b45848f592163e7b9..b62b39e351e6267cfad1f30ed5049b79c12ca03e 100644 (file)
@@ -228,13 +228,13 @@ void ExprEvalInterpTest::testInterpreter2()
   double res1;
   std::vector<std::string> vars; vars.push_back("x"); vars.push_back("y");
   expr1.prepareExprEvaluation(vars);
-  expr1.evaluateExpr(1,&res1,xyValue);
+  expr1.evaluateExpr(1,xyValue,&res1);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res1,1e-13);
   xyValue[0]=-2.;
-  CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,&res1,xyValue),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,xyValue,&res1),INTERP_KERNEL::Exception);
   double res2[2];
   xyValue[0]=1.;
-  expr1.evaluateExpr(2,res2,xyValue);
+  expr1.evaluateExpr(2,xyValue,res2);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[0],1e-13);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[1],1e-13);
   INTERP_KERNEL::ExprParser expr2("3.5*tan(2.3*x)*IVec+(cos(1.2+y/x)*JVec)");
@@ -245,13 +245,13 @@ void ExprEvalInterpTest::testInterpreter2()
   expected.insert("x"); expected.insert("y"); expected.insert("IVec"); expected.insert("JVec");
   CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin()));
   expr2.prepareExprEvaluation(vars);
-  expr2.evaluateExpr(2,res2,xyValue);
+  expr2.evaluateExpr(2,xyValue,res2);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.9172477460694637,res2[0],1e-14);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49026082134069943,res2[1],1e-14);
   INTERP_KERNEL::ExprParser expr3("3.5*u+u^2.4+2.");
   expr3.parse();
   expr3.prepareExprEvaluationVec();
-  expr3.evaluateExpr(2,res2,xyValue);
+  expr3.evaluateExpr(2,xyValue,res2);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(6.5,res2[0],1e-14);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(26.466610165238237,res2[1],1e-14);
   INTERP_KERNEL::ExprParser expr4("3.5*v+u^2.4+2.");
diff --git a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx
new file mode 100644 (file)
index 0000000..9a30b7d
--- /dev/null
@@ -0,0 +1,50 @@
+//  Copyright (C) 2007-2010  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 __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__
+
+#include "MEDCouplingRefCountObject.hxx"
+
+namespace ParaMEDMEM
+{
+  template<class T>
+  class MEDCouplingAutoRefCountObjectPtr
+  {
+  public:
+    MEDCouplingAutoRefCountObjectPtr(const MEDCouplingAutoRefCountObjectPtr& other):_ptr(0) { referPtr(other._ptr); }
+    MEDCouplingAutoRefCountObjectPtr(T *ptr=0):_ptr(ptr) { }
+    ~MEDCouplingAutoRefCountObjectPtr() { destroyPtr(); }
+    MEDCouplingAutoRefCountObjectPtr &operator=(const MEDCouplingAutoRefCountObjectPtr& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; }
+    MEDCouplingAutoRefCountObjectPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+    T *operator->() { return _ptr ; }
+    const T *operator->() const { return _ptr; }
+    T& operator*() { return *_ptr; }
+    const T& operator*() const { return *_ptr; }
+    operator T *() { return _ptr; }
+    operator const T *() const { return _ptr; }
+  private:
+    void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); }
+    void destroyPtr() { if(_ptr) _ptr->decrRef(); }
+  private:
+    T *_ptr;
+  };
+}
+
+#endif
index 8829b19de25764788ccde8ecb4f179700c8ae794..e7d9bcd3a8647fab580555b9ddf870a0c0b91f7f 100644 (file)
@@ -18,6 +18,7 @@
 //
 
 #include "MEDCouplingCMesh.hxx"
+#include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingMemArray.hxx"
 #include "MEDCouplingFieldDouble.hxx"
 
@@ -31,6 +32,31 @@ MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0)
 {
 }
 
+MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy):MEDCouplingMesh(other)
+{
+  if(deepCpy)
+    {
+      if(other._x_array)
+        _x_array=_x_array->deepCopy();
+      if(other._y_array)
+        _y_array=_y_array->deepCopy();
+      if(other._z_array)
+        _z_array=_z_array->deepCopy();
+    }
+  else
+    {
+      _x_array=other._x_array;
+      if(_x_array)
+        _x_array->incrRef();
+      _y_array=other._y_array;
+      if(_y_array)
+        _y_array->incrRef();
+      _z_array=other._z_array;
+      if(_z_array)
+        _z_array->incrRef();
+    }
+}
+
 MEDCouplingCMesh::~MEDCouplingCMesh()
 {
   if(_x_array)
@@ -46,6 +72,16 @@ MEDCouplingCMesh *MEDCouplingCMesh::New()
   return new MEDCouplingCMesh;
 }
 
+MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const
+{
+  return clone(true);
+}
+
+MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const
+{
+  return new MEDCouplingCMesh(*this,recDeepCpy);
+}
+
 void MEDCouplingCMesh::updateTime()
 {
   if(_x_array)
@@ -56,41 +92,119 @@ void MEDCouplingCMesh::updateTime()
     updateTimeWith(*_z_array);
 }
 
+/*!
+ * This method copyies all tiny strings from other (name and components name).
+ * @throw if other and this have not same mesh type.
+ */
+void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+{ 
+  const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
+  MEDCouplingMesh::copyTinyStringsFrom(other);
+  if(_x_array && otherC->_x_array)
+    _x_array->copyStringInfoFrom(*otherC->_x_array);
+  if(_y_array && otherC->_y_array)
+    _y_array->copyStringInfoFrom(*otherC->_y_array);
+  if(_z_array && otherC->_z_array)
+    _z_array->copyStringInfoFrom(*otherC->_z_array);
+}
+
 bool MEDCouplingCMesh::isEqual(const MEDCouplingMesh *other, double prec) const
 {
   const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
   if(!otherC)
     return false;
+  if(!MEDCouplingMesh::isEqual(other,prec))
+    return false;
+  const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+  const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
+  for(int i=0;i<3;i++)
+    {
+      if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
+        return false;
+      if(thisArr[i])
+        if(!thisArr[i]->isEqual(*otherArr[i],prec))
+          return false;
+    }
   return true;
 }
 
+bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
+{
+  const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
+  if(!otherC)
+    return false;
+  const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+  const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
+  for(int i=0;i<3;i++)
+    {
+      if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
+        return false;
+      if(thisArr[i])
+        if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec))
+          return false;
+    }
+  return true;
+}
+
+void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                            DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                       DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
 void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
 {
   const char msg0[]="Invalid ";
   const char msg1[]=" array ! Must contain more than 1 element.";
+  const char msg2[]=" array ! Must be with only one component.";
   if(_x_array)
-    if(_x_array->getNbOfElems()<2)
-      {
-        std::ostringstream os; os << msg0 << 'X' << msg1;
-        throw INTERP_KERNEL::Exception(os.str().c_str());
-      }
+    {
+      if(_x_array->getNbOfElems()<2)
+        {
+          std::ostringstream os; os << msg0 << 'X' << msg1;
+          throw INTERP_KERNEL::Exception(os.str().c_str());
+        }
+      if(_x_array->getNumberOfComponents()!=1)
+        {
+          std::ostringstream os; os << msg0 << 'X' << msg2;
+          throw INTERP_KERNEL::Exception(os.str().c_str());
+        }
+    }
   if(_y_array)
-    if(_y_array->getNbOfElems()<2)
-      {
-        std::ostringstream os; os << msg0 << 'Y' << msg1;
-        throw INTERP_KERNEL::Exception(os.str().c_str());
-      }
+    {
+      if(_y_array->getNbOfElems()<2)
+        {
+          std::ostringstream os; os << msg0 << 'Y' << msg1;
+          throw INTERP_KERNEL::Exception(os.str().c_str());
+        }
+      if(_y_array->getNumberOfComponents()!=1)
+        {
+          std::ostringstream os; os << msg0 << 'Y' << msg2;
+          throw INTERP_KERNEL::Exception(os.str().c_str());
+        }
+      
+    }
   if(_z_array)
-    if(_z_array->getNbOfElems()<2)
-      {
-        std::ostringstream os; os << msg0 << 'Z' << msg1;
-        throw INTERP_KERNEL::Exception(os.str().c_str());
-      }
-}
-
-bool MEDCouplingCMesh::isStructured() const
-{
-  return true;
+    {
+      if(_z_array->getNbOfElems()<2)
+        {
+          std::ostringstream os; os << msg0 << 'Z' << msg1;
+          throw INTERP_KERNEL::Exception(os.str().c_str());
+        }
+      if(_z_array->getNumberOfComponents()!=1)
+        {
+          std::ostringstream os; os << msg0 << 'Z' << msg2;
+          throw INTERP_KERNEL::Exception(os.str().c_str());
+        }
+    }
 }
 
 int MEDCouplingCMesh::getNumberOfCells() const
@@ -123,7 +237,7 @@ void MEDCouplingCMesh::getSplitCellValues(int *res) const
   for(int l=0;l<spaceDim;l++)
     {
       int val=1;
-      for(int p=l;p<spaceDim-1;p++)
+      for(int p=0;p<spaceDim-l-1;p++)
         val*=getCoordsAt(p)->getNbOfElems()-1;
       res[spaceDim-l-1]=val;
     }
@@ -135,7 +249,7 @@ void MEDCouplingCMesh::getSplitNodeValues(int *res) const
   for(int l=0;l<spaceDim;l++)
     {
       int val=1;
-      for(int p=l;p<spaceDim-1;p++)
+      for(int p=0;p<spaceDim-l-1;p++)
         val*=getCoordsAt(p)->getNbOfElems();
       res[spaceDim-l-1]=val;
     }
@@ -204,6 +318,27 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) co
     }
 }
 
+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
 {
   //not implemented yet
@@ -211,7 +346,43 @@ void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) cons
 
 void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
 {
-  //not implemented yet
+  int tmp[3];
+  int spaceDim=getSpaceDimension();
+  getSplitNodeValues(tmp);
+  const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
+  int tmp2[3];
+  getPosFromId(nodeId,spaceDim,tmp,tmp2);
+  for(int j=0;j<spaceDim;j++)
+    if(tabs[j])
+      coo.push_back(tabs[j]->getConstPointer()[tmp2[j]]);
+}
+
+std::string MEDCouplingCMesh::simpleRepr() const
+{
+  std::ostringstream ret;
+  ret << "Cartesian mesh with name : \"" << getName() << "\"\n";
+  ret << "Mesh and SpaceDimension dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
+  if(_x_array)
+    {
+      ret << "X Array :\n";
+      _x_array->reprZipWithoutNameStream(ret);
+    }
+  if(_y_array)
+    {
+      ret << "Y Array :\n";
+      _y_array->reprZipWithoutNameStream(ret);
+    }
+  if(_z_array)
+    {
+      ret << "Z Array :\n";
+      _z_array->reprZipWithoutNameStream(ret);
+    }
+  return ret.str();
+}
+
+std::string MEDCouplingCMesh::advancedRepr() const
+{
+  return simpleRepr();
 }
 
 DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception)
@@ -229,6 +400,22 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL:
     }
 }
 
+void MEDCouplingCMesh::setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception)
+{
+  DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
+  if(i<0 || i>2)
+    throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
+  if(arr!=*(thisArr[i]))
+    {
+      if(*(thisArr[i]))
+        (*(thisArr[i]))->decrRef();
+      (*(thisArr[i]))=arr;
+      if(*(thisArr[i]))
+        (*(thisArr[i]))->incrRef();
+      declareAsNew();
+    }
+}
+
 void MEDCouplingCMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coordsY, DataArrayDouble *coordsZ)
 {
   if(_x_array)
@@ -249,15 +436,94 @@ void MEDCouplingCMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coor
   declareAsNew();
 }
 
+MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const
+{
+  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;
+}
+
 void MEDCouplingCMesh::getBoundingBox(double *bbox) const
 {
-  //not implemented yet !
+  int dim=getSpaceDimension();
+  int j=0;
+  for (int idim=0; idim<dim; idim++)
+    {
+      DataArrayDouble *c=getCoordsAt(idim);
+      if(c)
+        {
+          const double *coords=c->getConstPointer();
+          int nb=c->getNbOfElems();
+          bbox[2*j]=coords[0];
+          bbox[2*j+1]=coords[nb-1];
+          j++;
+        }
+    }
 }
 
 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
 {
-  //not implemented yet !
-  return 0;
+  std::string name="MeasureOfMesh_";
+  name+=getName();
+  int nbelem=getNumberOfCells();
+  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS);
+  field->setName(name.c_str());
+  DataArrayDouble* array=DataArrayDouble::New();
+  array->alloc(nbelem,1);
+  double *area_vol=array->getPointer();
+  field->setArray(array) ;
+  array->decrRef();
+  field->setMesh(const_cast<MEDCouplingCMesh *>(this));
+  int tmp[3];
+  getSplitCellValues(tmp);
+  int dim=getSpaceDimension();
+  const double **thisArr=new const double *[dim];
+  const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array};
+  for(int i=0;i<dim;i++)
+    thisArr[i]=thisArr2[i]->getConstPointer();
+  for(int icell=0;icell<nbelem;icell++)
+    {
+      int tmp2[3];
+      getPosFromId(icell,dim,tmp,tmp2);
+      area_vol[icell]=1.;
+      for(int i=0;i<dim;i++)
+        area_vol[icell]*=thisArr[i][tmp2[i]+1]-thisArr[i][tmp2[i]];
+    }
+  delete [] thisArr;
+  return field;
 }
 
 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) const
@@ -285,8 +551,25 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const
 
 int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
 {
-  //not implemented yet !
-  return -1;
+  int dim=getSpaceDimension();
+  int ret=0;
+  int coeff=1;
+  for(int i=0;i<dim;i++)
+    {
+      const double *d=getCoordsAt(i)->getConstPointer();
+      int nbOfNodes=getCoordsAt(i)->getNbOfElems();
+      double ref=pos[i];
+      const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater<double>(),ref));
+      int w2=std::distance(d,w);
+      if(w2<nbOfNodes && w2!=0)
+        {
+          ret+=coeff*(w2-1);
+          coeff*=nbOfNodes-1;
+        }
+      else
+        return -1;
+    }
+  return ret;
 }
 
 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
@@ -307,6 +590,24 @@ void MEDCouplingCMesh::translate(const double *vector)
                    _z_array->getPointer(),std::bind2nd(std::plus<double>(),vector[2]));
 }
 
+void MEDCouplingCMesh::scale(const double *point, double factor)
+{
+  for(int i=0;i<3;i++)
+    {
+      DataArrayDouble *c=getCoordsAt(i);
+      if(c)
+        {
+          double *coords=c->getPointer();
+          int lgth=c->getNbOfElems();
+          std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus<double>(),point[i]));
+          std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies<double>(),factor));
+          std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus<double>(),point[i]));
+          c->declareAsNew();
+        }
+    }
+  updateTime();
+}
+
 MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
 {
   //not implemented yet !
@@ -364,3 +665,166 @@ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const
     }
   return ret;
 }
+
+void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  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;
+          double 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<int>& tinyInfo, std::vector<std::string>& littleStrings) const
+{
+  tinyInfo.clear();
+  littleStrings.clear();
+  littleStrings.push_back(getName());
+  const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+  for(int i=0;i<3;i++)
+    {
+      int val=-1;
+      std::string st;
+      if(thisArr[i])
+        {
+          val=thisArr[i]->getNumberOfTuples();
+          st=thisArr[i]->getInfoOnComponent(0);
+        }
+      tinyInfo.push_back(val);
+      littleStrings.push_back(st);
+    }
+}
+
+void MEDCouplingCMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
+{
+  a1->alloc(0,1);
+  int sum=0;
+  for(int i=0;i<3;i++)
+    if(tinyInfo[i]!=-1)
+      sum+=tinyInfo[i];
+  a2->alloc(sum,1);
+}
+
+void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
+{
+  a1=DataArrayInt::New();
+  a1->alloc(0,1);
+  const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+  int sz=0;
+  for(int i=0;i<3;i++)
+    {
+      if(thisArr[i])
+        sz+=thisArr[i]->getNumberOfTuples();
+    }
+  a2=DataArrayDouble::New();
+  a2->alloc(sz,1);
+  double *a2Ptr=a2->getPointer();
+  for(int i=0;i<3;i++)
+    if(thisArr[i])
+      a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr);
+}
+
+void MEDCouplingCMesh::unserialization(const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                                       const std::vector<std::string>& littleStrings)
+{
+  setName(littleStrings[0].c_str());
+  DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
+  const double *data=a2->getConstPointer();
+  for(int i=0;i<3;i++)
+    {
+      if(tinyInfo[i]!=-1)
+        {
+          (*(thisArr[i]))=DataArrayDouble::New();
+          (*(thisArr[i]))->alloc(tinyInfo[i],1);
+          (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+1].c_str());
+          std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
+          data+=tinyInfo[i];
+        }
+    }
+}
+
index a8f0b53011c320a2bf11ea0fa3dea1332f07ec84..434091f41738bb73b540c4900b618ff19da8555c 100644 (file)
 namespace ParaMEDMEM
 {
   class DataArrayDouble;
+  class MEDCouplingUMesh;
 
   class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingMesh
   {
   public:
     static MEDCouplingCMesh *New();
+    MEDCouplingMesh *deepCpy() const;
+    MEDCouplingCMesh *clone(bool recDeepCpy) const;
     void updateTime();
     MEDCouplingMeshType getType() const { return CARTESIAN; }
+    void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDCouplingMesh *other, double prec) const;
+    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);
-    bool isStructured() const;
     int getNumberOfCells() const;
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
@@ -44,13 +52,20 @@ namespace ParaMEDMEM
     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;
+    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;
+    std::string simpleRepr() const;
+    std::string advancedRepr() const;
     DataArrayDouble *getCoordsAt(int i) const throw(INTERP_KERNEL::Exception);
+    void setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception);
     void setCoords(DataArrayDouble *coordsX,
                    DataArrayDouble *coordsY=0,
                    DataArrayDouble *coordsZ=0);
     // tools
+    MEDCouplingUMesh *buildUnstructured() const;
+    MEDCouplingMesh *buildPart(const int *start, const int *end) const;
+    MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
     void getBoundingBox(double *bbox) const;
     MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
     MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
@@ -58,14 +73,26 @@ namespace ParaMEDMEM
     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) 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;
+    //serialisation-unserialization
+    void getTinySerializationInformation(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<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                         const std::vector<std::string>& littleStrings);
   private:
     MEDCouplingCMesh();
+    MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy);
     ~MEDCouplingCMesh();
   private:
     DataArrayDouble *_x_array;
index 3233ac549d6844ce51933712f460f8b771f4d377..d01e29149ca463794d55311bf5d4bddbfe5e3102 100644 (file)
@@ -47,25 +47,77 @@ MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *me
   return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId);
 }
 
+/*!
+ * This constructor is here only for unserialisation process.
+ * This constructor is normally completely useless for end user.
+ */
+MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New()
+{
+  return new MEDCouplingExtrudedMesh;
+}
+
 MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const
 {
   return EXTRUDED;
 }
 
+/*!
+ * This method copyies all tiny strings from other (name and components name).
+ * @throw if other and this have not same mesh type.
+ */
+void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !");
+  MEDCouplingMesh::copyTinyStringsFrom(other);
+  _mesh2D->copyTinyStringsFrom(otherC->_mesh2D);
+  _mesh1D->copyTinyStringsFrom(otherC->_mesh1D);
+}
+
 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception)
 try:_mesh2D(mesh2D),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId)
 {
   if(_mesh2D!=0)
     _mesh2D->incrRef();
   computeExtrusion(mesh3D);
+  setName(mesh3D->getName());
 }
-catch(INTERP_KERNEL::Exception&)
+catch(INTERP_KERNEL::Exception& e)
   {
+    if(_mesh2D)
+      _mesh2D->decrRef();
+    if(_mesh1D)
+      _mesh1D->decrRef();
+    if(_mesh3D_ids)
+      _mesh3D_ids->decrRef();
+    throw e;
   }
 
-bool MEDCouplingExtrudedMesh::isStructured() const
+MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1)
+{
+}
+
+MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCpy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id)
 {
-  return false;
+  if(deepCpy)
+    {
+      _mesh2D=other._mesh2D->clone(true);
+      _mesh1D=other._mesh1D->clone(true);
+      _mesh3D_ids=other._mesh3D_ids->deepCopy();
+    }
+  else
+    {
+      _mesh2D=other._mesh2D;
+      if(_mesh2D)
+        _mesh2D->incrRef();
+      _mesh1D=other._mesh1D;
+      if(_mesh1D)
+        _mesh1D->incrRef();
+      _mesh3D_ids=other._mesh3D_ids;
+      if(_mesh3D_ids)
+        _mesh3D_ids->incrRef();
+    }
 }
 
 int MEDCouplingExtrudedMesh::getNumberOfCells() const
@@ -88,14 +140,88 @@ int MEDCouplingExtrudedMesh::getMeshDimension() const
   return 3;
 }
 
+MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const
+{
+  return clone(true);
+}
+
+MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const
+{
+  return new MEDCouplingExtrudedMesh(*this,recDeepCpy);
+}
+
+bool MEDCouplingExtrudedMesh::isEqual(const MEDCouplingMesh *other, double prec) const
+{
+  const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
+  if(!otherC)
+    return false;
+  if(!MEDCouplingMesh::isEqual(other,prec))
+    return false;
+  if(!_mesh2D->isEqual(otherC->_mesh2D,prec))
+    return false;
+  if(!_mesh1D->isEqual(otherC->_mesh1D,prec))
+    return false;
+  if(!_mesh3D_ids->isEqual(*otherC->_mesh3D_ids))
+    return false;
+  if(_cell_2D_id!=otherC->_cell_2D_id)
+    return false;
+  return true;
+}
+
+bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
+{
+  const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
+  if(!otherC)
+    return false;
+  if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec))
+    return false;
+  if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec))
+    return false;
+  if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids))
+    return false;
+  if(_cell_2D_id!=otherC->_cell_2D_id)
+    return false;
+  return true;
+}
+
+void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                   DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !");
+}
+
+void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                              DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !");
+}
+
 INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const
 {
+  const int *ids=_mesh3D_ids->getConstPointer();
+  int nbOf3DCells=_mesh3D_ids->getNumberOfTuples();
+  const int *where=std::find(ids,ids+nbOf3DCells,cellId);
+  if(where==ids+nbOf3DCells)
+    throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !");
   int nbOfCells2D=_mesh2D->getNumberOfCells();
-  int locId=cellId%nbOfCells2D;
+  int locId=std::distance(ids,where)%nbOfCells2D;
   INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId);
   return INTERP_KERNEL::CellModel::getCellModel(tmp).getExtrudedType();
 }
 
+int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
+{
+  int ret=0;
+  int nbOfCells2D=_mesh2D->getNumberOfCells();
+  for(int i=0;i<nbOfCells2D;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=_mesh2D->getTypeOfCell(i);
+      if(INTERP_KERNEL::CellModel::getCellModel(t).getExtrudedType()==type)
+        ret++;
+    }
+  return ret*_mesh1D->getNumberOfCells();
+}
+
 void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
 {
   int nbOfCells2D=_mesh2D->getNumberOfCells();
@@ -127,6 +253,31 @@ void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector<doubl
   coo.insert(coo.end(),tmp2.begin(),tmp2.end());
 }
 
+std::string MEDCouplingExtrudedMesh::simpleRepr() const
+{
+  std::ostringstream ret;
+  ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
+  ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
+  ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
+  ret << "1D Mesh info : _____________________\n\n\n";
+  ret << _mesh1D->simpleRepr();
+  ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n";
+  return ret.str();
+}
+
+std::string MEDCouplingExtrudedMesh::advancedRepr() const
+{
+  std::ostringstream ret;
+  ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
+  ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
+  ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
+  ret << "1D Mesh info : _____________________\n\n\n";
+  ret << _mesh1D->advancedRepr();
+  ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n";
+  ret << "3D cell ids per level :\n";
+  return ret.str();
+}
+
 void MEDCouplingExtrudedMesh::checkCoherency() const throw (INTERP_KERNEL::Exception)
 {
 }
@@ -165,13 +316,49 @@ void MEDCouplingExtrudedMesh::updateTime()
     }
 }
 
+void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh");
+}
+
+MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const
+{
+  MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMeshFromThis(_mesh1D,0);
+  const int *renum=_mesh3D_ids->getConstPointer();
+  ret->renumberCells(renum,false);
+  ret->setName(getName());
+  return ret;
+}
+
 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
 {
-  //not implemented yet
-  return 0;
+  std::string name="MeasureOfMesh_";
+  name+=getName();
+  MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true);
+  MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true);
+  const double *ret2DPtr=ret2D->getArray()->getConstPointer();
+  const double *ret1DPtr=ret1D->getArray()->getConstPointer();
+  int nbOf2DCells=_mesh2D->getNumberOfCells();
+  int nbOf1DCells=_mesh1D->getNumberOfCells();
+  int nbOf3DCells=nbOf2DCells*nbOf1DCells;
+  const int *renum=_mesh3D_ids->getConstPointer();
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  ret->setMesh(this);
+  DataArrayDouble *da=DataArrayDouble::New();
+  da->alloc(nbOf3DCells,1);
+  double *retPtr=da->getPointer();
+  for(int i=0;i<nbOf1DCells;i++)
+    for(int j=0;j<nbOf2DCells;j++)
+      retPtr[renum[i*nbOf2DCells+j]]=ret2DPtr[j]*ret1DPtr[i];
+  ret->setArray(da);
+  da->decrRef();
+  ret->setName(name.c_str());
+  ret2D->decrRef();
+  ret1D->decrRef();
+  return ret;
 }
 
-MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool) const
+MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const
 {
   //not implemented yet
   return 0;
@@ -179,8 +366,7 @@ MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool) con
 
 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const
 {
-  //not implemented yet
-  throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField not implemented yet !");
+  throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !");
 }
 
 int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const
@@ -376,6 +562,24 @@ void MEDCouplingExtrudedMesh::translate(const double *vector)
   _mesh1D->translate(vector);
 }
 
+void MEDCouplingExtrudedMesh::scale(const double *point, double factor)
+{
+  _mesh2D->scale(point,factor);
+  _mesh1D->scale(point,factor);
+}
+
+MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const
+{
+  // not implemented yet !
+  return 0;
+}
+
+MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
+{
+  // not implemented yet !
+  return 0;
+}
+
 MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
 {
   // not implemented yet !
@@ -470,3 +674,109 @@ void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D
   revDesc->decrRef();
   revDescIndx->decrRef();
 }
+
+void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
+{
+  std::vector<int> tinyInfo1;
+  std::vector<std::string> ls1;
+  _mesh2D->getTinySerializationInformation(tinyInfo1,ls1);
+  std::vector<int> tinyInfo2;
+  std::vector<std::string> ls2;
+  _mesh1D->getTinySerializationInformation(tinyInfo2,ls2);
+  tinyInfo.clear(); littleStrings.clear();
+  tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end());
+  littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end());
+  tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
+  littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end());
+  tinyInfo.push_back(_cell_2D_id);
+  tinyInfo.push_back(tinyInfo1.size());
+  tinyInfo.push_back(_mesh3D_ids->getNbOfElems());
+  littleStrings.push_back(getName());
+}
+
+void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
+{
+  int sz=tinyInfo.size();
+  int sz1=tinyInfo[sz-2];
+  std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
+  std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
+  MEDCouplingUMesh *um=MEDCouplingUMesh::New();
+  DataArrayInt *a1tmp=DataArrayInt::New();
+  DataArrayDouble *a2tmp=DataArrayDouble::New();
+  int la1=0,la2=0;
+  std::vector<std::string> ls1,ls2;
+  um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
+  la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
+  a1tmp->decrRef(); a2tmp->decrRef();
+  a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
+  um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2);
+  la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
+  a1tmp->decrRef(); a2tmp->decrRef();
+  um->decrRef();
+  //
+  a1->alloc(la1+tinyInfo[sz-1],1);
+  a2->alloc(la2,1);
+  littleStrings.resize(ls1.size()+ls2.size()+1);
+}
+
+void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
+{
+  a1=DataArrayInt::New(); a2=DataArrayDouble::New();
+  DataArrayInt *a1_1=0,*a1_2=0;
+  DataArrayDouble *a2_1=0,*a2_2=0;
+  _mesh2D->serialize(a1_1,a2_1);
+  _mesh1D->serialize(a1_2,a2_2);
+  a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1);
+  int *ptri=a1->getPointer();
+  ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri);
+  a1_1->decrRef();
+  ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri);
+  a1_2->decrRef();
+  std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri);
+  a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1);
+  double *ptrd=a2->getPointer();
+  ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd);
+  a2_1->decrRef();
+  std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd);
+  a2_2->decrRef();
+}
+
+void MEDCouplingExtrudedMesh::unserialization(const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
+{
+  setName(littleStrings.back().c_str());
+  int sz=tinyInfo.size();
+  int sz1=tinyInfo[sz-2];
+  _cell_2D_id=tinyInfo[sz-3];
+  std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
+  std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
+  DataArrayInt *a1tmp=DataArrayInt::New();
+  DataArrayDouble *a2tmp=DataArrayDouble::New();
+  const int *a1Ptr=a1->getConstPointer();
+  const double *a2Ptr=a2->getConstPointer();
+  _mesh2D=MEDCouplingUMesh::New();
+  std::vector<std::string> ls1,ls2;
+  _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
+  std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
+  std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
+  a2Ptr+=a2tmp->getNbOfElems();
+  a1Ptr+=a1tmp->getNbOfElems();
+  ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size());
+  _mesh2D->unserialization(ti1,a1tmp,a2tmp,ls2);
+  a1tmp->decrRef(); a2tmp->decrRef();
+  //
+  ls2.clear();
+  ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-1);
+  _mesh1D=MEDCouplingUMesh::New();
+  a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
+  _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1);
+  std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
+  std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
+  a1Ptr+=a1tmp->getNbOfElems();
+  _mesh1D->unserialization(ti2,a1tmp,a2tmp,ls2);
+  a1tmp->decrRef(); a2tmp->decrRef();
+  //
+  _mesh3D_ids=DataArrayInt::New();
+  int szIds=std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems());
+  _mesh3D_ids->alloc(szIds,1);
+  std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer());
+}
index 60f46c0478c672832234b1f63f3a27f5d5810bdb..39a0dbf47bd90c7a766bc6493b458b007062cc32 100644 (file)
@@ -36,21 +36,35 @@ namespace ParaMEDMEM
   {
   public:
     static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingExtrudedMesh *New();
     MEDCouplingMeshType getType() const;
-    bool isStructured() const;
+    void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     int getNumberOfCells() const;
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
     int getMeshDimension() const;
+    MEDCouplingMesh *deepCpy() const;
+    MEDCouplingExtrudedMesh *clone(bool recDeepCpy) const;
+    bool isEqual(const MEDCouplingMesh *other, double prec) const;
+    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);
     INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) 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;
+    std::string simpleRepr() const;
+    std::string advancedRepr() const;
     void checkCoherency() const throw (INTERP_KERNEL::Exception);
     void getBoundingBox(double *bbox) const;
     void updateTime();
+    void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *getMesh2D() const { return _mesh2D; }
     MEDCouplingUMesh *getMesh1D() const { return _mesh1D; }
     DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; }
+    MEDCouplingUMesh *build3DUnstructuredMesh() const;
     MEDCouplingFieldDouble *getMeasureField(bool) const;
     MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const;
     MEDCouplingFieldDouble *buildOrthogonalField() const;
@@ -61,11 +75,22 @@ namespace ParaMEDMEM
                                 MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) throw(INTERP_KERNEL::Exception);
     void rotate(const double *center, const double *vector, double angle);
     void translate(const double *vector);
+    void scale(const double *point, double factor);
+    MEDCouplingMesh *buildPart(const int *start, const int *end) const;
+    MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
     MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
     DataArrayDouble *getCoordinatesAndOwner() const;
     DataArrayDouble *getBarycenterAndOwner() const;
+    //Serialization unserialisation
+    void getTinySerializationInformation(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<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                         const std::vector<std::string>& littleStrings);
   private:
     MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception);
+    MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCpy);
+    MEDCouplingExtrudedMesh();
     void computeExtrusion(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception);
     void computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception);
     void build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh,
@@ -80,6 +105,7 @@ namespace ParaMEDMEM
   private:
     MEDCouplingUMesh *_mesh2D;
     MEDCouplingUMesh *_mesh1D;
+    //! New to old 3D cell Ids Array
     DataArrayInt *_mesh3D_ids;
     int _cell_2D_id;
   };
index d64a03822c882d3a51e892ad759343e0c97ae9a8..41c3029f30d0c190e684dd101d27367df71bc16d 100644 (file)
@@ -29,7 +29,7 @@ bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, d
     return false;
   if(_desc!=other->_desc)
     return false;
-  if(!_type->isEqual(other->_type))
+  if(!_type->isEqual(other->_type,valsPrec))
     return false;
   if(_mesh==0 && other->_mesh==0)
     return true;
@@ -40,21 +40,50 @@ bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, d
   return _mesh->isEqual(other->_mesh,meshPrec);
 }
 
-bool MEDCouplingField::areCompatible(const MEDCouplingField *other) const
+bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
 {
-  if(!_type->isEqual(other->_type))
+  if(!_type->isEqualWithoutConsideringStr(other->_type,valsPrec))
+    return false;
+  if(_mesh==0 && other->_mesh==0)
+    return true;
+  if(_mesh==0 || other->_mesh==0)
+    return false;
+  if(_mesh==other->_mesh)
+    return true;
+  return _mesh->isEqualWithoutConsideringStr(other->_mesh,meshPrec);
+}
+
+/*!
+ * This method states if 'this' and 'other' are compatibles each other before performing any treatment.
+ * This method is good for methods like : mergeFields.
+ * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
+ */
+bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) const
+{
+  if(!_type->isEqual(other->_type,1.))
     return false;
   if(_mesh==other->_mesh)
     return true;
-  if(!_mesh->areCompatible(other->_mesh))
+  return _mesh->areCompatibleForMerge(other->_mesh);
+}
+
+/*!
+ * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
+ * This method is used for operation on fields to operate a first check before attempting operation.
+ */
+bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) const
+{
+  if(!_type->isEqual(other->_type,1.e-12))
     return false;
-  return true;
+  return _mesh==other->_mesh;
 }
 
 void MEDCouplingField::updateTime()
 {
   if(_mesh)
     updateTimeWith(*_mesh);
+  if(_type)
+    updateTimeWith(*_type);
 }
 
 TypeOfField MEDCouplingField::getTypeOfField() const
@@ -62,6 +91,17 @@ TypeOfField MEDCouplingField::getTypeOfField() const
   return _type->getEnum();
 }
 
+/*!
+ * This method retrieves the measure field of 'this'. If no '_mesh' is defined an exception will be thrown.
+ * Warning the retrieved field life cycle is the responsability of caller.
+ */
+MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception)
+{
+  if(_mesh==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingField::getMeasureField : no mesh defined !!!");
+  return _type->getMeasureField(_mesh,isAbs);
+}
+
 void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh)
 {
   if(mesh!=_mesh)
@@ -77,6 +117,126 @@ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh)
     }
 }
 
+/*!
+ * This method sets gauss localization by geometric type.
+ * @param type geometric type on which the gauss localization will be set.
+ * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType
+ * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType
+ * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element.
+ * @throw when size of 'RefCoo' is not valid regarding 'type' parameter, it throws too when the mesh is not set before or if it is not a field on Gauss points.
+ */
+void MEDCouplingField::setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                                  const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnType method !");
+  _type->setGaussLocalizationOnType(_mesh,type,refCoo,gsCoo,wg);
+}
+
+/*!
+ * This method sets on ids defined by [begin;end) their gauss localization. This method checks the coherency of cells ids in [begin;end) and 'refCoo' size.
+ * If an incoherence appears an exception will be thrown and no seting will be performed.
+ * An exception is thrown too if [begin,end) has a size lesser than 1.
+ * 
+ * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType
+ * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType
+ * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element.
+ * @throw when size of 'RefCoo' is not valid regarding cells in [begin,end) parameters, it throws too when the mesh is not set before or if it is not a field on Gauss points.
+ */
+void MEDCouplingField::setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector<double>& refCoo,
+                                                   const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnCells method !");
+  _type->setGaussLocalizationOnCells(_mesh,begin,end,refCoo,gsCoo,wg);
+}
+
+/*!
+ * This method resets all Gauss loalizations if any.
+ */
+void MEDCouplingField::clearGaussLocalizations()
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling clearGaussLocalizations method !");
+  _type->clearGaussLocalizations();
+}
+
+/*!
+ * This method returns reference to the Gauss localization object corresponding to 'locId' id.
+ * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by
+ * MEDCouplingField::getNbOfGaussLocalization method.
+ * Warning this method is not const, so the returned object could be modified without any problem.
+ */
+MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !");
+  return _type->getGaussLocalization(locId);
+}
+
+/*!
+ * This method returns reference to the Gauss localization object corresponding to 'locId' id.
+ * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if several localization ids have been found
+ * for a type.
+ */
+int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneType method !");
+  return _type->getGaussLocalizationIdOfOneType(type);
+}
+
+/*!
+ * This method returns number of Gauss localization available. Implicitely all ids in [0,getNbOfGaussLocalization()) is a valid Gauss localisation id.
+ * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss)
+ */
+int MEDCouplingField::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling getNbOfGaussLocalization method !");
+  return _type->getNbOfGaussLocalization();
+}
+
+/*!
+ * This method returns an id of Gauss localization in [0,getNbOfGaussLocalization()) that corresponds to the localization of the cell specified by its cellId.
+ * This methods throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) or if at the cell with id 'cellId' in this->_mesh no
+ * Gauss localization has been set.
+ */
+int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !");
+  return _type->getGaussLocalizationIdOfOneCell(cellId);
+}
+
+/*!
+ * This method returns all cellIds that share the same Gauss localization given by 'locId' parameter (in range [0,getNbOfGaussLocalization()) ).
+ * If no cells fit the Gauss localization given by 'locId' cellIds will be returned empty.
+ * @param locId input that specifies the id of Gauss localization.
+ * @param cellIds output parameter, that will contain the result if this method succeds. This parameter is systematically cleared when called.
+ * @throw  if there is no mesh, invalid FieldDescription (different from Gauss) or if locId not in [0,getNbOfGaussLocalization())
+ */
+void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception)
+{
+  cellIds.clear();
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !");
+  _type->getCellIdsHavingGaussLocalization(locId,cellIds);
+}
+
+/*!
+ * This method returns reference to the Gauss localization object corresponding to 'locId' id.
+ * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by
+ * MEDCouplingField::getNbOfGaussLocalization method.
+ * Warning this method is const.
+ */
+const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !");
+  return _type->getGaussLocalization(locId);
+}
+
 MEDCouplingField::~MEDCouplingField()
 {
   if(_mesh)
@@ -84,11 +244,15 @@ MEDCouplingField::~MEDCouplingField()
   delete _type;
 }
 
+MEDCouplingField::MEDCouplingField(MEDCouplingFieldDiscretization *type):_mesh(0),_type(type)
+{
+}
+
 MEDCouplingField::MEDCouplingField(TypeOfField type):_mesh(0),_type(MEDCouplingFieldDiscretization::New(type))
 {
 }
 
-MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):_name(other._name),_desc(other._name),
+MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):_name(other._name),_desc(other._desc),
                                                                   _mesh(0),_type(other._type->clone())
 {
   if(other._mesh)
@@ -98,8 +262,11 @@ MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):_name(other._n
     }
 }
 
-
+/*!
+ * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end).
+ * @param di is an array returned that specifies entity ids (nodes, cells ids...) in mesh 'mesh' of entity in returned submesh.
+ */
 MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const
 {
-  return _type->buildSubMeshData(start,end,_mesh,di);
+  return _type->buildSubMeshData(_mesh,start,end,di);
 }
index 932c5d54c4d69d6ce6ccf3dd377d0a6eb0783268..e6eedb5bc0823bf372e9daa4c5aa9ee8ad9e059f 100644 (file)
 #include "MEDCoupling.hxx"
 #include "MEDCouplingTimeLabel.hxx"
 #include "MEDCouplingRefCountObject.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
 #include "InterpKernelException.hxx"
 
 #include <string>
+#include <vector>
 
 namespace ParaMEDMEM
 {
   class DataArrayInt;
   class MEDCouplingMesh;
+  class MEDCouplingFieldDouble;
   class MEDCouplingFieldDiscretization;
+  class MEDCouplingGaussLocalization;
 
   class MEDCOUPLING_EXPORT MEDCouplingField : public RefCountObject, public TimeLabel
   {
   public:
     virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0;
-    virtual bool areCompatible(const MEDCouplingField *other) const;
+    virtual bool areCompatibleForMerge(const MEDCouplingField *other) const;
+    virtual bool areStrictlyCompatible(const MEDCouplingField *other) const;
     virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
+    virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
     void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh);
     const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _mesh; }
     void setName(const char *name) { _name=name; }
@@ -46,13 +52,27 @@ namespace ParaMEDMEM
     void setDescription(const char *desc) { _desc=desc; }
     const char *getName() const { return _name.c_str(); }
     TypeOfField getTypeOfField() const;
+    MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception);
     MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const;
     MEDCouplingFieldDiscretization *getDiscretization() const { return _type; }
+    // Gauss point specific methods
+    void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                    const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
+    void setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector<double>& refCoo,
+                                     const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
+    void clearGaussLocalizations();
+    MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception);
+    int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
+    int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
+    int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
+    void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
+    const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
   protected:
     void updateTime();
   protected:
     MEDCouplingField(TypeOfField type);
     MEDCouplingField(const MEDCouplingField& other);
+    MEDCouplingField(MEDCouplingFieldDiscretization *type);
     virtual ~MEDCouplingField();
   protected:
     std::string _name;
index 7e7c7b29893d7519560d452a4fd0564b6f205f09..dfa7049cc6398a5ed29970c2665c70f2f7a1d265 100644 (file)
 //
 
 #include "MEDCouplingFieldDiscretization.hxx"
-#include "MEDCouplingPointSet.hxx"
 #include "MEDCouplingCMesh.hxx"
 #include "MEDCouplingFieldDouble.hxx"
+#include "CellModel.hxx"
 
 #include "InterpolationUtils.hxx"
 
+#include <set>
 #include <limits>
 #include <algorithm>
-#include  <functional>
+#include <functional>
 
 using namespace ParaMEDMEM;
 
@@ -40,6 +41,14 @@ const char MEDCouplingFieldDiscretizationP1::REPR[]="P1";
 
 const TypeOfField MEDCouplingFieldDiscretizationP1::TYPE=ON_NODES;
 
+const char MEDCouplingFieldDiscretizationGauss::REPR[]="GAUSS";
+
+const TypeOfField MEDCouplingFieldDiscretizationGauss::TYPE=ON_GAUSS_PT;
+
+const char MEDCouplingFieldDiscretizationGaussNE::REPR[]="GSSNE";
+
+const TypeOfField MEDCouplingFieldDiscretizationGaussNE::TYPE=ON_GAUSS_NE;
+
 MEDCouplingFieldDiscretization::MEDCouplingFieldDiscretization():_precision(DFLT_PRECISION)
 {
 }
@@ -52,6 +61,10 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::New(TypeOfField
       return new MEDCouplingFieldDiscretizationP0;
     case MEDCouplingFieldDiscretizationP1::TYPE:
       return new MEDCouplingFieldDiscretizationP1;
+    case MEDCouplingFieldDiscretizationGauss::TYPE:
+      return new MEDCouplingFieldDiscretizationGauss;
+    case MEDCouplingFieldDiscretizationGaussNE::TYPE:
+      return new MEDCouplingFieldDiscretizationGaussNE;
     default:
       throw INTERP_KERNEL::Exception("Choosen discretization is not implemented yet.");
     }
@@ -64,9 +77,221 @@ TypeOfField MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(const c
     return MEDCouplingFieldDiscretizationP0::TYPE;
   if(reprCpp==MEDCouplingFieldDiscretizationP1::REPR)
     return MEDCouplingFieldDiscretizationP1::TYPE;
+  if(reprCpp==MEDCouplingFieldDiscretizationGauss::REPR)
+    return MEDCouplingFieldDiscretizationGauss::TYPE;
+  if(reprCpp==MEDCouplingFieldDiscretizationGaussNE::REPR)
+    return MEDCouplingFieldDiscretizationGaussNE::TYPE;
   throw INTERP_KERNEL::Exception("Representation does not match with any field discretization !");
 }
 
+bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const
+{
+  return isEqual(other,eps);
+}
+
+/*!
+ * Excepted for MEDCouplingFieldDiscretizationPerCell no underlying TimeLabel object : nothing to do in generally.
+ */
+void MEDCouplingFieldDiscretization::updateTime()
+{
+}
+
+/*!
+ * Computes normL1 of DataArrayDouble instance arr.
+ * @param res output parameter expected to be of size arr->getNumberOfComponents();
+ * @throw when the field discretization fails on getMeasure fields (gauss points for example)
+ */
+void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingFieldDouble *vol=getMeasureField(mesh,true);
+  int nbOfCompo=arr->getNumberOfComponents();
+  int nbOfElems=getNumberOfTuples(mesh);
+  std::fill(res,res+nbOfCompo,0.);
+  const double *arrPtr=arr->getConstPointer();
+  const double *volPtr=vol->getArray()->getConstPointer();
+  for(int i=0;i<nbOfElems;i++)
+    {
+      for(int j=0;j<nbOfCompo;j++)
+        res[j]+=fabs(arrPtr[i*nbOfCompo+j])*volPtr[i];
+    }
+  vol->decrRef();
+}
+
+/*!
+ * Computes normL2 of DataArrayDouble instance arr.
+ * @param res output parameter expected to be of size arr->getNumberOfComponents();
+ * @throw when the field discretization fails on getMeasure fields (gauss points for example)
+ */
+void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingFieldDouble *vol=getMeasureField(mesh,true);
+  int nbOfCompo=arr->getNumberOfComponents();
+  int nbOfElems=getNumberOfTuples(mesh);
+  std::fill(res,res+nbOfCompo,0.);
+  const double *arrPtr=arr->getConstPointer();
+  const double *volPtr=vol->getArray()->getConstPointer();
+  for(int i=0;i<nbOfElems;i++)
+    {
+      for(int j=0;j<nbOfCompo;j++)
+        res[j]+=arrPtr[i*nbOfCompo+j]*arrPtr[i*nbOfCompo+j]*fabs(volPtr[i]);
+    }
+  std::transform(res,res+nbOfCompo,res,std::ptr_fun<double,double>(std::sqrt));
+  vol->decrRef();
+}
+
+/*!
+ * Computes integral of DataArrayDouble instance arr.
+ * @param res output parameter expected to be of size arr->getNumberOfComponents();
+ * @throw when the field discretization fails on getMeasure fields (gauss points for example)
+ */
+void MEDCouplingFieldDiscretization::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingFieldDouble *vol=getMeasureField(mesh,isWAbs);
+  int nbOfCompo=arr->getNumberOfComponents();
+  int nbOfElems=getNumberOfTuples(mesh);
+  std::fill(res,res+nbOfCompo,0.);
+  const double *arrPtr=arr->getConstPointer();
+  const double *volPtr=vol->getArray()->getConstPointer();
+  double *tmp=new double[nbOfCompo];
+  for (int i=0;i<nbOfElems;i++)
+    {
+      std::transform(arrPtr+i*nbOfCompo,arrPtr+(i+1)*nbOfCompo,tmp,std::bind2nd(std::multiplies<double>(),volPtr[i]));
+      std::transform(tmp,tmp+nbOfCompo,res,res,std::plus<double>());
+    }
+  delete [] tmp;
+  vol->decrRef();
+}
+
+void MEDCouplingFieldDiscretization::getSerializationIntArray(DataArrayInt *& arr) const
+{
+  arr=0;
+}
+
+/*!
+ * Empty : Not a bug
+ */
+void MEDCouplingFieldDiscretization::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
+{
+}
+
+/*!
+ * Empty : Not a bug
+ */
+void MEDCouplingFieldDiscretization::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
+{
+}
+
+void MEDCouplingFieldDiscretization::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr)
+{
+  arr=0;
+}
+
+/*!
+ * Empty : Not a bug
+ */
+void MEDCouplingFieldDiscretization::finishUnserialization(const std::vector<double>& tinyInfo)
+{
+}
+
+/*!
+ * This method is typically the first step of renumbering. The implementation is empty it is not a bug only gauss is impacted
+ * virtualy by this method.
+ */
+void MEDCouplingFieldDiscretization::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+}
+
+double MEDCouplingFieldDiscretization::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da,
+                                              int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("getIJK Invalid ! only for GaussPoint and GaussNE discretizations !");
+}
+
+void MEDCouplingFieldDiscretization::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                                                const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+void MEDCouplingFieldDiscretization::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector<double>& refCoo,
+                                                                 const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+void MEDCouplingFieldDiscretization::clearGaussLocalizations() throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+const MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+int MEDCouplingFieldDiscretization::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
+void MEDCouplingFieldDiscretization::renumberEntitiesFromO2NArr(const int *old2NewPtr, DataArrayDouble *arr, const char *msg)
+{
+  int oldNbOfElems=arr->getNumberOfTuples();
+  int nbOfComp=arr->getNumberOfComponents();
+  int newNbOfTuples=(*std::max_element(old2NewPtr,old2NewPtr+oldNbOfElems))+1;
+  DataArrayDouble *arrCpy=arr->deepCopy();
+  const double *ptSrc=arrCpy->getConstPointer();
+  arr->reAlloc(newNbOfTuples);
+  double *ptToFill=arr->getPointer();
+  std::fill(ptToFill,ptToFill+nbOfComp*newNbOfTuples,std::numeric_limits<double>::max());
+  for(int i=0;i<oldNbOfElems;i++)
+    {
+      int newNb=old2NewPtr[i];
+      if(newNb>=0)//if newNb<0 the node is considered as out.
+        {
+          if(std::find_if(ptToFill+newNb*nbOfComp,ptToFill+(newNb+1)*nbOfComp,std::bind2nd(std::not_equal_to<double>(),std::numeric_limits<double>::max()))
+             ==ptToFill+(newNb+1)*nbOfComp)
+            std::copy(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp);
+          else
+            {
+              if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp))
+                {
+                  arrCpy->decrRef();
+                  std::ostringstream oss;
+                  oss << msg << " " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr
+                      << " have been merged and " << msg << " field on them are different !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+        }
+    }
+  arrCpy->decrRef();
+}
+
+MEDCouplingFieldDiscretization::~MEDCouplingFieldDiscretization()
+{
+}
+
 TypeOfField MEDCouplingFieldDiscretizationP0::getEnum() const
 {
   return TYPE;
@@ -82,7 +307,7 @@ const char *MEDCouplingFieldDiscretizationP0::getStringRepr() const
   return REPR;
 }
 
-bool MEDCouplingFieldDiscretizationP0::isEqual(const MEDCouplingFieldDiscretization *other) const
+bool MEDCouplingFieldDiscretizationP0::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const
 {
   const MEDCouplingFieldDiscretizationP0 *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationP0 *>(other);
   return otherC!=0;
@@ -93,11 +318,34 @@ int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *m
   return mesh->getNumberOfCells();
 }
 
+void MEDCouplingFieldDiscretizationP0::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                                                             const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  const int *array=old2NewBg;
+  if(check)
+    array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells());
+  for(std::vector<DataArrayDouble *>::const_iterator it=arrays.begin();it!=arrays.end();it++)
+    {
+      if(*it)
+        (*it)->renumberInPlace(array);
+    }
+  if(check)
+    delete [] array;
+}
+
 DataArrayDouble *MEDCouplingFieldDiscretizationP0::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const
 {
   return mesh->getBarycenterAndOwner();
 }
 
+void MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                                                          DataArrayInt *&cellRest)
+{
+  cellRest=DataArrayInt::New();
+  cellRest->alloc(std::distance(partBg,partEnd),1);
+  std::copy(partBg,partEnd,cellRest->getPointer());
+}
+
 void MEDCouplingFieldDiscretizationP0::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception)
 {
 }
@@ -113,7 +361,7 @@ void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMe
     }
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const
+MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
   return mesh->getMeasureField(isAbs);
 }
@@ -138,20 +386,25 @@ void MEDCouplingFieldDiscretizationP0::getValueOnPos(const DataArrayDouble *arr,
 /*!
  * Nothing to do. It's not a bug.
  */
-void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const
+void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(const int *, DataArrayDouble *) const
+{
+}
+
+void MEDCouplingFieldDiscretizationP0::renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
 {
+  renumberEntitiesFromO2NArr(old2New,arr,"Cell");
 }
 
 /*!
  * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end).
- * @ param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh.
+ * @param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh.
  * Example : The first cell id of returned mesh has the (*di)[0] id in 'mesh'
  */
-MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const
+MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const
 {
-  MEDCouplingPointSet* ret=((const MEDCouplingPointSet *) mesh)->buildPartOfMySelf(start,end,false);
+  MEDCouplingMesh *ret=mesh->buildPart(start,end);
   di=DataArrayInt::New();
-  di->alloc(end-start,1);
+  di->alloc(std::distance(start,end),1);
   int *pt=di->getPointer();
   std::copy(start,end,pt);
   return ret;
@@ -172,12 +425,20 @@ const char *MEDCouplingFieldDiscretizationP1::getStringRepr() const
   return REPR;
 }
 
-bool MEDCouplingFieldDiscretizationP1::isEqual(const MEDCouplingFieldDiscretization *other) const
+bool MEDCouplingFieldDiscretizationP1::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const
 {
   const MEDCouplingFieldDiscretizationP1 *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationP1 *>(other);
   return otherC!=0;
 }
 
+/*!
+ * Nothing to do here.
+ */
+void MEDCouplingFieldDiscretizationP1::renumberArraysForCell(const MEDCouplingMesh *, const std::vector<DataArrayDouble *>& arrays,
+                                                             const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+}
+
 int MEDCouplingFieldDiscretizationP1::getNumberOfTuples(const MEDCouplingMesh *mesh) const
 {
   return mesh->getNumberOfNodes();
@@ -188,6 +449,12 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP1::getLocalizationOfDiscValues(c
   return mesh->getCoordinatesAndOwner();
 }
 
+void MEDCouplingFieldDiscretizationP1::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                                                          DataArrayInt *&cellRest)
+{
+  cellRest=mesh->getCellIdsFullyIncludedInNodeIds(partBg,partEnd);
+}
+
 void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception)
 {
   if(nat!=ConservativeVolumic)
@@ -200,12 +467,12 @@ void MEDCouplingFieldDiscretizationP1::checkCoherencyBetween(const MEDCouplingMe
     {
       std::ostringstream message;
       message << "Field on nodes invalid because there are " << mesh->getNumberOfNodes();
-      message << " cells in mesh and " << da->getNumberOfTuples() << " tuples in field !";
+      message << " nodes in mesh and " << da->getNumberOfTuples() << " tuples in field !";
       throw INTERP_KERNEL::Exception(message.str().c_str());
     }
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const
+MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
   return mesh->getMeasureFieldOnNode(isAbs);
 }
@@ -252,64 +519,668 @@ void MEDCouplingFieldDiscretizationP1::getValueOnPos(const DataArrayDouble *arr,
   arr->getTuple(id,res);
 }
 
-void MEDCouplingFieldDiscretizationP1::renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const
+void MEDCouplingFieldDiscretizationP1::renumberValuesOnNodes(const int *old2NewPtr, DataArrayDouble *arr) const
 {
-  int oldNbOfElems=old2New->getNbOfElems();
-  const int *old2NewPtr=old2New->getConstPointer();
-  int nbOfComp=arr->getNumberOfComponents();
-  int newNbOfTuples=(*std::max_element(old2NewPtr,old2NewPtr+oldNbOfElems))+1;
-  DataArrayDouble *arrCpy=arr->deepCopy();
-  const double *ptSrc=arrCpy->getConstPointer();
-  arr->reAlloc(newNbOfTuples);
-  double *ptToFill=arr->getPointer();
-  std::fill(ptToFill,ptToFill+nbOfComp*newNbOfTuples,std::numeric_limits<double>::max());
-  for(int i=0;i<oldNbOfElems;i++)
+  renumberEntitiesFromO2NArr(old2NewPtr,arr,"Node");
+}
+
+/*!
+ * Nothing to do it's not a bug.
+ */
+void MEDCouplingFieldDiscretizationP1::renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
+{
+}
+
+/*!
+ * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end).
+* @param di is an array returned that specifies entity ids (here nodes ids) in mesh 'mesh' of entity in returned submesh.
+ * Example : The first node id of returned mesh has the (*di)[0] id in 'mesh'
+ */
+MEDCouplingMesh *MEDCouplingFieldDiscretizationP1::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const
+{
+  MEDCouplingMesh *ret=mesh->buildPartAndReduceNodes(start,end,di);
+  DataArrayInt *di2=di->invertArrayO2N2N2O(ret->getNumberOfNodes());
+  di->decrRef();
+  di=di2;
+  return ret;
+}
+
+MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0)
+{
+}
+
+MEDCouplingFieldDiscretizationPerCell::~MEDCouplingFieldDiscretizationPerCell()
+{
+  if(_discr_per_cell)
+    _discr_per_cell->decrRef();
+}
+
+MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other):_discr_per_cell(0)
+{
+  DataArrayInt *arr=other._discr_per_cell;
+  if(arr)
+    _discr_per_cell=arr->deepCopy();
+}
+
+void MEDCouplingFieldDiscretizationPerCell::updateTime()
+{
+  if(_discr_per_cell)
+    updateTimeWith(*_discr_per_cell);
+}
+
+void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_discr_per_cell)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has no discretization per cell !");
+  int nbOfTuples=_discr_per_cell->getNumberOfTuples();
+  if(nbOfTuples!=mesh->getNumberOfCells())
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has a discretization per cell but it's not matching the underlying mesh !");
+}
+
+bool MEDCouplingFieldDiscretizationPerCell::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const
+{
+  const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationPerCell *>(other);
+  if(!otherC)
+    return false;
+  if(_discr_per_cell==0)
+    return otherC->_discr_per_cell==0;
+  if(otherC->_discr_per_cell==0)
+    return false;
+  return _discr_per_cell->isEqual(*otherC->_discr_per_cell);
+}
+
+bool MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const
+{
+  const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationPerCell *>(other);
+  if(!otherC)
+    return false;
+  if(_discr_per_cell==0)
+    return otherC->_discr_per_cell==0;
+  if(otherC->_discr_per_cell==0)
+    return false;
+  return _discr_per_cell->isEqualWithoutConsideringStr(*otherC->_discr_per_cell);
+}
+
+/*!
+ * This method is typically the first step of renumbering. The impact on _discr_per_cell is necessary here.
+ * virtualy by this method.
+ */
+void MEDCouplingFieldDiscretizationPerCell::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  int nbCells=_discr_per_cell->getNumberOfTuples();
+  const int *array=old2NewBg;
+  if(check)
+    array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+nbCells);
+  //
+  DataArrayInt *dpc=_discr_per_cell->renumber(array);
+  _discr_per_cell->decrRef();
+  _discr_per_cell=dpc;
+  //
+  if(check)
+    delete [] (int *)array;
+}
+
+void MEDCouplingFieldDiscretizationPerCell::buildDiscrPerCellIfNecessary(const MEDCouplingMesh *m)
+{
+  if(!_discr_per_cell)
     {
-      int newNb=old2NewPtr[i];
-      if(std::find_if(ptToFill+newNb*nbOfComp,ptToFill+(newNb+1)*nbOfComp,std::bind2nd(std::not_equal_to<double>(),std::numeric_limits<double>::max()))
-         ==ptToFill+(newNb+1)*nbOfComp)
-        std::copy(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp);
-      else
+      _discr_per_cell=DataArrayInt::New();
+      int nbTuples=m->getNumberOfCells();
+      _discr_per_cell->alloc(nbTuples,1);
+      int *ptr=_discr_per_cell->getPointer();
+      std::fill(ptr,ptr+nbTuples,-1);
+    }
+}
+
+MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss()
+{
+}
+
+MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other):MEDCouplingFieldDiscretizationPerCell(other),_loc(other._loc)
+{
+}
+
+TypeOfField MEDCouplingFieldDiscretizationGauss::getEnum() const
+{
+  return TYPE;
+}
+
+bool MEDCouplingFieldDiscretizationGauss::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const
+{
+  const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(other);
+  if(!otherC)
+    return false;
+  if(!MEDCouplingFieldDiscretizationPerCell::isEqual(other,eps))
+    return false;
+  if(_loc.size()!=otherC->_loc.size())
+    return false;
+  int sz=_loc.size();
+  for(int i=0;i<sz;i++)
+    if(!_loc[i].isEqual(otherC->_loc[i],eps))
+      return false;
+  return true;
+}
+
+bool MEDCouplingFieldDiscretizationGauss::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const
+{
+  const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(other);
+  if(!otherC)
+    return false;
+  if(!MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(other,eps))
+    return false;
+  if(_loc.size()!=otherC->_loc.size())
+    return false;
+  int sz=_loc.size();
+  for(int i=0;i<sz;i++)
+    if(!_loc[i].isEqual(otherC->_loc[i],eps))
+      return false;
+  return true;
+}
+
+MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clone() const
+{
+  return new MEDCouplingFieldDiscretizationGauss(*this);
+}
+
+const char *MEDCouplingFieldDiscretizationGauss::getStringRepr() const
+{
+  return REPR;
+}
+
+int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const
+{
+  int ret=0;
+  const int *dcPtr=_discr_per_cell->getConstPointer();
+  int nbOfTuples=_discr_per_cell->getNumberOfTuples();
+  for(const int *w=dcPtr;w!=dcPtr+nbOfTuples;w++)
+    ret+=_loc[*w].getNumberOfGaussPt();
+  return ret;
+}
+
+void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                                                                const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  const int *array=old2NewBg;
+  if(check)
+    array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells());
+  int nbOfCells=_discr_per_cell->getNumberOfTuples();
+  int nbOfTuples=getNumberOfTuples(0);
+  const int *dcPtr=_discr_per_cell->getConstPointer();
+  int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace.
+  int *array3=new int[nbOfCells];//store for each cell in present dcp array (already renumbered) the offset needed by each cell in new numbering.
+  array3[0]=0;
+  for(int i=1;i<nbOfCells;i++)
+    array3[i]=array3[i-1]+_loc[dcPtr[i-1]].getNumberOfGaussPt();
+  int j=0;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int nbOfGaussPt=_loc[dcPtr[array[i]]].getNumberOfGaussPt();
+      for(int k=0;k<nbOfGaussPt;k++,j++)
+        array2[j]=array3[array[i]]+k;
+    }
+  delete [] array3;
+  for(std::vector<DataArrayDouble *>::const_iterator it=arrays.begin();it!=arrays.end();it++)
+    if(*it)
+      (*it)->renumberInPlace(array2);
+  delete [] array2;
+  if(check)
+    delete [] (int*)array;
+}
+
+DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                                                             DataArrayInt *&cellRest)
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+/*!
+ * Empty : not a bug
+ */
+void MEDCouplingFieldDiscretizationGauss::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception)
+{
+}
+
+void MEDCouplingFieldDiscretizationGauss::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
+{
+  int val=-1;
+  if(_discr_per_cell)
+    val=_discr_per_cell->getNumberOfTuples();
+  tinyInfo.push_back(val);
+  tinyInfo.push_back(_loc.size());
+  if(_loc.empty())
+    tinyInfo.push_back(-1);
+  else
+    tinyInfo.push_back(_loc[0].getDimension());
+  for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++)
+    (*iter).pushTinySerializationIntInfo(tinyInfo);
+}
+
+void MEDCouplingFieldDiscretizationGauss::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
+{
+  for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++)
+    (*iter).pushTinySerializationDblInfo(tinyInfo);
+}
+
+void MEDCouplingFieldDiscretizationGauss::getSerializationIntArray(DataArrayInt *& arr) const
+{
+  arr=0;
+  if(_discr_per_cell)
+    arr=_discr_per_cell;
+}
+
+void MEDCouplingFieldDiscretizationGauss::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr)
+{
+  int val=tinyInfo[0];
+  if(val>=0)
+    {
+      _discr_per_cell=DataArrayInt::New();
+      _discr_per_cell->alloc(val,1);
+    }
+  else
+    _discr_per_cell=0;
+  arr=_discr_per_cell;
+  int nbOfLoc=tinyInfo[1];
+  _loc.clear();
+  int dim=tinyInfo[2];
+  int delta=-1;
+  if(nbOfLoc>0)
+    delta=(tinyInfo.size()-3)/nbOfLoc;
+  for(int i=0;i<nbOfLoc;i++)
+    {
+      std::vector<int> tmp(tinyInfo.begin()+3+i*delta,tinyInfo.begin()+3+(i+1)*delta);
+      MEDCouplingGaussLocalization elt=MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo(dim,tmp);
+      _loc.push_back(elt);
+    }
+}
+
+void MEDCouplingFieldDiscretizationGauss::finishUnserialization(const std::vector<double>& tinyInfo)
+{
+  double *tmp=new double[tinyInfo.size()];
+  std::copy(tinyInfo.begin(),tinyInfo.end(),tmp);
+  const double *work=tmp;
+  for(std::vector<MEDCouplingGaussLocalization>::iterator iter=_loc.begin();iter!=_loc.end();iter++)
+    work=(*iter).fillWithValues(work);
+  delete [] tmp;
+}
+
+double MEDCouplingFieldDiscretizationGauss::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da,
+                                                   int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception)
+{
+  int offset=getOffsetOfCell(cellId);
+  return da->getIJ(offset+nodeIdInCell,compoId);
+}
+
+void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(mesh,da);
+  for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++)
+    (*iter).checkCoherency();
+  int nbOfDesc=_loc.size();
+  int nbOfCells=mesh->getNumberOfCells();
+  const int *dc=_discr_per_cell->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      if(dc[i]>=nbOfDesc)
         {
-          if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp))
-            {
-              arrCpy->decrRef();
-              std::ostringstream oss;
-              oss << "Node " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr
-                  << " have been merged and nodal field on them are different !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }
+          std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has an undefined gauss location ! Should never happend !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      if(dc[i]<0)
+        {
+          std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has no gauss location !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      if(mesh->getTypeOfCell(i)!=_loc[dc[i]].getType())
+        {
+          std::ostringstream oss; oss << "Types of mesh and gauss location mismatch for cell # " << i;
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  arrCpy->decrRef();
+  int nbOfTuples=getNumberOfTuples(mesh);
+  if(nbOfTuples!=da->getNumberOfTuples())
+    {
+      std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGauss::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGauss::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const
+{
+  throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !");
+}
+
+MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
 }
 
 /*!
- * This method invert array 'di' that is a conversion map from Old to New node numbering to New to Old node numbering.
+ * No implementation needed !
  */
-DataArrayInt *MEDCouplingFieldDiscretizationP1::invertArrayO2N2N2O(const MEDCouplingMesh *mesh, const DataArrayInt *di)
-{
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc(mesh->getNumberOfNodes(),1);
-  int nbOfOldNodes=di->getNumberOfTuples();
-  const int *old2New=di->getConstPointer();
-  int *pt=ret->getPointer();
-  for(int i=0;i!=nbOfOldNodes;i++)
-    if(old2New[i]!=-1)
-      pt[old2New[i]]=i;
+void MEDCouplingFieldDiscretizationGauss::renumberValuesOnNodes(const int *, DataArrayDouble *) const
+{
+}
+
+void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                                                     const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception)
+{
+  buildDiscrPerCellIfNecessary(m);
+  int id=_loc.size();
+  MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg);
+  _loc.push_back(elt);
+  int *ptr=_discr_per_cell->getPointer();
+  int nbCells=m->getNumberOfCells();
+  for(int i=0;i<nbCells;i++)
+    if(m->getTypeOfCell(i)==type)
+      ptr[i]=id;
+  zipGaussLocalizations();
+}
+
+void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector<double>& refCoo,
+                                                                      const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception)
+{
+  buildDiscrPerCellIfNecessary(m);
+  if(std::distance(begin,end)<1)
+    throw INTERP_KERNEL::Exception("Size of [begin,end) must be equal or greater than 1 !");
+  INTERP_KERNEL::NormalizedCellType type=m->getTypeOfCell(*begin);
+  MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg);
+  int id=_loc.size();
+  int *ptr=_discr_per_cell->getPointer();
+  for(const int *w=begin+1;w!=end;w++)
+    {
+      if(m->getTypeOfCell(*w)!=type)
+        {
+          std::ostringstream oss; oss << "The cell with id " << *w << " has been detected to be incompatible in the [begin,end) array specified !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  //
+  for(const int *w2=begin;w2!=end;w2++)
+    ptr[*w2]=id;
+  //
+  _loc.push_back(elt);
+  zipGaussLocalizations();
+}
+
+void MEDCouplingFieldDiscretizationGauss::clearGaussLocalizations() throw(INTERP_KERNEL::Exception)
+{
+  if(_discr_per_cell)
+    {
+      _discr_per_cell->decrRef();
+      _discr_per_cell=0;
+    }
+  _loc.clear();
+}
+
+MEDCouplingGaussLocalization& MEDCouplingFieldDiscretizationGauss::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception)
+{
+  checkLocalizationId(locId);
+  return _loc[locId];
+}
+
+int MEDCouplingFieldDiscretizationGauss::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception)
+{
+  return _loc.size();
+}
+
+int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_discr_per_cell)
+    throw INTERP_KERNEL::Exception("No Gauss localization still set !");
+  int locId=_discr_per_cell->getConstPointer()[cellId];
+  if(locId<0)
+    throw INTERP_KERNEL::Exception("No Gauss localization set for the specified cell !");
+  return locId;
+}
+
+int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_discr_per_cell)
+    throw INTERP_KERNEL::Exception("No Gauss localization still set !");
+  std::set<int> ret;
+  int id=0;
+  for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++,id++)
+    if((*iter).getType()==type)
+      ret.insert(id);
+  if(ret.empty())
+    throw INTERP_KERNEL::Exception("No gauss discretization found for the specified type !");
+  if(ret.size()>1)
+    throw INTERP_KERNEL::Exception("Several gauss discretizations have been found for the specified type !");
+  return *ret.begin();
+}
+
+void MEDCouplingFieldDiscretizationGauss::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception)
+{
+  if(locId<0 || locId>=(int)_loc.size())
+    throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !");
+  int nbOfTuples=_discr_per_cell->getNumberOfTuples();
+  const int *ptr=_discr_per_cell->getConstPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    if(ptr[i]==locId)
+      cellIds.push_back(i);
+}
+
+const MEDCouplingGaussLocalization& MEDCouplingFieldDiscretizationGauss::getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception)
+{
+  checkLocalizationId(locId);
+  return _loc[locId];
+}
+
+void MEDCouplingFieldDiscretizationGauss::checkLocalizationId(int locId) const throw(INTERP_KERNEL::Exception)
+{
+  if(locId<0 || locId>=(int)_loc.size())
+    throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !");
+}
+
+int MEDCouplingFieldDiscretizationGauss::getOffsetOfCell(int cellId) const throw(INTERP_KERNEL::Exception)
+{
+  int ret=0;
+  const int *start=_discr_per_cell->getConstPointer();
+  for(const int *w=start;w!=start+cellId;w++)
+    ret+=_loc[*w].getNumberOfGaussPt();
   return ret;
 }
 
 /*!
- * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end).
-* @ param di is an array returned that specifies entity ids (here nodes ids) in mesh 'mesh' of entity in returned submesh.
- * Example : The first node id of returned mesh has the (*di)[0] id in 'mesh'
+ * This method makes the assumption that _discr_per_cell is set.
+ * This method reduces as much as possible number size of _loc.
+ * This method is usefull when several set on same cells has been done and that some Gauss Localization are no more used.
  */
-MEDCouplingMesh *MEDCouplingFieldDiscretizationP1::buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const
+void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations()
 {
-  MEDCouplingPointSet* ret=((const MEDCouplingPointSet *) mesh)->buildPartOfMySelf(start,end,true);
-  DataArrayInt *diInv=ret->zipCoordsTraducer();
-  di=invertArrayO2N2N2O(ret,diInv);
-  diInv->decrRef();
+  const int *start=_discr_per_cell->getConstPointer();
+  int nbOfTuples=_discr_per_cell->getNumberOfTuples();
+  int *tmp=new int[_loc.size()];
+  std::fill(tmp,tmp+_loc.size(),-2);
+  for(const int *w=start;w!=start+nbOfTuples;w++)
+    if(*w>=0)
+      tmp[*w]=1;
+  int fid=0;
+  for(int i=0;i<(int)_loc.size();i++)
+    if(tmp[i]!=-2)
+      tmp[i]=fid++;
+  if(fid==(int)_loc.size())
+    {//no zip needed
+      delete [] tmp;
+      return;
+    }
+  // zip needed
+  int *start2=_discr_per_cell->getPointer();
+  for(int *w2=start2;w2!=start2+nbOfTuples;w2++)
+    *w2=tmp[*w2];
+  std::vector<MEDCouplingGaussLocalization> tmpLoc;
+  for(int i=0;i<(int)_loc.size();i++)
+    if(tmp[i]!=-2)
+      tmpLoc.push_back(_loc[tmp[i]]);
+  delete [] tmp;
+  _loc=tmpLoc;
+}
+
+MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE()
+{
+}
+
+TypeOfField MEDCouplingFieldDiscretizationGaussNE::getEnum() const
+{
+  return TYPE;
+}
+
+MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGaussNE::clone() const
+{
+  return new MEDCouplingFieldDiscretizationGaussNE(*this);
+}
+
+const char *MEDCouplingFieldDiscretizationGaussNE::getStringRepr() const
+{
+  return REPR;
+}
+
+bool MEDCouplingFieldDiscretizationGaussNE::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const
+{
+  const MEDCouplingFieldDiscretizationGaussNE *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationGaussNE *>(other);
+  return otherC!=0;
+}
+
+int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const
+{
+  int ret=0;
+  int nbOfCells=mesh->getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      if(cm.isDynamic())
+        throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !");
+      ret+=cm.getNumberOfNodes();
+    }
   return ret;
 }
+
+void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                                                                  const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  const int *array=old2NewBg;
+  if(check)
+    array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells());
+  int nbOfCells=mesh->getNumberOfCells();
+  int nbOfTuples=getNumberOfTuples(mesh);
+  int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace.
+  int *array3=new int[nbOfCells];//store for each cell in after renumbering the offset needed by each cell in new numbering.
+  array3[0]=0;
+  for(int i=1;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(std::distance(array,std::find(array,array+nbOfCells,i-1)));
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      array3[i]=array3[i-1]+cm.getNumberOfNodes();
+    }
+  int j=0;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      for(int k=0;k<(int)cm.getNumberOfNodes();k++,j++)
+        array2[j]=array3[array[i]]+k;
+    }
+  delete [] array3;
+  for(std::vector<DataArrayDouble *>::const_iterator it=arrays.begin();it!=arrays.end();it++)
+    if(*it)
+      (*it)->renumberInPlace(array2);
+  delete [] array2;
+  if(check)
+    delete [] (int*)array;
+}
+
+DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGaussNE::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                                                               DataArrayInt *&cellRest)
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGaussNE::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception)
+{
+}
+
+double MEDCouplingFieldDiscretizationGaussNE::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da,
+                                                     int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception)
+{
+  int offset=0;
+  for(int i=0;i<cellId;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      offset+=cm.getNumberOfNodes();
+    }
+  return da->getIJ(offset+nodeIdInCell,compoId);
+}
+
+void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfTuples=getNumberOfTuples(mesh);
+  if(nbOfTuples!=da->getNumberOfTuples())
+    {
+      std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGaussNE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+void MEDCouplingFieldDiscretizationGaussNE::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const
+{
+  throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !");
+}
+
+MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+/*!
+ * No implementation needed !
+ */
+void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnNodes(const int *, DataArrayDouble *) const
+{
+}
+
+void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
+MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other):MEDCouplingFieldDiscretization(other)
+{
+}
+
index 25d52f542b137e666bb8f43f9686a81bb02ce05d..316fa753dcec3c36a6b50cf889c27369004a065f 100644 (file)
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#ifndef __MEDCOUPLINGFIELDDISCRETIZATION_HXX__
-#define __MEDCOUPLINGFIELDDISCRETIZATION_HXX__
+#ifndef __PARAMEDMEM_MEDCOUPLINGFIELDDISCRETIZATION_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGFIELDDISCRETIZATION_HXX__
 
 #include "MEDCoupling.hxx"
 #include "MEDCouplingRefCountObject.hxx"
 #include "InterpKernelException.hxx"
+#include "MEDCouplingTimeLabel.hxx"
 #include "MEDCouplingNatureOfField.hxx"
+#include "MEDCouplingGaussLocalization.hxx"
+
+#include <vector>
 
 namespace ParaMEDMEM
 {
@@ -32,28 +36,58 @@ namespace ParaMEDMEM
   class DataArrayDouble;
   class MEDCouplingFieldDouble;
 
-  class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization
+  class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization : public TimeLabel
   {
   public:
     static MEDCouplingFieldDiscretization *New(TypeOfField type);
     double getPrecision() const { return _precision; }
     void setPrecision(double val) { _precision=val; }
+    void updateTime();
     static TypeOfField getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception);
     virtual TypeOfField getEnum() const = 0;
-    virtual bool isEqual(const MEDCouplingFieldDiscretization *other) const = 0;
+    virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const = 0;
+    virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const;
     virtual MEDCouplingFieldDiscretization *clone() const = 0;
     virtual const char *getStringRepr() const = 0;
     virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0;
+    virtual void normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception);
+    virtual void normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception);
+    virtual void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception);
     virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const = 0;
+    virtual void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                                    DataArrayInt *&cellRest) = 0;
     virtual void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
+    virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                                       const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) = 0;
+    virtual double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception);
     virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) = 0;
-    virtual MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const = 0;
+    virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const = 0;
     virtual void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const = 0;
     virtual void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const = 0;
-    virtual MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const = 0;
-    virtual void renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const = 0;
+    virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0;
+    virtual void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const = 0;
+    virtual void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const = 0;
+    virtual void getSerializationIntArray(DataArrayInt *& arr) const;
+    virtual void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
+    virtual void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
+    virtual void finishUnserialization(const std::vector<double>& tinyInfo);
+    virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr);
+    virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                            const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
+    virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector<double>& refCoo,
+                                             const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
+    virtual void clearGaussLocalizations() throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception);
+    virtual int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
+    virtual int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
+    virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
+    virtual void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
+    virtual const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
+    virtual ~MEDCouplingFieldDiscretization();
   protected:
     MEDCouplingFieldDiscretization();
+    static void renumberEntitiesFromO2NArr(const int *old2NewPtr, DataArrayDouble *arr, const char *msg);
   protected:
     double _precision;
     static const double DFLT_PRECISION;
@@ -65,16 +99,21 @@ namespace ParaMEDMEM
     TypeOfField getEnum() const;
     MEDCouplingFieldDiscretization *clone() const;
     const char *getStringRepr() const;
-    bool isEqual(const MEDCouplingFieldDiscretization *other) const;
+    bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const;
     int getNumberOfTuples(const MEDCouplingMesh *mesh) const;
+    void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                               const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const;
     void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception);
+    void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                            DataArrayInt *&cellRest);
     void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
-    MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const;
+    MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const;
     void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const;
     void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const;
-    void renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const;
-    MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const;
+    void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+    MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
   public:
     static const char REPR[];
     static const TypeOfField TYPE;
@@ -86,17 +125,127 @@ namespace ParaMEDMEM
     TypeOfField getEnum() const;
     MEDCouplingFieldDiscretization *clone() const;
     const char *getStringRepr() const;
-    bool isEqual(const MEDCouplingFieldDiscretization *other) const;
+    bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const;
+    int getNumberOfTuples(const MEDCouplingMesh *mesh) const;
+    void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                               const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
+    DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const;
+    void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                            DataArrayInt *&cellRest);
+    void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception);
+    void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const;
+    void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const;
+    void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const;
+    MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
+    void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+  public:
+    static const char REPR[];
+    static const TypeOfField TYPE;
+  };
+
+  /*!
+   * This class abstracts MEDCouplingFieldDiscretization that needs an information on each cell to perform their job.
+   * All classes that inherits from this are more linked to mesh.
+   */
+  class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization
+  {
+  protected:
+    MEDCouplingFieldDiscretizationPerCell();
+    MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other);
+    ~MEDCouplingFieldDiscretizationPerCell();
+    void updateTime();
+    void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
+    bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const;
+    void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
+  protected:
+    void buildDiscrPerCellIfNecessary(const MEDCouplingMesh *m);
+  protected:
+    DataArrayInt *_discr_per_cell;
+  };
+
+  class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGauss : public MEDCouplingFieldDiscretizationPerCell
+  {
+  public:
+    MEDCouplingFieldDiscretizationGauss();
+    TypeOfField getEnum() const;
+    bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const;
+    MEDCouplingFieldDiscretization *clone() const;
+    const char *getStringRepr() const;
     int getNumberOfTuples(const MEDCouplingMesh *mesh) const;
+    void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                               const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const;
+    void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                            DataArrayInt *&cellRest);
     void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception);
+    void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
+    void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
+    void finishUnserialization(const std::vector<double>& tinyInfo);
+    void getSerializationIntArray(DataArrayInt *& arr) const;
+    void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr);
+    double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception);
     void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
-    MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const;
+    MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const;
     void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const;
     void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const;
-    MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const;
-    void renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const;
-    static DataArrayInt *invertArrayO2N2N2O(const MEDCouplingMesh *mesh, const DataArrayInt *di);
+    MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
+    void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+    void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                    const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
+    void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector<double>& refCoo,
+                                     const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
+    void clearGaussLocalizations() throw(INTERP_KERNEL::Exception);
+    MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception);
+    int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
+    int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
+    int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
+    void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
+    const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
+  protected:
+    MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other);
+    void zipGaussLocalizations();
+    int getOffsetOfCell(int cellId) const throw(INTERP_KERNEL::Exception);
+    void checkLocalizationId(int locId) const throw(INTERP_KERNEL::Exception);
+  public:
+    static const char REPR[];
+    static const TypeOfField TYPE;
+  private:
+    std::vector<MEDCouplingGaussLocalization> _loc;
+  };
+
+  /*!
+   * Gauss with points of values located on nodes of element. This is a specialization of MEDCouplingFieldDiscretizationGauss.
+   */
+  class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE : public MEDCouplingFieldDiscretization
+  {
+  public:
+    MEDCouplingFieldDiscretizationGaussNE();
+    TypeOfField getEnum() const;
+    MEDCouplingFieldDiscretization *clone() const;
+    const char *getStringRepr() const;
+    bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const;
+    int getNumberOfTuples(const MEDCouplingMesh *mesh) const;
+    void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArrayDouble *>& arrays,
+                               const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
+    DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const;
+    void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd,
+                                            DataArrayInt *&cellRest);
+    void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception);
+    double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception);
+    void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const;
+    void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const;
+    void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const;
+    MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
+    void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+  protected:
+    MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other);
   public:
     static const char REPR[];
     static const TypeOfField TYPE;
index fcbfd84f72727e9e350441b6d33021a5a2eb9e75..2c62b3f44913fe14dcf21b0d64354380a9295011 100644 (file)
 //
 
 #include "MEDCouplingFieldDouble.hxx"
-#include "MEDCouplingPointSet.hxx"
+#include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingTimeDiscretization.hxx"
 #include "MEDCouplingFieldDiscretization.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MEDCouplingNatureOfField.hxx"
 
 #include <sstream>
+#include <limits>
 #include <functional>
 
 using namespace ParaMEDMEM;
@@ -37,16 +40,93 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
   return new MEDCouplingFieldDouble(*this,recDeepCpy);
 }
 
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
+{
+  MEDCouplingFieldDouble *ret=clone(recDeepCpy);
+  if(_mesh)
+    {
+      MEDCouplingMesh *mCpy=_mesh->deepCpy();
+      ret->setMesh(mCpy);
+      mCpy->decrRef();
+    }
+  return ret;
+}
+
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const
 {
   MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(_time_discr,td,deepCpy);
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,getTypeOfField());
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone());
   ret->setMesh(getMesh());
   ret->setName(getName());
   ret->setDescription(getDescription());
   return ret;
 }
 
+/*!
+ * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
+ */
+void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
+{
+  if(other)
+    {
+      setName(other->_name.c_str());
+      setDescription(other->_desc.c_str());
+      _time_discr->copyTinyStringsFrom(*other->_time_discr);
+    }
+}
+
+std::string MEDCouplingFieldDouble::simpleRepr() const
+{
+  std::ostringstream ret;
+  ret << "FieldDouble with name : \"" << getName() << "\"\n";
+  ret << "Description of field is : \"" << getDescription() << "\"\n";
+  ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
+  ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
+  ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n";
+  if(getArray())
+    {
+      int nbOfCompo=getArray()->getNumberOfComponents();
+      ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
+      ret << "FieldDouble default array has following info on components : ";
+      for(int i=0;i<nbOfCompo;i++)
+        ret << "\"" << getArray()->getInfoOnComponent(i) << "\" ";
+      ret << "\n";
+    }
+  if(_mesh)
+    ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr();
+  else
+    ret << "Mesh support information : No mesh set !\n";
+  return ret.str();
+}
+
+std::string MEDCouplingFieldDouble::advancedRepr() const
+{
+  std::ostringstream ret;
+  ret << "FieldDouble with name : \"" << getName() << "\"\n";
+  ret << "Description of field is : \"" << getDescription() << "\"\n";
+  ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
+  ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
+  if(getArray())
+    ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
+  if(_mesh)
+    ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr();
+  else
+    ret << "Mesh support information : No mesh set !\n";
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  int arrayId=0;
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
+    {
+      ret << "Array #" << arrayId << " :\n__________\n";
+      if(*iter)
+        (*iter)->reprWithoutNameStream(ret);
+      else
+        ret << "Array empty !";
+      ret << "\n";
+    }
+  return ret.str();
+}
+
 bool MEDCouplingFieldDouble::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const
 {
   const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
@@ -61,9 +141,28 @@ bool MEDCouplingFieldDouble::isEqual(const MEDCouplingField *other, double meshP
   return true;
 }
 
-bool MEDCouplingFieldDouble::areCompatible(const MEDCouplingField *other) const
+bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
 {
-  if(!MEDCouplingField::areCompatible(other))
+  const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
+  if(!otherC)
+    return false;
+  if(_nature!=otherC->_nature)
+    return false;
+  if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec))
+    return false;
+  if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec))
+    return false;
+  return true;
+}
+
+/*!
+ * This method states if 'this' and 'other' are compatibles each other before performing any treatment.
+ * This method is good for methods like : mergeFields.
+ * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
+ */
+bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
+{
+  if(!MEDCouplingField::areCompatibleForMerge(other))
     return false;
   const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
   if(!otherC)
@@ -75,20 +174,167 @@ bool MEDCouplingFieldDouble::areCompatible(const MEDCouplingField *other) const
   return true;
 }
 
+/*!
+ * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
+ * This method is used for operation on fields to operate a first check before attempting operation.
+ */
+bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const
+{
+  if(!MEDCouplingField::areStrictlyCompatible(other))
+    return false;
+  const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
+  if(!otherC)
+    return false;
+  if(_nature!=otherC->_nature)
+    return false;
+  if(!_time_discr->areStrictlyCompatible(otherC->_time_discr))
+    return false;
+  return true;
+}
+
+/*!
+ * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
+ * number of components between 'this' and 'other' can be different here (for operator*).
+ */
 bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const
 {
-  if(!MEDCouplingField::areCompatible(other))
+  if(!MEDCouplingField::areStrictlyCompatible(other))
     return false;
   const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
   if(!otherC)
     return false;
   if(_nature!=otherC->_nature)
     return false;
-  if(!_time_discr->areCompatibleForMul(otherC->_time_discr))
+  if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr))
     return false;
   return true;
 }
 
+/*!
+ * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same.
+ * The values of field are impacted in consequence to have the same geometrical field.
+ */
+void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  renumberCellsWithoutMesh(old2NewBg,check);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_mesh->deepCpy();
+  m->renumberCells(old2NewBg,check);
+  setMesh(m);
+  updateTime();
+}
+
+/*!
+ * \b WARNING : use this method with lot of care !
+ * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh.
+ * That is to say, the field content is changed by this method. The reason of this method is only for multi-field instances lying on the same mesh to
+ * avoid a systematic duplication and renumbering of _mesh attribute.
+ */
+void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+   if(!_mesh)
+    throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
+  //
+  _type->renumberCells(old2NewBg,check);
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check);
+  //
+  updateTime();
+}
+
+/*!
+ * This method performs a clone of mesh and a renumbering of underlying nodes of it. The number of nodes remains not compulsory the same as renumberCells method.
+ * The values of field are impacted in consequence to have the same geometrical field.
+ */
+void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
+  if(!meshC)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
+  int nbOfNodes=meshC->getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
+  renumberNodesWithoutMesh(old2NewBg);
+  meshC2->renumberNodes(old2NewBg,*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1);
+  setMesh(meshC2);
+}
+
+/*!
+ * \b WARNING : use this method with lot of care !
+ * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh.
+ * That is to say, the field content is changed by this method.
+ */
+void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    if(*iter)
+      _type->renumberValuesOnNodes(old2NewBg,*iter);
+}
+
+/*!
+ * This method makes the assumption that the default array is set. If not an exception will be thrown.
+ * This method is usable only if the default array has exactly one component. If not an exception will be thrown too.
+ * This method returns all tuples ids that fit the range [vmin,vmax].
+ * The caller has the responsability of the returned DataArrayInt.
+ */
+DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !");
+  return getArray()->getIdsInRange(vmin,vmax);
+}
+
+/*!
+ * Builds a newly created field, that the caller will have the responsability.
+ * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
+ * This method returns a restriction of 'this' so that only tuples id specified in 'part' will be contained in returned field. 
+ */
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception)
+{
+  if(part==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
+  const int *start=part->getConstPointer();
+  const int *end=start+part->getNbOfElems();
+  return buildSubPart(start,end);
+}
+
+/*!
+ * Builds a newly created field, that the caller will have the responsability.
+ * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
+ * This method returns a restriction of 'this' so that only tuples id specified in ['partBg';'partEnd') will be contained in returned field. 
+ */
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception)
+{
+  DataArrayInt *cellRest;
+  _type->computeMeshRestrictionFromTupleIds(_mesh,partBg,partEnd,cellRest);
+  DataArrayInt *arrSelect;
+  MEDCouplingMesh *m=_type->buildSubMeshData(_mesh,cellRest->getConstPointer(),cellRest->getConstPointer()+cellRest->getNbOfElems(),arrSelect);
+  if(cellRest)
+    cellRest->decrRef();
+  MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy.
+  ret->setMesh(m);
+  m->decrRef();
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  std::vector<DataArrayDouble *> arrs;
+  const int *arrSelBg=arrSelect->getConstPointer();
+  const int *arrSelEnd=arrSelBg+arrSelect->getNbOfElems();
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    {
+      DataArrayDouble *arr=0;
+      if(*iter)
+        arr=(*iter)->selectByTupleId(arrSelBg,arrSelEnd);
+      arrs.push_back(arr);
+    }
+  ret->_time_discr->setArrays(arrs,0);
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
+    if(*iter)
+      (*iter)->decrRef();
+  arrSelect->decrRef();
+  return ret;
+}
+
 TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const
 {
   return _time_discr->getEnum();
@@ -104,8 +350,8 @@ MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& oth
 {
 }
 
-MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, TypeOfField type):MEDCouplingField(type),
-                                                                                                                     _nature(n),_time_discr(td)
+MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type),
+                                                                                                                                         _nature(n),_time_discr(td)
 {
 }
 
@@ -118,37 +364,259 @@ void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Excepti
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
-  if(!getArray())
-    throw INTERP_KERNEL::Exception("Field invalid because no values set !");
+  _time_discr->checkCoherency();
   _type->checkCoherencyBetween(_mesh,getArray());
 }
 
 /*!
- * Returns the accumulation (the sum) of comId_th component of each tuples of default array.
+ * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array.
  */
 double MEDCouplingFieldDouble::accumulate(int compId) const
 {
-  const double *ptr=getArray()->getConstPointer();
-  int nbTuple=getArray()->getNumberOfTuples();
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
+  return getArray()->accumulate(compId);
+}
+
+/*!
+ * Returns the accumulation (the sum) of all tuples of \b default and \b only default array.
+ * The res is expected to be of size getNumberOfComponents().
+ */
+void MEDCouplingFieldDouble::accumulate(double *res) const
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
+  getArray()->accumulate(res);
+}
+
+/*!
+ * This method returns the max value in 'this'. 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown.
+ * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
+ * If no arrays exists, an exception will be thrown.
+ */
+double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  double ret=-std::numeric_limits<double>::max();
+  bool isExistingArr=false;
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    {
+      if(*iter)
+        {
+          isExistingArr=true;
+          int loc;
+          ret=std::max(ret,(*iter)->getMaxValue(loc));
+        }
+    }
+  if(!isExistingArr)
+    throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
+  return ret;
+}
+
+/*!
+ * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned 
+ * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
+ * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
+ * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
+ * to compute tupleIds.
+ */
+double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  double ret=-std::numeric_limits<double>::max();
+  bool isExistingArr=false;
+  tupleIds=0;
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    {
+      if(*iter)
+        {
+          isExistingArr=true;
+          DataArrayInt *tmp;
+          ret=std::max(ret,(*iter)->getMaxValue2(tmp));
+          if(!tupleIds)
+            tupleIds=tmp;
+          else
+            tmp->decrRef();
+        }
+    }
+  if(!isExistingArr)
+    throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
+  return ret;
+}
+
+/*!
+ * This method returns the min value in 'this'. 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown.
+ * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
+ * If no arrays exists, an exception will be thrown.
+ */
+double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  double ret=std::numeric_limits<double>::max();
+  bool isExistingArr=false;
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    {
+      if(*iter)
+        {
+          isExistingArr=true;
+          int loc;
+          ret=std::min(ret,(*iter)->getMinValue(loc));
+        }
+    }
+  if(!isExistingArr)
+    throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
+  return ret;
+}
+
+/*!
+ * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned 
+ * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
+ * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
+ * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
+ * to compute tupleIds.
+ */
+double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  double ret=-std::numeric_limits<double>::max();
+  bool isExistingArr=false;
+  tupleIds=0;
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    {
+      if(*iter)
+        {
+          isExistingArr=true;
+          DataArrayInt *tmp;
+          ret=std::max(ret,(*iter)->getMinValue2(tmp));
+          if(!tupleIds)
+            tupleIds=tmp;
+          else
+            tmp->decrRef();
+        }
+    }
+  if(!isExistingArr)
+    throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
+  return ret;
+}
+
+/*!
+ * This method returns the average value in 'this'. 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown.
+ * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
+ * If default array does not exist, an exception will be thrown.
+ */
+double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
+  return getArray()->getAverageValue();
+}
+
+/*!
+ * This method returns the average value in 'this' weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
+ * 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown.
+ * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
+ * If default array does not exist, an exception will be thrown.
+ */
+double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception)
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
+  MEDCouplingFieldDouble *w=buildMeasureField(true);
+  double deno=w->getArray()->accumulate(0);
+  w->getArray()->multiplyEqual(getArray());
+  double res=w->getArray()->accumulate(0);
+  w->decrRef();
+  return res/deno;
+}
+
+/*!
+ * Returns the normL1 of current field on compId component :
+ * \f[
+ * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
+ * \f]
+ * If compId>=nbOfComponent an exception is thrown.
+ */
+double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
   int nbComps=getArray()->getNumberOfComponents();
-  double ret=0.;
-  for(int i=0;i<nbTuple;i++)
-    ret+=ptr[i*nbComps+compId];
+  if(compId>=nbComps)
+    throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
+  double *res=new double[nbComps];
+  try
+    {
+      _type->normL1(_mesh,getArray(),res);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete [] res;
+      throw e;
+    }
+  double ret=res[compId];
+  delete [] res;
   return ret;
 }
 
 /*!
- * Returns the accumulation (the sum) of all tuples of default array.
+ * Returns the normL1 of current field on each components :
+ * \f[
+ * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
+ * \f]
  * The res is expected to be of size getNumberOfComponents().
  */
-void MEDCouplingFieldDouble::accumulate(double *res) const
+void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception)
 {
-  const double *ptr=getArray()->getConstPointer();
-  int nbTuple=getArray()->getNumberOfTuples();
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
+  _type->normL1(_mesh,getArray(),res);
+}
+
+/*!
+ * Returns the normL2 of current field on compId component :
+ * \f[
+ * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
+ * \f]
+ * If compId>=nbOfComponent an exception is thrown.
+ */
+double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
   int nbComps=getArray()->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<double>());
+  if(compId>=nbComps)
+    throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
+  double *res=new double[nbComps];
+  try
+    {
+      _type->normL2(_mesh,getArray(),res);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete [] res;
+      throw e;
+    }
+  double ret=res[compId];
+  delete [] res;
+  return ret;
+}
+
+/*!
+ * Returns the normL2 of current field on each components :
+ * \f[
+ * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
+ * \f]
+ * The res is expected to be of size getNumberOfComponents().
+ */
+void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
+  _type->normL2(_mesh,getArray(),res);
 }
 
 /*!
@@ -156,17 +624,25 @@ void MEDCouplingFieldDouble::accumulate(double *res) const
  * returns by getWeightingField relative of the _type of field of default array.
  * This method is usefull to check the conservativity of interpolation method.
  */
-double MEDCouplingFieldDouble::measureAccumulate(int compId, bool isWAbs) const
+double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
 {
   if(!_mesh)
-    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform measureAccumulate");
-  MEDCouplingFieldDouble *weight=_type->getWeightingField(_mesh,isWAbs);
-  const double *ptr=weight->getArray()->getConstPointer();
-  int nbOfValues=weight->getArray()->getNbOfElems();
-  double ret=0.;
-  for (int i=0; i<nbOfValues; i++)
-    ret+=getIJ(i,compId)*ptr[i];
-  weight->decrRef();
+    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
+  int nbComps=getArray()->getNumberOfComponents();
+  if(compId>=nbComps)
+    throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
+  double *res=new double[nbComps];
+  try
+    {
+      _type->integral(_mesh,getArray(),isWAbs,res);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete [] res;
+      throw e;
+    }
+  double ret=res[compId];
+  delete [] res;
   return ret;
 }
 
@@ -175,24 +651,11 @@ double MEDCouplingFieldDouble::measureAccumulate(int compId, bool isWAbs) const
  * returns by getWeightingField relative of the _type of field of default array.
  * This method is usefull to check the conservativity of interpolation method.
  */
-void MEDCouplingFieldDouble::measureAccumulate(bool isWAbs, double *res) const
+void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
 {
   if(!_mesh)
-    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform measureAccumulate2");
-  MEDCouplingFieldDouble *weight=_type->getWeightingField(_mesh,isWAbs);
-  const double *ptr=weight->getArray()->getConstPointer();
-  int nbOfValues=weight->getArray()->getNbOfElems();
-  int nbComps=getArray()->getNumberOfComponents();
-  const double *vals=getArray()->getConstPointer();
-  std::fill(res,res+nbComps,0.);
-  double *tmp=new double[nbComps];
-  for (int i=0; i<nbOfValues; i++)
-    {
-      std::transform(vals+i*nbComps,vals+(i+1)*nbComps,tmp,std::bind2nd(std::multiplies<double>(),ptr[i]));
-      std::transform(tmp,tmp+nbComps,res,res,std::plus<double>());
-    }
-  weight->decrRef();
-  delete [] tmp;
+    throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
+  _type->integral(_mesh,getArray(),isWAbs,res);
 }
 
 /*!
@@ -242,6 +705,46 @@ void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
   _time_discr->applyLin(a,b,compoId);
 }
 
+/*!
+ * This method sets 'this' to a uniform scalar field with one component.
+ * All tuples will have the same value 'value'.
+ * An exception is thrown if no underlying mesh is defined.
+ */
+MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
+  int nbOfTuple=_type->getNumberOfTuples(_mesh);
+  _time_discr->setUniformValue(nbOfTuple,1,value);
+  return *this;
+}
+
+/*!
+ * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
+ * The main difference is that the field as been started to be constructed here.
+ * An exception is throw if no underlying mesh is set before the call of this method.
+ */
+void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
+  _time_discr->fillFromAnalytic(loc,nbOfComp,func);
+}
+
+/*!
+ * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
+ * The main difference is that the field as been started to be constructed here.
+ * An exception is throw if no underlying mesh is set before the call of this method.
+ */
+void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
+  _time_discr->fillFromAnalytic(loc,nbOfComp,func);
+}
+
 /*!
  * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr.
  * If '*func' returns false during one evaluation an exception will be thrown.
@@ -251,6 +754,18 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
   _time_discr->applyFunc(nbOfComp,func);
 }
 
+/*!
+ * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to
+ * ParaMEDMEM::MEDCouplingFieldDouble::operator=.
+ */
+void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
+  int nbOfTuple=_type->getNumberOfTuples(_mesh);
+  _time_discr->setUniformValue(nbOfTuple,nbOfComp,val);
+}
+
 /*!
  * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
  * If '*func' fails in evaluation during one evaluation an exception will be thrown.
@@ -271,11 +786,45 @@ void MEDCouplingFieldDouble::applyFunc(const char *func)
   _time_discr->applyFunc(func);
 }
 
-int MEDCouplingFieldDouble::getNumberOfComponents() const
+/*!
+ * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
+ * The field will contain exactly the same number of components after the call.
+ * Use is not warranted for the moment !
+ */
+void MEDCouplingFieldDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
 {
+  _time_discr->applyFuncFast32(func);
+}
+
+/*!
+ * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
+ * The field will contain exactly the same number of components after the call.
+ * Use is not warranted for the moment !
+ */
+void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
+{
+  _time_discr->applyFuncFast64(func);
+}
+
+/*!
+ * This method makes the assumption that the default array has been set before.
+ * If not an exception will be sent.
+ * If default array set, the number of components will be sent.
+ */
+int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception)
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
   return getArray()->getNumberOfComponents();
 }
 
+/*!
+ * This method makes the assumption that _mesh has be set before the call of this method and description of gauss
+ * localizations in case of Gauss field. If not an exception will sent.
+ * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is
+ * \b not aware of the presence of the default array.
+ * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that !
+ */
 int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception)
 {
   if(!_mesh)
@@ -283,6 +832,18 @@ int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Excep
   return _type->getNumberOfTuples(_mesh);
 }
 
+/*!
+ * This method makes the assumption that the default array has been set before.
+ * If not an exception will be sent.
+ * If default array set, the number of values present in the default array will be sent.
+ */
+int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception)
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
+  return getArray()->getNbOfElems();
+}
+
 void MEDCouplingFieldDouble::updateTime()
 {
   MEDCouplingField::updateTime();
@@ -295,11 +856,21 @@ void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::E
   _nature=nat;
 }
 
+double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
+{
+  return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
+}
+
 void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
 {
   _time_discr->setArray(array,this);
 }
 
+void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
+{
+  _time_discr->setEndArray(array,this);
+}
+
 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
 {
   tinyInfo.clear();
@@ -320,6 +891,10 @@ void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>
   tinyInfo.push_back((int)_time_discr->getEnum());
   tinyInfo.push_back((int)_nature);
   _time_discr->getTinySerializationIntInformation(tinyInfo);
+  std::vector<int> tinyInfo2;
+  _type->getTinySerializationIntInformation(tinyInfo2);
+  tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
+  tinyInfo.push_back(tinyInfo2.size());
 }
 
 /*!
@@ -330,25 +905,45 @@ void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<dou
 {
   tinyInfo.clear();
   _time_discr->getTinySerializationDbleInformation(tinyInfo);
+  std::vector<double> tinyInfo2;
+  _type->getTinySerializationDbleInformation(tinyInfo2);
+  tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
+  tinyInfo.push_back(tinyInfo2.size());
 }
 
 /*!
  * This method has to be called to the new instance filled by CORBA, MPI, File...
  * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
+ * @param dataInt out parameter. If not null the pointer is already owned by 'this' after the call of this method. In this case no decrRef must be applied.
  * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by 'this' after the call of this method.
  *               No decrRef must be applied to every instances in returned vector.
  */
-void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays)
+void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
 {
-  std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
+  dataInt=0;
+  std::vector<int> tinyInfoITmp(tinyInfoI);
+  int sz=tinyInfoITmp.back();
+  tinyInfoITmp.pop_back();
+  std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
+  std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
   _time_discr->resizeForUnserialization(tinyInfoI2,arrays);
+  std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
+  _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
 }
 
 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
 {
   std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
-  _time_discr->finishUnserialization(tinyInfoI2,tinyInfoD,tinyInfoS);
+  //
+  std::vector<double> tmp(tinyInfoD);
+  int sz=tinyInfoD.back();
+  tmp.pop_back();
+  std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
+  std::vector<double> tmp2(tmp.end()-sz,tmp.end());
+  //
+  _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
   _nature=(NatureOfField)tinyInfoI[2];
+  _type->finishUnserialization(tmp2);
   int nbOfElemS=tinyInfoS.size();
   _name=tinyInfoS[nbOfElemS-2];
   _desc=tinyInfoS[nbOfElemS-1];
@@ -358,48 +953,251 @@ void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyI
  * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
  * The values returned must be consulted only in readonly mode.
  */
-void MEDCouplingFieldDouble::serialize(std::vector<DataArrayDouble *>& arrays) const
+void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
 {
   _time_discr->getArrays(arrays);
+  _type->getSerializationIntArray(dataInt);
+}
+
+/*!
+ * This method tries to to change the mesh support of 'this' following the parameter 'levOfCheck' and 'prec'.
+ * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job.
+ * If this->_mesh is not defined or other an exeption will be throw.
+ */
+void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
+{
+  if(_mesh==0 || other==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
+  DataArrayInt *cellCor,*nodeCor;
+  _mesh->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor);
+  if(cellCor)
+    {
+      renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
+      cellCor->decrRef();
+    }
+  if(nodeCor)
+    {
+      renumberNodesWithoutMesh(nodeCor->getConstPointer());
+      nodeCor->decrRef();
+    }
+  setMesh((MEDCouplingMesh *)other);
 }
 
 /*!
- * \b Warning ! This method potentially modifies the underlying mesh ! If the mesh is shared by other fields, these fields could be unavailable.
+ * This method is an extension of MEDCouplingFieldDouble::operator-=. It allows a user to operate a difference of 2 fields ('this' and 'f') even if they do not share same meshes.
+ * No interpolation will be done here only an analyze of two underlying mesh will be done to see if the meshes are geometrically equivalent. If yes, the eventual renumbering will be done and operator-= applyed after.
+ * This method requires that 'f' and 'this' are coherent (check coherency) and that 'f' and 'this' would be coherent for a merge.
+ * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method.
  */
-bool MEDCouplingFieldDouble::mergeNodes(double eps)
+void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
 {
-  MEDCouplingPointSet *meshC=dynamic_cast<MEDCouplingPointSet *>((MEDCouplingMesh *)(_mesh));
+  checkCoherency();
+  f->checkCoherency();
+  if(!areCompatibleForMerge(f))
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !");
+  changeUnderlyingMesh(f->getMesh(),levOfCheck,prec);
+  operator-=(*f);
+}
+
+/*!
+ * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
+ */
+bool MEDCouplingFieldDouble::mergeNodes(double eps) throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
   if(!meshC)
-    throw INTERP_KERNEL::Exception("Invalid mesh to apply mergeNodes on it !");
+    throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
   bool ret;
-  DataArrayInt *arr=meshC->mergeNodes(eps,ret);
+  int ret2;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
   if(!ret)//no nodes have been merged.
     return ret;
   std::vector<DataArrayDouble *> arrays;
   _time_discr->getArrays(arrays);
-  try
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    if(*iter)
+      _type->renumberValuesOnNodes(arr->getConstPointer(),*iter);
+  setMesh(meshC2);
+  return true;
+}
+
+/*!
+ * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet.
+ * If some nodes have disappeared true is returned.
+ */
+bool MEDCouplingFieldDouble::zipCoords() throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
+  if(!meshC)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
+  int oldNbOfNodes=meshC2->getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipCoordsTraducer();
+  if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
     {
+      std::vector<DataArrayDouble *> arrays;
+      _time_discr->getArrays(arrays);
       for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
-        _type->renumberValuesOnNodes(arr,*iter);
+        if(*iter)
+          _type->renumberValuesOnNodes(arr->getConstPointer(),*iter);
+      setMesh(meshC2);
+      return true;
     }
-  catch(INTERP_KERNEL::Exception& e)
+  return false;
+}
+
+/*!
+ * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh.
+ * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method.
+ */
+bool MEDCouplingFieldDouble::zipConnectivity(int compType) throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
+  if(!meshC)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCpy());
+  int oldNbOfCells=meshC2->getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
+  if(meshC2->getNumberOfCells()!=oldNbOfCells)
     {
-      arr->decrRef();
-      throw e;
+      std::vector<DataArrayDouble *> arrays;
+      _time_discr->getArrays(arrays);
+      for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+        if(*iter)
+          _type->renumberValuesOnCells(meshC,arr->getConstPointer(),*iter);
+      setMesh(meshC2);
+      return true;
     }
-  arr->decrRef();
-  return true;
+  return false;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("DoublyContractedProduct");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->determinant();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("Determinant");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->eigenValues();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("EigenValues");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("EigenVectors");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->inverse();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("Inversion");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->trace();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("Trace");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->deviator();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("Trace");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->magnitude();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName("Magnitude");
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple();
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  std::ostringstream oss;
+  oss << "Max_" << getName();
+  ret->setName(oss.str().c_str());
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception)
+{
+  _time_discr->changeNbOfComponents(newNbOfComp,dftValue);
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds);
+  td->copyTinyAttrFrom(*_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  ret->setName(getName());
+  ret->setMesh(getMesh());
+  return ret;
+}
+
+void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
+{
+  _time_discr->setSelectedComponents(f->_time_discr,compoIds);
+}
+
+void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
+{
+  _time_discr->sortPerTuple(asc);
 }
 
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
 {
-  if(!f1->areCompatible(f2))
+  if(!f1->areCompatibleForMerge(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply mergeFields on them !");
   const MEDCouplingMesh *m1=f1->getMesh();
   const MEDCouplingMesh *m2=f2->getMesh();
   MEDCouplingMesh *m=m1->mergeMyselfWith(m2);
   MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr);
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
   ret->setMesh(m);
   m->decrRef();
   ret->setName(f1->getName());
@@ -407,38 +1205,86 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFie
   return ret;
 }
 
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+{
+  if(!f1->areStrictlyCompatible(f2))
+    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply dotFields on them !");
+  MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  ret->setMesh(f1->getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+{
+  if(!f1->areStrictlyCompatible(f2))
+    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply crossProductFields on them !");
+  MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  ret->setMesh(f1->getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+{
+  if(!f1->areStrictlyCompatible(f2))
+    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply maxFields on them !");
+  MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  ret->setMesh(f1->getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+{
+  if(!f1->areStrictlyCompatible(f2))
+    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply minFields on them !");
+  MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  ret->setMesh(f1->getMesh());
+  return ret;
+}
+
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
 {
-  if(!f1->areCompatible(f2))
+  if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply addFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret;
 }
 
-void MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
 {
-  if(!areCompatible(&other))
+  if(!areStrictlyCompatible(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
   _time_discr->addEqual(other._time_discr);
+  return *this;
 }
 
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
 {
-  if(!f1->areCompatible(f2))
+  if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply substractFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr);
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret;
 }
 
-void MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
 {
-  if(!areCompatible(&other))
+  if(!areStrictlyCompatible(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !");
   _time_discr->substractEqual(other._time_discr);
+  return *this;
 }
 
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
@@ -446,31 +1292,35 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCoupling
   if(!f1->areCompatibleForMul(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply multiplyFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr);
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret;
 }
 
-void MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
 {
   if(!areCompatibleForMul(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
   _time_discr->multiplyEqual(other._time_discr);
+  return *this;
 }
 
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
 {
-  if(!f1->areCompatible(f2))
+  if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply divideFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr);
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret;
 }
 
-void MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
 {
-  if(!areCompatible(&other))
+  if(!areStrictlyCompatible(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
   _time_discr->divideEqual(other._time_discr);
+  return *this;
 }
index bffdc3e17ed743765c7a52a2ccf3ee22e8f94251..48c0bace0db8b96f447ecb9cfeeff11d272d6bc8 100644 (file)
@@ -32,64 +32,123 @@ namespace ParaMEDMEM
   {
   public:
     static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME);
+    void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
+    std::string simpleRepr() const;
+    std::string advancedRepr() const;
     bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
-    bool areCompatible(const MEDCouplingField *other) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
+    bool areCompatibleForMerge(const MEDCouplingField *other) const;
+    bool areStrictlyCompatible(const MEDCouplingField *other) const;
     bool areCompatibleForMul(const MEDCouplingField *other) const;
+    void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
+    void renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
+    void renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception);
+    void renumberNodesWithoutMesh(const int *old2NewBg) throw(INTERP_KERNEL::Exception);
+    DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *clone(bool recDeepCpy) const;
+    MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const;
     MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const;
     TypeOfTimeDiscretization getTimeDiscretization() const;
     void checkCoherency() const throw(INTERP_KERNEL::Exception);
     NatureOfField getNature() const { return _nature; }
     void setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception);
-    void setTime(double val, int dt, int it) { _time_discr->setTime(val,dt,it); }
-    void setStartTime(double val, int dt, int it) { _time_discr->setStartTime(val,dt,it); }
-    void setEndTime(double val, int dt, int it) { _time_discr->setEndTime(val,dt,it); }
-    double getTime(int& dt, int& it) const { return _time_discr->getTime(dt,it); }
-    double getStartTime(int& dt, int& it) const { return _time_discr->getStartTime(dt,it); }
-    double getEndTime(int& dt, int& it) const { return _time_discr->getEndTime(dt,it); }
+    void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); }
+    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); }
+    double getStartTime(int& iteration, int& order) const { return _time_discr->getStartTime(iteration,order); }
+    double getEndTime(int& iteration, int& order) const { return _time_discr->getEndTime(iteration,order); }
     double getIJ(int tupleId, int compoId) const { return getArray()->getIJ(tupleId,compoId); }
+    double getIJK(int cellId, int nodeIdInCell, int compoId) const;
     void setArray(DataArrayDouble *array);
+    void setEndArray(DataArrayDouble *array);
     DataArrayDouble *getArray() const { return _time_discr->getArray(); }
+    DataArrayDouble *getEndArray() const { return _time_discr->getEndArray(); }
     double accumulate(int compId) const;
     void accumulate(double *res) const;
-    double measureAccumulate(int compId, bool isWAbs) const;
-    void measureAccumulate(bool isWAbs, double *res) const;
+    double getMaxValue() const throw(INTERP_KERNEL::Exception);
+    double getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception);
+    double getMinValue() const throw(INTERP_KERNEL::Exception);
+    double getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception);
+    double getAverageValue() const throw(INTERP_KERNEL::Exception);
+    double getWeightedAverageValue() const throw(INTERP_KERNEL::Exception);
+    double normL1(int compId) const throw(INTERP_KERNEL::Exception);
+    void normL1(double *res) const throw(INTERP_KERNEL::Exception);
+    double normL2(int compId) const throw(INTERP_KERNEL::Exception);
+    void normL2(double *res) const throw(INTERP_KERNEL::Exception);
+    double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception);
+    void integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception);
     void getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception);
     void getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception);
     void getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception);
     //! \b temporary
     void applyLin(double a, double b, int compoId);
+    MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception);
+    void fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception);
+    void fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception);
     void applyFunc(int nbOfComp, FunctionToEvaluate func);
+    void applyFunc(int nbOfComp, double val);
     void applyFunc(int nbOfComp, const char *func);
     void applyFunc(const char *func);
-    int getNumberOfComponents() const;
+    void applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception);
+    void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception);
+    int getNumberOfComponents() const throw(INTERP_KERNEL::Exception);
     int getNumberOfTuples() const throw(INTERP_KERNEL::Exception);
+    int getNumberOfValues() const throw(INTERP_KERNEL::Exception);
     void updateTime();
     //
     void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
     void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
     void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
-    void resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays);
+    void resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays);
     void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
-    void serialize(std::vector<DataArrayDouble *>& arrays) const;
-    bool mergeNodes(double eps);
+    void serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const;
+    //
+    void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception);
+    void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception);
+    bool mergeNodes(double eps) throw(INTERP_KERNEL::Exception);
+    bool zipCoords() throw(INTERP_KERNEL::Exception);
+    bool zipConnectivity(int compType) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *determinant() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *eigenValues() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *eigenVectors() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *inverse() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *trace() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *deviator() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *magnitude() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception);
+    void changeNbOfComponents(int newNbOfComp, double dftValue=0.) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
+    void setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
+    void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception);
     static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const { return dotFields(this,&other); }
+    static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const { return crossProductFields(this,&other); }
+    static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const { return maxFields(this,&other); }
+    static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const { return minFields(this,&other); }
     MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const { return addFields(this,&other); }
-    void operator+=(const MEDCouplingFieldDouble& other);
+    const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other);
     static MEDCouplingFieldDouble *addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
     MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const { return substractFields(this,&other); }
-    void operator-=(const MEDCouplingFieldDouble& other);
+    const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other);
     static MEDCouplingFieldDouble *substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
     MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const { return multiplyFields(this,&other); }
-    void operator*=(const MEDCouplingFieldDouble& other);
+    const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other);
     static MEDCouplingFieldDouble *multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
     MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const { return divideFields(this,&other); }
-    void operator/=(const MEDCouplingFieldDouble& other);
+    const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other);
     static MEDCouplingFieldDouble *divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
   private:
     MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td);
     MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy);
-    MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, TypeOfField type);
+    MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type);
     ~MEDCouplingFieldDouble();
   private:
     NatureOfField _nature;
diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx
new file mode 100644 (file)
index 0000000..68c9a06
--- /dev/null
@@ -0,0 +1,215 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MEDCouplingGaussLocalization.hxx"
+#include "CellModel.hxx"
+
+#include <cmath>
+#include <numeric>
+#include <sstream>
+#include <algorithm>
+
+ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                                                       const std::vector<double>& gsCoo, const std::vector<double>& w) throw(INTERP_KERNEL::Exception)
+try:_type(type),_ref_coord(refCoo),_gauss_coord(gsCoo),_weight(w)
+  {
+    checkCoherency();
+  }
+catch(INTERP_KERNEL::Exception& e)
+  {
+    _type=INTERP_KERNEL::NORM_ERROR;
+    _ref_coord.clear();
+    _gauss_coord.clear();
+    _weight.clear();
+    throw e;
+  }
+
+void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(_type);
+  int nbNodes=cm.getNumberOfNodes();
+  int dim=cm.getDimension();
+  if(!cm.isDynamic())
+    {
+      if((int)_ref_coord.size()!=nbNodes*dim)
+        {
+          std::ostringstream oss; oss << "Invalid size of refCoo : expecting to be : " << nbNodes << " (nbNodePerCell) * " << dim << " (dim) !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  if(_gauss_coord.size()!=dim*_weight.size())
+    {
+       std::ostringstream oss; oss << "Invalid gsCoo size and weight size : gsCoo.size() must be equal to _weight.size() * " << dim << " (dim) !";
+       throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
+int ParaMEDMEM::MEDCouplingGaussLocalization::getDimension() const
+{
+  if(_weight.empty())
+    return -1;
+  return _gauss_coord.size()/_weight.size();
+}
+
+int ParaMEDMEM::MEDCouplingGaussLocalization::getNumberOfPtsInRefCell() const
+{
+  int dim=getDimension();
+  if(dim==0)
+    return -1;
+  return _ref_coord.size()/dim;
+}
+
+bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const
+{
+  if(_type!=other._type)
+    return false;
+  if(!areAlmostEqual(_ref_coord,other._ref_coord,eps))
+    return false;
+  if(!areAlmostEqual(_gauss_coord,other._gauss_coord,eps))
+    return false;
+  if(!areAlmostEqual(_weight,other._weight,eps))
+    return false;
+  return true;
+}
+
+double ParaMEDMEM::MEDCouplingGaussLocalization::getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(_type);
+  int nbNodes=cm.getNumberOfNodes();
+  int dim=cm.getDimension();
+  if(ptIdInCell<0 || ptIdInCell>=nbNodes)
+    throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !");
+  if(comp<0 || comp>=dim)
+    throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
+  return _ref_coord[ptIdInCell*dim+comp];
+}
+
+double ParaMEDMEM::MEDCouplingGaussLocalization::getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
+{
+  int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp);
+  return _gauss_coord[gaussPtIdInCell*dim+comp];
+}
+
+double ParaMEDMEM::MEDCouplingGaussLocalization::getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherencyOfRequest(gaussPtIdInCell,0);
+  return _weight[gaussPtIdInCell];
+}
+
+/*!
+ * Completely useless method for end user. Only for CORBA MPI serialization/unserialization.
+ * push at the end of tinyInfo its basic serialization info. The size of pushed data is always the same.
+ * @param tinyInfo inout parameter.
+ */
+void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo(std::vector<int>& tinyInfo) const
+{
+  tinyInfo.push_back((int)_type);
+  tinyInfo.push_back(getNumberOfPtsInRefCell());
+  tinyInfo.push_back(getNumberOfGaussPt());
+}
+
+/*!
+ * Completely useless method for end user. Only for CORBA MPI serialization/unserialization.
+ * push at the end of tinyInfo its basic serialization info. The size of pushed data is \b NOT always the same contrary to pushTinySerializationIntInfo.
+ * @param tinyInfo inout parameter.
+ */
+void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo(std::vector<double>& tinyInfo) const
+{
+  tinyInfo.insert(tinyInfo.end(),_ref_coord.begin(),_ref_coord.end());
+  tinyInfo.insert(tinyInfo.end(),_gauss_coord.begin(),_gauss_coord.end());
+  tinyInfo.insert(tinyInfo.end(),_weight.begin(),_weight.end());
+}
+
+/*!
+ * This method operates the exact inverse operation than ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo method. This is one of the last step of unserialization process.
+ * This method should be called on an object resized by buildNewInstanceFromTinyInfo static method.
+ * This method takes in argument a pointer 'vals' that point to the begin of double data pushed remotely by pushTinySerializationDblInfo method.
+ * This method returns the pointer 'vals' with an offset of size what it has been read in this method.
+ */
+const double *ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues(const double *vals)
+{
+  const double *work=vals;
+  std::copy(work,work+_ref_coord.size(),_ref_coord.begin());
+  work+=_ref_coord.size();
+  std::copy(work,work+_gauss_coord.size(),_gauss_coord.begin());
+  work+=_gauss_coord.size();
+  std::copy(work,work+_weight.size(),_weight.begin());
+  work+=_weight.size();
+  return work;
+}
+
+/*!
+ * This method sets the comp_th component of ptIdInCell_th point coordinate of reference element of type this->_type.
+ * @throw if not 0<=ptIdInCell<nbOfNodePerCell or if not 0<=comp<dim
+ */
+void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoord(int ptIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception)
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(_type);
+  int nbNodes=cm.getNumberOfNodes();
+  int dim=cm.getDimension();
+  if(ptIdInCell<0 || ptIdInCell>=nbNodes)
+    throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !");
+  if(comp<0 || comp>=dim)
+    throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
+  _ref_coord[ptIdInCell*dim+comp]=newVal;
+}
+
+void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception)
+{
+  int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp);
+  _gauss_coord[gaussPtIdInCell*dim+comp]=newVal;
+}
+
+void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception)
+{
+  checkCoherencyOfRequest(gaussPtIdInCell,0);
+  _weight[gaussPtIdInCell]=newVal;
+}
+
+/*!
+ * The format of 'tinyData' parameter is the same than pushed in method ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo.
+ */
+ParaMEDMEM::MEDCouplingGaussLocalization ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo(int dim, const std::vector<int>& tinyData)
+{
+  std::vector<double> v1(dim*tinyData[1]),v2(dim*tinyData[2]),v3(tinyData[2]);
+  return ParaMEDMEM::MEDCouplingGaussLocalization((INTERP_KERNEL::NormalizedCellType)tinyData[0],v1,v2,v3);
+}
+
+int ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(_type);
+  int dim=cm.getDimension();
+  int nbGsPts=getNumberOfGaussPt();
+  if(gaussPtIdInCell<0 || gaussPtIdInCell>=nbGsPts)
+    throw INTERP_KERNEL::Exception("gaussPtIdInCell specified is invalid : must be in [0:nbGsPts) !");
+  if(comp<0 || comp>=dim)
+    throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
+  return dim;
+}
+
+bool ParaMEDMEM::MEDCouplingGaussLocalization::areAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps)
+{
+  int sz=v1.size();
+  if(sz!=(int)v2.size())
+    return false;
+  std::vector<double> tmp(sz);
+  std::transform(v1.begin(),v1.end(),v2.begin(),tmp.begin(),std::minus<double>());
+  std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::ptr_fun<double,double>(fabs));
+  return *std::max_element(tmp.begin(),tmp.end())<eps;
+}
diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.hxx b/src/MEDCoupling/MEDCouplingGaussLocalization.hxx
new file mode 100644 (file)
index 0000000..791e243
--- /dev/null
@@ -0,0 +1,70 @@
+//  Copyright (C) 2007-2010  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 __PARAMEDMEM_MEDCOUPLINGGAUSSLOCALIZATION_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGGAUSSLOCALIZATION_HXX__
+
+#include "MEDCoupling.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
+#include "InterpKernelException.hxx"
+
+#include <vector>
+
+namespace ParaMEDMEM
+{
+  class MEDCouplingMesh;
+
+  class MEDCOUPLING_EXPORT MEDCouplingGaussLocalization
+  {
+  public:
+    MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                 const std::vector<double>& gsCoo, const std::vector<double>& w) throw(INTERP_KERNEL::Exception);
+    INTERP_KERNEL::NormalizedCellType getType() const { return _type; }
+    int getNumberOfGaussPt() const { return _weight.size(); }
+    int getDimension() const;
+    int getNumberOfPtsInRefCell() const;
+    void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const;
+    void pushTinySerializationIntInfo(std::vector<int>& tinyInfo) const;
+    void pushTinySerializationDblInfo(std::vector<double>& tinyInfo) const;
+    const double *fillWithValues(const double *vals);
+    //
+    const std::vector<double>& getRefCoords() const { return _ref_coord; }
+    double getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception);
+    const std::vector<double>& getGaussCoords() const { return _gauss_coord; }
+    double getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception);
+    const std::vector<double>& getWeights() const { return _weight; }
+    double getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception);
+    void setRefCoord(int ptIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception);
+    void setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception);
+    void setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception);
+    //
+    static MEDCouplingGaussLocalization buildNewInstanceFromTinyInfo(int dim, const std::vector<int>& tinyData);
+  private:
+    int checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception);
+    static bool areAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps);
+  private:
+    INTERP_KERNEL::NormalizedCellType _type;
+    std::vector<double> _ref_coord;
+    std::vector<double> _gauss_coord;
+    std::vector<double> _weight;
+  };
+}
+
+#endif
index 3456e329b73c0e36f7d0673c3b20e17e8212e21e..5365cb97c1b0d61a762e6551b8d4add3a9cfa499 100644 (file)
 //
 
 #include "MEDCouplingMemArray.txx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
+#include "GenMathFormulae.hxx"
+#include "InterpKernelExprParser.hxx"
+
+#include <set>
+#include <cmath>
+#include <numeric>
 #include <functional>
 
+typedef double (*MYFUNCPTR)(double);
+
 using namespace ParaMEDMEM;
 
 void DataArray::setName(const char *name)
@@ -36,6 +45,36 @@ void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::
   _info_on_compo=other._info_on_compo;
 }
 
+void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
+{
+  int nbOfCompoOth=other.getNumberOfComponents();
+  int newNbOfCompo=compoIds.size();
+  for(int i=0;i<newNbOfCompo;i++)
+    if(compoIds[i]>=nbOfCompoOth)
+      {
+        std::ostringstream oss; oss << "Specified component ids is to high (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  for(int i=0;i<newNbOfCompo;i++)
+    setInfoOnComponent(i,other.getInfoOnComponent(compoIds[i]).c_str());
+}
+
+void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
+{
+  int nbOfCompo=getNumberOfComponents();
+  int partOfCompoToSet=compoIds.size();
+  if(partOfCompoToSet!=other.getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
+  for(int i=0;i<partOfCompoToSet;i++)
+    if(compoIds[i]>=nbOfCompo)
+      {
+        std::ostringstream oss; oss << "Specified component ids is to high (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  for(int i=0;i<partOfCompoToSet;i++)
+    setInfoOnComponent(compoIds[i],other.getInfoOnComponent(i).c_str());
+}
+
 bool DataArray::areInfoEquals(const DataArray& other) const
 {
   if(_nb_of_tuples!=other._nb_of_tuples)
@@ -45,6 +84,37 @@ bool DataArray::areInfoEquals(const DataArray& other) const
   return _info_on_compo==other._info_on_compo;
 }
 
+void DataArray::reprWithoutNameStream(std::ostream& stream) const
+{
+  stream << "Nb of components : "<< getNumberOfComponents() << "\n";
+  stream << "Info of these components : ";
+  for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
+    stream << "\"" << *iter << "\"   ";
+  stream << "\n";
+}
+
+std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
+{
+  if(i<(int)_info_on_compo.size())
+    return _info_on_compo[i];
+  else
+    {
+      std::ostringstream oss; oss << "getInfoOnComponent : Invalid component id transmitted (" << i << ") >= " << (int) _info_on_compo.size();
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
+void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
+{
+  if(i<(int)_info_on_compo.size())
+    _info_on_compo[i]=info;
+  else
+    {
+      std::ostringstream oss; oss << "setInfoOnComponent : Invalid component id transmitted (" << i << ") >= " << (int) _info_on_compo.size();
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
 DataArrayDouble *DataArrayDouble::New()
 {
   return new DataArrayDouble;
@@ -74,6 +144,58 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
   declareAsNew();
 }
 
+void DataArrayDouble::fillWithZero()
+{
+  _mem.fillWithValue(0.);
+  declareAsNew();
+}
+
+void DataArrayDouble::fillWithValue(double val)
+{
+  _mem.fillWithValue(val);
+  declareAsNew();
+}
+
+std::string DataArrayDouble::repr() const
+{
+  std::ostringstream ret;
+  reprStream(ret);
+  return ret.str();
+}
+
+std::string DataArrayDouble::reprZip() const
+{
+  std::ostringstream ret;
+  reprZipStream(ret);
+  return ret.str();
+}
+
+void DataArrayDouble::reprStream(std::ostream& stream) const
+{
+  stream << "Name of double array : \"" << _name << "\"\n";
+  reprWithoutNameStream(stream);
+}
+
+void DataArrayDouble::reprZipStream(std::ostream& stream) const
+{
+  stream << "Name of double array : \"" << _name << "\"\n";
+  reprZipWithoutNameStream(stream);
+}
+
+void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
+{
+  DataArray::reprWithoutNameStream(stream);
+  stream.precision(15);
+  _mem.repr(getNumberOfComponents(),stream);
+}
+
+void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
+{
+  DataArray::reprWithoutNameStream(stream);
+  stream.precision(15);
+  _mem.reprZip(getNumberOfComponents(),stream);
+}
+
 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
 {
   if(!areInfoEquals(other))
@@ -81,6 +203,11 @@ bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
   return _mem.isEqual(other._mem,prec);
 }
 
+bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
+{
+  return _mem.isEqual(other._mem,prec);
+}
+
 void DataArrayDouble::reAlloc(int nbOfTuples)
 {
   _mem.reAlloc(_info_on_compo.size()*nbOfTuples);
@@ -88,6 +215,220 @@ void DataArrayDouble::reAlloc(int nbOfTuples)
   declareAsNew();
 }
 
+DataArrayInt *DataArrayDouble::convertToIntArr() const
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(getNumberOfTuples(),getNumberOfComponents());
+  int nbOfVals=getNbOfElems();
+  const double *src=getConstPointer();
+  int *dest=ret->getPointer();
+  std::copy(src,src+nbOfVals,dest);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * This method does \b not change the number of tuples after this call.
+ * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used.
+ */
+void DataArrayDouble::renumberInPlace(const int *old2New)
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  double *tmp=new double[nbTuples*nbOfCompo];
+  const double *iptr=getConstPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
+  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
+  delete [] tmp;
+  declareAsNew();
+}
+
+/*!
+ * This method does \b not change the number of tuples after this call.
+ * Only a permutation is done.
+ */
+void DataArrayDouble::renumberInPlaceR(const int *new2Old)
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  double *tmp=new double[nbTuples*nbOfCompo];
+  const double *iptr=getConstPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
+  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
+  delete [] tmp;
+  declareAsNew();
+}
+
+/*!
+ * This method does \b not change the number of tuples after this call.
+ * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used.
+ */
+DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(nbTuples,nbOfCompo);
+  ret->copyStringInfoFrom(*this);
+  const double *iptr=getConstPointer();
+  double *optr=ret->getPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * This method does \b not change the number of tuples after this call.
+ * Only a permutation is done.
+ */
+DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(nbTuples,nbOfCompo);
+  ret->copyStringInfoFrom(*this);
+  const double *iptr=getConstPointer();
+  double *optr=ret->getPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * Idem DataArrayDouble::renumber method except that the number of tuples is reduced.
+ * That is to say that it is expected that newNbOfTuple<this->getNumberOfTuples().
+ * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'+getNumberOfTuples()) the corresponding tuple is
+ * omitted.
+ */
+DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(newNbOfTuple,nbOfCompo);
+  const double *iptr=getConstPointer();
+  double *optr=ret->getPointer();
+  for(int i=0;i<nbTuples;i++)
+    {
+      int w=old2New[i];
+      if(w>=0)
+        std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
+    }
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here.
+ * This method is equavalent to DataArrayDouble::renumberAndReduce except that convention in input is new2old and \b not old2new.
+ */
+DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
+{
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbComp=getNumberOfComponents();
+  ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
+  ret->copyStringInfoFrom(*this);
+  double *pt=ret->getPointer();
+  const double *srcPt=getConstPointer();
+  int i=0;
+  for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
+    std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components.
+ * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept.
+ * This method check that interval is valid regarding this, if not an exception will be thrown.
+ */
+DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
+{
+  int nbt=getNumberOfTuples();
+  if(tupleIdBg<0)
+    throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
+  if(tupleIdBg>=nbt)
+    throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
+  int trueEnd=tupleIdEnd;
+  if(tupleIdEnd!=-1)
+    {
+      if(tupleIdEnd>nbt)
+        throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
+    }
+  else
+    trueEnd=nbt;
+  int nbComp=getNumberOfComponents();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(trueEnd-tupleIdBg,nbComp);
+  ret->copyStringInfoFrom(*this);
+  std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
+  return ret;
+}
+
+/*!
+ * This method builds a new instance of DataArrayDouble (to deal with) that is reduction or an extension of 'this'.
+ * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept.
+ * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken.
+ */
+DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
+{
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(getNumberOfTuples(),newNbOfComp);
+  const double *oldc=getConstPointer();
+  double *nc=ret->getPointer();
+  int nbOfTuples=getNumberOfTuples();
+  int oldNbOfComp=getNumberOfComponents();
+  int dim=std::min(oldNbOfComp,newNbOfComp);
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      int j=0;
+      for(;j<dim;j++)
+        nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
+      for(;j<newNbOfComp;j++)
+        nc[newNbOfComp*i+j]=dftValue;
+    }
+  ret->setName(getName().c_str());
+  for(int i=0;i<dim;i++)
+    ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
+  ret->setName(getName().c_str());
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
+  int newNbOfCompo=compoIds.size();
+  int oldNbOfCompo=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  ret->alloc(nbOfTuples,newNbOfCompo);
+  ret->copyPartOfStringInfoFrom(*this,compoIds);
+  const double *oldc=getConstPointer();
+  double *nc=ret->getPointer();
+  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;
+}
+
+void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
+{
+  copyPartOfStringInfoFrom2(compoIds,*a);
+  int partOfCompoSz=compoIds.size();
+  int nbOfCompo=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  const double *ac=a->getConstPointer();
+  double *nc=getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    for(int j=0;j<partOfCompoSz;j++,ac++)
+      nc[nbOfCompo*i+compoIds[j]]=*ac;
+}
+
 void DataArrayDouble::setArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
 {
   if(newArray!=arrayToSet)
@@ -117,7 +458,450 @@ void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
 }
 
-DataArrayDouble *DataArrayDouble::aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
+double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component !");
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples<=0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
+  const double *vals=getConstPointer();
+  const double *loc=std::max_element(vals,vals+nbOfTuples);
+  tupleId=std::distance(vals,loc);
+  return *loc;
+}
+
+double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
+{
+  int tmp;
+  tupleIds=0;
+  double ret=getMaxValue(tmp);
+  tupleIds=getIdsInRange(ret,ret);
+  return ret;
+}
+
+double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component !");
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples<=0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
+  const double *vals=getConstPointer();
+  const double *loc=std::min_element(vals,vals+nbOfTuples);
+  tupleId=std::distance(vals,loc);
+  return *loc;
+}
+
+double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
+{
+  int tmp;
+  tupleIds=0;
+  double ret=getMinValue(tmp);
+  tupleIds=getIdsInRange(ret,ret);
+  return ret;
+}
+
+double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component !");
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples<=0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
+  const double *vals=getConstPointer();
+  double ret=std::accumulate(vals,vals+nbOfTuples,0.);
+  return ret/nbOfTuples;
+}
+
+void DataArrayDouble::accumulate(double *res) const
+{
+  const double *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<double>());
+}
+
+double DataArrayDouble::accumulate(int compId) const
+{
+  const double *ptr=getConstPointer();
+  int nbTuple=getNumberOfTuples();
+  int nbComps=getNumberOfComponents();
+  if(compId>=nbComps)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
+  double ret=0.;
+  for(int i=0;i<nbTuple;i++)
+    ret+=ptr[i*nbComps+compId];
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  if(nbOfComp!=6)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,1);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
+    *dest=src[0]*src[0]+src[1]*src[1]+src[2]*src[2]+2.*src[3]*src[3]+2.*src[4]*src[4]+2.*src[5]*src[5];
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
+{
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,1);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  switch(getNumberOfComponents())
+    {
+    case 6:
+      for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
+        *dest=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
+        return ret;
+    case 4:
+      for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
+        *dest=src[0]*src[3]-src[1]*src[2];
+      return ret;
+    case 9:
+      for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
+        *dest=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6];
+      return ret;
+    default:
+      ret->decrRef();
+      throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
+    }
+}
+
+DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  if(nbOfComp!=6)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,3);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
+    INTERP_KERNEL::computeEigenValues6(src,dest);
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  if(nbOfComp!=6)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,9);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,src+=6)
+    {
+      double tmp[3];
+      INTERP_KERNEL::computeEigenValues6(src,tmp);
+      for(int j=0;j<3;j++,dest+=3)
+        INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
+    }
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,nbOfComp);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+if(nbOfComp==6)
+    for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
+      {
+        double det=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
+        dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
+        dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
+        dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
+        dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
+        dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
+        dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
+      }
+  else if(nbOfComp==4)
+    for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
+      {
+        double det=src[0]*src[3]-src[1]*src[2];
+        dest[0]=src[3]/det;
+        dest[1]=-src[1]/det;
+        dest[2]=-src[2]/det;
+        dest[3]=src[0]/det;
+      }
+  else
+    for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
+      {
+        double det=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6];
+        dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
+        dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
+        dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
+        dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
+        dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
+        dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
+        dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
+        dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
+        dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
+      }
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,1);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  if(nbOfComp==6)
+    for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
+      *dest=src[0]+src[1]+src[2];
+  else if(nbOfComp==4)
+    for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
+      *dest=src[0]+src[3];
+  else
+    for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
+      *dest=src[0]+src[4]+src[8];
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  if(nbOfComp!=6)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,6);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
+    {
+      double tr=(src[0]+src[1]+src[2])/3.;
+      dest[0]=src[0]-tr;
+      dest[1]=src[1]-tr;
+      dest[2]=src[2]-tr;
+      dest[3]=src[3];
+      dest[4]=src[4];
+      dest[5]=src[5];
+    }
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,1);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,dest++)
+    {
+      double sum=0.;
+      for(int j=0;j<nbOfComp;j++,src++)
+        sum+=(*src)*(*src);
+      *dest=sqrt(sum);
+    }
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=getNumberOfComponents();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret->alloc(nbOfTuple,1);
+  const double *src=getConstPointer();
+  double *dest=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
+    *dest=*std::max_element(src,src+nbOfComp);
+  return ret;
+}
+
+void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
+{
+  double *pt=getPointer();
+  int nbOfTuple=getNumberOfTuples();
+  int nbOfComp=getNumberOfComponents();
+  if(asc)
+    for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
+      std::sort(pt,pt+nbOfComp);
+  else
+    for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
+      std::sort(pt,pt+nbOfComp,std::greater<double>());
+  declareAsNew();
+}
+
+void DataArrayDouble::applyLin(double a, double b, int compoId)
+{
+  double *ptr=getPointer()+compoId;
+  int nbOfComp=getNumberOfComponents();
+  int nbOfTuple=getNumberOfTuples();
+  for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
+    *ptr=a*(*ptr)+b;
+  declareAsNew();
+}
+
+DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
+{
+  DataArrayDouble *newArr=DataArrayDouble::New();
+  int nbOfTuples=getNumberOfTuples();
+  int oldNbOfComp=getNumberOfComponents();
+  newArr->alloc(nbOfTuples,nbOfComp);
+  const double *ptr=getConstPointer();
+  double *ptrToFill=newArr->getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
+        {
+          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
+          std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
+          oss << ") : Evaluation of function failed !";
+          newArr->decrRef();
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  return newArr;
+}
+
+DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
+{
+  INTERP_KERNEL::ExprParser expr(func);
+  expr.parse();
+  std::set<std::string> vars;
+  expr.getTrueSetOfVars(vars);
+  int oldNbOfComp=getNumberOfComponents();
+  if((int)vars.size()>oldNbOfComp)
+    {
+      std::ostringstream oss; oss << "The field has a " << oldNbOfComp << " components and there are ";
+      oss << vars.size() << " variables : ";
+      std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  std::vector<std::string> varsV(vars.begin(),vars.end());
+  expr.prepareExprEvaluation(varsV);
+  //
+  DataArrayDouble *newArr=DataArrayDouble::New();
+  int nbOfTuples=getNumberOfTuples();
+  newArr->alloc(nbOfTuples,nbOfComp);
+  const double *ptr=getConstPointer();
+  double *ptrToFill=newArr->getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      try
+        {
+          expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
+        }
+      catch(INTERP_KERNEL::Exception& e)
+        {
+          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
+          std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
+          oss << ") : Evaluation of function failed !" << e.what();
+          newArr->decrRef();
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  return newArr;
+}
+
+DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
+{
+  INTERP_KERNEL::ExprParser expr(func);
+  expr.parse();
+  expr.prepareExprEvaluationVec();
+  //
+  DataArrayDouble *newArr=DataArrayDouble::New();
+  int nbOfTuples=getNumberOfTuples();
+  int nbOfComp=getNumberOfComponents();
+  newArr->alloc(nbOfTuples,nbOfComp);
+  const double *ptr=getConstPointer();
+  double *ptrToFill=newArr->getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      try
+        {
+          expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
+        }
+      catch(INTERP_KERNEL::Exception& e)
+        {
+          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
+          std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
+          oss << ") : Evaluation of function failed ! " << e.what();
+          newArr->decrRef();
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  return newArr;
+}
+
+void DataArrayDouble::applyFuncFast32(const char *func)
+{
+  INTERP_KERNEL::ExprParser expr(func);
+  expr.parse();
+  char *funcStr=expr.compileX86();
+  MYFUNCPTR funcPtr=(MYFUNCPTR)funcStr;//he he...
+  //
+  double *ptr=getPointer();
+  int nbOfComp=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  int nbOfElems=nbOfTuples*nbOfComp;
+  for(int i=0;i<nbOfElems;i++,ptr++)
+    *ptr=funcPtr(*ptr);
+  declareAsNew();
+}
+
+void DataArrayDouble::applyFuncFast64(const char *func)
+{
+  INTERP_KERNEL::ExprParser expr(func);
+  expr.parse();
+  char *funcStr=expr.compileX86_64();
+  MYFUNCPTR funcPtr=(MYFUNCPTR)funcStr;//he he...
+  //
+  double *ptr=getPointer();
+  int nbOfComp=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  int nbOfElems=nbOfTuples*nbOfComp;
+  for(int i=0;i<nbOfElems;i++,ptr++)
+    *ptr=funcPtr(*ptr);
+  declareAsNew();
+}
+
+DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : the default array must have only one component !");
+  const double *cptr=getConstPointer();
+  std::vector<int> res;
+  int nbOfTuples=getNumberOfTuples();
+  for(int i=0;i<nbOfTuples;i++,cptr++)
+    if(*cptr>=vmin && *cptr<=vmax)
+      res.push_back(i);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(res.size(),1);
+  std::copy(res.begin(),res.end(),ret->getPointer());
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
 {
   int nbOfComp=a1->getNumberOfComponents();
   if(nbOfComp!=a2->getNumberOfComponents())
@@ -132,7 +916,97 @@ DataArrayDouble *DataArrayDouble::aggregate(const DataArrayDouble *a1, const Dat
   return ret;
 }
 
-DataArrayDouble *DataArrayDouble::add(const DataArrayDouble *a1, const DataArrayDouble *a2)
+DataArrayDouble *DataArrayDouble::dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=a1->getNumberOfComponents();
+  if(nbOfComp!=a2->getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("Nb of components mismatch for array dot !");
+  int nbOfTuple=a1->getNumberOfTuples();
+  if(nbOfTuple!=a2->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array dot !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(nbOfTuple,1);
+  double *retPtr=ret->getPointer();
+  const double *a1Ptr=a1->getConstPointer();
+  const double *a2Ptr=a2->getConstPointer();
+  for(int i=0;i<nbOfTuple;i++)
+    {
+      double sum=0.;
+      for(int j=0;j<nbOfComp;j++)
+        sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
+      retPtr[i]=sum;
+    }
+  ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
+  ret->setName(a1->getName().c_str());
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::crossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=a1->getNumberOfComponents();
+  if(nbOfComp!=a2->getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
+  if(nbOfComp!=3)
+    throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
+  int nbOfTuple=a1->getNumberOfTuples();
+  if(nbOfTuple!=a2->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(nbOfTuple,3);
+  double *retPtr=ret->getPointer();
+  const double *a1Ptr=a1->getConstPointer();
+  const double *a2Ptr=a2->getConstPointer();
+  for(int i=0;i<nbOfTuple;i++)
+    {
+      retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
+      retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
+      retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
+    }
+  ret->copyStringInfoFrom(*a1);
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=a1->getNumberOfComponents();
+  if(nbOfComp!=a2->getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("Nb of components mismatch for array max !");
+  int nbOfTuple=a1->getNumberOfTuples();
+  if(nbOfTuple!=a2->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array max !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(nbOfTuple,nbOfComp);
+  double *retPtr=ret->getPointer();
+  const double *a1Ptr=a1->getConstPointer();
+  const double *a2Ptr=a2->getConstPointer();
+  int nbElem=nbOfTuple*nbOfComp;
+  for(int i=0;i<nbElem;i++)
+    retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
+  ret->copyStringInfoFrom(*a1);
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
+{
+  int nbOfComp=a1->getNumberOfComponents();
+  if(nbOfComp!=a2->getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
+  int nbOfTuple=a1->getNumberOfTuples();
+  if(nbOfTuple!=a2->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(nbOfTuple,nbOfComp);
+  double *retPtr=ret->getPointer();
+  const double *a1Ptr=a1->getConstPointer();
+  const double *a2Ptr=a2->getConstPointer();
+  int nbElem=nbOfTuple*nbOfComp;
+  for(int i=0;i<nbElem;i++)
+    retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
+  ret->copyStringInfoFrom(*a1);
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
 {
   int nbOfComp=a1->getNumberOfComponents();
   if(nbOfComp!=a2->getNumberOfComponents())
@@ -147,7 +1021,7 @@ DataArrayDouble *DataArrayDouble::add(const DataArrayDouble *a1, const DataArray
   return ret;
 }
 
-void DataArrayDouble::addEqual(const DataArrayDouble *other)
+void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
 {
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=other->getNumberOfComponents())
@@ -159,7 +1033,7 @@ void DataArrayDouble::addEqual(const DataArrayDouble *other)
   declareAsNew();
 }
 
-DataArrayDouble *DataArrayDouble::substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
+DataArrayDouble *DataArrayDouble::substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
 {
   int nbOfComp=a1->getNumberOfComponents();
   if(nbOfComp!=a2->getNumberOfComponents())
@@ -174,7 +1048,7 @@ DataArrayDouble *DataArrayDouble::substract(const DataArrayDouble *a1, const Dat
   return ret;
 }
 
-void DataArrayDouble::substractEqual(const DataArrayDouble *other)
+void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
 {
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=other->getNumberOfComponents())
@@ -186,7 +1060,7 @@ void DataArrayDouble::substractEqual(const DataArrayDouble *other)
   declareAsNew();
 }
 
-DataArrayDouble *DataArrayDouble::multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
+DataArrayDouble *DataArrayDouble::multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
 {
   int nbOfTuple=a1->getNumberOfTuples();
   int nbOfTuple2=a2->getNumberOfTuples();
@@ -233,7 +1107,7 @@ DataArrayDouble *DataArrayDouble::multiply(const DataArrayDouble *a1, const Data
   return ret;
 }
 
-void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
+void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
 {
   int nbOfTuple=getNumberOfTuples();
   int nbOfTuple2=other->getNumberOfTuples();
@@ -241,11 +1115,8 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
   int nbOfComp2=other->getNumberOfComponents();
   if(nbOfTuple!=nbOfTuple2)
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array multiplyEqual !");
-  DataArrayDouble *ret=0;
   if(nbOfComp==nbOfComp2)
     {
-      ret=DataArrayDouble::New();
-      ret->alloc(nbOfTuple,nbOfComp);
       std::transform(getConstPointer(),getConstPointer()+nbOfTuple*nbOfComp,other->getConstPointer(),getPointer(),std::multiplies<double>());
     }
   else
@@ -263,7 +1134,7 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
   declareAsNew();
 }
 
-DataArrayDouble *DataArrayDouble::divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
+DataArrayDouble *DataArrayDouble::divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
 {
   int nbOfComp=a1->getNumberOfComponents();
   if(nbOfComp!=a2->getNumberOfComponents())
@@ -278,7 +1149,7 @@ DataArrayDouble *DataArrayDouble::divide(const DataArrayDouble *a1, const DataAr
   return ret;
 }
 
-void DataArrayDouble::divideEqual(const DataArrayDouble *other)
+void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
 {
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=other->getNumberOfComponents())
@@ -319,6 +1190,98 @@ void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
   declareAsNew();
 }
 
+void DataArrayInt::fillWithZero()
+{
+  _mem.fillWithValue(0);
+  declareAsNew();
+}
+
+void DataArrayInt::fillWithValue(int val)
+{
+  _mem.fillWithValue(val);
+  declareAsNew();
+}
+
+std::string DataArrayInt::repr() const
+{
+  std::ostringstream ret;
+  reprStream(ret);
+  return ret.str();
+}
+
+std::string DataArrayInt::reprZip() const
+{
+  std::ostringstream ret;
+  reprZipStream(ret);
+  return ret.str();
+}
+
+void DataArrayInt::reprStream(std::ostream& stream) const
+{
+  stream << "Name of int array : \"" << _name << "\"\n";
+  reprWithoutNameStream(stream);
+}
+
+void DataArrayInt::reprZipStream(std::ostream& stream) const
+{
+  stream << "Name of int array : \"" << _name << "\"\n";
+  reprZipWithoutNameStream(stream);
+}
+
+void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
+{
+  DataArray::reprWithoutNameStream(stream);
+  _mem.repr(getNumberOfComponents(),stream);
+}
+
+void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
+{
+  DataArray::reprWithoutNameStream(stream);
+  _mem.reprZip(getNumberOfComponents(),stream);
+}
+
+void DataArrayInt::transformWithIndArr(const int *indArr)
+{
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component !");
+  int nbOfTuples=getNumberOfTuples();
+  int *pt=getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    pt[i]=indArr[pt[i]];
+}
+
+/*!
+ * This method invert array 'di' that is a conversion map from Old to New numbering to New to Old numbering.
+ */
+DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(newNbOfElem,1);
+  int nbOfOldNodes=getNumberOfTuples();
+  const int *old2New=getConstPointer();
+  int *pt=ret->getPointer();
+  for(int i=0;i!=nbOfOldNodes;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.
+ */
+DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(oldNbOfElem,1);
+  const int *new2Old=getConstPointer();
+  int *pt=ret->getPointer();
+  std::fill(pt,pt+oldNbOfElem,-1);
+  int nbOfNewElems=getNumberOfTuples();
+  for(int i=0;i<nbOfNewElems;i++)
+    pt[new2Old[i]]=i;
+  return ret;
+}
+
 bool DataArrayInt::isEqual(const DataArrayInt& other) const
 {
   if(!areInfoEquals(other))
@@ -326,6 +1289,11 @@ bool DataArrayInt::isEqual(const DataArrayInt& other) const
   return _mem.isEqual(other._mem,0);
 }
 
+bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
+{
+  return _mem.isEqual(other._mem,0);
+}
+
 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
 {
   _nb_of_tuples=nbOfTuple;
@@ -334,6 +1302,191 @@ void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type,
   declareAsNew();
 }
 
+void DataArrayInt::renumberInPlace(const int *old2New)
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  int *tmp=new int[nbTuples*nbOfCompo];
+  const int *iptr=getConstPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
+  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
+  delete [] tmp;
+  declareAsNew();
+}
+
+void DataArrayInt::renumberInPlaceR(const int *new2Old)
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  int *tmp=new int[nbTuples*nbOfCompo];
+  const int *iptr=getConstPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
+  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
+  delete [] tmp;
+  declareAsNew();
+}
+
+DataArrayInt *DataArrayInt::renumber(const int *old2New) const
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbTuples,nbOfCompo);
+  ret->copyStringInfoFrom(*this);
+  const int *iptr=getConstPointer();
+  int *optr=ret->getPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbTuples,nbOfCompo);
+  ret->copyStringInfoFrom(*this);
+  const int *iptr=getConstPointer();
+  int *optr=ret->getPointer();
+  for(int i=0;i<nbTuples;i++)
+    std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * Idem DataArrayDouble::renumber method except that the number of tuples is reduced.
+ * That is to say that it is expected that newNbOfTuple<this->getNumberOfTuples().
+ * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'getNumberOfTuples()) the corresponding tuple is
+ * omitted.
+ */
+DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
+{
+  int nbTuples=getNumberOfTuples();
+  int nbOfCompo=getNumberOfComponents();
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(newNbOfTuple,nbOfCompo);
+  const int *iptr=getConstPointer();
+  int *optr=ret->getPointer();
+  for(int i=0;i<nbTuples;i++)
+    {
+      int w=old2New[i];
+      if(w>=0)
+        std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
+    }
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * This method is a generalization of DataArrayDouble::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
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  int nbComp=getNumberOfComponents();
+  ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
+  ret->copyStringInfoFrom(*this);
+  int *pt=ret->getPointer();
+  const int *srcPt=getConstPointer();
+  int i=0;
+  for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
+    std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * This method checks that 'this' is with numberofcomponents == 1 and that it is equal to
+ * stdext::iota() of size getNumberOfTuples. This method is particalary usefull for DataArrayInt instances
+ * that represents a renumbering array to check the real need in renumbering. 
+ */
+bool DataArrayInt::isIdentity() const
+{
+  if(getNumberOfComponents()!=1)
+    return false;
+  int nbOfTuples=getNumberOfTuples();
+  const int *pt=getConstPointer();
+  for(int i=0;i<nbOfTuples;i++,pt++)
+    if(*pt!=i)
+      return false;
+  return true;
+}
+
+DataArrayDouble *DataArrayInt::convertToDblArr() const
+{
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(getNumberOfTuples(),getNumberOfComponents());
+  int nbOfVals=getNbOfElems();
+  const int *src=getConstPointer();
+  double *dest=ret->getPointer();
+  std::copy(src,src+nbOfVals,dest);
+  ret->copyStringInfoFrom(*this);
+  return ret;
+}
+
+/*!
+ * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components.
+ * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept.
+ * This method check that interval is valid regarding this, if not an exception will be thrown.
+ */
+DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
+{
+  int nbt=getNumberOfTuples();
+  if(tupleIdBg<0)
+    throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
+  if(tupleIdBg>=nbt)
+    throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
+  int trueEnd=tupleIdEnd;
+  if(tupleIdEnd!=-1)
+    {
+      if(tupleIdEnd>nbt)
+        throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
+    }
+  else
+    trueEnd=nbt;
+  int nbComp=getNumberOfComponents();
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(trueEnd-tupleIdBg,nbComp);
+  ret->copyStringInfoFrom(*this);
+  std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
+  return ret;
+}
+
+/*!
+ * This method builds a new instance of DataArrayInt (to deal with) that is reduction or an extension of 'this'.
+ * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept.
+ * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken.
+ */
+DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(getNumberOfTuples(),newNbOfComp);
+  const int *oldc=getConstPointer();
+  int *nc=ret->getPointer();
+  int nbOfTuples=getNumberOfTuples();
+  int oldNbOfComp=getNumberOfComponents();
+  int dim=std::min(oldNbOfComp,newNbOfComp);
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      int j=0;
+      for(;j<dim;j++)
+        nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
+      for(;j<newNbOfComp;j++)
+        nc[newNbOfComp*i+j]=dftValue;
+    }
+  ret->setName(getName().c_str());
+  for(int i=0;i<dim;i++)
+    ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
+  ret->setName(getName().c_str());
+  return ret;
+}
+
 void DataArrayInt::reAlloc(int nbOfTuples)
 {
   _mem.reAlloc(_info_on_compo.size()*nbOfTuples);
@@ -341,6 +1494,36 @@ void DataArrayInt::reAlloc(int nbOfTuples)
   declareAsNew();
 }
 
+DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
+  int newNbOfCompo=compoIds.size();
+  int oldNbOfCompo=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  ret->alloc(nbOfTuples,newNbOfCompo);
+  ret->copyPartOfStringInfoFrom(*this,compoIds);
+  const int *oldc=getConstPointer();
+  int *nc=ret->getPointer();
+  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;
+}
+
+void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
+{
+  copyPartOfStringInfoFrom2(compoIds,*a);
+  int partOfCompoSz=compoIds.size();
+  int nbOfCompo=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  const int *ac=a->getConstPointer();
+  int *nc=getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    for(int j=0;j<partOfCompoSz;j++,ac++)
+      nc[nbOfCompo*i+compoIds[j]]=*ac;
+}
+
 void DataArrayInt::setArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
 {
   if(newArray!=arrayToSet)
@@ -368,6 +1551,57 @@ DataArrayInt *DataArrayInt::aggregate(const DataArrayInt *a1, const DataArrayInt
   return ret;
 }
 
+/*!
+ * This method create a minimal partition of groups 'groups' the std::iota array of size 'newNb'.
+ * This method returns an array of size 'newNb' that specifies for each item at which familyId it owns to, and this method returns
+ * for each group the familyId it contains. If an id so that id<newNb and that appears in no groups will appears with 0 in return array.
+ *
+ * @param groups in arrays specifying ids of each groups.
+ * @param newNb specifies size of whole set. Must be at least equal to max eltid in 'groups'.
+ * @return an array of size newNb specifying fid of each item.
+ */
+DataArrayInt *DataArrayInt::makePartition(const std::vector<DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(newNb,1);
+  int *retPtr=ret->getPointer();
+  std::fill(retPtr,retPtr+newNb,0);
+  int fid=1;
+  for(std::vector<DataArrayInt *>::const_iterator iter=groups.begin();iter!=groups.end();iter++)
+    {
+      const int *ptr=(*iter)->getConstPointer();
+      int nbOfElem=(*iter)->getNbOfElems();
+      int sfid=fid;
+      for(int j=0;j<sfid;j++)
+        {
+          bool found=false;
+          for(int i=0;i<nbOfElem;i++)
+            {
+              if(retPtr[ptr[i]]==j)
+                {
+                  retPtr[ptr[i]]=fid;
+                  found=true;
+                }
+            }
+          if(found)
+            fid++;
+        }
+    }
+  fidsOfGroups.clear();
+  fidsOfGroups.resize(groups.size());
+  int grId=0;
+  for(std::vector<DataArrayInt *>::const_iterator iter=groups.begin();iter!=groups.end();iter++,grId++)
+    {
+      std::set<int> tmp;
+      const int *ptr=(*iter)->getConstPointer();
+      int nbOfElem=(*iter)->getNbOfElems();
+      for(const int *p=ptr;p!=ptr+nbOfElem;p++)
+        tmp.insert(retPtr[*p]);
+      fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
+    }
+  return ret;
+}
+
 int *DataArrayInt::checkAndPreparePermutation(const int *start, const int *end)
 {
   int sz=std::distance(start,end);
index 74d165bb983217cc4e79a560adde2997c6546021..0f5d600d9de142b7fa7b61bea548bf5afe22d6c7 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <string>
 #include <vector>
+#include <iterator>
 
 namespace ParaMEDMEM
 {
@@ -60,6 +61,9 @@ namespace ParaMEDMEM
     T operator[](int id) const { return _pointer.getConstPointer()[id]; }
     T& operator[](int id) { return _pointer.getPointer()[id]; }
     bool isEqual(const MemArray<T>& other, T prec) const;
+    void repr(int sl, std::ostream& stream) const;
+    void reprZip(int sl, std::ostream& stream) const;
+    void fillWithValue(const T& val);
     void alloc(int nbOfElements);
     void reAlloc(int newNbOfElements);
     void useArray(const T *array, bool ownership, DeallocType type, int nbOfElem);
@@ -72,7 +76,6 @@ namespace ParaMEDMEM
     int _nb_of_elem;
     bool _ownership;
     MEDCouplingPointer<T> _pointer;
-    //T *_pointer;
     DeallocType _dealloc;
   };
 
@@ -81,10 +84,14 @@ namespace ParaMEDMEM
   public:
     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);
+    MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const;
+    MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT std::string getName() const { return _name; }
-    MEDCOUPLING_EXPORT std::string getInfoOnComponent(int i) const { return _info_on_compo[i]; }
-    MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const char *info) { _info_on_compo[i]=info; }
+    MEDCOUPLING_EXPORT const std::vector<std::string> &getInfoOnComponent() const { return _info_on_compo; }
+    MEDCOUPLING_EXPORT std::string getInfoOnComponent(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 _info_on_compo.size(); }
     MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _nb_of_tuples; }
     MEDCOUPLING_EXPORT int getNbOfElems() const { return _info_on_compo.size()*_nb_of_tuples; }
@@ -101,6 +108,7 @@ namespace ParaMEDMEM
 
 namespace ParaMEDMEM
 {
+  class DataArrayInt;
   class DataArrayDouble : public DataArray
   {
   public:
@@ -108,27 +116,75 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayDouble *deepCopy() const;
     MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo);
+    MEDCOUPLING_EXPORT void fillWithZero();
+    MEDCOUPLING_EXPORT void fillWithValue(double val);
+    MEDCOUPLING_EXPORT std::string repr() const;
+    MEDCOUPLING_EXPORT std::string reprZip() const;
+    MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const;
+    MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const;
     //!alloc or useArray should have been called before.
     MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples);
+    MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const;
+    MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New);
+    MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old);
+    MEDCOUPLING_EXPORT DataArrayDouble *renumber(const int *old2New) const;
+    MEDCOUPLING_EXPORT DataArrayDouble *renumberR(const int *new2Old) const;
+    MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const;
+    MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const;
+    MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
     MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
-    MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
+    MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
     MEDCOUPLING_EXPORT double *getPointer() const { return _mem.getPointer(); }
     MEDCOUPLING_EXPORT static void setArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet);
     MEDCOUPLING_EXPORT const double *getConstPointer() const { return _mem.getConstPointer(); }
     MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
     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 static DataArrayDouble *aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2);
-    MEDCOUPLING_EXPORT static DataArrayDouble *add(const DataArrayDouble *a1, const DataArrayDouble *a2);
-    MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other);
-    MEDCOUPLING_EXPORT static DataArrayDouble *substract(const DataArrayDouble *a1, const DataArrayDouble *a2);
-    MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other);
-    MEDCOUPLING_EXPORT static DataArrayDouble *multiply(const DataArrayDouble *a1, const DataArrayDouble *a2);
-    MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other);
-    MEDCOUPLING_EXPORT static DataArrayDouble *divide(const DataArrayDouble *a1, const DataArrayDouble *a2);
-    MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other);
+    MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT double getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT double getAverageValue() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void accumulate(double *res) const;
+    MEDCOUPLING_EXPORT double accumulate(int compId) const;
+    MEDCOUPLING_EXPORT DataArrayDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *determinant() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *eigenValues() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *eigenVectors() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *inverse() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *trace() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *deviator() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *magnitude() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId);
+    MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(const char *func) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void applyFuncFast32(const char *func);
+    MEDCOUPLING_EXPORT void applyFuncFast64(const char *func);
+    MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *crossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception);
     //! nothing to do here because this class does not aggregate any TimeLabel instance.
     MEDCOUPLING_EXPORT void updateTime() { }
   private:
@@ -145,8 +201,32 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const;
+    MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const;
+    MEDCOUPLING_EXPORT void fillWithZero();
+    MEDCOUPLING_EXPORT void fillWithValue(int val);
+    MEDCOUPLING_EXPORT std::string repr() const;
+    MEDCOUPLING_EXPORT std::string reprZip() const;
+    MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArr);
+    MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const;
+    MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const;
     //!alloc or useArray should have been called before.
     MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples);
+    MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const;
+    MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New);
+    MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old);
+    MEDCOUPLING_EXPORT DataArrayInt *renumber(const int *old2New) const;
+    MEDCOUPLING_EXPORT DataArrayInt *renumberR(const int *new2Old) const;
+    MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const;
+    MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const;
+    MEDCOUPLING_EXPORT bool isIdentity() const;
+    MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
     MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
     MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
@@ -154,6 +234,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static void setArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet);
     MEDCOUPLING_EXPORT const int *getConstPointer() const { return _mem.getConstPointer(); }
     MEDCOUPLING_EXPORT static DataArrayInt *aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2);
+    MEDCOUPLING_EXPORT static DataArrayInt *makePartition(const std::vector<DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups);
     MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); }
     //! nothing to do here because this class does not aggregate any TimeLabel instance.
index 476f147aeb1d505f42160008474826792ca3bf47..5a1a048d553304d659ae378bf2870fa0b0dcf828 100644 (file)
@@ -87,11 +87,99 @@ namespace ParaMEDMEM
       return true;
     if(pt1==0 || pt2==0)
       return false;
+    if(pt1==pt2)
+      return true;
     for(int i=0;i<_nb_of_elem;i++)
       if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec)
         return false;
     return true;
   }
+  
+  /*!
+   * @param sl is typically the number of components [in parameter]
+   */
+  template<class T>
+  void MemArray<T>::repr(int sl, std::ostream& stream) const
+  {
+    stream << "Number of tuples : ";
+    if(!_pointer.isNull())
+      {
+        if(sl!=0)
+          stream << _nb_of_elem/sl;
+        else
+          stream << "Empty Data";
+      }
+    else
+      stream << "No data";
+    stream << "\n";
+    stream << "Data content :\n";
+    const T *data=getConstPointer();
+    if(!_pointer.isNull())
+      {
+        if(_nb_of_elem!=0 && sl!=0)
+          {
+            int nbOfTuples=_nb_of_elem/sl;
+            for(int i=0;i<nbOfTuples;i++)
+              {
+                stream << "Tuple #" << i << " : ";
+                std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
+                stream << "\n";
+                data+=sl;
+              }
+          }
+        else
+          stream << "Empty Data\n";
+      }
+    else
+      stream << "No data !\n";
+  }
+  
+  /*!
+   * @param sl is typically the number of components [in parameter]
+   */
+  template<class T>
+  void MemArray<T>::reprZip(int sl, std::ostream& stream) const
+  {
+    stream << "Number of tuples : ";
+    if(!_pointer.isNull())
+      {
+        if(sl!=0)
+          stream << _nb_of_elem/sl;
+        else
+          stream << "Empty Data";
+      }
+    else
+      stream << "No data";
+    stream << "\n";
+    stream << "Data content : ";
+    const T *data=getConstPointer();
+    if(!_pointer.isNull())
+      {
+        if(_nb_of_elem!=0 && sl!=0)
+          {
+            int nbOfTuples=_nb_of_elem/sl;
+            for(int i=0;i<nbOfTuples;i++)
+              {
+                stream << "|";
+                std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
+                stream << "| ";
+                data+=sl;
+              }
+            stream << "\n";
+          }
+        else
+          stream << "Empty Data\n";
+      }
+    else
+      stream << "No data !\n";
+  }
+  
+  template<class T>
+  void MemArray<T>::fillWithValue(const T& val)
+  {
+    T *pt=_pointer.getPointer();
+    std::fill(pt,pt+_nb_of_elem,val);
+  }
 
   template<class T>
   void MemArray<T>::alloc(int nbOfElements)
index a552ea588b192af4eede092d06f7252abb197a90..cd3157568165b4259b423bd352a05fdd47f423fa 100644 (file)
 #include "MEDCouplingMemArray.hxx"
 #include "MEDCouplingFieldDouble.hxx"
 #include "MEDCouplingFieldDiscretization.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
-#include "InterpKernelExprParser.hxx"
-
+#include <set>
 #include <sstream>
 #include <iterator>
 
 using namespace ParaMEDMEM;
 
-bool MEDCouplingMesh::areCompatible(const MEDCouplingMesh *other) const
+/*!
+ * This method is only for ParaMEDMEM in ParaFIELD constructor.
+ */
+bool MEDCouplingMesh::isStructured() const
+{
+  return getType()==CARTESIAN;
+}
+
+bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const
+{
+  return _name==other->_name;
+}
+
+/*!
+ * This method checks geo equivalence between two meshes : 'this' and 'other'.
+ * If no exception is throw 'this' and 'other' are geometrically equivalent regarding 'levOfCheck' level.
+ * This method is typically used to change the mesh of a field "safely" depending the 'levOfCheck' level considered.
+ * 
+ * @param levOfCheck input that specifies the level of check specified. The possible values are listed below.
+ * @param prec input that specifies precision for double float data used for comparison in meshes.
+ * @param cellCor output array not always informed (depending 'levOfCheck' param) that gives the corresponding array for cells from 'other' to 'this'.
+ * @param nodeCor output array not always informed (depending 'levOfCheck' param) that gives the corresponding array for nodes from 'other' to 'this'.
+ *
+ * Possible values for levOfCheck :
+ *   - 0 for strict equality. This is the strongest level. 'cellCor' and 'nodeCor' params are never informed.
+ *   - 10,11,12 for less strict equality. Two meshes are compared geometrically. In case of success 'cellCor' and 'nodeCor' are informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details)
+ *   - 20,21,22, for less strict equality. Two meshes are compared geometrically. The difference with the previous version is that nodes(coordinates) are expected to be the same between this and other. In case of success 'cellCor' is informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details)
+ *   - 1 for fast 'equality'. This is a lazy level. Just number of cells and number of nodes are considered here and 3 cells (begin,middle,end)
+ *   - 2 for deep 'equality' as 0 option except that no control is done on all strings in mesh.
+ */
+void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,
+                                          DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+{
+  cellCor=0;
+  nodeCor=0;
+  if(this==other)
+    return ;
+  switch(levOfCheck)
+    {
+    case 0:
+      {
+        if(!isEqual(other,prec))
+          throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal !");
+        return ;
+      }
+    case 10:
+    case 11:
+    case 12:
+      {
+        checkDeepEquivalWith(other,levOfCheck-10,prec,cellCor,nodeCor);
+        return ;
+      }
+    case 20:
+    case 21:
+    case 22:
+      {
+        checkDeepEquivalOnSameNodesWith(other,levOfCheck-20,prec,cellCor);
+        return ;
+      }
+    case 1:
+      {
+        checkFastEquivalWith(other,prec);
+        return;
+      }
+    case 2:
+      {
+        if(!isEqualWithoutConsideringStr(other,prec))
+          throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal without considering strings !");
+        return ;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("checkGeoFitWith : Invalid levOfCheck specified ! Value must be in 0,1,2,10,11 or 12.");
+    }
+}
+
+/*!
+ * Given a nodeIds range ['partBg','partEnd'), this method returns the set of cell ids in ascendant order whose connectivity of
+ * these cells are fully included in the range. As a consequence the returned set of cell ids does \b not \b always fit the nodes in ['partBg','partEnd')
+ * This method returns the corresponding cells in a newly created array that the caller has the responsability.
+ */
+DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
+{
+  std::vector<int> crest;
+  std::set<int> p(partBg,partEnd);
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      std::vector<int> conn;
+      getNodeIdsOfCell(i,conn);
+      bool cont=true;
+      for(std::vector<int>::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++)
+        if(p.find(*iter)==p.end())
+          cont=false;
+      if(cont)
+        crest.push_back(i);
+    }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(crest.size(),1);
+  std::copy(crest.begin(),crest.end(),ret->getPointer());
+  return ret;
+}
+
+/*!
+ * This method checks fastly that 'this' and 'other' are equal. All common checks are done here.
+ */
+void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=other->getMeshDimension())
+    throw INTERP_KERNEL::Exception("checkFastEquivalWith : Mesh dimensions are not equal !");
+  if(getSpaceDimension()!=other->getSpaceDimension())
+    throw INTERP_KERNEL::Exception("checkFastEquivalWith : Space dimensions are not equal !");
+  if(getNumberOfCells()!=other->getNumberOfCells())
+    throw INTERP_KERNEL::Exception("checkFastEquivalWith : number of cells are not equal !");
+}
+
+/*!
+ * This method is very poor and looks only if 'this' and 'other' are candidate for merge of fields lying repectively on them.
+ */
+bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const
 {
   if(getMeshDimension()!=other->getMeshDimension())
     return false;
@@ -51,35 +169,22 @@ bool MEDCouplingMesh::areCompatible(const MEDCouplingMesh *other) const
  */
 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const
 {
-  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(t);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
   ret->setMesh(this);
-  DataArrayDouble *loc=ret->getDiscretization()->getLocalizationOfDiscValues(this);
-  DataArrayDouble *array=DataArrayDouble::New();
-  int nbOfTuple=loc->getNumberOfTuples();
-  int nbCompIn=loc->getNumberOfComponents();
-  const double *locPtr=loc->getConstPointer();
-  array->alloc(nbOfTuple,nbOfComp);
-  double *ptToFill=array->getPointer();
-  for(int i=0;i<nbOfTuple;i++)
-    {
-      if(!func(locPtr+nbCompIn*i,ptToFill))
-        {
-          std::ostringstream oss; oss << "For tuple # " << i << " localized on (";
-          std::copy(locPtr+nbCompIn*i,locPtr+nbCompIn*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed !";
-          loc->decrRef();
-          array->decrRef();
-          ret->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-      ptToFill+=nbOfComp;
-    }
-  loc->decrRef();
-  ret->setArray(array);
-  array->decrRef();
+  ret->fillFromAnalytic(nbOfComp,func);
+  ret->incrRef();
   return ret;
 }
 
+/*!
+ * This method copyies all tiny strings from other (name and components name).
+ * @throw if other and this have not same mesh type.
+ */
+void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+{
+  _name=other->_name;
+}
+
 /*!
  * This method builds a field lying on 'this' with 'nbOfComp' components.
  * 'func' is a string that is the expression to evaluate.
@@ -92,50 +197,10 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbO
  */
 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const
 {
-  INTERP_KERNEL::ExprParser expr(func);
-  expr.parse();
-  std::set<std::string> vars;
-  expr.getTrueSetOfVars(vars);
-  if((int)vars.size()>getSpaceDimension())
-    {
-      std::ostringstream oss; oss << "The mesh has a spaceDim==" << getSpaceDimension() << " and there are ";
-      oss << vars.size() << " variables : ";
-      std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  std::vector<std::string> varsV(vars.begin(),vars.end());
-  expr.prepareExprEvaluation(varsV);
-  //
-  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(t);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
   ret->setMesh(this);
-  DataArrayDouble *loc=ret->getDiscretization()->getLocalizationOfDiscValues(this);
-  DataArrayDouble *array=DataArrayDouble::New();
-  int nbOfTuple=loc->getNumberOfTuples();
-  int nbCompIn=loc->getNumberOfComponents();
-  const double *locPtr=loc->getConstPointer();
-  array->alloc(nbOfTuple,nbOfComp);
-  double *ptToFill=array->getPointer();
-  for(int i=0;i<nbOfTuple;i++)
-    {
-      try
-        {
-          expr.evaluateExpr(nbOfComp,ptToFill,locPtr+nbCompIn*i);
-        }
-      catch(INTERP_KERNEL::Exception& e)
-        {
-          std::ostringstream oss; oss << "For tuple # " << i << " localized on (";
-          std::copy(locPtr+nbCompIn*i,locPtr+nbCompIn*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed ! " << e.what();
-          loc->decrRef();
-          array->decrRef();
-          ret->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-      ptToFill+=nbOfComp;
-    }
-  loc->decrRef();
-  ret->setArray(array);
-  array->decrRef();
+  ret->fillFromAnalytic(nbOfComp,func);
+  ret->incrRef();
   return ret;
 }
 
index 8d11cd5731646207faeb8ca91a94007235d17dd2..524c230178c11241d6eac0794e1feed20c86f9e1 100644 (file)
@@ -38,6 +38,7 @@ namespace ParaMEDMEM
       EXTRUDED = 8
     } MEDCouplingMeshType;
 
+  class DataArrayInt;
   class DataArrayDouble;
   class MEDCouplingFieldDouble;
 
@@ -46,19 +47,35 @@ namespace ParaMEDMEM
   public:
     void setName(const char *name) { _name=name; }
     const char *getName() const { return _name.c_str(); }
+    virtual MEDCouplingMesh *deepCpy() const = 0;
     virtual MEDCouplingMeshType getType() const = 0;
-    virtual bool isEqual(const MEDCouplingMesh *other, double prec) const { return _name==other->_name; }
+    bool isStructured() const;
+    virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
+    // comparison methods
+    virtual bool isEqual(const MEDCouplingMesh *other, double prec) const;
+    virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0;
+    virtual void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                      DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                 DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception);
+    void checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,
+                             DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception);
+    //
     virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0;
-    virtual bool isStructured() const = 0;
     virtual int getNumberOfCells() const = 0;
     virtual int getNumberOfNodes() const = 0;
     virtual int getSpaceDimension() const = 0;
     virtual int getMeshDimension() const = 0;
     virtual DataArrayDouble *getCoordinatesAndOwner() const = 0;
     virtual DataArrayDouble *getBarycenterAndOwner() const = 0;
+    virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0;
     virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0;
     virtual void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const = 0;
+    virtual DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const;
     virtual void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const = 0;
+    virtual std::string simpleRepr() const = 0;
+    virtual std::string advancedRepr() const = 0;
     // tools
     virtual void getBoundingBox(double *bbox) const = 0;
     virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0;
@@ -69,9 +86,19 @@ namespace ParaMEDMEM
     virtual MEDCouplingFieldDouble *buildOrthogonalField() const = 0;
     virtual void rotate(const double *center, const double *vector, double angle) = 0;
     virtual void translate(const double *vector) = 0;
+    virtual void scale(const double *point, double factor) = 0;
+    virtual void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) = 0;
     virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0;
-    virtual bool areCompatible(const MEDCouplingMesh *other) const;
+    virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0;
+    virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0;
+    virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const;
     static MEDCouplingMesh *mergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2);
+    //serialisation-unserialization
+    virtual void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const = 0;
+    virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const = 0;
+    virtual void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0;
+    virtual void unserialization(const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                                 const std::vector<std::string>& littleStrings) = 0;
   protected:
     MEDCouplingMesh() { }
     MEDCouplingMesh(const MEDCouplingMesh& other):_name(other._name) { }
diff --git a/src/MEDCoupling/MEDCouplingNatureOfField.cxx b/src/MEDCoupling/MEDCouplingNatureOfField.cxx
new file mode 100644 (file)
index 0000000..7969909
--- /dev/null
@@ -0,0 +1,44 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MEDCouplingNatureOfField.hxx"
+
+#include <algorithm>
+
+namespace ParaMEDMEM
+{
+  const char *MEDCouplingNatureOfField::REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]=
+    { "NoNature",
+      "ConservativeVolumic",
+      "Integral",
+      "IntegralGlobConstraint",
+      "RevIntegral"};
+  
+  const int MEDCouplingNatureOfField::POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]={17,26,32,35,37};
+
+  const char *MEDCouplingNatureOfField::getRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception)
+  {
+    const int *pos=std::find(POS_OF_NATUREOFFIELD,POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES,(int)nat);
+    if(pos==POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES)
+      throw INTERP_KERNEL::Exception("MEDCouplingNatureOfField::getRepr : Unrecognized nature of field !");
+    int pos2=std::distance(POS_OF_NATUREOFFIELD,pos);
+    return REPR_OF_NATUREOFFIELD[pos2];
+  }
+}
index bdc1c78ddf18e21c40164740ecde0570b2975f49..89f9125e03eb95b66a3070fc4b993e96f88cbc7d 100644 (file)
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#ifndef __MEDCOUPLINGNATUREOFFIELD_HXX__
-#define __MEDCOUPLINGNATUREOFFIELD_HXX__
+#ifndef __PARAMEDMEM_MEDCOUPLINGNATUREOFFIELD_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGNATUREOFFIELD_HXX__
+
+#include "MEDCoupling.hxx"
+#include "InterpKernelException.hxx"
 
 namespace ParaMEDMEM
 {
@@ -30,6 +33,16 @@ namespace ParaMEDMEM
       IntegralGlobConstraint = 35,
       RevIntegral            = 37
     } NatureOfField;
+
+  class MEDCouplingNatureOfField
+  {
+  public:
+    MEDCOUPLING_EXPORT static const char *getRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception);
+  private:
+    static const int NB_OF_POSSIBILITIES=5;
+    static const char *REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES];
+    static const int POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES];
+  };
 }
 
 #endif
index ebb12e01a96c59737cfad183e1c2913452199036..c2643f327ec16aa84d5aa442fc1b0c885ff8e5f6 100644 (file)
@@ -17,8 +17,8 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#ifndef __MEDCouplingNormalizedCartesianMesh_HXX__
-#define __MEDCouplingNormalizedCartesianMesh_HXX__
+#ifndef __PARAMEDMEM_MEDCOUPLINGNORMALIZEDCARTESIANMESH_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDCARTESIANMESH_HXX__
 
 #include "NormalizedUnstructuredMesh.hxx"
 
index b3ebcbc7f0da924eb75334e396ea02616e997e2a..5ebd3ae1947b516d983a15e372018e85801ee0c0 100644 (file)
@@ -17,8 +17,8 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#ifndef __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__
-#define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__
+#ifndef __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__
 
 #include "NormalizedUnstructuredMesh.hxx"
 
index 0c0ce18879bbcfe90a320f561d39cd326ab02a3e..87964cbdf0be8ba4989a6cccad2315e61d172bac 100644 (file)
@@ -73,11 +73,6 @@ void MEDCouplingPointSet::updateTime()
     }
 }
 
-bool MEDCouplingPointSet::isStructured() const
-{
-  return false;
-}
-
 void MEDCouplingPointSet::setCoords(DataArrayDouble *coords)
 {
   if( coords != _coords )
@@ -98,6 +93,20 @@ DataArrayDouble *MEDCouplingPointSet::getCoordinatesAndOwner() const
   return _coords;
 }
 
+/*!
+ * This method copyies all tiny strings from other (name and components name).
+ * @throw if other and this have not same mesh type.
+ */
+void MEDCouplingPointSet::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::copyTinyStringsFrom : meshes have not same type !");
+  MEDCouplingMesh::copyTinyStringsFrom(other);
+  if(_coords && otherC->_coords)
+    _coords->copyStringInfoFrom(*otherC->_coords);
+}
+
 bool MEDCouplingPointSet::isEqual(const MEDCouplingMesh *other, double prec) const
 {
   const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other);
@@ -110,6 +119,16 @@ bool MEDCouplingPointSet::isEqual(const MEDCouplingMesh *other, double prec) con
   return true;
 }
 
+bool MEDCouplingPointSet::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
+{
+  const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other);
+  if(!otherC)
+    return false;
+  if(!areCoordsEqualWithoutConsideringStr(*otherC,prec))
+    return false;
+  return true;
+}
+
 bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, double prec) const
 {
   if(_coords==0 && other._coords==0)
@@ -121,13 +140,45 @@ bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, doubl
   return _coords->isEqual(*other._coords,prec);
 }
 
+bool MEDCouplingPointSet::areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const
+{
+  if(_coords==0 && other._coords==0)
+    return true;
+  if(_coords==0 || other._coords==0)
+    return false;
+  if(_coords==other._coords)
+    return true;
+  return _coords->isEqualWithoutConsideringStr(*other._coords,prec);
+}
+
+/*!
+ * This method is typically the base method used for implementation of mergeNodes. This method computes this permutation array using as input,
+ * This method is const ! So this method simply computes the array, no permutation of nodes is done.
+ * a precision 'precision' and a 'limitNodeId' that is the node id so that every nodes which id is strictly lower than 'limitNodeId' will not be merged.
+ * To desactivate this advanced feature put -1 to this argument.
+ * @param areNodesMerged output parameter that states if some nodes have been "merged" in returned array
+ * @param newNbOfNodes output parameter too this is the maximal id in returned array to avoid to recompute it.
+ */
+DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const
+{
+  DataArrayInt *comm,*commI;
+  findCommonNodes(limitNodeId,precision,comm,commI);
+  int oldNbOfNodes=getNumberOfNodes();
+  DataArrayInt *ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes);
+  areNodesMerged=(oldNbOfNodes!=newNbOfNodes);
+  comm->decrRef();
+  commI->decrRef();
+  return ret;
+}
+
 /*!
  * This methods searches for each node n1 nodes in _coords that are less far than 'prec' from n1. if any these nodes are stored in params
  * comm and commIndex.
+ * @param limitNodeId is the limit node id. All nodes which id is strictly lower than 'limitNodeId' will not be merged.
  * @param comm out parameter (not inout)
  * @param commIndex out parameter (not inout)
  */
-void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const
+void MEDCouplingPointSet::findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const
 {
   comm=DataArrayInt::New();
   commIndex=DataArrayInt::New();
@@ -149,13 +200,13 @@ void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&co
   switch(spaceDim)
     {
     case 3:
-      findCommonNodesAlg<3>(bbox,nbNodesOld,prec,c,cI);
+      findCommonNodesAlg<3>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
       break;
     case 2:
-      findCommonNodesAlg<2>(bbox,nbNodesOld,prec,c,cI);
+      findCommonNodesAlg<2>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
       break;
     case 1:
-      findCommonNodesAlg<1>(bbox,nbNodesOld,prec,c,cI);
+      findCommonNodesAlg<1>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
       break;
     default:
       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords. Must be 1,2 or 3.");
@@ -171,8 +222,8 @@ void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&co
  * @param commI in param in the same format than one returned by findCommonNodes method.
  * @return the old to new correspondance array.
  */
-DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommNodesFrmt(const DataArrayInt *comm, const DataArrayInt *commIndex,
-                                                                      int& newNbOfNodes) const
+DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex,
+                                                                          int& newNbOfNodes) const
 {
   DataArrayInt *ret=DataArrayInt::New();
   int nbNodesOld=getNumberOfNodes();
@@ -272,6 +323,25 @@ void MEDCouplingPointSet::zipCoords()
   traducer->decrRef();
 }
 
+struct MEDCouplingCompAbs
+{
+  bool operator()(double x, double y) { return std::abs(x)<std::abs(y);}
+};
+
+/*!
+ * This method expects that _coords attribute is set.
+ * @return the carateristic dimension of point set. This caracteristic dimension is the max of difference 
+ * @exception If _coords attribute not set.
+ */
+double MEDCouplingPointSet::getCaracteristicDimension() const
+{
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCaracteristicDimension : Coordinates not set !");
+  const double *coords=_coords->getConstPointer();
+  int nbOfValues=_coords->getNbOfElems();
+  return std::abs(*std::max_element(coords,coords+nbOfValues,MEDCouplingCompAbs()));
+}
+
 /*!
  * Non const method that operates a rotation of 'this'.
  * If spaceDim==2 'vector' parameter is ignored (and could be 0) and the rotation is done around 'center' with angle specified by 'angle'.
@@ -339,7 +409,7 @@ void MEDCouplingPointSet::scale(const double *point, double factor)
  * - by ignoring each \f$ i^{th} \f$ components of each coord of nodes so that i >= 'newSpaceDim', 'newSpaceDim'<getSpaceDimension()
  * If newSpaceDim==getSpaceDim() nothing is done by this method.
  */
-void MEDCouplingPointSet::changeSpaceDimension(int newSpaceDim) throw(INTERP_KERNEL::Exception)
+void MEDCouplingPointSet::changeSpaceDimension(int newSpaceDim, double dftValue) throw(INTERP_KERNEL::Exception)
 {
   if(getCoords()==0)
     throw INTERP_KERNEL::Exception("changeSpaceDimension must be called on an MEDCouplingPointSet instance with coordinates set !");
@@ -348,25 +418,10 @@ void MEDCouplingPointSet::changeSpaceDimension(int newSpaceDim) throw(INTERP_KER
   int oldSpaceDim=getSpaceDimension();
   if(newSpaceDim==oldSpaceDim)
     return ;
-  DataArrayDouble *newCoords=DataArrayDouble::New();
-  newCoords->alloc(getCoords()->getNumberOfTuples(),newSpaceDim);
-  const double *oldc=getCoords()->getConstPointer();
-  double *nc=newCoords->getPointer();
-  int nbOfNodes=getNumberOfNodes();
-  int dim=std::min(oldSpaceDim,newSpaceDim);
-  for(int i=0;i<nbOfNodes;i++)
-    {
-      int j=0;
-      for(;j<dim;j++)
-        nc[newSpaceDim*i+j]=oldc[i*oldSpaceDim+j];
-      for(;j<newSpaceDim;j++)
-        nc[newSpaceDim*i+j]=0.;
-    }
-  newCoords->setName(getCoords()->getName().c_str());
-  for(int i=0;i<dim;i++)
-    newCoords->setInfoOnComponent(i,getCoords()->getInfoOnComponent(i).c_str());
+  DataArrayDouble *newCoords=getCoords()->changeNbOfComponents(newSpaceDim,dftValue);
   setCoords(newCoords);
   newCoords->decrRef();
+  updateTime();
 }
 
 /*!
@@ -381,7 +436,7 @@ void MEDCouplingPointSet::tryToShareSameCoords(const MEDCouplingPointSet& other,
     throw INTERP_KERNEL::Exception("Current instance has no coords whereas other has !");
   if(!other._coords)
     throw INTERP_KERNEL::Exception("Other instance has no coords whereas current has !");
-  if(!_coords->isEqual(*other._coords,epsilon))
+  if(!_coords->isEqualWithoutConsideringStr(*other._coords,epsilon))
     throw INTERP_KERNEL::Exception("Coords are not the same !");
   setCoords(other._coords);
 }
@@ -485,7 +540,7 @@ void MEDCouplingPointSet::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) con
  * Second step of serialization process.
  * @param tinyInfo must be equal to the result given by getTinySerializationInformation method.
  */
-void MEDCouplingPointSet::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings)
+void MEDCouplingPointSet::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
 {
   if(tinyInfo[2]>=0 && tinyInfo[1]>=1)
     {
@@ -502,7 +557,7 @@ void MEDCouplingPointSet::resizeForUnserialization(const std::vector<int>& tinyI
  * Second and final unserialization process.
  * @param tinyInfo must be equal to the result given by getTinySerializationInformation method.
  */
-void MEDCouplingPointSet::unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
+void MEDCouplingPointSet::unserialization(const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
 {
   if(tinyInfo[2]>=0 && tinyInfo[1]>=1)
     {
@@ -624,6 +679,33 @@ void MEDCouplingPointSet::rotate3DAlg(const double *center, const double *vect,
     }
 }
 
+/*!
+ * This method implements pure virtual method MEDCouplingMesh::buildPart.
+ * This method build a part of 'this' by simply keeping cells whose ids are in ['start','end').
+ * The coords are kept unchanged contrary to pure virtual method MEDCouplingMesh::buildPartAndReduceNodes.
+ * The returned mesh has to be managed by the caller.
+ */
+MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end) const
+{
+  return buildPartOfMySelf(start,end,false);
+}
+
+/*!
+ * This method implements pure virtual method MEDCouplingMesh::buildPartAndReduceNodes.
+ * This method build a part of 'this' by simply keeping cells whose ids are in ['start','end') \b and potentially reduces the nodes set
+ * behind returned mesh. This cause an overhead but it is lesser in memory.
+ * This method returns an array too. This array allows to the caller to know the mapping between nodeids in 'this' and nodeids in 
+ * returned mesh. This is quite usefull for MEDCouplingFieldDouble on nodes for example...
+ * The returned mesh has to be managed by the caller.
+ */
+MEDCouplingMesh *MEDCouplingPointSet::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
+{
+  MEDCouplingPointSet *ret=buildPartOfMySelf(start,end,true);
+  arr=ret->zipCoordsTraducer();
+  return ret;
+}
+
+
 /*!
  * 'This' is expected to be of spaceDim==2. Idem for 'center' and 'vect'
  */
index 601777efc1a6338045e4f41b0808e692605244d4..87a4c04ec89c1c6105ca639fc34c326a8054a0e5 100644 (file)
@@ -43,43 +43,50 @@ namespace ParaMEDMEM
     ~MEDCouplingPointSet();
   public:
     void updateTime();
-    bool isStructured() const;
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
     void setCoords(DataArrayDouble *coords);
     DataArrayDouble *getCoords() const { return _coords; }
     DataArrayDouble *getCoordinatesAndOwner() const;
+    void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDCouplingMesh *other, double prec) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const;
     bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const;
-    virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged) = 0;
-    void findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const;
-    DataArrayInt *buildNewNumberingFromCommNodesFrmt(const DataArrayInt *comm, const DataArrayInt *commIndex,
-                                                     int& newNbOfNodes) const;
+    bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const;
+    virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0;
+    DataArrayInt *buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const;
+    void findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const;
+    DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex,
+                                                         int& newNbOfNodes) const;
     void getBoundingBox(double *bbox) const;
     void zipCoords();
+    double getCaracteristicDimension() const;
     void rotate(const double *center, const double *vector, double angle);
     void translate(const double *vector);
     void scale(const double *point, double factor);
-    void changeSpaceDimension(int newSpaceDim) throw(INTERP_KERNEL::Exception);
+    void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception);
     void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
+    virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0;
     void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector<int>& nodes) const throw(INTERP_KERNEL::Exception);
     static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2);
     static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type);
     static void rotate2DAlg(const double *center, double angle, int nbNodes, double *coords);
     static void rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords);
+    MEDCouplingMesh *buildPart(const int *start, const int *end) const;
+    MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
     virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const = 0;
     virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
     virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
     virtual void findBoundaryNodes(std::vector<int>& nodes) const = 0;
     virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0;
     virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
-    //! size of returned tinyInfo must be always the same.
-    virtual void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
     virtual bool isEmptyMesh(const std::vector<int>& tinyInfo) const = 0;
-    virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings);
-    virtual void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const;
-    virtual void unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2,
-                                 const std::vector<std::string>& littleStrings);
+    //! size of returned tinyInfo must be always the same.
+    void getTinySerializationInformation(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<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                         const std::vector<std::string>& littleStrings);
     virtual void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) = 0;
     virtual void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems) = 0;
     virtual DataArrayInt *zipCoordsTraducer() = 0;
@@ -93,7 +100,7 @@ namespace ParaMEDMEM
     static bool isButterfly2DCell(const std::vector<double>& res, bool isQuad);
     template<int SPACEDIM>
     void findCommonNodesAlg(std::vector<double>& bbox,
-                            int nbNodes, double prec, std::vector<int>& c, std::vector<int>& cI) const;
+                            int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const;
   protected:
     DataArrayDouble *_coords;
   };
index 300aab2352ec854ec68fea03008ee153aa86a438..bae1955669521d800191c474531e4e76168d8ce1 100644 (file)
@@ -29,7 +29,7 @@ namespace ParaMEDMEM
 {
   template<int SPACEDIM>
   void MEDCouplingPointSet::findCommonNodesAlg(std::vector<double>& bbox,
-                                               int nbNodes, double prec,
+                                               int nbNodes, int limitNodeId, double prec,
                                                std::vector<int>& c, std::vector<int>& cI) const
   {
     const double *coordsPtr=_coords->getConstPointer();
@@ -52,8 +52,9 @@ namespace ParaMEDMEM
             std::vector<int> commonNodes;
             for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
               if(*it!=i)
-                if(INTERP_KERNEL::distance2<SPACEDIM>(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))<prec2)
-                  commonNodes.push_back(*it);
+                if(*it>=limitNodeId)
+                  if(INTERP_KERNEL::distance2<SPACEDIM>(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))<prec2)
+                    commonNodes.push_back(*it);
             if(!commonNodes.empty())
               {
                 cI.push_back(cI.back()+commonNodes.size()+1);
index 6929b85331b180ad3dbb2a4624380c29ad115960..7a473b6da726029ebac29149fc17e0d128359249 100644 (file)
@@ -33,7 +33,9 @@ namespace ParaMEDMEM
   typedef enum
     {
       ON_CELLS = 0,
-      ON_NODES = 1
+      ON_NODES = 1,
+      ON_GAUSS_PT = 2,
+      ON_GAUSS_NE = 3
     } TypeOfField;
 
   typedef enum
index ca57b48a6dc1b8d3c9dc69dbbd49865f9f643050..bb494899b7fdbbaf94537fb4d1b590eb45ab6fac 100644 (file)
@@ -41,7 +41,7 @@ MEDCouplingRemapper::~MEDCouplingRemapper()
   releaseData(false);
 }
 
-int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method)
+int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method) throw(INTERP_KERNEL::Exception)
 {
   releaseData(true);
   _src_mesh=(MEDCouplingMesh *)srcMesh; _target_mesh=(MEDCouplingMesh *)targetMesh;
@@ -58,7 +58,7 @@ int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCoupli
     }
 }
 
-void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue)
+void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception)
 {
   if(_src_method!=srcField->getDiscretization()->getStringRepr())
     throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field");
@@ -86,7 +86,7 @@ void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCo
   computeProduct(inputPointer,srcNbOfCompo,dftValue,resPointer);
 }
 
-void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue)
+void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception)
 {
   if(_src_method!=srcField->getDiscretization()->getStringRepr())
     throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field");
@@ -114,7 +114,7 @@ void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, cons
   computeReverseProduct(inputPointer,trgNbOfCompo,dftValue,resPointer);
 }
 
-MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue)
+MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception)
 {
   if(_src_method!=srcField->getDiscretization()->getStringRepr())
     throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field");
@@ -125,7 +125,7 @@ MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFiel
   return ret;
 }
 
-MEDCouplingFieldDouble *MEDCouplingRemapper::reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue)
+MEDCouplingFieldDouble *MEDCouplingRemapper::reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception)
 {
   if(_target_method!=targetField->getDiscretization()->getStringRepr())
     throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field");
@@ -146,12 +146,12 @@ bool MEDCouplingRemapper::setOptionDouble(const std::string& key, double value)
   return INTERP_KERNEL::InterpolationOptions::setOptionDouble(key,value);
 }
 
-bool MEDCouplingRemapper::setOptionString(const std::string& key, std::string& value)
+bool MEDCouplingRemapper::setOptionString(const std::string& key, const std::string& value)
 {
   return INTERP_KERNEL::InterpolationOptions::setOptionString(key,value);
 }
 
-int MEDCouplingRemapper::prepareUU(const char *method)
+int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingUMesh *src_mesh=(MEDCouplingUMesh *)_src_mesh;
   MEDCouplingUMesh *target_mesh=(MEDCouplingUMesh *)_target_mesh;
@@ -168,7 +168,21 @@ int MEDCouplingRemapper::prepareUU(const char *method)
     if(trgSpaceDim!=-1 && srcSpaceDim!=-1)
       throw INTERP_KERNEL::Exception("Incoherent space dimension detected between target and source.");
   int nbCols;
-  if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==2)
+  if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==1)
+    {
+      MEDCouplingNormalizedUnstructuredMesh<1,1> source_mesh_wrapper(src_mesh);
+      MEDCouplingNormalizedUnstructuredMesh<1,1> target_mesh_wrapper(target_mesh);
+      INTERP_KERNEL::Interpolation1D interpolation(*this);
+      nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method);
+    }
+  else if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==2)
+    {
+      MEDCouplingNormalizedUnstructuredMesh<2,1> source_mesh_wrapper(src_mesh);
+      MEDCouplingNormalizedUnstructuredMesh<2,1> target_mesh_wrapper(target_mesh);
+      INTERP_KERNEL::Interpolation2DCurve interpolation(*this);
+      nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method);
+    }
+  else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==2)
     {
       MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh);
       MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh);
@@ -287,7 +301,7 @@ int MEDCouplingRemapper::prepareUU(const char *method)
   return 1;
 }
 
-int MEDCouplingRemapper::prepareEE(const char *method)
+int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingExtrudedMesh *src_mesh=(MEDCouplingExtrudedMesh *)_src_mesh;
   MEDCouplingExtrudedMesh *target_mesh=(MEDCouplingExtrudedMesh *)_target_mesh;
@@ -351,7 +365,7 @@ void MEDCouplingRemapper::computeDeno(NatureOfField nat, const MEDCouplingFieldD
     return computeDenoFromScratch(nat,srcField,trgField);
 }
 
-void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField)
+void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) throw(INTERP_KERNEL::Exception)
 {
   _nature_of_deno=nat;
   _time_deno_update=getTimeOfThis();
@@ -364,8 +378,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou
       }
     case Integral:
       {
-        MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getWeightingField(srcField->getMesh(),true);
-        MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getWeightingField(trgField->getMesh(),true);
+        MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true);
+        MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true);
         const double *denoPtr=deno->getArray()->getConstPointer();
         const double *denoRPtr=denoR->getArray()->getConstPointer();
         if(trgField->getMesh()->getMeshDimension()==-1)
@@ -396,8 +410,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou
       }
     case RevIntegral:
       {
-        MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getWeightingField(trgField->getMesh(),true);
-        MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getWeightingField(srcField->getMesh(),true);
+        MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true);
+        MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true);
         const double *denoPtr=deno->getArray()->getConstPointer();
         const double *denoRPtr=denoR->getArray()->getConstPointer();
         if(trgField->getMesh()->getMeshDimension()==-1)
index 5e2bd63dd357ab4a7c7890aca4e5dd25438a717b..14d402d0365d5a45e3db4e631866af24db86ea7a 100644 (file)
@@ -24,6 +24,7 @@
 #include "MEDCouplingTimeLabel.hxx"
 #include "InterpolationOptions.hxx"
 #include "MEDCouplingNatureOfField.hxx"
+#include "InterpKernelException.hxx"
 
 #include <map>
 #include <vector>
@@ -42,23 +43,23 @@ namespace ParaMEDMEM
   public:
     MEDCOUPLINGREMAPPER_EXPORT MEDCouplingRemapper();
     MEDCOUPLINGREMAPPER_EXPORT ~MEDCouplingRemapper();
-    MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method);
-    MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue);
-    MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue);
-    MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue);
-    MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue);
+    MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception);
     MEDCOUPLINGREMAPPER_EXPORT bool setOptionInt(const std::string& key, int value);
     MEDCOUPLINGREMAPPER_EXPORT bool setOptionDouble(const std::string& key, double value);
-    MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, std::string& value);
+    MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, const std::string& value);
   public:
     MEDCOUPLINGREMAPPER_EXPORT static void printMatrix(const std::vector<std::map<int,double> >& m);
   private:
-    int prepareUU(const char *method);
-    int prepareEE(const char *method);
+    int prepareUU(const char *method) throw(INTERP_KERNEL::Exception);
+    int prepareEE(const char *method) throw(INTERP_KERNEL::Exception);
     void updateTime();
     void releaseData(bool matrixSuppression);
     void computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField);
-    void computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField);
+    void computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) throw(INTERP_KERNEL::Exception);
     void computeProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer);
     void computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer);
     void buildFinalInterpolationMatrixByConvolution(const std::vector< std::map<int,double> >& m1D,
index a030e1b4c148250a1e4c3690e4a33171db34ca39..a150a9cd4e15c2585651a1bc16986efa76c3fccf 100644 (file)
 
 #include "MEDCouplingTimeDiscretization.hxx"
 #include "MEDCouplingMemArray.hxx"
-
-#include "InterpKernelExprParser.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
 #include <cmath>
 #include <iterator>
+#include <functional>
 
 using namespace ParaMEDMEM;
 
+const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12;
+
 const char MEDCouplingNoTimeLabel::EXCEPTION_MSG[]="MEDCouplingNoTimeLabel::setTime : no time info attached.";
 
+const char MEDCouplingNoTimeLabel::REPR[]="No time label defined.";
+
 const char MEDCouplingWithTimeStep::EXCEPTION_MSG[]="No data on this time.";
 
+const char MEDCouplingWithTimeStep::REPR[]="One time label.";
+
 const char MEDCouplingConstOnTimeInterval::EXCEPTION_MSG[]="No data on this time.";
 
-const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12;
+const char MEDCouplingConstOnTimeInterval::REPR[]="Constant on a time interval.";
+
+const char MEDCouplingTwoTimeSteps::EXCEPTION_MSG[]="No data on this time.";
+
+const char MEDCouplingLinearTime::REPR[]="Linear time between 2 time steps.";
 
 MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDiscretization type)
 {
@@ -45,11 +55,32 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDisc
       return new MEDCouplingWithTimeStep;
     case MEDCouplingConstOnTimeInterval::DISCRETIZATION:
       return new MEDCouplingConstOnTimeInterval;
+    case MEDCouplingLinearTime::DISCRETIZATION:
+      return new MEDCouplingLinearTime;
     default:
       throw INTERP_KERNEL::Exception("Time discretization not implemented yet");
     }
 }
 
+void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other)
+{
+  _time_tolerance=other._time_tolerance;
+}
+
+void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other)
+{
+  if(_array && other._array)
+    _array->copyStringInfoFrom(*other._array);
+}
+
+void MEDCouplingTimeDiscretization::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  if(!_array)
+    throw INTERP_KERNEL::Exception("Field invalid because no values set !");
+  if(_time_tolerance<0.)
+    throw INTERP_KERNEL::Exception("time tolerance is expected to be greater than 0. !");
+}
+
 void MEDCouplingTimeDiscretization::updateTime()
 {
   if(_array)
@@ -69,7 +100,22 @@ bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretiz
   return true;
 }
 
-bool MEDCouplingTimeDiscretization::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const
+{
+  if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
+    return false;
+  if(_array==0 && other->_array==0)
+    return true;
+  if(_array==0 || other->_array==0)
+    return false;
+  if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents())
+    return false;
+  if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples())
+    return false;
+  return true;
+}
+
+bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
 {
   if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
     return false;
@@ -87,13 +133,22 @@ bool MEDCouplingTimeDiscretization::areCompatibleForMul(const MEDCouplingTimeDis
 
 bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
 {
-  if(!areCompatible(other))
+  if(!areStrictlyCompatible(other))
     return false;
   if(_array==other->_array)
     return true;
   return _array->isEqual(*other->_array,prec);
 }
 
+bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const
+{
+  if(!areStrictlyCompatible(other))
+    return false;
+  if(_array==other->_array)
+    return true;
+  return _array->isEqualWithoutConsideringStr(*other->_array,prec);
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFromThis(const MEDCouplingTimeDiscretization *other,
                                                                                        TypeOfTimeDiscretization type, bool deepCpy) const
 {
@@ -190,6 +245,16 @@ void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel *
     }
 }
 
+DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const
+{
+  throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !");
+}
+
+void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner)
+{
+  throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !");
+}
+
 void MEDCouplingTimeDiscretization::setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception)
 {
   if(arrays.size()!=1)
@@ -205,122 +270,403 @@ void MEDCouplingTimeDiscretization::getArrays(std::vector<DataArrayDouble *>& ar
 
 bool MEDCouplingTimeDiscretization::isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception)
 {
-  int dt,it;
-  double time1=getEndTime(dt,it)-_time_tolerance;
-  double time2=other->getStartTime(dt,it)+other->getTimeTolerance();
+  int iteration,order;
+  double time1=getEndTime(iteration,order)-_time_tolerance;
+  double time2=other->getStartTime(iteration,order)+other->getTimeTolerance();
   return time1<=time2;
 }
 
 bool MEDCouplingTimeDiscretization::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception)
 {
-  int dt,it;
-  double time1=getEndTime(dt,it)+_time_tolerance;
-  double time2=other->getStartTime(dt,it)-other->getTimeTolerance();
+  int iteration,order;
+  double time1=getEndTime(iteration,order)+_time_tolerance;
+  double time2=other->getStartTime(iteration,order)-other->getTimeTolerance();
   return time1<time2;
 }
 
-void MEDCouplingTimeDiscretization::applyLin(double a, double b, int compoId)
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
 {
-  double *ptr=_array->getPointer()+compoId;
-  int nbOfComp=_array->getNumberOfComponents();
-  int nbOfTuple=_array->getNumberOfTuples();
-  for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
-    *ptr=a*(*ptr)+b;
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->doublyContractedProduct();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  ret->setArrays(arrays3,0);
+  return ret;
 }
 
-void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func)
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::determinant() const throw(INTERP_KERNEL::Exception)
 {
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=_array->getNumberOfTuples();
-  int oldNbOfComp=_array->getNumberOfComponents();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const double *ptr=_array->getConstPointer();
-  double *ptrToFill=newArr->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
     {
-      if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
-        {
-          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
-          std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed !";
-          newArr->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
+      if(arrays[j])
+        arrays2[j]=arrays[j]->determinant();
+      else
+        arrays2[j]=0;
     }
-  _array->decrRef();
-  _array=newArr;
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
 }
 
-void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, const char *func)
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenValues() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->eigenValues();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenVectors() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->eigenVectors();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::inverse() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->inverse();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::trace() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->trace();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::deviator() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->deviator();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::magnitude() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->magnitude();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::maxPerTuple() const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->maxPerTuple();
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->keepSelectedComponents(compoIds);
+      else
+        arrays2[j]=0;
+    }
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum());
+  ret->setArrays(arrays3,0);
+  return ret;
+}
+
+void MEDCouplingTimeDiscretization::setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays1,arrays2;
+  getArrays(arrays1);
+  other->getArrays(arrays2);
+  if(arrays1.size()!=arrays2.size())
+    throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : number of arrays mismatch !");
+  for(unsigned int i=0;i<arrays1.size();i++)
+    {
+      if(arrays1[i]!=0 && arrays2[i]!=0)
+        arrays1[i]->setSelectedComponents(arrays2[i],compoIds);
+      else if(arrays1[i]!=0 || arrays2[i]!=0)
+        throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : some time array in correspondance are not defined symetrically !");
+    }
+}
+
+void MEDCouplingTimeDiscretization::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception)
 {
-  INTERP_KERNEL::ExprParser expr(func);
-  expr.parse();
-  std::set<std::string> vars;
-  expr.getTrueSetOfVars(vars);
-  int oldNbOfComp=_array->getNumberOfComponents();
-  if((int)vars.size()>oldNbOfComp)
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
     {
-      std::ostringstream oss; oss << "The field has a " << oldNbOfComp << " components and there are ";
-      oss << vars.size() << " variables : ";
-      std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
+      if(arrays[j])
+        arrays2[j]=arrays[j]->changeNbOfComponents(newNbOfComp,dftValue);
+      else
+        arrays2[j]=0;
     }
-  std::vector<std::string> varsV(vars.begin(),vars.end());
-  expr.prepareExprEvaluation(varsV);
-  //
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=_array->getNumberOfTuples();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const double *ptr=_array->getConstPointer();
-  double *ptrToFill=newArr->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  setArrays(arrays3,0);
+}
+
+void MEDCouplingTimeDiscretization::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays[j]->sortPerTuple(asc);
+    }
+}
+
+void MEDCouplingTimeDiscretization::setUniformValue(int nbOfTuple, int nbOfCompo, double value)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
     {
-      try
+      if(arrays[j])
         {
-          expr.evaluateExpr(nbOfComp,ptrToFill+i*nbOfComp,ptr+i*oldNbOfComp);
+          arrays[j]->incrRef();
+          arrays[j]->fillWithValue(value);
+          arrays2[j]=arrays[j];
         }
-      catch(INTERP_KERNEL::Exception& e)
+      else
         {
-          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
-          std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed !" << e.what();
-          newArr->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
+          DataArrayDouble *tmp=DataArrayDouble::New();
+          tmp->alloc(nbOfTuple,nbOfCompo);
+          tmp->fillWithValue(value);
+          arrays2[j]=tmp;
         }
     }
-  _array->decrRef();
-  _array=newArr;
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  setArrays(arrays3,0);
+}
+
+void MEDCouplingTimeDiscretization::applyLin(double a, double b, int compoId)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays[j]->applyLin(a,b,compoId);
+    }
+}
+
+void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector<DataArrayDouble *> arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->applyFunc(nbOfComp,func);
+      else
+        arrays2[j]=0;
+    }
+  setArrays(arrays2,0);
+  for(int j=0;j<(int)arrays.size();j++)
+    if(arrays2[j])
+      arrays2[j]->decrRef();
+}
+
+void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, const char *func)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector<DataArrayDouble *> arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays2[j]=arrays[j]->applyFunc(nbOfComp,func);
+      else
+        arrays2[j]=0;
+    }
+  setArrays(arrays2,0);
+  for(int j=0;j<(int)arrays.size();j++)
+    if(arrays2[j])
+      arrays2[j]->decrRef();
 }
 
 void MEDCouplingTimeDiscretization::applyFunc(const char *func)
 {
-  INTERP_KERNEL::ExprParser expr(func);
-  expr.parse();
-  expr.prepareExprEvaluationVec();
-  //
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=_array->getNumberOfTuples();
-  int nbOfComp=_array->getNumberOfComponents();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const double *ptr=_array->getConstPointer();
-  double *ptrToFill=newArr->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector<DataArrayDouble *> arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
     {
-      try
-        {
-          expr.evaluateExpr(nbOfComp,ptrToFill+i*nbOfComp,ptr+i*nbOfComp);
-        }
-      catch(INTERP_KERNEL::Exception& e)
-        {
-          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
-          std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed ! " << e.what();
-          newArr->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
+      if(arrays[j])
+        arrays2[j]=arrays[j]->applyFunc(func);
+      else
+        arrays2[j]=0;
+    }
+  setArrays(arrays2,0);
+  for(int j=0;j<(int)arrays.size();j++)
+    if(arrays2[j])
+      arrays2[j]->decrRef();
+}
+
+void MEDCouplingTimeDiscretization::applyFuncFast32(const char *func)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays[j]->applyFuncFast32(func);
+    }
+}
+
+void MEDCouplingTimeDiscretization::applyFuncFast64(const char *func)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  for(int j=0;j<(int)arrays.size();j++)
+    {
+      if(arrays[j])
+        arrays[j]->applyFuncFast64(func);
     }
-  _array->decrRef();
-  _array=newArr;
+}
+
+void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays2[j]=loc->applyFunc(nbOfComp,func);
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  setArrays(arrays3,0);
+}
+
+void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<DataArrayDouble *> arrays;
+  getArrays(arrays);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays2[j]=loc->applyFunc(nbOfComp,func);
+  std::vector<DataArrayDouble *> arrays3(arrays.size());
+  for(int j=0;j<(int)arrays.size();j++)
+    arrays3[j]=arrays2[j];
+  setArrays(arrays3,0);
 }
 
 MEDCouplingNoTimeLabel::MEDCouplingNoTimeLabel()
@@ -331,6 +677,13 @@ MEDCouplingNoTimeLabel::MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretizati
 {
 }
 
+std::string MEDCouplingNoTimeLabel::getStringRepr() const
+{
+  std::ostringstream stream;
+  stream << REPR;
+  return stream.str();
+}
+
 bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization *other) const
 {
   if(!MEDCouplingTimeDiscretization::areCompatible(other))
@@ -339,9 +692,17 @@ bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization *
   return otherC!=0;
 }
 
-bool MEDCouplingNoTimeLabel::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+bool MEDCouplingNoTimeLabel::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other))
+    return false;
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  return otherC!=0;
+}
+
+bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
 {
-  if(!MEDCouplingTimeDiscretization::areCompatibleForMul(other))
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other))
     return false;
   const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
   return otherC!=0;
@@ -355,14 +716,70 @@ bool MEDCouplingNoTimeLabel::isEqual(const MEDCouplingTimeDiscretization *other,
   return MEDCouplingTimeDiscretization::isEqual(other,prec);
 }
 
+bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const
+{
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  if(!otherC)
+    return false;
+  return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec);
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCouplingTimeDiscretization *other) const
 {
   const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("NoTimeLabel::aggregation on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   ret->setTimeTolerance(getTimeTolerance());
-  DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("NoTimeLabel::dot on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::dot(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("NoTimeLabel::crossProduct on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::crossProduct(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::max(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::min(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   ret->setArray(arr,0);
   arr->decrRef();
   return ret;
@@ -373,8 +790,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTime
   const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("NoTimeLabel::add on mismatched time discretization !");
-  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   ret->setArray(arr,0);
   arr->decrRef();
   return ret;
@@ -393,8 +810,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCoupli
   const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("NoTimeLabel::substract on mismatched time discretization !");
-  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   ret->setArray(arr,0);
   arr->decrRef();
   return ret;
@@ -413,8 +830,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplin
   const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("NoTimeLabel::multiply on mismatched time discretization !");
-  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   DataArrayDouble *arr=DataArrayDouble::multiply(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   ret->setArray(arr,0);
   arr->decrRef();
   return ret;
@@ -433,8 +850,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingT
   const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("divide on mismatched time discretization !");
-  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   DataArrayDouble *arr=DataArrayDouble::divide(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   ret->setArray(arr,0);
   arr->decrRef();
   return ret;
@@ -478,22 +895,22 @@ bool MEDCouplingNoTimeLabel::isStrictlyBefore(const MEDCouplingTimeDiscretizatio
   throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
-double MEDCouplingNoTimeLabel::getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception)
+double MEDCouplingNoTimeLabel::getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
-double MEDCouplingNoTimeLabel::getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception)
+double MEDCouplingNoTimeLabel::getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
-void MEDCouplingNoTimeLabel::setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception)
+void MEDCouplingNoTimeLabel::setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
-void MEDCouplingNoTimeLabel::setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception)
+void MEDCouplingNoTimeLabel::setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
@@ -503,25 +920,32 @@ void MEDCouplingNoTimeLabel::getValueOnTime(int eltId, double time, double *valu
   throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
-void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
 MEDCouplingWithTimeStep::MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy),
-                                                                                                     _time(other._time),_dt(other._dt),_it(other._it)
+                                                                                                     _time(other._time),_iteration(other._iteration),_order(other._order)
+{
+}
+
+MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_iteration(-1),_order(-1)
 {
 }
 
-MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_dt(-1),_it(-1)
+std::string MEDCouplingWithTimeStep::getStringRepr() const
 {
+  std::ostringstream stream;
+  stream << REPR << " Time is defined by iteration=" << _iteration << " order=" << _order << " and time=" << _time << ".";
+  return stream.str();
 }
 
 void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
 {
   MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo);
-  tinyInfo.push_back(_dt);
-  tinyInfo.push_back(_it);
+  tinyInfo.push_back(_iteration);
+  tinyInfo.push_back(_order);
 }
 
 void MEDCouplingWithTimeStep::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
@@ -534,8 +958,8 @@ void MEDCouplingWithTimeStep::finishUnserialization(const std::vector<int>& tiny
 {
   MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS);
   _time=tinyInfoD[1];
-  _dt=tinyInfoI[2];
-  _it=tinyInfoI[3];
+  _iteration=tinyInfoI[2];
+  _order=tinyInfoI[3];
 }
 
 bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization *other) const
@@ -543,19 +967,23 @@ bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization
   if(!MEDCouplingTimeDiscretization::areCompatible(other))
     return false;
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
-  if(!otherC)
-    return false;
-  return std::fabs(_time-otherC->_time)<_time_tolerance;
+  return otherC!=0;
 }
 
-bool MEDCouplingWithTimeStep::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const
 {
-  if(!MEDCouplingTimeDiscretization::areCompatibleForMul(other))
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other))
     return false;
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
-  if(!otherC)
+  return otherC!=0;
+}
+
+bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other))
     return false;
-  return std::fabs(_time-otherC->_time)<_time_tolerance;
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  return otherC!=0;
 }
 
 bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
@@ -563,23 +991,46 @@ bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
   if(!otherC)
     return false;
-  if(_dt!=otherC->_dt)
+  if(_iteration!=otherC->_iteration)
     return false;
-  if(_it!=otherC->_it)
+  if(_order!=otherC->_order)
     return false;
   if(std::fabs(_time-otherC->_time)>_time_tolerance)
     return false;
   return MEDCouplingTimeDiscretization::isEqual(other,prec);
 }
 
+bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const
+{
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  if(!otherC)
+    return false;
+  if(_iteration!=otherC->_iteration)
+    return false;
+  if(_order!=otherC->_order)
+    return false;
+  if(std::fabs(_time-otherC->_time)>_time_tolerance)
+    return false;
+  return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec);
+}
+
+void MEDCouplingWithTimeStep::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other)
+{
+  MEDCouplingTimeDiscretization::copyTinyAttrFrom(other);
+  const MEDCouplingWithTimeStep& otherC=dynamic_cast<const MEDCouplingWithTimeStep& >(other);
+  _time=otherC._time;
+  _iteration=otherC._iteration;
+  _order=otherC._order;
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const
 {
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("WithTimeStep::aggregation on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
   ret->setTimeTolerance(getTimeTolerance());
-  DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -588,39 +1039,87 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCoupl
   return ret;
 }
 
-MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTimeDiscretization *other) const
 {
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
   if(!otherC)
-    throw INTERP_KERNEL::Exception("WithTimeStep::add on mismatched time discretization !");
+    throw INTERP_KERNEL::Exception("WithTimeStep::dot on mismatched time discretization !");
   MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
-  DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray());
+  DataArrayDouble *arr=DataArrayDouble::dot(getArray(),other->getArray());
   ret->setArray(arr,0);
   arr->decrRef();
-  int tmp1,tmp2;
-  double tmp3=getStartTime(tmp1,tmp2);
-  ret->setStartTime(tmp3,tmp1,tmp2);
   return ret;
 }
 
-void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *other)
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCouplingTimeDiscretization *other) const
 {
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
   if(!otherC)
-    throw INTERP_KERNEL::Exception("WithTimeStep::addEqual on mismatched time discretization !");
-  getArray()->addEqual(other->getArray());
+    throw INTERP_KERNEL::Exception("WithTimeStep::crossProduct on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::crossProduct(getArray(),other->getArray());
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
 }
 
-MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTimeDiscretization *other) const
 {
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
   if(!otherC)
-    throw INTERP_KERNEL::Exception("WithTimeStep::substract on mismatched time discretization !");
+    throw INTERP_KERNEL::Exception("WithTimeStep::max on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::max(getArray(),other->getArray());
   MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
-  DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray());
   ret->setArray(arr,0);
   arr->decrRef();
-  int tmp1,tmp2;
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("WithTimeStep::min on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::min(getArray(),other->getArray());
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("WithTimeStep::add on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray());
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  int tmp1,tmp2;
+  double tmp3=getStartTime(tmp1,tmp2);
+  ret->setStartTime(tmp3,tmp1,tmp2);
+  return ret;
+}
+
+void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("WithTimeStep::addEqual on mismatched time discretization !");
+  getArray()->addEqual(other->getArray());
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("WithTimeStep::substract on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray());
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  int tmp1,tmp2;
   double tmp3=getStartTime(tmp1,tmp2);
   ret->setStartTime(tmp3,tmp1,tmp2);
   return ret;
@@ -639,8 +1138,8 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCoupli
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("WithTimeStep::multiply on mismatched time discretization !");
-  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
   DataArrayDouble *arr=DataArrayDouble::multiply(getArray(),other->getArray());
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -662,8 +1161,8 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCoupling
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("WithTimeStep::divide on mismatched time discretization !");
-  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
   DataArrayDouble *arr=DataArrayDouble::divide(getArray(),other->getArray());
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -728,9 +1227,9 @@ void MEDCouplingWithTimeStep::getValueOnTime(int eltId, double time, double *val
     throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
-void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception)
 {
-  if(_dt==dt && _it==it)
+  if(_iteration==iteration && _order==order)
     if(_array)
       _array->getTuple(eltId,value);
     else
@@ -739,17 +1238,29 @@ void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int dt, int it, doub
     throw INTERP_KERNEL::Exception("No data on this discrete time.");
 }
 
-MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval():_start_time(0.),_end_time(0.),_start_dt(-1),_end_dt(-1),_start_it(-1),_end_it(-1)
+MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1)
 {
 }
 
+void MEDCouplingConstOnTimeInterval::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other)
+{
+  MEDCouplingTimeDiscretization::copyTinyAttrFrom(other);
+  const MEDCouplingConstOnTimeInterval& otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval& >(other);
+  _start_time=otherC._start_time;
+  _end_time=otherC._end_time;
+  _start_iteration=otherC._start_iteration;
+  _end_iteration=otherC._end_iteration;
+  _start_order=otherC._start_order;
+  _end_order=otherC._end_order;
+}
+
 void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
 {
   MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo);
-  tinyInfo.push_back(_start_dt);
-  tinyInfo.push_back(_start_it);
-  tinyInfo.push_back(_end_dt);
-  tinyInfo.push_back(_end_it);
+  tinyInfo.push_back(_start_iteration);
+  tinyInfo.push_back(_start_order);
+  tinyInfo.push_back(_end_iteration);
+  tinyInfo.push_back(_end_order);
 }
 
 void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
@@ -764,18 +1275,26 @@ void MEDCouplingConstOnTimeInterval::finishUnserialization(const std::vector<int
   MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS);
   _start_time=tinyInfoD[1];
   _end_time=tinyInfoD[2];
-  _start_dt=tinyInfoI[2];
-  _start_it=tinyInfoI[3];
-  _end_dt=tinyInfoI[4];
-  _end_it=tinyInfoI[5];
+  _start_iteration=tinyInfoI[2];
+  _start_order=tinyInfoI[3];
+  _end_iteration=tinyInfoI[4];
+  _end_order=tinyInfoI[5];
 }
 
 MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy):
-  MEDCouplingTimeDiscretization(other,deepCpy),_start_time(other._start_time),_end_time(other._end_time),_start_dt(other._start_dt),
-  _end_dt(other._end_dt),_start_it(other._start_it),_end_it(other._end_it)
+  MEDCouplingTimeDiscretization(other,deepCpy),_start_time(other._start_time),_end_time(other._end_time),_start_iteration(other._start_iteration),
+  _end_iteration(other._end_iteration),_start_order(other._start_order),_end_order(other._end_order)
 {
 }
 
+std::string MEDCouplingConstOnTimeInterval::getStringRepr() const
+{
+  std::ostringstream stream;
+  stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n";
+  stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n";
+  return stream.str();
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const
 {
   return new MEDCouplingConstOnTimeInterval(*this,deepCpy);
@@ -803,19 +1322,23 @@ bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscreti
   if(!MEDCouplingTimeDiscretization::areCompatible(other))
     return false;
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
-  if(!otherC)
-    return false;
-  return (std::fabs(_start_time-otherC->_start_time)<_time_tolerance && std::fabs(_end_time-otherC->_end_time)<_time_tolerance);
+  return otherC!=0;
 }
 
-bool MEDCouplingConstOnTimeInterval::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const
 {
-  if(!MEDCouplingTimeDiscretization::areCompatible(other))
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other))
     return false;
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
-  if(!otherC)
+  return otherC!=0;
+}
+
+bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other))
     return false;
-  return (std::fabs(_start_time-otherC->_start_time)<_time_tolerance && std::fabs(_end_time-otherC->_end_time)<_time_tolerance);
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  return otherC!=0;
 }
 
 bool MEDCouplingConstOnTimeInterval::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
@@ -823,21 +1346,41 @@ bool MEDCouplingConstOnTimeInterval::isEqual(const MEDCouplingTimeDiscretization
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
   if(!otherC)
     return false;
-  if(_start_dt!=otherC->_start_dt)
+  if(_start_iteration!=otherC->_start_iteration)
     return false;
-  if(_start_it!=otherC->_start_it)
+  if(_start_order!=otherC->_start_order)
     return false;
   if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance)
     return false;
-  if(_end_dt!=otherC->_end_dt)
+  if(_end_iteration!=otherC->_end_iteration)
     return false;
-  if(_end_it!=otherC->_end_it)
+  if(_end_order!=otherC->_end_order)
     return false;
   if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance)
     return false;
   return MEDCouplingTimeDiscretization::isEqual(other,prec);
 }
 
+bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const
+{
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  if(!otherC)
+    return false;
+  if(_start_iteration!=otherC->_start_iteration)
+    return false;
+  if(_start_order!=otherC->_start_order)
+    return false;
+  if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance)
+    return false;
+  if(_end_iteration!=otherC->_end_iteration)
+    return false;
+  if(_end_order!=otherC->_end_order)
+    return false;
+  if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance)
+    return false;
+  return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec);
+}
+
 void MEDCouplingConstOnTimeInterval::getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception)
 {
   if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance)
@@ -849,9 +1392,9 @@ void MEDCouplingConstOnTimeInterval::getValueOnTime(int eltId, double time, doub
     throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
 }
 
-void MEDCouplingConstOnTimeInterval::getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingConstOnTimeInterval::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception)
 {
-  if(dt>=_start_dt && dt<=_end_dt)
+  if(iteration>=_start_iteration && iteration<=_end_iteration)
     if(_array)
       _array->getTuple(eltId,value);
     else
@@ -870,7 +1413,7 @@ void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const throw(
   if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance)
     {
       std::ostringstream stream;
-      stream << "The field is defined between times " << _start_time << " and " << _end_time << " with tolerance ";
+      stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance ";
       stream << _time_tolerance << " and trying to access on time = " << time;
       throw INTERP_KERNEL::Exception(stream.str().c_str());
     }
@@ -881,9 +1424,9 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const M
    const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregation on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   ret->setTimeTolerance(getTimeTolerance());
-  DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -894,13 +1437,61 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const M
   return ret;
 }
 
+MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("ConstOnTimeInterval::dot on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::dot(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("ConstOnTimeInterval::crossProduct on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::crossProduct(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("ConstOnTimeInterval::max on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::max(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("ConstOnTimeInterval::min on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::min(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCouplingTimeDiscretization *other) const
 {
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("ConstOnTimeInterval::add on mismatched time discretization !");
-  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -924,8 +1515,8 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const M
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substract on mismatched time discretization !");
-  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -949,8 +1540,8 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const ME
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("multiply on mismatched time discretization !");
-  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   DataArrayDouble *arr=DataArrayDouble::multiply(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -974,8 +1565,8 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDC
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("divide on mismatched time discretization !");
-  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   DataArrayDouble *arr=DataArrayDouble::divide(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   ret->setArray(arr,0);
   arr->decrRef();
   int tmp1,tmp2;
@@ -994,7 +1585,109 @@ void MEDCouplingConstOnTimeInterval::divideEqual(const MEDCouplingTimeDiscretiza
   getArray()->divideEqual(other->getArray());
 }
 
-MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_dt(-1),_end_dt(-1),_start_it(-1),_end_it(-1),_end_array(0)
+MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy),
+                                                                                                     _start_time(other._start_time),_end_time(other._end_time),
+                                                                                                     _start_iteration(other._start_iteration),_end_iteration(other._end_iteration),
+                                                                                                     _start_order(other._start_order),_end_order(other._end_order)
+{
+  if(other._end_array)
+    _end_array=other._end_array->performCpy(deepCpy);
+  else
+    _end_array=0;
+}
+
+void MEDCouplingTwoTimeSteps::updateTime()
+{
+  MEDCouplingTimeDiscretization::updateTime();
+  if(_end_array)
+    updateTimeWith(*_end_array);
+}
+
+void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other)
+{
+  MEDCouplingTimeDiscretization::copyTinyAttrFrom(other);
+  const MEDCouplingTwoTimeSteps& otherC=dynamic_cast<const MEDCouplingTwoTimeSteps& >(other);
+  _start_time=otherC._start_time;
+  _end_time=otherC._end_time;
+  _start_iteration=otherC._start_iteration;
+  _end_iteration=otherC._end_iteration;
+  _start_order=otherC._start_order;
+  _end_order=otherC._end_order;
+}
+
+void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other)
+{
+  MEDCouplingTimeDiscretization::copyTinyStringsFrom(other);
+  const MEDCouplingTwoTimeSteps* otherC=dynamic_cast<const MEDCouplingTwoTimeSteps* >(&other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("Trying to operate copyTinyStringsFrom on different field type (two times//one time) !");
+  if(_end_array && otherC->_end_array)
+    _end_array->copyStringInfoFrom(*otherC->_end_array);
+}
+
+DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const
+{
+  return _end_array;
+}
+
+void MEDCouplingTwoTimeSteps::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization::checkCoherency();
+  if(!_end_array)
+    throw INTERP_KERNEL::Exception("No end array specified !");
+  if(_array->getNumberOfComponents()!=_end_array->getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("The number of components mismatch between the start and the end arrays !");
+  if(_array->getNumberOfTuples()!=_end_array->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("The number of tuples mismatch between the start and the end arrays !");
+}
+
+bool MEDCouplingTwoTimeSteps::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
+{
+  const MEDCouplingTwoTimeSteps *otherC=dynamic_cast<const MEDCouplingTwoTimeSteps *>(other);
+  if(!otherC)
+    return false;
+  if(_start_iteration!=otherC->_start_iteration)
+    return false;
+  if(_end_iteration!=otherC->_end_iteration)
+    return false;
+  if(_start_order!=otherC->_start_order)
+    return false;
+  if(_end_order!=otherC->_end_order)
+    return false;
+  if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance)
+    return false;
+  if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance)
+    return false;
+  if(_end_array!=otherC->_end_array)
+    if(!_end_array->isEqual(*otherC->_end_array,prec))
+      return false;
+  return MEDCouplingTimeDiscretization::isEqual(other,prec);
+}
+
+bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const
+{
+  const MEDCouplingTwoTimeSteps *otherC=dynamic_cast<const MEDCouplingTwoTimeSteps *>(other);
+  if(!otherC)
+    return false;
+  if(_start_iteration!=otherC->_start_iteration)
+    return false;
+  if(_end_iteration!=otherC->_end_iteration)
+    return false;
+  if(_start_order!=otherC->_start_order)
+    return false;
+  if(_end_order!=otherC->_end_order)
+    return false;
+  if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance)
+    return false;
+  if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance)
+    return false;
+  if(_end_array!=otherC->_end_array)
+    if(!_end_array->isEqualWithoutConsideringStr(*otherC->_end_array,prec))
+      return false;
+  return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec);
+}
+
+MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1),_end_array(0)
 {
 }
 
@@ -1014,7 +1707,7 @@ void MEDCouplingTwoTimeSteps::checkTimePresence(double time) const throw(INTERP_
   if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance)
     {
       std::ostringstream stream;
-      stream << "The field is defined between times " << _start_time << " and " << _end_time << " with tolerance ";
+      stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance ";
       stream << _time_tolerance << " and trying to access on time = " << time;
       throw INTERP_KERNEL::Exception(stream.str().c_str());
     }
@@ -1027,6 +1720,55 @@ void MEDCouplingTwoTimeSteps::getArrays(std::vector<DataArrayDouble *>& arrays)
   arrays[1]=_end_array;
 }
 
+void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner)
+{
+  if(array!=_end_array)
+    {
+      if(_end_array)
+        _end_array->decrRef();
+      _end_array=array;
+      if(_end_array)
+        _end_array->incrRef();
+      if(owner)
+        owner->declareAsNew();
+    }
+}
+
+void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
+{
+  MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo);
+  tinyInfo.push_back(_start_iteration);
+  tinyInfo.push_back(_start_order);
+  tinyInfo.push_back(_end_iteration);
+  tinyInfo.push_back(_end_order);
+  if(_end_array)
+    {
+      tinyInfo.push_back(_end_array->getNumberOfTuples());
+      tinyInfo.push_back(_end_array->getNumberOfComponents());
+    }
+  else
+    {
+      tinyInfo.push_back(-1);
+      tinyInfo.push_back(-1);
+    }
+}
+
+void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
+{
+  MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo);
+  tinyInfo.push_back(_start_time);
+  tinyInfo.push_back(_end_time);
+}
+
+void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
+{
+  int nbOfCompo=_array->getNumberOfComponents();
+  for(int i=0;i<nbOfCompo;i++)
+    tinyInfo.push_back(_array->getInfoOnComponent(i));
+  for(int i=0;i<nbOfCompo;i++)
+    tinyInfo.push_back(_end_array->getInfoOnComponent(i));
+}
+
 void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays)
 {
   arrays.resize(2);
@@ -1043,10 +1785,10 @@ void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector<int>& t
   _array=arr;
   arrays[0]=arr;
   arr=0;
-  if(tinyInfoI[2]!=-1 && tinyInfoI[3]!=-1)
+  if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1)
     {
       arr=DataArrayDouble::New();
-      arr->alloc(tinyInfoI[2],tinyInfoI[3]);
+      arr->alloc(tinyInfoI[6],tinyInfoI[7]);
     }
   _end_array=arr;
   arrays[1]=arr;
@@ -1057,8 +1799,305 @@ void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector<int>& tiny
   MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS);
   _start_time=tinyInfoD[1];
   _end_time=tinyInfoD[2];
-  _start_dt=tinyInfoI[2];
-  _end_dt=tinyInfoI[3];
-  _start_it=tinyInfoI[4];
-  _end_it=tinyInfoI[5];
+  _start_iteration=tinyInfoI[2];
+  _start_order=tinyInfoI[3];
+  _end_iteration=tinyInfoI[4];
+  _end_order=tinyInfoI[5];
+}
+
+std::vector< const DataArrayDouble *> MEDCouplingTwoTimeSteps::getArraysForTime(double time) const throw(INTERP_KERNEL::Exception)
+{
+   if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance)
+    {
+      std::vector< const DataArrayDouble *> ret(2);
+      ret[0]=_array;
+      ret[1]=_end_array;
+      return ret;
+    }
+  else
+    throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
+}
+
+void MEDCouplingTwoTimeSteps::setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception)
+{
+  if(arrays.size()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::setArrays : number of arrays must be two.");
+  setArray(arrays.front(),owner);
+  setEndArray(arrays.back(),owner);
+}
+
+MEDCouplingLinearTime::MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy):MEDCouplingTwoTimeSteps(other,deepCpy)
+{
+}
+
+MEDCouplingLinearTime::MEDCouplingLinearTime()
+{
+}
+
+std::string MEDCouplingLinearTime::getStringRepr() const
+{
+  std::ostringstream stream;
+  stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n";
+  stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n";
+  return stream.str();
+}
+
+void MEDCouplingLinearTime::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTwoTimeSteps::checkCoherency();
+  if(std::fabs(_start_time-_end_time)<_time_tolerance)
+    throw INTERP_KERNEL::Exception("Start time and end time are equals regarding time tolerance.");
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const
+{
+  return new MEDCouplingLinearTime(*this,deepCpy);
+}
+
+bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areCompatible(other))
+    return false;
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  return otherC!=0;
+}
+
+bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other))
+    return false;
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  return otherC!=0;
+}
+
+bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other))
+    return false;
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  return otherC!=0;
+}
+
+/*!
+ * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples()
+ */
+void MEDCouplingLinearTime::getValueForTime(double time, const std::vector<double>& vals, double *res) const
+{
+  double alpha=(_end_time-time)/(_end_time-_start_time);
+  int nbComp=vals.size()/2;
+  std::transform(vals.begin(),vals.begin()+nbComp,res,std::bind2nd(std::multiplies<double>(),alpha));
+  std::vector<double> tmp(nbComp);
+  std::transform(vals.begin()+nbComp,vals.end(),tmp.begin(),std::bind2nd(std::multiplies<double>(),1-alpha));
+  std::transform(tmp.begin(),tmp.end(),res,res,std::plus<double>());
+}
+
+void MEDCouplingLinearTime::getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception)
+{
+  double alpha=(_end_time-time)/(_end_time-_start_time);
+  int nbComp;
+  if(_array)
+    _array->getTuple(eltId,value);
+  else
+    throw INTERP_KERNEL::Exception("No start array existing.");
+  nbComp=_array->getNumberOfComponents();
+  std::transform(value,value+nbComp,value,std::bind2nd(std::multiplies<double>(),alpha));
+  std::vector<double> tmp(nbComp);
+  if(_end_array)
+    _end_array->getTuple(eltId,&tmp[0]);
+  else
+    throw INTERP_KERNEL::Exception("No end array existing.");
+  std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::multiplies<double>(),1-alpha));
+  std::transform(tmp.begin(),tmp.end(),value,value,std::plus<double>());
+}
+
+void MEDCouplingLinearTime::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception)
+{
+  if(iteration==_start_iteration && order==_start_order)
+    {
+      if(_array)
+        _array->getTuple(eltId,value);
+      else
+        throw INTERP_KERNEL::Exception("iteration order match with start time but no start array existing.");
+    }
+  if(iteration==_end_iteration && order==_end_order)
+    {
+      if(_end_array)
+        _end_array->getTuple(eltId,value);
+      else
+        throw INTERP_KERNEL::Exception("iteration order match with end time but no end array existing.");
+    }
+  else
+    throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::aggregation on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::aggregate(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::aggregate(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setTimeTolerance(getTimeTolerance());
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::dot on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::dot(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::dot(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::crossProduct on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::crossProduct(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::crossProduct(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::max on mismatched time discretization !");
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  DataArrayDouble *arr1=DataArrayDouble::max(getArray(),other->getArray());
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  DataArrayDouble *arr2=DataArrayDouble::max(getEndArray(),other->getEndArray());
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::min on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::min(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::min(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::add on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::add(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::add(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->addEqual(other->getArray());
+  getEndArray()->addEqual(other->getEndArray());
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::substract on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::substract(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::substract(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->substractEqual(other->getArray());
+  getEndArray()->substractEqual(other->getEndArray());
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::multiply on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::multiply(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::multiply(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->multiplyEqual(other->getArray());
+  getEndArray()->multiplyEqual(other->getEndArray());
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::divide on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::divide(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::divide(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->divideEqual(other->getArray());
+  getEndArray()->divideEqual(other->getEndArray());
 }
index 8ea2f8c6df465abcf9ea0cbfbaedfe723774b969..e826e12ced90714acd1fe1f42f579d4ce4080243 100644 (file)
@@ -17,8 +17,8 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#ifndef __MEDCOUPLINGTIMEDISCRETIZATION_HXX__
-#define __MEDCOUPLINGTIMEDISCRETIZATION_HXX__
+#ifndef __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__
 
 #include "MEDCoupling.hxx"
 #include "MEDCouplingTimeLabel.hxx"
@@ -40,13 +40,23 @@ namespace ParaMEDMEM
   public:
     void updateTime();
     static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type);
+    virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
+    virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other);
+    virtual void checkCoherency() const throw(INTERP_KERNEL::Exception);
     virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
-    virtual bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
+    virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
     virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
+    virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const;
     virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(const MEDCouplingTimeDiscretization *other,
                                                                     TypeOfTimeDiscretization type, bool deepCpy) const;
+    virtual std::string getStringRepr() const = 0;
     virtual TypeOfTimeDiscretization getEnum() const = 0;
     virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0;
+    virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0;
+    virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0;
+    virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0;
+    virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const = 0;
     virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const = 0;
     virtual void addEqual(const MEDCouplingTimeDiscretization *other) = 0;
     virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const = 0;
@@ -66,27 +76,46 @@ namespace ParaMEDMEM
     virtual void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) = 0;
     virtual void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception) = 0;
     virtual void setArray(DataArrayDouble *array, TimeLabel *owner);
+    virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner);
     virtual void setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getArray() const { return _array; }
-    virtual DataArrayDouble *getEndArray() const { return _array; }
+    virtual DataArrayDouble *getEndArray() const;
     virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception) = 0;
     virtual void getValueForTime(double time, const std::vector<double>& vals, double *res) const = 0; 
     virtual void getArrays(std::vector<DataArrayDouble *>& arrays) const;
     virtual bool isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception);
     virtual bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception);
-    double getTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { return getStartTime(dt,it); }
-    virtual double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) = 0;
-    virtual double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) = 0;
-    void setTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { setStartTime(time,dt,it); }
-    virtual void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) = 0;
-    virtual void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) = 0;
+    double getTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { return getStartTime(iteration,order); }
+    virtual double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) = 0;
+    void setTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { setStartTime(time,iteration,order); }
+    virtual void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) = 0;
+    virtual void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) = 0;
     virtual void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception) = 0;
-    virtual void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception) = 0;
     //
+    virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *determinant() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *eigenValues() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *eigenVectors() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *inverse() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *trace() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *deviator() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *magnitude() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *maxPerTuple() const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingTimeDiscretization *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
+    virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
+    virtual void changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception);
+    virtual void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception);
+    virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value);
     virtual void applyLin(double a, double b, int compoId);
     virtual void applyFunc(int nbOfComp, FunctionToEvaluate func);
     virtual void applyFunc(int nbOfComp, const char *func);
     virtual void applyFunc(const char *func);
+    virtual void applyFuncFast32(const char *func);
+    virtual void applyFuncFast64(const char *func);
+    virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception);
+    virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception);
     //
     virtual ~MEDCouplingTimeDiscretization();
   protected:
@@ -101,8 +130,13 @@ namespace ParaMEDMEM
   public:
     MEDCouplingNoTimeLabel();
     MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy);
+    std::string getStringRepr() const;
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const;
     void addEqual(const MEDCouplingTimeDiscretization *other);
     MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const;
@@ -112,8 +146,10 @@ namespace ParaMEDMEM
     MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const;
     void divideEqual(const MEDCouplingTimeDiscretization *other);
     bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const;
     bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
-    bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const;
     void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) { }
     void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception);
@@ -121,14 +157,15 @@ namespace ParaMEDMEM
     void getValueForTime(double time, const std::vector<double>& vals, double *res) const;
     bool isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception);
     bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception);
-    double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception);
-    double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception);
-    void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception);
-    void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception);
+    double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception);
+    double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception);
+    void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception);
+    void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception);
     void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception);
-    void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception);
+    void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception);
   public:
     static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME;
+    static const char REPR[];
   private:
     static const char EXCEPTION_MSG[];
   };
@@ -139,8 +176,14 @@ namespace ParaMEDMEM
     MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy);
   public:
     MEDCouplingWithTimeStep();
+    std::string getStringRepr() const;
+    void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const;
     void addEqual(const MEDCouplingTimeDiscretization *other);
     MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const;
@@ -150,31 +193,33 @@ namespace ParaMEDMEM
     MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const;
     void divideEqual(const MEDCouplingTimeDiscretization *other);
     bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const;
     bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
-    bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
     void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
     void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
     void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
     MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const;
     void checkNoTimePresence() const throw(INTERP_KERNEL::Exception);
     void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception);
-    void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _time=time; _dt=dt; _it=it; }
-    void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _time=time; _dt=dt; _it=it; }
-    double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_dt; it=_it; return _time; }
-    double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_dt; it=_it; return _time; }
-    DataArrayDouble *getArrayOnTime(double time) const throw(INTERP_KERNEL::Exception);
+    void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _time=time; _iteration=iteration; _order=order; }
+    void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _time=time; _iteration=iteration; _order=order; }
+    double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_iteration; order=_order; return _time; }
+    double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_iteration; order=_order; return _time; }
     std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception);
     void getValueForTime(double time, const std::vector<double>& vals, double *res) const;
     void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception);
-    void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception);
+    void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception);
   public:
     static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME;
+    static const char REPR[];
   private:
     static const char EXCEPTION_MSG[];
   protected:
     double _time;
-    int _dt;
-    int _it;
+    int _iteration;
+    int _order;
   };
 
   class MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization
@@ -183,19 +228,27 @@ namespace ParaMEDMEM
     MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy);
   public:
     MEDCouplingConstOnTimeInterval();
+    void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
     void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
     void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
     void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
     MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const;
     bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
-    bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
     bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const;
     std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception);
     void getValueForTime(double time, const std::vector<double>& vals, double *res) const;
     void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception);
-    void getValueOnDiscTime(int eltId, int dt, int it, 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; }
+    std::string getStringRepr() const;
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const;
     void addEqual(const MEDCouplingTimeDiscretization *other);
     MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const;
@@ -204,56 +257,99 @@ namespace ParaMEDMEM
     void multiplyEqual(const MEDCouplingTimeDiscretization *other);
     MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const;
     void divideEqual(const MEDCouplingTimeDiscretization *other);
-    void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_dt=dt; _start_it=it; }
-    void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_dt=dt; _end_it=it; }
-    double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_start_dt; it=_start_it; return _start_time; }
-    double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_end_dt; it=_end_it; return _end_time; }
+    void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_iteration=iteration; _start_order=order; }
+    void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_iteration=iteration; _end_order=order; }
+    double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_start_iteration; order=_start_order; return _start_time; }
+    double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_end_iteration; order=_end_order; return _end_time; }
     void checkNoTimePresence() const throw(INTERP_KERNEL::Exception);
     void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception);
   public:
     static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL;
+    static const char REPR[];
   private:
     static const char EXCEPTION_MSG[];
   protected:
     double _start_time;
     double _end_time;
-    int _start_dt;
-    int _end_dt;
-    int _start_it;
-    int _end_it;
+    int _start_iteration;
+    int _end_iteration;
+    int _start_order;
+    int _end_order;
   };
 
   class MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization
   {
   protected:
+    MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy);
     MEDCouplingTwoTimeSteps();
     ~MEDCouplingTwoTimeSteps();
   public:
+    void updateTime();
+    void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
+    void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other);
+    DataArrayDouble *getEndArray() const;
+    void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
+    bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const;
     void checkNoTimePresence() const throw(INTERP_KERNEL::Exception);
     void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception);
     void getArrays(std::vector<DataArrayDouble *>& arrays) const;
-    DataArrayDouble *getEndArray() const { return _end_array; }
-    void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_dt=dt; _start_it=it; }
-    void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_dt=dt; _end_it=it; }
-    double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_start_dt; it=_start_it; return _start_time; }
-    double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_end_dt; it=_end_it; return _end_time; }
+    void setEndArray(DataArrayDouble *array, TimeLabel *owner);
+    void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_iteration=iteration; _start_order=order; }
+    void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_iteration=iteration; _end_order=order; }
+    double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_start_iteration; order=_start_order; return _start_time; }
+    double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_end_iteration; order=_end_order; return _end_time; }
+    void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
+    void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
+    void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
     void resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays);
     void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
+    std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception);
+    void setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception);
+  protected:
+    static const char EXCEPTION_MSG[];
   protected:
     double _start_time;
     double _end_time;
-    int _start_dt;
-    int _end_dt;
-    int _start_it;
-    int _end_it;
+    int _start_iteration;
+    int _end_iteration;
+    int _start_order;
+    int _end_order;
     DataArrayDouble *_end_array;
   };
 
   class MEDCOUPLING_EXPORT MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps
   {
+  protected:
+    MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy);
   public:
+    MEDCouplingLinearTime();
+    std::string getStringRepr() const;
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
+    void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const;
+    bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
+    bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    void getValueForTime(double time, const std::vector<double>& vals, double *res) const;
+    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);
+    MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const;
+    void addEqual(const MEDCouplingTimeDiscretization *other);
+    MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const;
+    void substractEqual(const MEDCouplingTimeDiscretization *other);
+    MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const;
+    void multiplyEqual(const MEDCouplingTimeDiscretization *other);
+    MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const;
+    void divideEqual(const MEDCouplingTimeDiscretization *other);
+  public:
     static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME;
+    static const char REPR[];
   };
 }
 
index 62e64ce7e639a51b6427b2a47cf32f941d29adf2..11f9d12ea4e110521cb7014ea7e08d1dc029dd1f 100644 (file)
 #include "PointLocatorAlgos.txx"
 #include "BBTree.txx"
 #include "DirectedBoundingBox.hxx"
+#include "InterpKernelMeshQuality.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
 #include <sstream>
 #include <numeric>
+#include <cstring>
 #include <limits>
 #include <list>
 
@@ -35,6 +38,8 @@ using namespace ParaMEDMEM;
 
 const char MEDCouplingUMesh::PART_OF_NAME[]="PartOf_";
 
+double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14;
+
 MEDCouplingUMesh *MEDCouplingUMesh::New()
 {
   return new MEDCouplingUMesh;
@@ -48,6 +53,11 @@ MEDCouplingUMesh *MEDCouplingUMesh::New(const char *meshName, int meshDim)
   return ret;
 }
 
+MEDCouplingMesh *MEDCouplingUMesh::deepCpy() const
+{
+  return clone(true);
+}
+
 MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const
 {
   return new MEDCouplingUMesh(*this,recDeepCpy);
@@ -71,6 +81,12 @@ MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2),
 {
 }
 
+/*!
+ * This method checks that this is correctly designed. For example le coordinates are set, nodal connectivity.
+ * When this method returns without throwing any exception, 'this' is expected to be writable, exchangeable and to be 
+ * available for most of algorithm. When a mesh has been constructed from scratch it is a good habits to call this method to check
+ * that all is in order in 'this'.
+ */
 void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
 {
   if(_mesh_dim<-1)
@@ -84,6 +100,20 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
           throw INTERP_KERNEL::Exception(message.str().c_str());
         }
     }
+  if(_nodal_connec)
+    {
+      if(_nodal_connec->getNumberOfComponents()!=1)
+        throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
+      if(_nodal_connec->getInfoOnComponent(0)!="")
+        throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
+    }
+  if(_nodal_connec_index)
+    {
+      if(_nodal_connec_index->getNumberOfComponents()!=1)
+        throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
+      if(_nodal_connec_index->getInfoOnComponent(0)!="")
+        throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
+    }
 }
 
 void MEDCouplingUMesh::setMeshDimension(int meshDim)
@@ -178,6 +208,150 @@ bool MEDCouplingUMesh::isEqual(const MEDCouplingMesh *other, double prec) const
   return true;
 }
 
+bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
+{
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    return false;
+  if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
+    return false;
+  if(_mesh_dim!=otherC->_mesh_dim)
+    return false;
+  if(_types!=otherC->_types)
+    return false;
+  if(_nodal_connec!=0 || otherC->_nodal_connec!=0)
+    if(_nodal_connec==0 || otherC->_nodal_connec==0)
+      return false;
+  if(_nodal_connec!=otherC->_nodal_connec)
+    if(!_nodal_connec->isEqualWithoutConsideringStr(*otherC->_nodal_connec))
+      return false;
+  if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0)
+    if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0)
+      return false;
+  if(_nodal_connec_index!=otherC->_nodal_connec_index)
+    if(!_nodal_connec_index->isEqualWithoutConsideringStr(*otherC->_nodal_connec_index))
+      return false;
+  return true;
+}
+
+/*!
+ * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one
+ * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter.
+ * 
+ * In case of success cellCor and nodeCor are informed both. 
+ * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method.
+ * @param cellCor output array giving the correspondance of cells from 'other' to 'this'.
+ * @param nodeCor output array giving the correspondance of nodes from 'other' to 'this'.
+ */
+void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                            DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Two meshes are not not unstructured !");
+  MEDCouplingMesh::checkFastEquivalWith(other,prec);
+  if(_types!=otherC->_types)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Types are not equal !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=mergeUMeshes(this,otherC);
+  bool areNodesMerged;
+  int newNbOfNodes;
+  int oldNbOfNodes=getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->buildPermArrayForMergeNode(oldNbOfNodes,prec,areNodesMerged,newNbOfNodes);
+  //mergeNodes
+  if(!areNodesMerged)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! ");
+  const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),oldNbOfNodes-1));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !");
+  m->renumberNodes(da->getConstPointer(),newNbOfNodes);
+  //
+  nodeCor=da->substr(oldNbOfNodes);
+  da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes);
+  if(nodeCor->isIdentity())
+    {
+      nodeCor->decrRef();
+      nodeCor=0;
+    }
+  //
+  da=m->zipConnectivityTraducer(cellCompPol);
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells());
+  pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    {
+      nodeCor->decrRef(); nodeCor=0;
+      throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !");
+    }
+  cellCor=DataArrayInt::New();
+  cellCor->alloc(otherC->getNumberOfCells(),1);
+  std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor->getPointer());
+  if(cellCor->isIdentity())
+    {
+      cellCor->decrRef();
+      cellCor=0;
+    }
+}
+
+/*!
+ * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one
+ * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter. The difference with MEDCouplingUMesh::checkDeepEquivalWith method is that
+ * coordinates of 'this' and 'other' are expected to be the same. If not an exception will be thrown.
+ * 
+ * In case of success cellCor are informed both. 
+ * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method.
+ * @param cellCor output array giving the correspondance of cells from 'other' to 'this'.
+ */
+void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                       DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Two meshes are not not unstructured !");
+  MEDCouplingMesh::checkFastEquivalWith(other,prec);
+  if(_types!=otherC->_types)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Types are not equal !");
+  if(_coords!=otherC->_coords)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !");
+  std::vector<MEDCouplingUMesh *> ms(2);
+  ms[0]=const_cast<MEDCouplingUMesh *>(this);
+  ms[1]=const_cast<MEDCouplingUMesh *>(otherC);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=mergeUMeshesOnSameCoords(ms);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->zipConnectivityTraducer(cellCompPol);
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells());
+  const int *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("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !");
+    }
+  cellCor=DataArrayInt::New();
+  cellCor->alloc(otherC->getNumberOfCells(),1);
+  std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor->getPointer());
+  if(cellCor->isIdentity())
+    {
+      cellCor->decrRef();
+      cellCor=0;
+    }
+}
+
+/*!
+ * This method checks fastly that 'this' and 'other' are equal. 
+ */
+void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not not unstructured !");
+  MEDCouplingPointSet::checkFastEquivalWith(other,prec);
+  int nbOfCells=getNumberOfCells();
+  if(nbOfCells<1)
+    return ;
+  bool status=true;
+  status&=areCellsFrom2MeshEqual(otherC,0,prec);
+  status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec);
+  status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec);
+  if(!status)
+    throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !");
+}
+
 /*!
  * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
  * For speed reasons no check of this will be done.
@@ -386,22 +560,22 @@ void MEDCouplingUMesh::convertToPolyTypes(const std::vector<int>& cellIdsToConve
       int *newConnPtr=_nodal_connec->getPointer();
       std::copy(connNew.begin(),connNew.end(),newConnPtr);
     }
+  computeTypes();
 }
 
 /*!
- * Array returned is the correspondance old to new.
+ * Array returned is the correspondance new to old.
  * The maximum value stored in returned array is the number of nodes of '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.
  */
 DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer()
 {
-  DataArrayInt *ret=DataArrayInt::New();
   int nbOfNodes=getNumberOfNodes();
-  int spaceDim=getSpaceDimension();
-  int *traducer=new int[nbOfNodes];
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfNodes,1);
+  int *traducer=ret->getPointer();
   std::fill(traducer,traducer+nbOfNodes,-1);
-  ret->useArray(traducer,true,CPP_DEALLOC,nbOfNodes,1);
   int nbOfCells=getNumberOfCells();
   const int *connIndex=_nodal_connec_index->getConstPointer();
   int *conn=_nodal_connec->getPointer();
@@ -415,79 +589,358 @@ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer()
     for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
       if(conn[j]>=0)
         conn[j]=traducer[conn[j]];
-  DataArrayDouble *newCoords=DataArrayDouble::New();
-  double *newCoordsPtr=new double[newNbOfNodes*spaceDim];
-  const double *oldCoordsPtr=_coords->getConstPointer();
-  newCoords->useArray(newCoordsPtr,true,CPP_DEALLOC,newNbOfNodes,spaceDim);
-  int *work=std::find_if(traducer,traducer+nbOfNodes,std::bind2nd(std::not_equal_to<int>(),-1));
-  for(;work!=traducer+nbOfNodes;work=std::find_if(work,traducer+nbOfNodes,std::bind2nd(std::not_equal_to<int>(),-1)))
-    {
-      newCoordsPtr=std::copy(oldCoordsPtr+spaceDim*(work-traducer),oldCoordsPtr+spaceDim*(work-traducer+1),newCoordsPtr);
-      work++;
-    }
+  DataArrayDouble *newCoords=_coords->renumberAndReduce(traducer,newNbOfNodes);
   setCoords(newCoords);
   newCoords->decrRef();
   return ret;
 }
 
+/*!
+ * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy.
+ * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method.
+ */
+bool MEDCouplingUMesh::areCellsEqual(int cell1, int cell2, int compType) const
+{
+  switch(compType)
+    {
+    case 0:
+      return areCellsEqual0(cell1,cell2);
+    case 1:
+      return areCellsEqual1(cell1,cell2);
+    case 2:
+      return areCellsEqual2(cell1,cell2);
+    }
+  throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1 or 2.");
+}
+
+/*!
+ * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 0.
+ */
+bool MEDCouplingUMesh::areCellsEqual0(int cell1, int cell2) const
+{
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  return std::equal(conn+connI[cell1],conn+connI[cell1+1],conn+connI[cell2]);
+}
+
+/*!
+ * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 1.
+ */
+bool MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const
+{
+  throw INTERP_KERNEL::Exception("Policy comparison, not implemented yet !");
+}
+
+/*!
+ * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 2.
+ */
+bool MEDCouplingUMesh::areCellsEqual2(int cell1, int cell2) const
+{
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  std::set<int> s1(conn+connI[cell1],conn+connI[cell1+1]);
+  std::set<int> s2(conn+connI[cell2],conn+connI[cell2+1]);
+  return s1==s2;
+}
+
+/*!
+ * This method compares 2 cells coming from two unstructured meshes : 'this' and 'other'.
+ * This method compares 2 cells having the same id 'cellId' in 'this' and 'other'.
+ */
+bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const
+{
+  if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId))
+    return false;
+  std::vector<int> c1,c2;
+  getNodeIdsOfCell(cellId,c1);
+  other->getNodeIdsOfCell(cellId,c2);
+  int sz=c1.size();
+  if(sz!=(int)c2.size())
+    return false;
+  for(int i=0;i<sz;i++)
+    {
+      std::vector<double> n1,n2;
+      getCoordinatesOfNode(c1[0],n1);
+      other->getCoordinatesOfNode(c2[0],n2);
+      std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus<double>());
+      std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun<double,double>(fabs));
+      if(*std::max_element(n1.begin(),n1.end())>prec)
+        return false;
+    }
+  return true;
+}
+
+/*!
+ * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'.
+ * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned
+ * and result remains unchanged.
+ * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method.
+ * 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
+{
+  std::set<int> cand(candidates.begin(),candidates.end());
+  cand.erase(-1);
+  if(cand.size()<=1)
+    return false;
+  std::set<int>::const_iterator end=cand.end(); end--;
+  bool ret=false;
+  for(std::set<int>::const_iterator iter=cand.begin();iter!=end && !ret;iter++)
+    {
+      std::set<int>::const_iterator begin2=iter; begin2++;
+      for(std::set<int>::const_iterator iter2=begin2;iter2!=cand.end();iter2++)
+        {
+          if(areCellsEqual(*iter,*iter2,compType))
+            {
+              if(!ret)
+                {
+                  result.push_back(*iter);
+                  ret=true;
+                }
+              result.push_back(*iter2);
+            }
+        }
+    }
+  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 
+ */
+template<int SPACEDIM>
+void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector<int>& res, std::vector<int>& resI) const
+{
+  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++)
+    {
+      if(!isFetched[k])
+        {
+          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++)
+                  {
+                    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]);
+                  }
+              }
+          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))
+            {
+              int pos=resI.back();
+              resI.push_back(res.size());
+              for(std::vector<int>::const_iterator it=res.begin()+pos;it!=res.end();it++)
+                isFetched[*it]=true;
+            }
+          isFetched[k]=true;
+        }
+    }
+}
+
+/*!
+ * 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'.
+ *
+ * @param 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. cell1 and cell2 are equal if and the connectivity of cell2 can be deduced by those of cell1 by direct permutation and their type equal.
+ *                 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.
+ * @return the correspondance array old to new.
+ */
+DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType)
+{
+  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 int nbOfTupleSmCells=commonCellsI.size()-1;
+  int id=-1;
+  std::vector<int> cellsToKeep;
+  for(int 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);
+  setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true);
+  self->decrRef();
+  return ret;
+}
+
 /*!
  * @param areNodesMerged if at least two nodes have been merged.
  * @return old to new node correspondance.
  */
-DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged)
+DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
 {
-  DataArrayInt *comm,*commI;
-  findCommonNodes(comm,commI,precision);
-  int newNbOfNodes;
-  int oldNbOfNodes=getNumberOfNodes();
-  DataArrayInt *ret=buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
-  areNodesMerged=(oldNbOfNodes!=newNbOfNodes);
-  comm->decrRef();
-  commI->decrRef();
+  DataArrayInt *ret=buildPermArrayForMergeNode(-1,precision,areNodesMerged,newNbOfNodes);
   if(areNodesMerged)
     renumberNodes(ret->getConstPointer(),newNbOfNodes);
   return ret;
 }
 
 /*!
- * build a sub part of 'this'. This sub part is defined by the cell ids contained in the array in [start,end).
- * @param start start of array containing the cell ids to keep.
+ * This method tries to use 'other' coords and use it for 'this'. If no exception was thrown after the call of this method :
+ * this->_coords==other->_coords. If not a exception is thrown this remains unchanged.
+ */
+void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception)
+{
+  DataArrayDouble *coords=other.getCoords();
+  if(!coords)
+    throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in other !");
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !");
+  int otherNbOfNodes=other.getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=mergeNodesArray(&other,this);
+  _coords->incrRef();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> oldCoords=_coords;
+  setCoords(newCoords);
+  bool areNodesMerged;
+  int newNbOfNodes;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=buildPermArrayForMergeNode(otherNbOfNodes,epsilon,areNodesMerged,newNbOfNodes);
+  if(!areNodesMerged)
+    {
+      setCoords(oldCoords);
+      throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !");
+    }
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes);
+  const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    {
+      setCoords(oldCoords);
+      throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : some nodes in this are not in other !");
+    }
+  setCoords(oldCoords);
+  renumberNodesInConn(da->getConstPointer()+otherNbOfNodes);
+  setCoords(coords);
+}
+
+/*!
+ * build a sub part of 'this'. This sub part is defined by the cell ids contained in the array in [begin,end).
+ * @param begin begin of array containing the cell ids to keep.
  * @param end end of array of cell ids to keep. \b WARNING end param is \b not included ! Idem STL standard definitions.
  * @param keepCoords that specifies if you want or not to keep coords as this or zip it (see zipCoords)
  */
-MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const
+MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const
 {
   if(getMeshDimension()!=-1)
     {
-      MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(start,end);
+      MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(begin,end);
       if(!keepCoords)
         ret->zipCoords();
       return ret;
     }
   else
     {
-      if(end-start!=1)
+      if(end-begin!=1)
         throw INTERP_KERNEL::Exception("-1D mesh has only one cell !");
-      if(start[0]!=0)
+      if(begin[0]!=0)
         throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !");
       incrRef();
       return (MEDCouplingUMesh *)this;
     }
 }
 
+DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
+{
+  std::vector<int> cellIdsKept;
+  fillCellIdsToKeepFromNodeIds(partBg,partEnd,true,cellIdsKept);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(cellIdsKept.size(),1);
+  std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer());
+  return ret;
+}
+
 /*!
- * Keeps from 'this' only cells which constituing point id are in the ids specified by ['start','end').
- * The return newly allocated mesh will share the same coordinates as 'this'.
+ * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end').
+ * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
  * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not.
- * If 'fullyIn' is true only cells whose ids are \b fully contained in ['start','end') tab will be kept.
+ * 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.
  */
-MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
+void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector<int>& cellIdsKept) const
 {
-  std::set<int> fastFinder(start,end);
+  std::set<int> fastFinder(begin,end);
+  int nbOfCells=getNumberOfCells();
   const int *conn=getNodalConnectivity()->getConstPointer();
   const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
-  int nbOfCells=getNumberOfCells();
-  std::vector<int> cellIdsKept;
   for(int i=0;i<nbOfCells;i++)
     {
       std::set<int> connOfCell(conn+connIndex[i]+1,conn+connIndex[i+1]);
@@ -499,22 +952,34 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *start, c
       if(((int)locMerge.size()==refLgth && fullyIn) || (locMerge.size()!=0 && !fullyIn))
         cellIdsKept.push_back(i);
     }
+}
+
+/*!
+ * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end').
+ * The return newly allocated mesh will share the same coordinates as 'this'.
+ * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not.
+ * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept.
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const
+{
+  std::vector<int> cellIdsKept;
+  fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept);
   return buildPartOfMySelf(&cellIdsKept[0],&cellIdsKept[0]+cellIdsKept.size(),true);
 }
 
 /*!
- * Contrary to MEDCouplingUMesh::buildPartOfMySelfNode method this method a mesh with a meshDimension equal to
+ * Contrary to MEDCouplingUMesh::buildPartOfMySelfNode method this method builds a mesh with a meshDimension equal to
  * this->getMeshDimension()-1. The return newly allocated mesh will share the same coordinates as 'this'.
  * Parameter 'fullyIn' specifies if a face that has part of its nodes in ids array is kept or not.
- * If 'fullyIn' is true only faces whose ids are \b fully contained in ['start','end') tab will be kept.
+ * If 'fullyIn' is true only faces whose ids are \b fully contained in ['begin','end') tab will be kept.
  */
-MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
+MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const
 {
   DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx;
   desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New();
   MEDCouplingUMesh *subMesh=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
   desc->decrRef(); descIndx->decrRef(); revDesc->decrRef(); revDescIndx->decrRef();
-  MEDCouplingUMesh *ret=(MEDCouplingUMesh *)subMesh->buildPartOfMySelfNode(start,end,fullyIn);
+  MEDCouplingUMesh *ret=(MEDCouplingUMesh *)subMesh->buildPartOfMySelfNode(begin,end,fullyIn);
   subMesh->decrRef();
   return ret;
 }
@@ -585,12 +1050,23 @@ void MEDCouplingUMesh::findBoundaryNodes(std::vector<int>& nodes) const
  * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes.
  * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes())
  * This value is asked because often known by the caller of this method.
+ * This method, contrary to MEDCouplingMesh::renumberCells does NOT conserve the number of nodes before and after.
+ *
  * @param newNodeNumbers array specifying the new numbering.
  * @param newNbOfNodes the new number of nodes.
  */
 void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
 {
   MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes);
+  renumberNodesInConn(newNodeNumbers);
+}
+
+/*!
+ * This method renumbers nodes in connectivity only without any reference with coords.
+ * Use it with care !
+ */
+void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbers)
+{
   int *conn=getNodalConnectivity()->getPointer();
   const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
   int nbOfCells=getNumberOfCells();
@@ -608,8 +1084,10 @@ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes
 }
 
 /*!
- * This method renumbers cells of 'this' using the array specified by [old2NewBg;old2NewEnd)
- * If std::distance(old2NewBg,old2NewEnd)!=this->getNumberOfCells() an INTERP_KERNEL::Exception will be thrown.
+ * This method renumbers cells of 'this' using the array specified by [old2NewBg;old2NewBg+getNumberOfCells())
+ *
+ * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell.
+ * After the call of this method the number of cells remains the same as before.
  *
  * If 'check' equals true the method will check that any elements in [old2NewBg;old2NewEnd) is unique ; if not
  * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [old2NewBg;old2NewEnd) is not expected to
@@ -619,14 +1097,12 @@ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes
  * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [old2NewBg;old2NewEnd) should be unique and
  * should be contained in[0;this->getNumberOfCells()).
  */
-void MEDCouplingUMesh::renumberCells(const int *old2NewBg, const int *old2NewEnd, bool check)
+void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
 {
   int nbCells=getNumberOfCells();
   const int *array=old2NewBg;
-  if(std::distance(old2NewBg,old2NewEnd)!=nbCells)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::renumberCells expected to take an array of size getNumberOfCells !");
   if(check)
-    array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewEnd);
+    array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+nbCells);
   //
   const int *conn=_nodal_connec->getConstPointer();
   const int *connI=_nodal_connec_index->getConstPointer();
@@ -772,8 +1248,25 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) co
   return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]];
 }
 
+/*!
+ * Returns nb of cells having the geometric type 'type'.
+ */
+int MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
+{
+  const int *ptI=_nodal_connec_index->getConstPointer();
+  const int *pt=_nodal_connec->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  int ret=0;
+  for(int i=0;i<nbOfCells;i++)
+    if((INTERP_KERNEL::NormalizedCellType) pt[ptI[i]]==type)
+      ret++;
+  return ret;
+}
+
 /*!
  * Appends the nodal connectivity in 'conn' of cell with id 'cellId'.
+ * All elements added in conn can be used by MEDCouplingUMesh::getCoordinatesOfNode method.
+ * That is to say -1 separator is omitted in returned conn.
  */
 void MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
 {
@@ -794,6 +1287,75 @@ void MEDCouplingUMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo
   coo.insert(coo.end(),cooPtr+spaceDim*nodeId,cooPtr+spaceDim*(nodeId+1));
 }
 
+std::string MEDCouplingUMesh::simpleRepr() const
+{
+  static const char msg0[]="No coordinates specified !";
+  std::ostringstream ret;
+  ret << "Unstructured mesh with name : \"" << getName() << "\"\n";
+  ret << "Mesh dimension : " << _mesh_dim << "\nSpace dimension : ";
+  if(_coords!=0)
+    ret << getSpaceDimension() << "\n";
+  else
+    ret << msg0 << "\n";
+  ret << "Number of nodes : ";
+  if(_coords!=0)
+    ret << getNumberOfNodes() << "\n";
+  else
+    ret << msg0 << "\n";
+  ret << "Number of cells : ";
+  if(_nodal_connec!=0 && _nodal_connec_index!=0)
+    ret << getNumberOfCells() << "\n";
+  else
+    ret << "No connectivity specified !" << "\n";
+  ret << "Cell types present : ";
+  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(*iter);
+      ret << cm.getRepr() << " ";
+    }
+  ret << "\n";
+  return ret.str();
+}
+
+std::string MEDCouplingUMesh::advancedRepr() const
+{
+  std::ostringstream ret;
+  ret << simpleRepr();
+  ret << "\nCoordinates array : \n___________________\n\n";
+  if(_coords)
+    _coords->reprWithoutNameStream(ret);
+  else
+    ret << "No array set !\n";
+  ret << "\n\nConnectivity arrays : \n_____________________\n\n";
+  reprConnectivityOfThisLL(ret);
+  return ret.str();
+}
+std::string MEDCouplingUMesh::reprConnectivityOfThis() const
+{
+  std::ostringstream ret;
+  reprConnectivityOfThisLL(ret);
+  return ret.str();
+}
+
+void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const
+{
+  if(_nodal_connec!=0 && _nodal_connec_index!=0)
+    {
+      int nbOfCells=getNumberOfCells();
+      const int *c=_nodal_connec->getConstPointer();
+      const int *ci=_nodal_connec_index->getConstPointer();
+      for(int i=0;i<nbOfCells;i++)
+        {
+          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[i]]);
+          stream << "Cell #" << i << " " << cm.getRepr() << " : ";
+          std::copy(c+ci[i]+1,c+ci[i+1],std::ostream_iterator<int>(stream," "));
+          stream << "\n";
+        }
+    }
+  else
+    stream << "Connectivity not defined !\n";
+}
+
 int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const
 {
   const int *ptI=_nodal_connec_index->getConstPointer();
@@ -919,7 +1481,7 @@ bool MEDCouplingUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
  * Second step of serialization process.
  * @param tinyInfo must be equal to the result given by getTinySerializationInformation method.
  */
-void MEDCouplingUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings)
+void MEDCouplingUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
 {
   MEDCouplingPointSet::resizeForUnserialization(tinyInfo,a1,a2,littleStrings);
   if(tinyInfo[5]!=-1)
@@ -950,7 +1512,7 @@ void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
  * Second and final unserialization process.
  * @param tinyInfo must be equal to the result given by getTinySerializationInformation method.
  */
-void MEDCouplingUMesh::unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
+void MEDCouplingUMesh::unserialization(const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
 {
   MEDCouplingPointSet::unserialization(tinyInfo,a1,a2,littleStrings);
   setMeshDimension(tinyInfo[3]);
@@ -972,29 +1534,38 @@ void MEDCouplingUMesh::unserialization(const std::vector<int>& tinyInfo, DataArr
 
 /*!
  * This is the low algorithm of buildPartOfMySelf. 
- * Keeps from 'this' only cells which constituing point id are in the ids specified by ['start','end').
+ * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end').
  * The return newly allocated mesh will share the same coordinates as 'this'.
  */
-MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *start, const int *end) const
+MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
 {
   checkFullyDefined();
   MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
-  std::ostringstream stream; stream << PART_OF_NAME << getName();
-  ret->setName(stream.str().c_str());
+  std::string name(getName());
+  int sz=strlen(PART_OF_NAME);
+  if((int)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->_mesh_dim=_mesh_dim;
   ret->setCoords(_coords);
-  int nbOfElemsRet=end-start;
+  int nbOfElemsRet=end-begin;
   int *connIndexRet=new int[nbOfElemsRet+1];
   connIndexRet[0]=0;
   const int *conn=_nodal_connec->getConstPointer();
   const int *connIndex=_nodal_connec_index->getConstPointer();
   int newNbring=0;
-  for(const int *work=start;work!=end;work++,newNbring++)
+  for(const int *work=begin;work!=end;work++,newNbring++)
     connIndexRet[newNbring+1]=connIndexRet[newNbring]+connIndex[*work+1]-connIndex[*work];
   int *connRet=new int[connIndexRet[nbOfElemsRet]];
   int *connRetWork=connRet;
   std::set<INTERP_KERNEL::NormalizedCellType> types;
-  for(const int *work=start;work!=end;work++)
+  for(const int *work=begin;work!=end;work++)
     {
       types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]);
       connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork);
@@ -1047,8 +1618,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
           area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space);
         }
       if(isAbs)
-        for(int iel=0;iel<nbelem;iel++)
-          area_vol[iel]=fabs(area_vol[iel]);
+        std::transform(area_vol,area_vol+nbelem,area_vol,std::ptr_fun<double,double>(fabs));
     }
   else
     {
@@ -1132,15 +1702,15 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
 }
 
 /*!
- * This methods returns a vector newly created field on cells that represents the director vector of each 1D cell of this.
+ * This methods returns a vector newly created field on cells that represents the direction vector of each 1D cell of this.
  * This method is only callable on mesh with meshdim == 1 containing only SEG2.
  */
-MEDCouplingFieldDouble *MEDCouplingUMesh::buildLinearField() const
+MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const
 {
    if(getMeshDimension()!=1)
-    throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildLinearField !");
+    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 buildLinearField !");
+     throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !");
    MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
    DataArrayDouble *array=DataArrayDouble::New();
    int nbOfCells=getNumberOfCells();
@@ -1178,7 +1748,7 @@ void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps,
      throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for project1D !");
    if(getSpaceDimension()!=3)
      throw INTERP_KERNEL::Exception("Expected a umesh with spaceDim==3 for project1D !");
-   MEDCouplingFieldDouble *f=buildLinearField();
+   MEDCouplingFieldDouble *f=buildDirectionVectorField();
    const double *fPtr=f->getArray()->getConstPointer();
    double tmp[3];
    for(int i=0;i<getNumberOfCells();i++)
@@ -1324,6 +1894,8 @@ void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoint
 /*!
  * This method is only available for a mesh with meshDim==2 and spaceDim==2||spaceDim==3.
  * This method returns a vector 'cells' where all detected butterfly cells have been added to cells.
+ * A 2D cell is considered to be butterfly if it exists at least one pair of distinct edges of it that intersect each other
+ * anywhere excepted their extremities. An INTERP_KERNEL::NORM_NORI3 could \b not be butterfly.
  */
 void MEDCouplingUMesh::checkButterflyCells(std::vector<int>& cells) const
 {
@@ -1352,10 +1924,585 @@ void MEDCouplingUMesh::checkButterflyCells(std::vector<int>& cells) const
 }
 
 /*!
- * This method aggregate the bbox of each cell and put it into bbox parameter.
- * @param bbox out parameter of size 2*spacedim*nbOfcells.
+ * This method is \b NOT const because it can modify 'this'.
+ * 'this' is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown.
+ * @param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown.
+ * @param policy specifies the type of extrusion chosen. \b 0 for translation (most simple),
+ * \b 1 for translation and rotation around point of 'mesh1D'.
+ * @return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than 'this'.  
  */
-void MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector<double>& bbox) const
+MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy)
+{
+  checkFullyDefined();
+  mesh1D->checkFullyDefined();
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMeshFromThis method : must be meshDim==2 and spaceDim ==3 !");
+  if(mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMeshFromThis method : must be meshDim==1 and spaceDim ==3 !");
+  bool isQuad=false;
+  if(isPresenceOfQuadratic())
+    {
+      if(mesh1D->isFullyQuadratic())
+        isQuad=true;
+      else
+        throw INTERP_KERNEL::Exception("Invalid 2D mesh and 1D mesh because 2D mesh has quadratic cells and 1D is not fully quadratic !");
+    }
+  zipCoords();
+  int oldNbOfNodes=getNumberOfNodes();
+  DataArrayDouble *newCoords=0;
+  switch(policy)
+    {
+    case 0:
+      {
+        newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad);
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !");
+    }
+  setCoords(newCoords);
+  newCoords->decrRef();
+  MEDCouplingUMesh *ret=buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad);
+  updateTime();
+  return ret;
+}
+
+/*!
+ * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMeshFromThis method.
+ * @param mesh1D is the input 1D mesh used for translation computation.
+ * @return newCoords new coords filled by this method. 
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const
+{
+  int oldNbOfNodes=getNumberOfNodes();
+  int nbOf1DCells=mesh1D->getNumberOfCells();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  std::vector<bool> isQuads;
+  int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1;
+  ret->alloc(oldNbOfNodes*nbOfLevsInVec,3);
+  double *retPtr=ret->getPointer();
+  const double *coords=getCoords()->getConstPointer();
+  double *work=std::copy(coords,coords+3*oldNbOfNodes,retPtr);
+  std::vector<int> v;
+  std::vector<double> c;
+  double vec[3];
+  v.reserve(3);
+  c.reserve(6);
+  for(int i=0;i<nbOf1DCells;i++)
+    {
+      v.resize(0);
+      mesh1D->getNodeIdsOfCell(i,v);
+      c.resize(0);
+      mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c);
+      mesh1D->getCoordinatesOfNode(v[0],c);
+      std::transform(c.begin(),c.begin()+3,c.begin()+3,vec,std::minus<double>());
+      for(int j=0;j<oldNbOfNodes;j++)
+        work=std::transform(vec,vec+3,retPtr+3*(i*oldNbOfNodes+j),work,std::plus<double>());
+      if(isQuad)
+        {
+          c.resize(0);
+          mesh1D->getCoordinatesOfNode(v[1],c);
+          mesh1D->getCoordinatesOfNode(v[0],c);
+          std::transform(c.begin(),c.begin()+3,c.begin()+3,vec,std::minus<double>());
+          for(int j=0;j<oldNbOfNodes;j++)
+            work=std::transform(vec,vec+3,retPtr+3*(i*oldNbOfNodes+j),work,std::plus<double>());
+        }
+    }
+  ret->copyStringInfoFrom(*getCoords());
+  return ret;
+}
+
+/*!
+ * This method is private because not easy to use for end user. This method is const contrary to
+ * MEDCouplingUMesh::buildExtrudedMeshFromThis method because this->_coords are expected to contain
+ * the coords sorted slice by slice.
+ * @param isQuad specifies presence of quadratic cells.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const
+{
+  int nbOf1DCells=getNumberOfNodes()/nbOfNodesOf1Lev-1;
+  int nbOf2DCells=getNumberOfCells();
+  int nbOf3DCells=nbOf2DCells*nbOf1DCells;
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("Extruded",3);
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  DataArrayInt *newConn=DataArrayInt::New();
+  DataArrayInt *newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOf3DCells+1,1);
+  int *newConnIPtr=newConnI->getPointer();
+  *newConnIPtr++=0;
+  std::vector<int> newc;
+  for(int j=0;j<nbOf2DCells;j++)
+    {
+      appendExtrudedCell(conn+connI[j],conn+connI[j+1],nbOfNodesOf1Lev,isQuad,newc);
+      *newConnIPtr++=newc.size();
+    }
+  newConn->alloc(newc.size()*nbOf1DCells,1);
+  int *newConnPtr=newConn->getPointer();
+  int deltaPerLev=isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev;
+  newConnIPtr=newConnI->getPointer();
+  for(int iz=0;iz<nbOf1DCells;iz++)
+    {
+      if(iz!=0)
+        std::transform(newConnIPtr+1,newConnIPtr+1+nbOf2DCells,newConnIPtr+1+iz*nbOf2DCells,std::bind2nd(std::plus<int>(),newConnIPtr[iz*nbOf2DCells]));
+      for(std::vector<int>::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++)
+        {
+          int icell=iter-newc.begin();
+          if(std::find(newConnIPtr,newConnIPtr+nbOf2DCells,icell)==newConnIPtr+nbOf2DCells)
+            {
+              if(*iter!=-1)
+                *newConnPtr=(*iter)+iz*deltaPerLev;
+              else
+                *newConnPtr=-1;
+            }
+          else
+            *newConnPtr=(*iter);
+        }
+    }
+  ret->setConnectivity(newConn,newConnI,true);
+  newConn->decrRef();
+  newConnI->decrRef();
+  ret->setCoords(getCoords());
+  return ret;
+}
+
+/*!
+ * This method returns if 'this' is constituted by only quadratic cells.
+ */
+bool MEDCouplingUMesh::isFullyQuadratic() const
+{
+  checkFullyDefined();
+  bool ret=true;
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells && ret;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      ret=cm.isQuadratic();
+    }
+  return ret;
+}
+
+/*!
+ * This method returns if there is at least one quadratic cell.
+ */
+bool MEDCouplingUMesh::isPresenceOfQuadratic() const
+{
+  checkFullyDefined();
+  bool ret=false;
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells && !ret;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      ret=cm.isQuadratic();
+    }
+  return ret;
+}
+
+/*!
+ * This method convert quadratic cells to linear cells if any was found.
+ * If no such cells exists 'this' remains unchanged.
+ */
+void MEDCouplingUMesh::convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  int nbOfCells=getNumberOfCells();
+  int delta=0;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      if(cm.isQuadratic())
+        {
+          INTERP_KERNEL::NormalizedCellType typel=cm.getLinearType();
+          const INTERP_KERNEL::CellModel& cml=INTERP_KERNEL::CellModel::getCellModel(typel);
+          delta+=cm.getNumberOfNodes()-cml.getNumberOfNodes();
+        }
+    }
+  if(delta==0)
+    return ;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConn->alloc(getMeshLength()-delta,1);
+  newConnI->alloc(nbOfCells+1,1);
+  const int *icptr=_nodal_connec->getConstPointer();
+  const int *iciptr=_nodal_connec_index->getConstPointer();
+  int *ocptr=newConn->getPointer();
+  int *ociptr=newConnI->getPointer();
+  *ociptr=0;
+  _types.clear();
+  for(int i=0;i<nbOfCells;i++,ociptr++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+      if(!cm.isQuadratic())
+        {
+          _types.insert(type);
+          ocptr=std::copy(icptr+iciptr[i],icptr+iciptr[i+1],ocptr);
+          ociptr[1]=ociptr[0]+iciptr[i+1]-iciptr[i];
+        }
+      else
+        {
+          INTERP_KERNEL::NormalizedCellType typel=cm.getLinearType();
+          _types.insert(typel);
+          const INTERP_KERNEL::CellModel& cml=INTERP_KERNEL::CellModel::getCellModel(typel);
+          int newNbOfNodes=cml.getNumberOfNodes();
+          *ocptr++=(int)typel;
+          ocptr=std::copy(icptr+iciptr[i]+1,icptr+iciptr[i]+newNbOfNodes+1,ocptr);
+          ociptr[1]=ociptr[0]+newNbOfNodes+1;
+        }
+    }
+  setConnectivity(newConn,newConnI,false);
+}
+
+/*!
+ * This method checks that all or only polygons (depending 'polyOnly' parameter) 2D cells are correctly oriented relative to 'vec' vector.
+ * The 'vec' vector has to have a non nul norm.
+ * If not 'cells' parameter will be appended with cellIds of incorrect cells.
+ * @throw when 'this' is not a mesh with meshdim==2 and spacedim==3
+ */
+void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      if(!polyOnly || type==INTERP_KERNEL::NORM_POLYGON)
+        {
+          if(!isPolygonWellOriented(vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+            cells.push_back(i);
+        }
+    }
+}
+
+/*!
+ * This method orient correctly (if needed) all or only polygons (depending 'polyOnly' parameter)  2D cells are correctly oriented relative to 'vec' vector.
+ * The 'vec' vector has to have a non nul norm.
+ * @throw when 'this' is not a mesh with meshdim==2 and spacedim==3
+ */
+void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  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(!polyOnly || type==INTERP_KERNEL::NORM_POLYGON)
+        if(!isPolygonWellOriented(vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+          {
+            isModified=true;
+            std::vector<int> tmp(connI[i+1]-connI[i]-2);
+            std::copy(conn+connI[i]+2,conn+connI[i+1],tmp.rbegin());
+            std::copy(tmp.begin(),tmp.end(),conn+connI[i]+2);
+          }
+    }
+  if(isModified)
+    _nodal_connec->declareAsNew();
+  updateTime();
+}
+
+/*!
+ * This method checks that all polyhedrons cells have correctly oriented faces.
+ * If not, 'cells' parameter will be appended with cellIds of incorrect cells.
+ * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3
+ */
+void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply arePolyhedronsNotCorrectlyOriented on it : must be meshDim==3 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  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))
+            cells.push_back(i);
+        }
+    }
+}
+
+/*!
+ * 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.
+ */
+void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectlyPolyhedrons 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();
+  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))
+          {
+            tryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
+            isModified=true;
+          }
+    }
+  if(isModified)
+    _nodal_connec->declareAsNew();
+  updateTime();
+}
+
+/*!
+ * This method has a sense for meshes with spaceDim==3 and meshDim==2.
+ * If it is not the case an exception will be thrown.
+ * This method is fast because the first cell of 'this' is used to compute the plane.
+ * @param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane.
+ * @param pos output of size at least 3 used to store a point owned of searched plane.
+ */
+void MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply getFastAveragePlaneOfThis on it : must be meshDim==2 and spaceDim==3 !");
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(conn+1,connI[1]-connI[0]-1,coordsPtr,vec);
+  std::copy(coordsPtr+3*conn[1],coordsPtr+3*conn[1]+3,pos);
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension and spacedimension of this are expected to be both in [2,3]. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_TRI3, NORM_QUAD4 and NORM_TETRA4 geometric types.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=2 && spaceDim!=3)
+    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);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_TRI3:
+            {
+              fillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::triEdgeRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadEdgeRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_TETRA4:
+            {
+              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::tetraEdgeRatio(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : A cell with not manged type (NORM_TRI3, NORM_QUAD4 and NORM_TETRA4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("EdgeRatio");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension and spacedimension of this are expected to be both in [2,3]. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_TRI3, NORM_QUAD4 and NORM_TETRA4 geometric types.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=2 && spaceDim!=3)
+    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);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_TRI3:
+            {
+              fillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::triAspectRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadAspectRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_TETRA4:
+            {
+              fillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::tetraAspectRatio(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : A cell with not manged type (NORM_TRI3, NORM_QUAD4 and NORM_TETRA4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("AspectRatio");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension must be equal to 2 and the spacedimension must be equal to 3. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_QUAD4 geometric type.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=3)
+    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);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              fillInCompact3DMode(3,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadWarp(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : A cell with not manged type (NORM_QUAD4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("Warp");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension must be equal to 2 and the spacedimension must be equal to 3. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_QUAD4 geometric type.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=3)
+    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);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              fillInCompact3DMode(3,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadSkew(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : A cell with not manged type (NORM_QUAD4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("Skew");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This method aggregate the bbox of each cell and put it into bbox parameter.
+ * @param bbox out parameter of size 2*spacedim*nbOfcells.
+ */
+void MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector<double>& bbox) const
 {
   int spaceDim=getSpaceDimension();
   int nbOfCells=getNumberOfCells();
@@ -1398,8 +2545,13 @@ namespace ParaMEDMEMImpl
   };
 }
 
+/*!
+ * This methods checks that cells are sorted by their types.
+ * This method makes asumption (no check) that connectivity is correctly set before calling.
+ */
 bool MEDCouplingUMesh::checkConsecutiveCellTypes() const
 {
+  checkFullyDefined();
   const int *conn=_nodal_connec->getConstPointer();
   const int *connI=_nodal_connec_index->getConstPointer();
   int nbOfCells=getNumberOfCells();
@@ -1415,6 +2567,198 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const
   return true;
 }
 
+/*!
+ * 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). 
+ */
+bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const
+{
+  checkFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  int lastPos=-1;
+  for(const int *i=connI;i!=connI+nbOfCells;)
+    {
+      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+      int pos=std::distance(orderBg,std::find(orderBg,orderEnd,curType));
+      if(pos<=lastPos)
+        return false;
+      lastPos=pos;
+      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+    }
+  return true;
+}
+
+/*!
+ * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [orderBg,orderEnd) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation is 'this'.
+ * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells.
+ * The mesh after this call will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs.
+ * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same.
+ */
+DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const
+{
+  checkFullyDefined();
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int *tmp=new int[nbOfCells];
+  int minPos=std::numeric_limits<int>::max();
+  for(const int *i=connI;i!=connI+nbOfCells;i++)
+    {
+      int pos=std::distance(orderBg,std::find(orderBg,orderEnd,(INTERP_KERNEL::NormalizedCellType)conn[*i]));
+      tmp[std::distance(connI,i)]=pos;
+      minPos=std::min(minPos,pos);
+    }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfCells,1);
+  int *optr=ret->getPointer();
+  int k=0;
+  while(minPos!=std::numeric_limits<int>::max())
+    {    
+      int nextMinPos=std::numeric_limits<int>::max();
+      for(int j=0;j<nbOfCells;j++)
+        {
+          if(tmp[j]==minPos)
+            {
+              optr[j]=k++;
+              tmp[j]=std::numeric_limits<int>::max();
+            }
+          else
+            nextMinPos=std::min(nextMinPos,tmp[j]);
+        }
+      minPos=nextMinPos;
+    }
+  delete [] tmp;
+  return ret;
+}
+
+/*!
+ * This method reorganize the cells of 'this' so that the cells with same geometric types are put together.
+ * If checkConsecutiveCellTypes() returns true, this method do not change anything of this.
+ * The number of cells remains unchanged after the call of this method.
+ * @return the array giving the correspondance old to new.
+ */
+DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes()
+{
+  checkFullyDefined();
+  computeTypes();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<INTERP_KERNEL::NormalizedCellType> types;
+  for(const int *i=connI;i!=connI+nbOfCells && (types.size()!=_types.size());)
+    if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)conn[*i])==types.end())
+      {
+        INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+        types.push_back(curType);
+        for(i++;i!=connI+nbOfCells && (INTERP_KERNEL::NormalizedCellType)conn[*i]==curType;i++);
+      }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfCells,1);
+  int *retPtr=ret->getPointer();
+  std::fill(retPtr,retPtr+nbOfCells,-1);
+  int newCellId=0;
+  for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=types.begin();iter!=types.end();iter++)
+    {
+      for(const int *i=connI;i!=connI+nbOfCells;i++)
+        if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter))
+          retPtr[std::distance(connI,i)]=newCellId++;
+    }
+  renumberCells(retPtr,false);
+  return ret;
+}
+
+/*!
+ * This methods split this into as mush as untructured meshes that consecutive set of same type cells.
+ * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense.
+ * This method makes asumption that connectivity is correctly set before calling.
+ */
+std::vector<MEDCouplingUMesh *> MEDCouplingUMesh::splitByType() const
+{
+  checkFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<MEDCouplingUMesh *> ret;
+  for(const int *i=connI;i!=connI+nbOfCells;)
+    {
+      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+      int beginCellId=std::distance(connI,i);
+      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+      int endCellId=std::distance(connI,i);
+      int sz=endCellId-beginCellId;
+      int *cells=new int[sz];
+      for(int j=0;j<sz;j++)
+        cells[j]=beginCellId+j;
+      MEDCouplingUMesh *m=(MEDCouplingUMesh *)buildPartOfMySelf(cells,cells+sz,true);
+      delete [] cells;
+      ret.push_back(m);
+    }
+  return ret;
+}
+
+/*!
+ * This method makes the assumption that da->getNumberOfTuples()<this->getNumberOfCells(). This method makes the assumption that ids contained in 'da'
+ * are in [0:getNumberOfCells())
+ */
+DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::set<INTERP_KERNEL::NormalizedCellType> types=getAllTypes();
+  int *tmp=new int[nbOfCells];
+  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=types.begin();iter!=types.end();iter++)
+    {
+      int j=0;
+      for(const int *i=connI;i!=connI+nbOfCells;i++)
+        if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter))
+          tmp[std::distance(connI,i)]=j++;
+    }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(da->getNumberOfTuples(),da->getNumberOfComponents());
+  ret->copyStringInfoFrom(*da);
+  int *retPtr=ret->getPointer();
+  const int *daPtr=da->getConstPointer();
+  int nbOfElems=da->getNbOfElems();
+  for(int k=0;k<nbOfElems;k++)
+    retPtr[k]=tmp[daPtr[k]];
+  delete [] tmp;
+  return ret;
+}
+
+/*!
+ * This method reduced number of cells of this by keeping cells whose type is different from 'type' and if type=='type'
+ * cells whose ids is in 'idsPerGeoType' array.
+ * This method conserves coords and name of mesh.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const std::vector<int>& idsPerGeoType) const
+{
+  std::vector<int> idsTokeep;
+  int nbOfCells=getNumberOfCells();
+  int j=0;
+  for(int i=0;i<nbOfCells;i++)
+    if(getTypeOfCell(i)!=type)
+      idsTokeep.push_back(i);
+    else
+      {
+        if(std::find(idsPerGeoType.begin(),idsPerGeoType.end(),j)!=idsPerGeoType.end())
+          idsTokeep.push_back(i);
+        j++;
+      }
+  MEDCouplingPointSet *ret=buildPartOfMySelf(&idsTokeep[0],&idsTokeep[0]+idsTokeep.size(),true);
+  MEDCouplingUMesh *ret2=dynamic_cast<MEDCouplingUMesh *>(ret);
+  if(!ret2)
+    {
+      ret->decrRef();
+      return 0;
+    }
+  ret2->setName(getName());
+  return ret2;
+}
+
 /*!
  * Returns a newly created mesh (with ref count ==1) that contains merge of 'this' and 'other'.
  */
@@ -1444,15 +2788,9 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const
   const double *coor=_coords->getConstPointer();
   for(int i=0;i<nbOfCells;i++)
     {
-      int nbOfPts=0;
-      std::fill(tmp,tmp+spaceDim,0.);
-      for(const int *node=nodal+nodalI[i]+1;node!=nodal+nodalI[i+1];node++)
-        if(*node!=-1)
-          {
-            std::transform(tmp,tmp+spaceDim,coor+(*node)*spaceDim,tmp,std::plus<double>());
-            nbOfPts++;
-          }
-      ptToFill=std::transform(tmp,tmp+spaceDim,ptToFill,std::bind2nd(std::divides<double>(),(double)nbOfPts));
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[i]];
+      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;
@@ -1460,6 +2798,7 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const
 
 /*!
  * Returns a newly created mesh (with ref count ==1) that contains merge of 'mesh1' and 'other'.
+ * The coords of 'mesh2' are added at the end of coords of 'mesh1'.
  */
 MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2)
 {
@@ -1498,3 +2837,291 @@ MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1,
   nodal->decrRef();
   return ret;
 }
+
+/*!
+ * Idem mergeUMeshes except that 'meshes' are expected to lyie on the same coords and 'meshes' have the same meshdim.
+ * 'meshes' must be a non empty vector.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes)
+{
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("meshes input parameter is expected to be non empty.");
+  DataArrayDouble *coords=meshes.front()->getCoords();
+  int meshDim=meshes.front()->getMeshDimension();
+  std::vector<MEDCouplingUMesh *>::const_iterator iter=meshes.begin();
+  int meshLgth=0;
+  int meshIndexLgth=0;
+  for(;iter!=meshes.end();iter++)
+    {
+      if(coords!=(*iter)->getCoords())
+        throw INTERP_KERNEL::Exception("meshes does not share the same coords ! Try using tryToShareSameCoords method !");
+      if(meshDim!=(*iter)->getMeshDimension())
+        throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, fuseUMeshesOnSameCoords impossible !");
+      meshLgth+=(*iter)->getMeshLength();
+      meshIndexLgth+=(*iter)->getNumberOfCells();
+    }
+  DataArrayInt *nodal=DataArrayInt::New();
+  nodal->alloc(meshLgth,1);
+  int *nodalPtr=nodal->getPointer();
+  DataArrayInt *nodalIndex=DataArrayInt::New();
+  nodalIndex->alloc(meshIndexLgth+1,1);
+  int *nodalIndexPtr=nodalIndex->getPointer();
+  int offset=0;
+  for(iter=meshes.begin();iter!=meshes.end();iter++)
+    {
+      const int *nod=(*iter)->getNodalConnectivity()->getConstPointer();
+      const int *index=(*iter)->getNodalConnectivityIndex()->getConstPointer();
+      int nbOfCells=(*iter)->getNumberOfCells();
+      int meshLgth=(*iter)->getMeshLength();
+      nodalPtr=std::copy(nod,nod+meshLgth,nodalPtr);
+      if(iter!=meshes.begin())
+        nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind2nd(std::plus<int>(),offset));
+      else
+        nodalIndexPtr=std::copy(index,index+nbOfCells+1,nodalIndexPtr);
+      offset+=meshLgth;
+    }
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
+  ret->setName("merge");
+  ret->setMeshDimension(meshDim);
+  ret->setConnectivity(nodal,nodalIndex,true);
+  ret->setCoords(coords);
+  nodalIndex->decrRef();
+  nodal->decrRef();
+  return ret;
+}
+
+/*!
+ * This method fuses meshes 'meshes' and returns the fused mesh and the correspondances arrays for each mesh in 'meshes' in returned mesh.
+ * If a same cell is detected in several meshes in 'meshes', this cell will appear only once in returned mesh (see ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for more details)
+ *
+ * @param meshes input non empty vector containing meshes having same coordiantes array and same mesh dimension.
+ * @param compType see MEDCouplingUMesh::zipConnectivityTraducer
+ * @param corr output vector with same size as 'meshes' parameter. corr[i] is the correspondance array of mesh meshes[i] in returned mesh.
+ *             The arrays contained in 'corr' parameter are returned with refcounter set to one.
+ *             To avoid memory leaks the caller have to deal with each instances of DataArrayInt contained in 'corr' parameter.
+ * @return The mesh lying on the same coordinates than those in meshes. All cells in 'meshes' are in returned mesh with 
+ * @exception if meshes is a empty vector or meshes are not lying on same coordinates or meshes not have the same dimension.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::fuseUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr)
+{
+  //All checks are delegated to mergeUMeshesOnSameCoords
+  MEDCouplingUMesh *ret=mergeUMeshesOnSameCoords(meshes);
+  DataArrayInt *o2n=ret->zipConnectivityTraducer(compType);
+  corr.resize(meshes.size());
+  int nbOfMeshes=meshes.size();
+  int offset=0;
+  const int *o2nPtr=o2n->getConstPointer();
+  for(int i=0;i<nbOfMeshes;i++)
+    {
+      DataArrayInt *tmp=DataArrayInt::New();
+      int curNbOfCells=meshes[i]->getNumberOfCells();
+      tmp->alloc(curNbOfCells,1);
+      std::copy(o2nPtr+offset,o2nPtr+offset+curNbOfCells,tmp->getPointer());
+      offset+=curNbOfCells;
+      corr[i]=tmp;
+    }
+  o2n->decrRef();
+  return ret;
+}
+
+/*!
+ * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [connBg,connEnd) and returns its extruded cell by inserting the result at the end of ret.
+ * @param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset
+ * @param isQuad specifies the policy of connectivity.
+ * @ret in/out parameter in which the result will be append
+ */
+void MEDCouplingUMesh::appendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret)
+{
+  INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0];
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(flatType);
+  ret.push_back(cm.getExtrudedType());
+  int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev;
+  switch(flatType)
+    {
+    case INTERP_KERNEL::NORM_POINT0:
+      {
+        ret.push_back(connBg[1]);
+        ret.push_back(connBg[1]+nbOfNodesPerLev);
+        break;
+      }
+    case INTERP_KERNEL::NORM_SEG2:
+      {
+        int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz};
+        ret.insert(ret.end(),conn,conn+4);
+        break;
+      }
+    case INTERP_KERNEL::NORM_SEG3:
+      {
+        int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev};
+        ret.insert(ret.end(),conn,conn+8);
+        break;
+      }
+    case INTERP_KERNEL::NORM_QUAD4:
+      {
+        int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz};
+        ret.insert(ret.end(),conn,conn+8);
+        break;
+      }
+    case INTERP_KERNEL::NORM_TRI3:
+      {
+        int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz};
+        ret.insert(ret.end(),conn,conn+6);
+        break;
+      }
+    case INTERP_KERNEL::NORM_TRI6:
+      {
+        int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz,
+                      connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev};
+        ret.insert(ret.end(),conn,conn+15);
+        break;
+      }
+    case INTERP_KERNEL::NORM_QUAD8:
+      {
+        int conn[20]={
+          connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz,
+          connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz,
+          connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev
+        };
+        ret.insert(ret.end(),conn,conn+20);
+        break;
+      }
+    case INTERP_KERNEL::NORM_POLYGON:
+      {
+        std::back_insert_iterator< std::vector<int> > ii(ret);
+        std::copy(connBg+1,connEnd,ii);
+        *ii++=-1;
+        std::reverse_iterator<const int *> rConnBg(connEnd);
+        std::reverse_iterator<const int *> rConnEnd(connBg+1);
+        std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus<int>(),deltaz));
+        int nbOfRadFaces=std::distance(connBg+1,connEnd);
+        for(int i=0;i<nbOfRadFaces;i++)
+          {
+            *ii++=-1;
+            int conn[4]={connBg[(i+1)%nbOfRadFaces+1],connBg[i+1],connBg[i+1]+deltaz,connBg[(i+1)%nbOfRadFaces+1]+deltaz};
+            std::copy(conn,conn+4,ii);
+          }
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("A flat type has been detected that has not its extruded representation !");
+    }
+}
+
+/*!
+ * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [begin,end).
+ */
+bool MEDCouplingUMesh::isPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords)
+{
+  double v[3]={0.,0.,0.};
+  int sz=std::distance(begin,end);
+  for(int i=0;i<sz;i++)
+    {
+      v[0]+=coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]+2]-coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]+1];
+      v[1]+=coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]]-coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+2];
+      v[2]+=coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+1]-coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]];
+    }
+  return vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2]<0.;
+}
+
+/*!
+ * The polyhedron is specfied by its connectivity nodes in [begin,end).
+ */
+bool MEDCouplingUMesh::isPolyhedronWellOriented(const int *begin, const int *end, const double *coords)
+{
+  std::vector<std::pair<int,int> > edges;
+  int nbOfFaces=std::count(begin,end,-1)+1;
+  const int *bgFace=begin;
+  for(int i=0;i<nbOfFaces;i++)
+    {
+      const int *endFace=std::find(bgFace+1,end,-1);
+      int nbOfEdgesInFace=std::distance(bgFace,endFace);
+      for(int j=0;j<nbOfEdgesInFace;j++)
+        {
+          std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
+          if(std::find(edges.begin(),edges.end(),p1)!=edges.end())
+            return false;
+          edges.push_back(p1);
+        }
+      bgFace=endFace+1;
+    }
+  return INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION;
+}
+
+/*!
+ * This method tries to obtain a well oriented polyhedron.
+ * If the algorithm fails, an exception will be thrown.
+ */
+void MEDCouplingUMesh::tryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<std::pair<int,int> > edges;
+  int nbOfFaces=std::count(begin,end,-1)+1;
+  int *bgFace=begin;
+  std::vector<bool> isPerm(nbOfFaces);
+  for(int i=0;i<nbOfFaces;i++)
+    {
+      int *endFace=std::find(bgFace+1,end,-1);
+      int nbOfEdgesInFace=std::distance(bgFace,endFace);
+      for(int 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(int k=i+1;k<nbOfFaces;k++)
+        {
+          int *endFace2=std::find(bgFace2+1,end,-1);
+          int nbOfEdgesInFace2=std::distance(bgFace2,endFace2);
+          for(int j=0;j<nbOfEdgesInFace2;j++)
+            {
+              std::pair<int,int> p2(bgFace2[j],bgFace2[(j+1)%nbOfEdgesInFace2]);
+              if(std::find(edges.begin(),edges.end(),p2)!=edges.end())
+                {
+                  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;
+                }
+            }
+          bgFace2=endFace2+1;
+        }
+      bgFace=endFace+1;
+    }
+  if(INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION)
+    {//not lucky ! The first face was not correctly oriented : reorient all faces...
+      bgFace=begin;
+      for(int i=0;i<nbOfFaces;i++)
+        {
+          int *endFace=std::find(bgFace+1,end,-1);
+          int 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);
+          bgFace=endFace+1;
+        }
+    }
+}
+
+/*!
+ * This method put in zip format into parameter 'zipFrmt' in full interlace mode.
+ * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array.
+ */
+void MEDCouplingUMesh::fillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception)
+{
+  double *w=zipFrmt;
+  if(spaceDim==3)
+    for(int i=0;i<nbOfNodesInCell;i++)
+      w=std::copy(coo+3*conn[i],coo+3*conn[i]+3,w);
+  else if(spaceDim==2)
+    {
+      for(int i=0;i<nbOfNodesInCell;i++)
+        {
+          w=std::copy(coo+2*conn[i],coo+2*conn[i]+2,w);
+          *w++=0.;
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
+}
index 074de0b7b5de9a8fcba41928c9a9563abaf77b3d..eb989c9a6383233562ff54596d45b44758aa456c 100644 (file)
@@ -33,10 +33,17 @@ namespace ParaMEDMEM
   public:
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *New();
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *New(const char *meshName, int meshDim);
+    MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *clone(bool recDeepCpy) const;
     MEDCOUPLING_EXPORT void updateTime();
     MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED; }
     MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingMesh *other, double prec) const;
+    MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const;
+    MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                            DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setMeshDimension(int meshDim);
     MEDCOUPLING_EXPORT void allocateCells(int nbOfCells);
@@ -47,58 +54,107 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const { return _nodal_connec; }
     MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() const { return _nodal_connec_index; }
     MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const;
+    MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const;
     MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const;
+    MEDCOUPLING_EXPORT DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const;
     MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const;
+    MEDCOUPLING_EXPORT std::string simpleRepr() const;
+    MEDCOUPLING_EXPORT std::string advancedRepr() const;
+    MEDCOUPLING_EXPORT std::string reprConnectivityOfThis() const;
     MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const;
     MEDCOUPLING_EXPORT int getNumberOfCells() const;
     MEDCOUPLING_EXPORT int getMeshDimension() const;
     MEDCOUPLING_EXPORT int getMeshLength() const;
+    MEDCOUPLING_EXPORT void computeTypes();
     //! size of returned tinyInfo must be always the same.
     MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
     MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector<int>& tinyInfo) const;
-    MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings);
+    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<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings);
+    MEDCOUPLING_EXPORT void unserialization(const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings);
     //tools
+    MEDCOUPLING_EXPORT bool areCellsEqual(int cell1, int cell2, int compType) const;
+    MEDCOUPLING_EXPORT bool areCellsEqual0(int cell1, int cell2) const;
+    MEDCOUPLING_EXPORT bool areCellsEqual1(int cell1, int cell2) const;
+    MEDCOUPLING_EXPORT bool areCellsEqual2(int cell1, int cell2) const;
+    MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const;
     MEDCOUPLING_EXPORT void convertToPolyTypes(const std::vector<int>& cellIdsToConvert);
     MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer();
+    MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType);
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
-    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged);
-    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
-    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
-    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
+    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
+    MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const;
+    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
+    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector<int>& nodes) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const;
     MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
-    MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, const int *old2NewEnd, bool check);
+    MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems);
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const;
-    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildLinearField() const;
+    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildDirectionVectorField() const;
     MEDCOUPLING_EXPORT void project1D(const double *pt, const double *v, double eps, double *res) const;
     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) const;
     MEDCOUPLING_EXPORT void getBoundingBoxForBBTree(std::vector<double>& bbox) const;
+    MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy);
+    MEDCOUPLING_EXPORT bool isFullyQuadratic() const;
+    MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const;
+    MEDCOUPLING_EXPORT void convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void orientCorrectly2DCells(const double *vec, bool polyOnly) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void getFastAveragePlaneOfThis(double *vec, double *pos) const throw(INTERP_KERNEL::Exception);
+    //Mesh quality
+    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getEdgeRatioField() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getAspectRatioField() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception);
+    //utilities for MED File RW
     MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const;
+    MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const;
+    MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const;
+    MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes();
+    MEDCOUPLING_EXPORT std::vector<MEDCouplingUMesh *> splitByType() const;
+    MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const std::vector<int>& idsPerGeoType) const;
+    //
     MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
     MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const;
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2);
+    MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes);
+    MEDCOUPLING_EXPORT static MEDCouplingUMesh *fuseUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr);
+    MEDCOUPLING_EXPORT static bool isPolygonWellOriented(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 tryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception);
   private:
     MEDCouplingUMesh();
     MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCpy);
     ~MEDCouplingUMesh();
-    void computeTypes();
     void checkFullyDefined() const throw(INTERP_KERNEL::Exception);
+    void reprConnectivityOfThisLL(std::ostringstream& stream) const;
     //tools
-    MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *start, const int *end) const;
+    void renumberNodesInConn(const int *newNodeNumbers);
+    void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector<int>& cellIdsKept) const;
+    MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const;
+    DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const;
+    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;
+    MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const;
     template<int SPACEDIM>
     void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
                                      double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const;
+    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);
   private:
     //! this iterator stores current position in _nodal_connec array.
     mutable int _iterator;
@@ -108,6 +164,8 @@ namespace ParaMEDMEM
     std::set<INTERP_KERNEL::NormalizedCellType> _types;
   private:
     static const char PART_OF_NAME[];
+  public:
+    static double EPS_FOR_POLYH_ORIENTATION;
   };
 }
 
index 29f1e58e3c1d8bb242fb31b9375b665b1f7a51fc..f45cd5eba7e3eedfde41065a0ba3e3dedc7d94c3 100644 (file)
@@ -55,6 +55,14 @@ MEDCouplingUMeshDesc *MEDCouplingUMeshDesc::New(const char *meshName, int meshDi
   return ret;
 }
 
+/*!
+ * not implemented
+ */
+MEDCouplingMesh *MEDCouplingUMeshDesc::deepCpy() const
+{
+  return 0;
+}
+
 void MEDCouplingUMeshDesc::checkCoherency() const throw(INTERP_KERNEL::Exception)
 {
   for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
@@ -68,6 +76,18 @@ void MEDCouplingUMeshDesc::checkCoherency() const throw(INTERP_KERNEL::Exception
     }
 }
 
+void MEDCouplingUMeshDesc::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::checkDeepEquivalWith : not implemented yet !");
+}
+
+void MEDCouplingUMeshDesc::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                           DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::checkDeepEquivalOnSameNodesWith : not implemented yet !");
+}
+
 void MEDCouplingUMeshDesc::setMeshDimension(unsigned meshDim)
 {
   _mesh_dim=meshDim;
@@ -107,6 +127,18 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshDesc::getTypeOfCell(int cellId
   return (INTERP_KERNEL::NormalizedCellType)desc_connec[desc_connec_index[cellId]+1];
 }
 
+int MEDCouplingUMeshDesc::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
+{
+  const int *desc_connec=_desc_connec->getConstPointer();
+  const int *desc_connec_index=_desc_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  int ret=0;
+  for(int i=0;i<nbOfCells;i++)
+    if((INTERP_KERNEL::NormalizedCellType) desc_connec[desc_connec_index[i]]==type)
+      ret++;
+  return ret;
+}
+
 void MEDCouplingUMeshDesc::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
 {
   //not implemented yet.
@@ -117,6 +149,22 @@ void MEDCouplingUMeshDesc::getCoordinatesOfNode(int nodeId, std::vector<double>&
   //not implemented yet.
 }
 
+std::string MEDCouplingUMeshDesc::simpleRepr() const
+{
+  std::string ret("Unstructured mesh with descending connectivity : ");
+  ret+=getName();
+  ret+="\n";
+  return ret;
+}
+
+std::string MEDCouplingUMeshDesc::advancedRepr() const
+{
+  std::string ret("Unstructured mesh with descending connectivity : ");
+  ret+=getName();
+  ret+="\n";
+  return ret;
+}
+
 void MEDCouplingUMeshDesc::setConnectivity(DataArrayInt *descConn, DataArrayInt *descConnIndex, DataArrayInt *nodalFaceConn, DataArrayInt *nodalFaceConnIndx)
 {
   DataArrayInt::setArrayIn(descConn,_desc_connec);
@@ -283,13 +331,18 @@ void MEDCouplingUMeshDesc::giveElemsInBoundingBox(const INTERP_KERNEL::DirectedB
   delete [] elem_bb;
 }
 
-DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged)
+DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
 {
   //not implemented yet.
   areNodesMerged=false;
   return 0;
 }
 
+void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const
 {
   //not implemented yet.
@@ -319,6 +372,11 @@ MEDCouplingPointSet *MEDCouplingUMeshDesc::buildBoundaryMesh(bool keepCoords) co
   return 0;
 }
 
+void MEDCouplingUMeshDesc::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Available for UMesh desc but not implemented yet !");
+}
+
 void MEDCouplingUMeshDesc::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
 {
   MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes);
index 91ce649ed75a0f4fd76dc675a5c25a7726136e82..7c965a31c6335a24909caff07e4b002f21257b48 100644 (file)
@@ -33,7 +33,12 @@ namespace ParaMEDMEM
   public:
     MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New();
     MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(const char *meshName, int meshDim);
+    MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const;
     MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                            DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setMeshDimension(unsigned meshDim);
     MEDCOUPLING_EXPORT int getNumberOfCells() const;
     MEDCOUPLING_EXPORT int getNumberOfFaces() const;
@@ -41,8 +46,11 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT int getFaceMeshLength() const;
     MEDCOUPLING_EXPORT int getMeshDimension() const { return _mesh_dim; }
     MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const;
+    MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const;
     MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const;
     MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const;
+    MEDCOUPLING_EXPORT std::string simpleRepr() const;
+    MEDCOUPLING_EXPORT std::string advancedRepr() const;
     MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED_DESC; }
     MEDCOUPLING_EXPORT void setConnectivity(DataArrayInt *descConn, DataArrayInt *descConnIndex, DataArrayInt *nodalFaceConn, DataArrayInt *nodalFaceConnIndx);
     //tools to overload
@@ -53,12 +61,14 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector<int>& elems);
-    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged);
+    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
+    MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector<int>& nodes) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const;
+    MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
index 20117023a8115898bf359d9aac9087e480821bf6..28553f2880da23db04fac15f2cc94e472cc04424 100644 (file)
@@ -36,17 +36,19 @@ MEDCouplingCMesh.hxx MEDCouplingTimeDiscretization.hxx
 MEDCouplingFieldDiscretization.hxx MEDCouplingPointSet.hxx MEDCouplingPointSet.txx                \
 MEDCouplingUMeshDesc.hxx MEDCouplingNatureOfField.hxx                                             \
 MEDCouplingNormalizedCartesianMesh.hxx MEDCouplingNormalizedCartesianMesh.txx                     \
-MEDCouplingRemapper.hxx MEDCouplingExtrudedMesh.hxx
+MEDCouplingRemapper.hxx MEDCouplingExtrudedMesh.hxx MEDCouplingGaussLocalization.hxx              \
+MEDCouplingAutoRefCountObjectPtr.hxx
 
 # Libraries targets
 
 dist_libmedcoupling_la_SOURCES = \
-       MEDCouplingField.cxx  MEDCouplingFieldDouble.cxx                          \
-       MEDCouplingUMesh.cxx  MEDCouplingMemArray.cxx  MEDCouplingTimeLabel.cxx   \
-       MEDCouplingCMesh.cxx MEDCouplingTimeDiscretization.cxx                    \
-       MEDCouplingFieldDiscretization.cxx MEDCouplingRefCountObject.cxx          \
-       MEDCouplingPointSet.cxx MEDCouplingUMeshDesc.cxx                          \
-       MEDCouplingExtrudedMesh.cxx MEDCouplingMesh.cxx
+       MEDCouplingField.cxx  MEDCouplingFieldDouble.cxx                                    \
+       MEDCouplingUMesh.cxx  MEDCouplingMemArray.cxx  MEDCouplingTimeLabel.cxx             \
+       MEDCouplingCMesh.cxx MEDCouplingTimeDiscretization.cxx                              \
+       MEDCouplingFieldDiscretization.cxx MEDCouplingRefCountObject.cxx                    \
+       MEDCouplingPointSet.cxx MEDCouplingUMeshDesc.cxx                                    \
+       MEDCouplingExtrudedMesh.cxx MEDCouplingMesh.cxx MEDCouplingGaussLocalization.cxx    \
+       MEDCouplingNatureOfField.cxx
 
 libmedcoupling_la_LDFLAGS= 
 
@@ -70,9 +72,6 @@ libmedcouplingremapper_la_LIBADD = libmedcoupling.la
 
 AM_CPPFLAGS += $(libinterpkernel_la_CPPFLAGS)
 LDADD= $(libinterpkernel_la_LDFLAGS)
-if MED_ENABLE_KERNEL
-     LDADD+=-lSALOMEBasics
-endif
 
 EXTRA_DIST += \
        MEDCouplingFieldDouble.hxx                \
@@ -92,4 +91,6 @@ EXTRA_DIST += \
        MEDCouplingPointSet.txx                   \
        MEDCouplingUMeshDesc.hxx                  \
        MEDCouplingNatureOfField.hxx              \
-       MEDCouplingRemapper.hxx
+       MEDCouplingRemapper.hxx                   \
+       MEDCouplingExtrudedMesh.hxx               \
+       MEDCouplingGaussLocalization.hxx 
index 87393c8f962c2a060db2b4cbe2d22375ea0d8dd8..569560584be281df96e24bb42f92de136ea06917 100644 (file)
@@ -32,7 +32,10 @@ namespace ParaMEDMEM
   class MEDCouplingBasicsTest : public CppUnit::TestFixture
   {
     CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest);
+    //MEDCouplingBasicsTest1.cxx
     CPPUNIT_TEST( testArray );
+    CPPUNIT_TEST( testArray2 );
+    CPPUNIT_TEST( testArray3 );
     CPPUNIT_TEST( testMesh );
     CPPUNIT_TEST( testMeshPointsCloud );
     CPPUNIT_TEST( testMeshM1D );
@@ -46,15 +49,19 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testBuildPartOfMySelf );
     CPPUNIT_TEST( testBuildPartOfMySelfNode );
     CPPUNIT_TEST( testZipCoords );
+    CPPUNIT_TEST( testZipConnectivity );
     CPPUNIT_TEST( testEqualMesh );
     CPPUNIT_TEST( testEqualFieldDouble );
     CPPUNIT_TEST( testNatureChecking );
     CPPUNIT_TEST( testBuildSubMeshData );
     CPPUNIT_TEST( testExtrudedMesh1 );
     CPPUNIT_TEST( testExtrudedMesh2 );
+    CPPUNIT_TEST( testExtrudedMesh3 );
+    CPPUNIT_TEST( testExtrudedMesh4 );
     CPPUNIT_TEST( testFindCommonNodes );
     CPPUNIT_TEST( testCheckButterflyCells );
     CPPUNIT_TEST( testMergeMesh1 );
+    CPPUNIT_TEST( testMergeMeshOnSameCoords1 );
     CPPUNIT_TEST( testMergeField1 );
     CPPUNIT_TEST( testFillFromAnalytic );
     CPPUNIT_TEST( testFillFromAnalytic2 );
@@ -63,8 +70,13 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testOperationsOnFields );
     CPPUNIT_TEST( testOperationsOnFields2 );
     CPPUNIT_TEST( testOperationsOnFields3 );
+    CPPUNIT_TEST( testOperationsOnFields4 );
     CPPUNIT_TEST( testMergeNodesOnField );
     CPPUNIT_TEST( testCheckConsecutiveCellTypes );
+    CPPUNIT_TEST( testRearrange2ConsecutiveCellTypes );
+    CPPUNIT_TEST( testSplitByType );
+    CPPUNIT_TEST( testFuseUMeshesOnSameCoords );
+    CPPUNIT_TEST( testFuseUMeshesOnSameCoords2 );
     CPPUNIT_TEST( testBuildOrthogonalField );
     CPPUNIT_TEST( testGetCellsContainingPoint );
     CPPUNIT_TEST( testGetValueOn1 );
@@ -74,6 +86,64 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testFindNodeOnPlane );
     CPPUNIT_TEST( testRenumberCells );
     CPPUNIT_TEST( testChangeSpaceDimension );
+    //MEDCouplingBasicsTest2.cxx
+    CPPUNIT_TEST( testGaussPointField1 );
+    CPPUNIT_TEST( testGaussPointNEField1 );
+    CPPUNIT_TEST( testCellOrientation1 );
+    CPPUNIT_TEST( testCellOrientation2 );
+    CPPUNIT_TEST( testPolyhedronBarycenter );
+    CPPUNIT_TEST( testNormL12Integ1D );
+    CPPUNIT_TEST( testAreaBary2D );
+    CPPUNIT_TEST( testAreaBary3D );
+    CPPUNIT_TEST( testRenumberCellsForFields );
+    CPPUNIT_TEST( testRenumberNodesForFields );
+    CPPUNIT_TEST( testConvertQuadraticCellsToLinear );
+    CPPUNIT_TEST( testCheckGeoEquivalWith );
+    CPPUNIT_TEST( testCheckGeoEquivalWith2 );
+    CPPUNIT_TEST( testCopyTinyStringsFromOnFields );
+    CPPUNIT_TEST( testTryToShareSameCoordsPermute );
+    CPPUNIT_TEST( testTryToShareSameCoordsPermute2 );
+    CPPUNIT_TEST( testChangeUnderlyingMesh1 );
+    CPPUNIT_TEST( testGetMaxValue1 );
+    CPPUNIT_TEST( testSubstractInPlaceDM1 );
+    CPPUNIT_TEST( testDotCrossProduct1 );
+    CPPUNIT_TEST( testMinMaxFields1 );
+    CPPUNIT_TEST( testApplyLin1 );
+    CPPUNIT_TEST( testGetIdsInRange1 );
+    CPPUNIT_TEST( testBuildSubPart1 );
+    CPPUNIT_TEST( testDoublyContractedProduct1 );
+    CPPUNIT_TEST( testDeterminant1 );
+    CPPUNIT_TEST( testEigenValues1 );
+    CPPUNIT_TEST( testEigenVectors1 );
+    CPPUNIT_TEST( testInverse1 );
+    CPPUNIT_TEST( testTrace1 );
+    CPPUNIT_TEST( testDeviator1 );
+    CPPUNIT_TEST( testMagnitude1 );
+    CPPUNIT_TEST( testMaxPerTuple1 );
+    CPPUNIT_TEST( testChangeNbOfComponents );
+    CPPUNIT_TEST( testSortPerTuple1 );
+    CPPUNIT_TEST( testIsEqualWithoutConsideringStr1 );
+    CPPUNIT_TEST( testGetNodeIdsOfCell1 );
+    CPPUNIT_TEST( testGetEdgeRatioField1 );
+    CPPUNIT_TEST( testFillFromAnalytic3 );
+    CPPUNIT_TEST( testFieldDoubleOpEqual1 );
+    CPPUNIT_TEST( testAreaBary3D2 );
+    CPPUNIT_TEST( testGetMeasureFieldCMesh1 );
+    CPPUNIT_TEST( testFieldDoubleZipCoords1 );
+    CPPUNIT_TEST( testFieldDoubleZipConnectivity1 );
+    CPPUNIT_TEST( testDaDoubleRenumber1 );
+    CPPUNIT_TEST( testDaDoubleRenumberAndReduce1 );
+    CPPUNIT_TEST( testDaDoubleRenumberInPlace1 );
+    CPPUNIT_TEST( testDaDoubleSelectByTupleId1 );
+    CPPUNIT_TEST( testDaDoubleRenumberR1 );
+    CPPUNIT_TEST( testDaDoubleRenumberInPlaceR1 );
+    CPPUNIT_TEST( testDaDoubleGetMinMaxValues1 );
+    CPPUNIT_TEST( testFieldDoubleGetMinMaxValues2 );
+    CPPUNIT_TEST( testBuildUnstructuredCMesh1 );
+    CPPUNIT_TEST( testDataArrayIntInvertO2NNO21 );
+    CPPUNIT_TEST( testKeepSetSelectedComponent1 );
+    CPPUNIT_TEST( testKeepSetSelectedComponent2 );
+    //MEDCouplingBasicsTestInterp.cxx
     CPPUNIT_TEST( test2DInterpP0P0_1 );
     CPPUNIT_TEST( test2DInterpP0P0PL_1 );
     CPPUNIT_TEST( test2DInterpP0P0PL_2 );
@@ -131,10 +201,12 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( test2DCurveInterpP0P1_1 );
     CPPUNIT_TEST( test2DCurveInterpP1P0_1 );
     CPPUNIT_TEST( test2DCurveInterpP1P1_1 );
-
     CPPUNIT_TEST_SUITE_END();
   public:
+    //MEDCouplingBasicsTest1.cxx
     void testArray();
+    void testArray2();
+    void testArray3();
     void testMesh();
     void testMeshPointsCloud();
     void testMeshM1D();
@@ -148,15 +220,19 @@ namespace ParaMEDMEM
     void testBuildPartOfMySelf();
     void testBuildPartOfMySelfNode();
     void testZipCoords();
+    void testZipConnectivity();
     void testEqualMesh();
     void testEqualFieldDouble();
     void testNatureChecking();
     void testBuildSubMeshData();
     void testExtrudedMesh1();
     void testExtrudedMesh2();
+    void testExtrudedMesh3();
+    void testExtrudedMesh4();
     void testFindCommonNodes();
     void testCheckButterflyCells();
     void testMergeMesh1();
+    void testMergeMeshOnSameCoords1();
     void testMergeField1();
     void testFillFromAnalytic();
     void testFillFromAnalytic2();
@@ -165,8 +241,13 @@ namespace ParaMEDMEM
     void testOperationsOnFields();
     void testOperationsOnFields2();
     void testOperationsOnFields3();
+    void testOperationsOnFields4();
     void testMergeNodesOnField();
     void testCheckConsecutiveCellTypes();
+    void testRearrange2ConsecutiveCellTypes();
+    void testSplitByType();
+    void testFuseUMeshesOnSameCoords();
+    void testFuseUMeshesOnSameCoords2();
     void testBuildOrthogonalField();
     void testGetCellsContainingPoint();
     void testGetValueOn1();
@@ -176,6 +257,64 @@ namespace ParaMEDMEM
     void testFindNodeOnPlane();
     void testRenumberCells();
     void testChangeSpaceDimension();
+    //MEDCouplingBasicsTest2.cxx
+    void testGaussPointField1();
+    void testGaussPointNEField1();
+    void testCellOrientation1();
+    void testCellOrientation2();
+    void testPolyhedronBarycenter();
+    void testNormL12Integ1D();
+    void testAreaBary2D();
+    void testAreaBary3D();
+    void testRenumberCellsForFields();
+    void testRenumberNodesForFields();
+    void testConvertQuadraticCellsToLinear();
+    void testCheckGeoEquivalWith();
+    void testCheckGeoEquivalWith2();
+    void testCopyTinyStringsFromOnFields();
+    void testTryToShareSameCoordsPermute();
+    void testTryToShareSameCoordsPermute2();
+    void testChangeUnderlyingMesh1();
+    void testGetMaxValue1();
+    void testSubstractInPlaceDM1();
+    void testDotCrossProduct1();
+    void testMinMaxFields1();
+    void testApplyLin1();
+    void testGetIdsInRange1();
+    void testBuildSubPart1();
+    void testDoublyContractedProduct1();
+    void testDeterminant1();
+    void testEigenValues1();
+    void testEigenVectors1();
+    void testInverse1();
+    void testTrace1();
+    void testDeviator1();
+    void testMagnitude1();
+    void testMaxPerTuple1();
+    void testChangeNbOfComponents();
+    void testSortPerTuple1();
+    void testIsEqualWithoutConsideringStr1();
+    void testGetNodeIdsOfCell1();
+    void testGetEdgeRatioField1();
+    void testFillFromAnalytic3();
+    void testFieldDoubleOpEqual1();
+    void testAreaBary3D2();
+    void testGetMeasureFieldCMesh1();
+    void testFieldDoubleZipCoords1();
+    void testFieldDoubleZipConnectivity1();
+    void testDaDoubleRenumber1();
+    void testDaDoubleRenumberAndReduce1();
+    void testDaDoubleRenumberInPlace1();
+    void testDaDoubleSelectByTupleId1();
+    void testDaDoubleRenumberR1();
+    void testDaDoubleRenumberInPlaceR1();
+    void testDaDoubleGetMinMaxValues1();
+    void testFieldDoubleGetMinMaxValues2();
+    void testBuildUnstructuredCMesh1();
+    void testDataArrayIntInvertO2NNO21();
+    void testKeepSetSelectedComponent1();
+    void testKeepSetSelectedComponent2();
+    //MEDCouplingBasicsTestInterp.cxx
     void test2DInterpP0P0_1();
     void test2DInterpP0P0PL_1();
     void test2DInterpP0P0PL_2();
@@ -259,6 +398,15 @@ namespace ParaMEDMEM
     static MEDCouplingUMesh *build2DTargetMeshMerged_1();
     static MEDCouplingUMesh *build2DCurveMesh(double dx, double dy);
     static MEDCouplingUMesh *build1DMesh(double dx);
+    static MEDCouplingUMesh *build1DSourceMesh_2();
+    static MEDCouplingUMesh *build1DTargetMesh_2();
+    static MEDCouplingUMesh *build2DCurveSourceMesh_2();
+    static MEDCouplingUMesh *build2DCurveTargetMesh_2();
+    static MEDCouplingUMesh *build1DTargetMesh_3();
+    static MEDCouplingUMesh *build2DCurveTargetMesh_3();
+    static MEDCouplingUMesh *build2DTargetMesh_3();
+    static MEDCouplingUMesh *build3DTargetMesh_3();
+    static MEDCouplingUMesh *build2DTargetMesh_4();
     static double sumAll(const std::vector< std::map<int,double> >& matrix);
   };
 }
index 959a8c2c32c5a889adfe4be781e484d5761454e3..3f7adf58ad5bc03c762eda70eac166b985ecd641 100644 (file)
@@ -678,6 +678,170 @@ MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMesh(double dx)
   return targetMesh;
 }
 
+MEDCouplingUMesh *MEDCouplingBasicsTest::build1DSourceMesh_2()
+{
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1);
+  ret->allocateCells(4);
+  int conn[8]={0,1,2,3,1,2,3,4};
+  for(int i=0;i<4;i++)
+    ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i);
+  ret->finishInsertingCells();
+  double coords[5]={0.3,0.7,0.9,1.0,1.12};
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(5,1);
+  std::copy(coords,coords+5,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  return ret;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_2()
+{
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1);
+  ret->allocateCells(2);
+  int conn[4]={1,2,0,1};
+  for(int i=0;i<2;i++)
+    ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i);
+  ret->finishInsertingCells();
+  double coords[3]={0.5,0.75,1.2};
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(3,1);
+  std::copy(coords,coords+3,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  return ret;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveSourceMesh_2()
+{
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1);
+  ret->allocateCells(4);
+  int conn[8]={0,1,2,3,1,2,3,4};
+  for(int i=0;i<4;i++)
+    ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i);
+  ret->finishInsertingCells();
+  double coords[10]={0.3,0.3,0.7,0.7,0.9,0.9,1.0,1.0,1.12,1.12};
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(5,2);
+  std::copy(coords,coords+10,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  return ret;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_2()
+{
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1);
+  ret->allocateCells(2);
+  int conn[4]={1,2,0,1};
+  for(int i=0;i<2;i++)
+    ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i);
+  ret->finishInsertingCells();
+  double coords[6]={0.5,0.5,0.75,0.75,1.2,1.2};
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(3,2);
+  std::copy(coords,coords+6,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  return ret;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_3()
+{
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DMesh_3",1);
+  ret->allocateCells(4);
+  int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8};
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn);
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3);
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5);
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8);
+  ret->finishInsertingCells();
+  double coords[10]={0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31};
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(10,1);
+  std::copy(coords,coords+10,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  return ret;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_3()
+{
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DCurveMesh_3",1);
+  ret->allocateCells(4);
+  int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8};
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn);
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3);
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5);
+  ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8);
+  ret->finishInsertingCells();
+  double coords[20]={0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31};
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(10,2);
+  std::copy(coords,coords+20,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  return ret;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_3()
+{
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DMesh_3",2);
+  ret->allocateCells(10);
+  int conn[52]={
+    0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10,
+    0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6
+  };
+  ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn);
+  ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+3);
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+7);
+  ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+12);
+  ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+18);
+  ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+26);
+  ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+29);
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+33);
+  ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+38);
+  ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+44);
+  ret->finishInsertingCells();
+  double coords[22]={0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5};
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(11,2);
+  std::copy(coords,coords+22,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  ret->checkCoherency();
+  return ret;
+}
+
+/*!
+ * Same as build2DTargetMesh_1 but with more nodes than needed. To check tryToShareSameCoordsPermute method.
+ */
+MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_4()
+{
+  double targetCoords[20]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 };
+  int targetConn[18]={0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5};
+  MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
+  targetMesh->setMeshDimension(2);
+  targetMesh->allocateCells(5);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14);
+  targetMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(10,2);
+  std::copy(targetCoords,targetCoords+20,myCoords->getPointer());
+  targetMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return targetMesh;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_3()
+{
+  return 0;
+}
+
 double MEDCouplingBasicsTest::sumAll(const std::vector< std::map<int,double> >& matrix)
 {
   double ret=0.;
index dbd2a6ff95ed8e23d3e36e60de0eef70a6013c52..ffa8b6a759498ef924fac8840ceadbf820047f5f 100644 (file)
@@ -59,6 +59,68 @@ void MEDCouplingBasicsTest::testArray()
   }
 }
 
+void MEDCouplingBasicsTest::testArray2()
+{
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(3,4);
+  double *tmp=arr->getPointer();
+  const double arrRef[12]={12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.};
+  std::copy(arrRef,arrRef+12,tmp);
+  arr->setInfoOnComponent(0,"ggg");
+  arr->setInfoOnComponent(1,"hhhh");
+  arr->setInfoOnComponent(2,"jj");
+  arr->setInfoOnComponent(3,"kkkkkk");
+  DataArrayInt *arr2=arr->convertToIntArr();
+  DataArrayDouble *arr3=arr2->convertToDblArr();
+  arr2->decrRef();
+  CPPUNIT_ASSERT(arr->isEqual(*arr3,1e-14));
+  arr3->decrRef();
+  arr->decrRef();
+}
+
+void MEDCouplingBasicsTest::testArray3()
+{
+  DataArrayInt *arr1=DataArrayInt::New();
+  arr1->alloc(7,2);
+  int *tmp=arr1->getPointer();
+  const int arr1Ref[14]={0,10,1,11,2,12,3,13,4,14,5,15,6,16};
+  std::copy(arr1Ref,arr1Ref+14,tmp);
+  CPPUNIT_ASSERT_EQUAL(7,arr1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(arr1Ref,arr1Ref+14,arr1->getConstPointer()));
+  DataArrayInt *arr2=arr1->substr(3);
+  CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,arr2->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(arr1Ref+6,arr1Ref+14,arr2->getConstPointer()));
+  arr2->decrRef();
+  DataArrayInt *arr3=arr1->substr(2,5);
+  CPPUNIT_ASSERT_EQUAL(3,arr3->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,arr3->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(arr1Ref+4,arr1Ref+10,arr3->getConstPointer()));
+  arr1->decrRef();
+  arr3->decrRef();
+  //
+  DataArrayDouble *arr4=DataArrayDouble::New();
+  arr4->alloc(7,2);
+  double *tmp2=arr4->getPointer();
+  const int arr4Ref[14]={0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5};
+  std::copy(arr4Ref,arr4Ref+14,tmp2);
+  CPPUNIT_ASSERT_EQUAL(7,arr4->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,arr4->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(arr4Ref,arr4Ref+14,arr4->getConstPointer()));
+  DataArrayDouble *arr5=arr4->substr(3);
+  CPPUNIT_ASSERT_EQUAL(4,arr5->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,arr5->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(arr4Ref+6,arr4Ref+14,arr5->getConstPointer()));
+  arr5->decrRef();
+  DataArrayDouble *arr6=arr4->substr(2,5);
+  CPPUNIT_ASSERT_EQUAL(3,arr6->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,arr6->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(arr4Ref+4,arr4Ref+10,arr6->getConstPointer()));
+  arr4->decrRef();
+  arr6->decrRef();
+}
+
 void MEDCouplingBasicsTest::testMesh()
 {
   const int nbOfCells=6;
@@ -542,7 +604,12 @@ void MEDCouplingBasicsTest::testBuildPartOfMySelf()
   CPPUNIT_ASSERT_EQUAL(4,subMesh->getNodalConnectivityIndex()->getNbOfElems());
   CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer()));
   CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer()));
+  const int tab3[3]={0,1,2};
+  MEDCouplingPointSet *subMeshSimple2=subMeshSimple->buildPartOfMySelf(tab3,tab3+3,true);
   subMesh->decrRef();
+  name=subMeshSimple2->getName();
+  CPPUNIT_ASSERT(name=="PartOf_Toto");
+  subMeshSimple2->decrRef();
   //
   mesh->decrRef();
 }
@@ -653,6 +720,47 @@ void MEDCouplingBasicsTest::testZipCoords()
   mesh->decrRef();
 }
 
+void MEDCouplingBasicsTest::testZipConnectivity()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  MEDCouplingUMesh *m2=build2DTargetMesh_1();
+  int cells1[3]={2,3,4};
+  MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true);
+  MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1);
+  CPPUNIT_ASSERT(m3);
+  m2->decrRef();
+  MEDCouplingUMesh *m4=build2DSourceMesh_1();
+  MEDCouplingUMesh *m5=MEDCouplingUMesh::mergeUMeshes(m1,m3);
+  m1->decrRef();
+  m3->decrRef();
+  MEDCouplingUMesh *m6=MEDCouplingUMesh::mergeUMeshes(m5,m4);
+  m4->decrRef();
+  m5->decrRef();
+  //
+  bool areNodesMerged;
+  int newNbOfNodes;
+  CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes());
+  DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes);
+  arr->decrRef();
+  CPPUNIT_ASSERT(areNodesMerged);
+  CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(9,newNbOfNodes);
+  //
+  arr=m6->zipConnectivityTraducer(0);
+  CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells());
+  arr->decrRef();
+  MEDCouplingUMesh *m7=m6->clone(true);
+  arr=m6->zipConnectivityTraducer(0);
+  CPPUNIT_ASSERT(m7->isEqual(m6,1e-12));
+  CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells());
+  arr->decrRef();
+  //
+  m7->decrRef();
+  m6->decrRef();
+}
+
 void MEDCouplingBasicsTest::testEqualMesh()
 {
   MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
@@ -887,7 +995,8 @@ void MEDCouplingBasicsTest::testExtrudedMesh2()
   build3DExtrudedUMesh_2(mN,mTT,mTF);
   //
   bool b=false;
-  DataArrayInt *da=mTT->mergeNodes(1e-12,b);
+  int newNbOfNodes;
+  DataArrayInt *da=mTT->mergeNodes(1e-12,b,newNbOfNodes);
   CPPUNIT_ASSERT(b);
   da->decrRef();
   std::vector<int> n;
@@ -903,7 +1012,7 @@ void MEDCouplingBasicsTest::testExtrudedMesh2()
   mTT3dSurf->decrRef();
   //
   b=false;
-  da=mN->mergeNodes(1e-12,b);
+  da=mN->mergeNodes(1e-12,b,newNbOfNodes);
   da->decrRef();
   CPPUNIT_ASSERT(!b);
   n.clear();
@@ -917,7 +1026,7 @@ void MEDCouplingBasicsTest::testExtrudedMesh2()
   mN3dSurf->decrRef();
   //
   b=false;
-  da=mTF->mergeNodes(1e-12,b);
+  da=mTF->mergeNodes(1e-12,b,newNbOfNodes);
   da->decrRef();
   CPPUNIT_ASSERT(!b);
   n.clear();
@@ -939,15 +1048,122 @@ void MEDCouplingBasicsTest::testExtrudedMesh2()
   mTF->decrRef();
 }
 
+/*!
+ * This test check MEDCouplingUMesh::buildExtrudedMeshFromThis method.
+ */
+void MEDCouplingBasicsTest::testExtrudedMesh3()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  m1->changeSpaceDimension(3);
+  MEDCouplingUMesh *m2=buildCU1DMesh_U();
+  m2->changeSpaceDimension(3);
+  double center[3]={0.,0.,0.};
+  double vector[3]={0,1,0};
+  m2->rotate(center,vector,-M_PI/2.);
+  MEDCouplingUMesh *m3=m1->buildExtrudedMeshFromThis(m2,0);
+  //
+  MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0);
+  CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells());
+  const int *m3DIds=m4->getMesh3DIds()->getConstPointer();
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_EQUAL(i,m3DIds[i]);
+  m4->decrRef();
+  //some random in cells to check that extrusion alg find it correctly
+  const int expected1[15]={1,3,2,0,6,5,7,10,11,8,12,9,14,13,4};
+  m3->renumberCells(expected1,false);
+  m4=MEDCouplingExtrudedMesh::New(m3,m1,0);
+  CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells());
+  m3DIds=m4->getMesh3DIds()->getConstPointer();
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]);
+  m4->decrRef();
+  m3->decrRef();
+  //play with polygons and polyedrons
+  std::vector<int> cells(2); cells[0]=2; cells[1]=3;
+  m1->convertToPolyTypes(cells);
+  m3=m1->buildExtrudedMeshFromThis(m2,0);
+  CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(0));
+  CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_PENTA6,(int)m3->getTypeOfCell(1));
+  CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(2));
+  CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(3));
+  CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(4));
+  m3->renumberCells(expected1,false);
+  m4=MEDCouplingExtrudedMesh::New(m3,m1,0);
+  CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells());
+  m3DIds=m4->getMesh3DIds()->getConstPointer();
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]);
+  m4->decrRef();
+  m3->decrRef();
+  //
+  m2->decrRef();
+  m1->decrRef();
+}
+
+/*!
+ * This test check MEDCouplingUMesh::buildExtrudedMeshFromThis method, but also, MEDCouplingExtrudedMesh following methods :
+ * getCellContainingPoint getMeasureField getNodeIdsOfCell getCoordinateOfNode getTypeOfCell build3DUnstructuredMesh.
+ */
+void MEDCouplingBasicsTest::testExtrudedMesh4()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  std::vector<int> cells(2); cells[0]=2; cells[1]=4;
+  m1->convertToPolyTypes(cells);
+  m1->changeSpaceDimension(3);
+  MEDCouplingUMesh *m2=buildCU1DMesh_U();
+  m2->changeSpaceDimension(3);
+  double center[3]={0.,0.,0.};
+  double vector[3]={0.,1.,0.};
+  m2->rotate(center,vector,-M_PI/2.);
+  MEDCouplingUMesh *m3=m1->buildExtrudedMeshFromThis(m2,0);
+  const int expected1[15]= {1,3,2,0,6,5,7,10,11,8,12,9,14,13,4};
+  const int rexpected1[15]={3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12};
+  m3->renumberCells(expected1,false);
+  MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0);
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(0));
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(1));
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYHED,m4->getTypeOfCell(2));
+  CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,m4->getTypeOfCell(7));
+  MEDCouplingFieldDouble *f=m4->getMeasureField(true);
+  DataArrayDouble *arr=f->getArray();
+  CPPUNIT_ASSERT_EQUAL(15,arr->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents());
+  const double *arrPtr=arr->getConstPointer();
+  const double expected2[15]={0.075,0.0375,0.0375,0.075,0.075,   0.1125,0.05625,0.05625,0.1125,0.1125,   0.0625,0.03125,0.03125,0.0625,0.0625};
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16);
+  f->decrRef();
+  MEDCouplingUMesh *m5=m4->build3DUnstructuredMesh();
+  CPPUNIT_ASSERT(m5->isEqual(m3,1e-12));
+  f=m5->getMeasureField(true);
+  arr=f->getArray();
+  arrPtr=arr->getConstPointer();
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16);
+  f->decrRef();
+  m5->decrRef();
+  //
+  m4->decrRef();
+  m3->decrRef();
+  m2->decrRef();
+  m1->decrRef();
+}
+
 void MEDCouplingBasicsTest::testFindCommonNodes()
 {
   DataArrayInt *comm,*commI;
   MEDCouplingUMesh *targetMesh=build3DTargetMesh_1();
-  targetMesh->findCommonNodes(comm,commI,1e-10);
+  targetMesh->findCommonNodes(-1,1e-10,comm,commI);
   CPPUNIT_ASSERT_EQUAL(1,commI->getNumberOfTuples());
   CPPUNIT_ASSERT_EQUAL(0,comm->getNumberOfTuples());
   int newNbOfNodes;
-  DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
+  DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes);
   CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes);
   CPPUNIT_ASSERT_EQUAL(27,o2n->getNumberOfTuples());
   const int o2nExp1[27]=
@@ -963,14 +1179,14 @@ void MEDCouplingBasicsTest::testFindCommonNodes()
   //
   targetMesh=build3DTargetMeshMergeNode_1();
   CPPUNIT_ASSERT_EQUAL(31,targetMesh->getNumberOfNodes());
-  targetMesh->findCommonNodes(comm,commI,1e-10);
+  targetMesh->findCommonNodes(-1,1e-10,comm,commI);
   CPPUNIT_ASSERT_EQUAL(3,commI->getNumberOfTuples());
   CPPUNIT_ASSERT_EQUAL(6,comm->getNumberOfTuples());
   const int commExpected[6]={1,27,28,29,23,30};
   const int commIExpected[3]={0,4,6};
   CPPUNIT_ASSERT(std::equal(commExpected,commExpected+6,comm->getConstPointer()));
   CPPUNIT_ASSERT(std::equal(commIExpected,commIExpected+3,commI->getConstPointer()));
-  o2n=targetMesh->buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
+  o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes);
   CPPUNIT_ASSERT_EQUAL(31,o2n->getNumberOfTuples());
   CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes);
   const int o2nExp2[31]=
@@ -987,7 +1203,7 @@ void MEDCouplingBasicsTest::testFindCommonNodes()
   targetMesh=build3DTargetMesh_1();
   bool areNodesMerged;
   unsigned int time=targetMesh->getTimeOfThis();
-  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged);
+  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes);
   targetMesh->updateTime();
   CPPUNIT_ASSERT(time==targetMesh->getTimeOfThis());
   CPPUNIT_ASSERT(!areNodesMerged);
@@ -996,7 +1212,7 @@ void MEDCouplingBasicsTest::testFindCommonNodes()
   //
   targetMesh=build3DTargetMeshMergeNode_1();
   time=targetMesh->getTimeOfThis();
-  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged);
+  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes);
   targetMesh->updateTime();
   CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis());
   CPPUNIT_ASSERT(areNodesMerged);
@@ -1021,7 +1237,7 @@ void MEDCouplingBasicsTest::testFindCommonNodes()
   targetMesh=build2DTargetMeshMergeNode_1();
   CPPUNIT_ASSERT_EQUAL(18,targetMesh->getNumberOfNodes());
   time=targetMesh->getTimeOfThis();
-  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged);
+  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes);
   CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis());
   CPPUNIT_ASSERT(areNodesMerged);
   CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes());
@@ -1081,8 +1297,10 @@ void MEDCouplingBasicsTest::testMergeMesh1()
   CPPUNIT_ASSERT(m3->isEqual(m4,1.e-12));
   m4->decrRef();
   bool isMerged;
-  DataArrayInt *da=m3C->mergeNodes(1.e-12,isMerged);
+  int newNbOfNodes;
+  DataArrayInt *da=m3C->mergeNodes(1.e-12,isMerged,newNbOfNodes);
   CPPUNIT_ASSERT_EQUAL(11,m3C->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(11,newNbOfNodes);
   CPPUNIT_ASSERT(isMerged);
   da->decrRef();
   m3->decrRef();
@@ -1090,6 +1308,43 @@ void MEDCouplingBasicsTest::testMergeMesh1()
   m2->decrRef();
 }
 
+void MEDCouplingBasicsTest::testMergeMeshOnSameCoords1()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  MEDCouplingUMesh *m2=build2DTargetMesh_1();
+  std::vector<int> cells(5);
+  for(int i=0;i<5;i++)
+    cells[i]=i;
+  m2->convertToPolyTypes(cells);
+  m1->tryToShareSameCoords(*m2,1e-12);
+  MEDCouplingUMesh *m3=build2DTargetMesh_1();
+  m3->tryToShareSameCoords(*m2,1e-12);
+  std::vector<MEDCouplingUMesh *> meshes;
+  meshes.push_back(m1); meshes.push_back(m2); meshes.push_back(m3);
+  MEDCouplingUMesh *m4=MEDCouplingUMesh::mergeUMeshesOnSameCoords(meshes);
+  m4->checkCoherency();
+  CPPUNIT_ASSERT(m4->getCoords()==m1->getCoords());
+  CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells());
+  const int cells1[5]={0,1,2,3,4};
+  MEDCouplingPointSet *m1_1=m4->buildPartOfMySelf(cells1,cells1+5,true);
+  m1_1->setName(m1->getName());
+  CPPUNIT_ASSERT(m1->isEqual(m1_1,1e-12));
+  const int cells2[5]={5,6,7,8,9};
+  MEDCouplingPointSet *m2_1=m4->buildPartOfMySelf(cells2,cells2+5,true);
+  m2_1->setName(m2->getName());
+  CPPUNIT_ASSERT(m2->isEqual(m2_1,1e-12));
+  const int cells3[5]={10,11,12,13,14};
+  MEDCouplingPointSet *m3_1=m4->buildPartOfMySelf(cells3,cells3+5,true);
+  m3_1->setName(m3->getName());
+  CPPUNIT_ASSERT(m3->isEqual(m3_1,1e-12));
+  m1_1->decrRef(); m2_1->decrRef(); m3_1->decrRef();
+  //
+  m4->decrRef();
+  m1->decrRef();
+  m2->decrRef();
+  m3->decrRef();
+}
+
 void MEDCouplingBasicsTest::testMergeField1()
 {
   MEDCouplingUMesh *m1=build2DTargetMesh_1();
@@ -1195,7 +1450,7 @@ void MEDCouplingBasicsTest::testFillFromAnalytic()
   f1->accumulate(values4);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12);
-  f1->measureAccumulate(true,values4);
+  f1->integral(true,values4);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12);
   f1->decrRef();
@@ -1265,7 +1520,7 @@ void MEDCouplingBasicsTest::testFillFromAnalytic2()
   f1->accumulate(values4);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12);
-  f1->measureAccumulate(true,values4);
+  f1->integral(true,values4);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12);
   CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12);
   f1->decrRef();
@@ -1525,6 +1780,105 @@ void MEDCouplingBasicsTest::testOperationsOnFields3()
   m->decrRef();
 }
 
+/*!
+ * Check of LINEAR_TIME and CONST_ON_TIME_INTERVAL policies
+ */
+void MEDCouplingBasicsTest::testOperationsOnFields4()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  int nbOfCells=m->getNumberOfCells();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL);
+  f1->setMesh(m);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(nbOfCells,3);
+  f1->setArray(array);
+  CPPUNIT_ASSERT_THROW(f1->setEndArray(array),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(f1->getEndArray(),INTERP_KERNEL::Exception);
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[15]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.};
+  const double arr2[15]={5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.};
+  std::copy(arr1,arr1+15,tmp);
+  f1->setStartTime(2.,0,0);
+  f1->setEndTime(3.,0,0);
+  f1->checkCoherency();
+  double res[3];
+  const double pos[2]={0.3,-0.2};
+  f1->getValueOn(pos,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12);
+  std::fill(res,res+3,0.);
+  f1->getValueOn(pos,2.2,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12);
+  std::fill(res,res+3,0.);
+  CPPUNIT_ASSERT_THROW(f1->getValueOn(pos,3.2,res),INTERP_KERNEL::Exception);
+  MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME);
+  f2->setMesh(m);
+  f2->setArray(f1->getArray());
+  f2->setStartTime(2.,3,0);
+  f2->setEndTime(4.,13,0);
+  CPPUNIT_ASSERT_THROW(f2->checkCoherency(),INTERP_KERNEL::Exception);
+  DataArrayDouble *array2=DataArrayDouble::New();
+  array2->alloc(nbOfCells,3);
+  tmp=array2->getPointer();
+  std::copy(arr2,arr2+15,tmp);
+  f2->setEndArray(array2);
+  array2->decrRef();
+  f2->checkCoherency();
+  //
+  std::fill(res,res+3,0.);
+  f2->getValueOn(pos,3.21,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(4.025,res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(14.025,res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(24.025,res[2],1.e-12);
+  MEDCouplingFieldDouble *f3=f2->clone(true);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-12));
+  f3->getEndArray()->getPointer()[0]=5.001;
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-12));
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.1,3,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,3,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,4,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,3,1);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,3,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.1,13,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,13,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,14,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,13,1);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,13,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->decrRef();
+  MEDCouplingFieldDouble *f4=(*f2)+(*f2);
+  std::fill(res,res+3,0.);
+  f4->getValueOn(pos,3.21,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(8.05,res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(28.05,res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(48.05,res[2],1.e-12);
+  (*f4)+=*f2;
+  std::fill(res,res+3,0.);
+  f4->getValueOn(pos,3.21,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(12.075,res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(42.075,res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(72.075,res[2],1.e-12);
+  f4->decrRef();
+  //
+  f2->decrRef();
+  f1->decrRef();
+  m->decrRef();
+}
+
 bool func4(const double *pt, double *res)
 {
   res[0]=pt[0]+pt[1]+pt[2];
@@ -1562,11 +1916,178 @@ void MEDCouplingBasicsTest::testCheckConsecutiveCellTypes()
   MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1();
   MEDCouplingUMesh *targetMesh=build2DTargetMesh_1();
   CPPUNIT_ASSERT(sourceMesh->checkConsecutiveCellTypes());
+  const INTERP_KERNEL::NormalizedCellType order1[]={INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4};
+  const INTERP_KERNEL::NormalizedCellType order2[]={INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI3};
   CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypes());
+  CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2));
+  CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2));
+  DataArrayInt *da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order1,order1+2);
+  CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents());
+  const int expected1[5]={2,0,1,3,4};
+  CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer()));
+  da->decrRef();
+  da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order2,order2+2);
+  CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents());
+  const int expected2[5]={0,3,4,1,2};
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+5,da->getConstPointer()));
+  da->decrRef();
+  const int renumber1[5]={4,0,1,2,3};
+  targetMesh->renumberCells(renumber1,false);
+  CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypes());
+  CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2));
+  CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2));
   targetMesh->decrRef();
   sourceMesh->decrRef();
 }
 
+void MEDCouplingBasicsTest::testRearrange2ConsecutiveCellTypes()
+{
+  MEDCouplingUMesh *m1_1=build2DSourceMesh_1();
+  MEDCouplingUMesh *m2_1=build2DTargetMesh_1();
+  DataArrayInt *arr1=m1_1->rearrange2ConsecutiveCellTypes();
+  MEDCouplingUMesh *m1_2=build2DSourceMesh_1();
+  CPPUNIT_ASSERT(m1_2->isEqual(m1_1,1e-12));
+  const int expected1[2]={0,1};
+  CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(expected1,expected1+2,arr1->getConstPointer()));
+  arr1->decrRef();
+  const int expected2[5]={0,3,4,1,2};
+  arr1=m2_1->rearrange2ConsecutiveCellTypes();
+  CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer()));
+  MEDCouplingUMesh *m2_2=build2DTargetMesh_1();
+  CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer()));
+  CPPUNIT_ASSERT(!m2_2->isEqual(m2_1,1e-12));
+  m2_2->renumberCells(expected2,false);
+  CPPUNIT_ASSERT(m2_2->isEqual(m2_1,1e-12));
+  arr1->decrRef();
+  m1_1->decrRef();
+  m1_2->decrRef();
+  m2_1->decrRef();
+  m2_2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testSplitByType()
+{
+  MEDCouplingUMesh *m1=build3DSurfTargetMesh_1();
+  std::vector<MEDCouplingUMesh *> v=m1->splitByType();
+  CPPUNIT_ASSERT_EQUAL(3,(int)v.size());
+  MEDCouplingUMesh *m2=MEDCouplingUMesh::mergeUMeshesOnSameCoords(v);
+  m2->setName(m1->getName());
+  CPPUNIT_ASSERT(m1->isEqual(m2,1.e-12));
+  for(std::vector<MEDCouplingUMesh *>::const_iterator iter=v.begin();iter!=v.end();iter++)
+    (*iter)->decrRef();
+  m2->decrRef();
+  m1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords()
+{
+  std::vector<MEDCouplingUMesh *> meshes;
+  MEDCouplingUMesh *m2=build2DTargetMesh_1();
+  int cells1[3]={2,3,4};
+  MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true);
+  MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1);
+  CPPUNIT_ASSERT(m3);
+  meshes.push_back(m3);
+  int cells2[3]={1,2,4};
+  MEDCouplingPointSet *m4_1=m2->buildPartOfMySelf(cells2,cells2+3,true);
+  MEDCouplingUMesh *m4=dynamic_cast<MEDCouplingUMesh *>(m4_1);
+  CPPUNIT_ASSERT(m4);
+  meshes.push_back(m4);
+  int cells3[2]={1,2};
+  MEDCouplingPointSet *m5_1=m2->buildPartOfMySelf(cells3,cells3+2,true);
+  MEDCouplingUMesh *m5=dynamic_cast<MEDCouplingUMesh *>(m5_1);
+  CPPUNIT_ASSERT(m5);
+  meshes.push_back(m5);
+  m2->decrRef();
+  //
+  std::vector<DataArrayInt *> corr;
+  MEDCouplingUMesh *m7=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr);
+  CPPUNIT_ASSERT_EQUAL(4,m7->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(3,(int)corr.size());
+  const int expectedVals1[3]={3,3,2};
+  const int expectedVals2[3][3]={{0,1,2},{3,0,2},{3,0,111111}};
+  for(int i=0;i<3;i++)
+    {
+      DataArrayInt *arr=corr[i];
+      CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents());
+      int nbOfVals=expectedVals1[i];
+      CPPUNIT_ASSERT_EQUAL(nbOfVals,arr->getNumberOfTuples());
+      const int *vals=arr->getConstPointer();
+      for(int j=0;j<nbOfVals;j++)
+        CPPUNIT_ASSERT_EQUAL(expectedVals2[i][j],vals[j]);
+    }
+  std::vector< std::vector<int> > fidsOfGroups;
+  DataArrayInt *arr2=DataArrayInt::makePartition(corr,m7->getNumberOfCells(),fidsOfGroups);
+  const int fidExp[4]={5,1,3,4};
+  const int fidsGrp[3][3]={{1,3,5},{3,4,5},{4,5,23344}};
+  CPPUNIT_ASSERT_EQUAL(3,(int)fidsOfGroups.size());
+  CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(fidExp,fidExp+4,arr2->getConstPointer()));
+  for(int i=0;i<3;i++)
+    {
+      int nbOfVals=expectedVals1[i];
+      CPPUNIT_ASSERT_EQUAL(nbOfVals,(int)fidsOfGroups[i].size());
+      CPPUNIT_ASSERT(std::equal(fidsOfGroups[i].begin(),fidsOfGroups[i].end(),fidsGrp[i]));
+    }
+  for(std::vector<DataArrayInt *>::iterator iter=corr.begin();iter!=corr.end();iter++)
+    (*iter)->decrRef();
+  arr2->decrRef();
+  m7->decrRef();
+  //
+  m3->decrRef();
+  m4->decrRef();
+  m5->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords2()
+{
+  MEDCouplingUMesh *m2;
+  MEDCouplingUMesh *m1=build3DExtrudedUMesh_1(m2);
+  m2->decrRef();
+  const int part1[5]={2,3,6,4,10};
+  MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part1,part1+5,true);
+  const int part2[4]={5,6,4,7};
+  MEDCouplingUMesh *m4=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part2,part2+4,true);
+  std::vector<MEDCouplingUMesh *> meshes;
+  meshes.push_back(m1);
+  meshes.push_back(m3);
+  meshes.push_back(m3);
+  meshes.push_back(m4);
+  std::vector<DataArrayInt *> corr;
+  MEDCouplingUMesh *m5=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr);
+  CPPUNIT_ASSERT_EQUAL(18,m5->getNumberOfCells());
+  std::vector<DataArrayInt *>::iterator it=corr.begin();
+  const int exp1[4]={18,5,5,4};
+  const int exp2[4][18]={
+    {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17},
+    {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
+    {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
+    {5,6,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
+  };
+  int i=0;
+  for(;it!=corr.end();it++,i++)
+    {
+      int sz=(*it)->getNumberOfTuples();
+      CPPUNIT_ASSERT_EQUAL(exp1[i],sz);
+      CPPUNIT_ASSERT(std::equal(exp2[i],exp2[i]+sz,(*it)->getConstPointer()));
+    }
+  for(it=corr.begin();it!=corr.end();it++)
+    (*it)->decrRef();
+  m5->decrRef();
+  m4->decrRef();
+  m3->decrRef();
+  m1->decrRef();
+}
+
 void MEDCouplingBasicsTest::testBuildOrthogonalField()
 {
   MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1();
@@ -1845,7 +2366,7 @@ void MEDCouplingBasicsTest::testRenumberCells()
   MEDCouplingUMesh *m2=build3DSurfTargetMesh_1();
   CPPUNIT_ASSERT(m->isEqual(m2,0));
   const int arr[5]={12,3,25,2,26};
-  m->renumberCells(arr,arr+5,true);
+  m->renumberCells(arr,true);
   CPPUNIT_ASSERT(!m->isEqual(m2,0));
   CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(0));
   CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1));
@@ -1853,7 +2374,7 @@ void MEDCouplingBasicsTest::testRenumberCells()
   CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3));
   CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(4));
   const int arr2[5]={5,-1,-5,4,8};
-  m->renumberCells(arr2,arr2+5,true);
+  m->renumberCells(arr2,true);
   CPPUNIT_ASSERT(m->isEqual(m2,0));
   m->decrRef();
   m2->decrRef();
diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx
new file mode 100644 (file)
index 0000000..0c36bdb
--- /dev/null
@@ -0,0 +1,3007 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MEDCouplingBasicsTest.hxx"
+#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingCMesh.hxx"
+#include "MEDCouplingExtrudedMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingGaussLocalization.hxx"
+
+#include <cmath>
+#include <functional>
+#include <iterator>
+
+using namespace ParaMEDMEM;
+
+void MEDCouplingBasicsTest::testGaussPointField1()
+{
+  const double _a=0.446948490915965;
+  const double _b=0.091576213509771;
+  const double _p1=0.11169079483905;
+  const double _p2=0.0549758718227661;
+  const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. };
+  const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b,
+                            2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 };
+  const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 };
+  std::vector<double> _refCoo1(refCoo1,refCoo1+6);
+  std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12);
+  std::vector<double> _wg1(wg1,wg1+6);
+  //
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME);
+  f->setMesh(m);
+  CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization());
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+  CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo1,_gsCoo1,_wg1),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization());
+  const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. };
+  std::vector<double> _refCoo2(refCoo2,refCoo2+8);
+  _gsCoo1.resize(4); _wg1.resize(2);
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1);
+  CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization());
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(18,2);
+  double *ptr=array->getPointer();
+  for(int i=0;i<18*2;i++)
+    ptr[i]=(double)(i+1);
+  f->setArray(array);
+  f->setName("MyFirstFieldOnGaussPoint");
+  array->decrRef();
+  f->checkCoherency();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(27.,f->getIJK(2,5,0),1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(16.,f->getIJK(1,5,1),1e-14);
+  //
+  f->clearGaussLocalizations();
+  CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization());
+  CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);
+  int ids1[4]={0,1,3,4};
+  CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnCells(ids1,ids1+4,_refCoo2,_gsCoo1,_wg1),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization());
+  int ids2[2]={0,4};
+  f->setGaussLocalizationOnCells(ids2,ids2+2,_refCoo2,_gsCoo1,_wg1);
+  CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization());
+  CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0));
+  CPPUNIT_ASSERT_THROW(f->getGaussLocalizationIdOfOneCell(1),INTERP_KERNEL::Exception);
+  int ids3[2]={1,2};
+  f->setGaussLocalizationOnCells(ids3,ids3+2,_refCoo1,_gsCoo1,_wg1);
+  CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization());
+  CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0));
+  CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(1));
+  CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(2));
+  CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- cell 3 has no localization
+  int ids4[1]={3};
+  std::vector<double> _gsCoo2(_gsCoo1);
+  std::vector<double> _wg2(_wg1);
+  _gsCoo2[0]=0.8888777776666; _wg2[0]=0.1234567892377;
+  f->setGaussLocalizationOnCells(ids4,ids4+1,_refCoo2,_gsCoo2,_wg2);
+  CPPUNIT_ASSERT_EQUAL(3,f->getNbOfGaussLocalization());
+  std::vector<int> tmpIds;
+  f->getCellIdsHavingGaussLocalization(0,tmpIds);
+  CPPUNIT_ASSERT_EQUAL(2,(int)tmpIds.size());
+  CPPUNIT_ASSERT(std::equal(ids2,ids2+2,tmpIds.begin()));
+  CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- it's always not ok because undelying array not with the good size.
+  DataArrayDouble *array2=f->getArray()->substr(0,10);
+  f->setArray(array2);
+  array2->decrRef();
+  f->checkCoherency();//<- here it is OK
+  MEDCouplingFieldDouble *f2=f->clone(true);
+  CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14));
+  MEDCouplingGaussLocalization& gl1=f2->getGaussLocalization(0);
+  double tmp=gl1.getGaussCoord(1,1);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.07*_b-1,tmp,1e-14);
+  gl1.setGaussCoord(1,1,0.07);
+  CPPUNIT_ASSERT(!f->isEqual(f2,1e-14,1e-14));
+  gl1.setGaussCoord(1,1,tmp);
+  CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14));
+  f->decrRef();
+  f2->checkCoherency();
+  //
+  f2->decrRef();
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testGaussPointNEField1()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME);
+  f->setMesh(m);
+  f->setName("MyFirstFieldOnNE");
+  f->setDescription("MyDescriptionNE");
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(18,2);
+  double *ptr=array->getPointer();
+  for(int i=0;i<18*2;i++)
+    ptr[i]=(double)(i+7);
+  f->setArray(array);
+  array->decrRef();
+  //
+  f->checkCoherency();
+  MEDCouplingFieldDouble *f2=f->clone(true);
+  CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14));
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,f->getIJK(2,0,0),1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,f->getIJK(1,1,1),1e-14);
+  f2->decrRef();
+  //
+  f->decrRef();
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testCellOrientation1()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  double vec[3]={0.,0.,1.};
+  std::vector<int> res1;
+  CPPUNIT_ASSERT_THROW(m->are2DCellsNotCorrectlyOriented(vec,false,res1),INTERP_KERNEL::Exception);
+  m->changeSpaceDimension(3);
+  res1.clear();
+  m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+  CPPUNIT_ASSERT(res1.empty());
+  vec[2]=-1;
+  m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+  CPPUNIT_ASSERT_EQUAL(5,(int)res1.size());
+  res1.clear();
+  //
+  vec[2]=1.;
+  // connectivity inversion
+  int *conn=m->getNodalConnectivity()->getPointer();
+  int tmp=conn[11];
+  conn[11]=conn[12];
+  conn[12]=tmp;
+  m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+  CPPUNIT_ASSERT_EQUAL(1,(int)res1.size());
+  CPPUNIT_ASSERT_EQUAL(2,res1[0]);
+  res1.clear();
+  m->orientCorrectly2DCells(vec,false);
+  m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+  CPPUNIT_ASSERT(res1.empty());
+  MEDCouplingUMesh *m2=build2DTargetMesh_1();
+  m2->changeSpaceDimension(3);
+  CPPUNIT_ASSERT(m->isEqual(m2,1e-12));
+  m2->decrRef();
+  //
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testCellOrientation2()
+{
+  MEDCouplingUMesh *m1=0;
+  MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1);
+  m1->decrRef();
+  std::vector<int> res1;
+  m2->arePolyhedronsNotCorrectlyOriented(res1);
+  CPPUNIT_ASSERT_EQUAL(6,(int)res1.size());
+  m2->orientCorrectlyPolyhedrons();
+  res1.clear();
+  m2->arePolyhedronsNotCorrectlyOriented(res1);
+  CPPUNIT_ASSERT(res1.empty());
+  m2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells());
+  int cellIds[3]={0,6,12};
+  std::vector<int> cellIds2(cellIds,cellIds+3);
+  m2->convertToPolyTypes(cellIds2);
+  m2->orientCorrectlyPolyhedrons();
+  res1.clear();
+  m2->arePolyhedronsNotCorrectlyOriented(res1);
+  CPPUNIT_ASSERT(res1.empty());
+  MEDCouplingFieldDouble *f2=m2->getMeasureField(false);
+  //Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation
+  MEDCouplingUMesh *m3=build2DTargetMesh_1();
+  double vec[3]={0.,0.,-1.};//<- important for the test
+  m3->changeSpaceDimension(3);
+  const int ids1[5]={0,1,2,3,4};
+  std::vector<int> ids2(ids1,ids1+5);
+  m3->convertToPolyTypes(ids2);
+  m3->orientCorrectly2DCells(vec,false);
+  MEDCouplingUMesh *m4=buildCU1DMesh_U();
+  m4->changeSpaceDimension(3);
+  double center[3]={0.,0.,0.};
+  double vector[3]={0.,1.,0.};
+  m4->rotate(center,vector,-M_PI/2.);
+  MEDCouplingUMesh *m5=m3->buildExtrudedMeshFromThis(m4,0);
+  res1.clear();
+  m5->arePolyhedronsNotCorrectlyOriented(res1);
+  CPPUNIT_ASSERT_EQUAL(15,(int)res1.size());
+  m5->orientCorrectlyPolyhedrons();
+  res1.clear();
+  m5->arePolyhedronsNotCorrectlyOriented(res1);
+  CPPUNIT_ASSERT(res1.empty());
+  MEDCouplingFieldDouble *f3=m5->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(15,f3->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents());
+  const double *f3Ptr=f3->getArray()->getConstPointer();
+  const double expected1[15]={
+    0.075,0.0375,0.0375,0.075,0.075,
+    0.1125,0.05625,0.05625,0.1125,0.1125,
+    0.0625,0.03125,0.03125,0.0625,0.0625
+  };
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),f3Ptr[i],1e-12);
+  f3->decrRef();
+  DataArrayDouble *f4=m5->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(15,f4->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,f4->getNumberOfComponents());
+  const double *f4Ptr=f4->getConstPointer();
+  const double expected2[45]={
+    -0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15,
+    -0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525,
+    -0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875
+  };
+  for(int i=0;i<45;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4Ptr[i],1e-12);
+  f4->decrRef();
+  m5->decrRef();
+  m3->decrRef();
+  m4->decrRef();
+  //
+  f2->decrRef();
+  m2->decrRef();
+}
+
+/*!
+ * This test check polyhedron true barycenter computation. 
+ */
+void MEDCouplingBasicsTest::testPolyhedronBarycenter()
+{
+  int connN[]={0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0};
+  double coords[]={0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5};
+  MEDCouplingUMesh *meshN=MEDCouplingUMesh::New();
+  meshN->setName("ForBary");
+  meshN->setMeshDimension(3);
+  meshN->allocateCells(4);
+  meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,29,connN);
+  meshN->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(9,3);
+  std::copy(coords,coords+27,myCoords->getPointer());
+  meshN->setCoords(myCoords);
+  myCoords->decrRef();
+  meshN->checkCoherency();
+  //
+  std::vector<int> res1;
+  meshN->arePolyhedronsNotCorrectlyOriented(res1);
+  meshN->orientCorrectlyPolyhedrons();
+  CPPUNIT_ASSERT(res1.empty());
+  const double *ref,*daPtr;
+  DataArrayDouble *da=meshN->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents());
+  daPtr=da->getConstPointer();
+  ref=meshN->getCoords()->getConstPointer()+24;
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12);
+  da->decrRef();
+  //
+  const double center[]={0.,0.,0.};
+  const double vec[]={0.,2.78,0.};
+  da=meshN->getBarycenterAndOwner();
+  daPtr=da->getConstPointer();
+  ref=meshN->getCoords()->getConstPointer()+24;
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12);
+  da->decrRef();
+  //
+  meshN->rotate(center,vec,M_PI/7.);
+  meshN->translate(vec);
+  da=meshN->getBarycenterAndOwner();
+  daPtr=da->getConstPointer();
+  ref=meshN->getCoords()->getConstPointer()+24;
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12);
+  da->decrRef();
+  //
+  const double center2[]={1.12,3.45,6.78};
+  const double vec2[]={4.5,9.3,2.8};
+  meshN->rotate(center2,vec2,M_E);
+  meshN->translate(vec2);
+  da=meshN->getBarycenterAndOwner();
+  daPtr=da->getConstPointer();
+  ref=meshN->getCoords()->getConstPointer()+24;
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-10);
+  da->decrRef();
+  //
+  meshN->decrRef();
+}
+
+void MEDCouplingBasicsTest::testNormL12Integ1D()
+{
+  MEDCouplingUMesh *m1=build1DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(m1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(m1->getNumberOfCells(),3);
+  const double arr[12]={-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72};
+  std::copy(arr,arr+12,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  const double *ptr;
+  DataArrayDouble *f3=m1->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents());
+  double expected9[4]={0.75,5.105,0.8,5.155};
+  ptr=f3->getConstPointer();
+   for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],ptr[i],1e-12);
+  f3->decrRef();
+  //
+  MEDCouplingFieldDouble *f2=m1->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  double expected1[4]={0.5,0.21,-0.6,-0.31};
+  ptr=f2->getArray()->getConstPointer();
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12);
+  f2->decrRef();
+  double expected2[4]={0.5,0.21,0.6,0.31};
+  f2=m1->getMeasureField(true);
+  ptr=f2->getArray()->getConstPointer();
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12);
+  f2->decrRef();
+  //integral
+  double res[3];
+  f1->integral(false,res);
+  double expected3[3]={0.9866,-0.3615,0.4217};
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f1->integral(0,false),1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f1->integral(1,false),1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f1->integral(2,false),1e-12);
+  f1->integral(true,res);
+  double expected4[3]={-3.4152,8.7639,-14.6879};
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],res[i],1e-12);
+  //normL1
+  f1->normL1(res);
+  double expected5[3]={11.3068,27.3621,43.7881};
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[0],f1->normL1(0),1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[1],f1->normL1(1),1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[2],f1->normL1(2),1e-12);
+  //normL2
+  f1->normL2(res);
+  double expected7[3]={9.0252562290496776, 21.545259176904789, 34.433193070059595};
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[0],f1->normL2(0),1e-9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[1],f1->normL2(1),1e-9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[2],f1->normL2(2),1e-9);
+  //buildMeasureField
+  MEDCouplingFieldDouble *f4=f1->buildMeasureField(false);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2,f4->accumulate(0),1e-12);
+  f4->decrRef();
+  f4=f1->buildMeasureField(true);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.62,f4->accumulate(0),1e-12);
+  f4->decrRef();
+  //
+  f1->decrRef();
+  m1->decrRef();
+  // Testing with 2D Curve
+  m1=build2DCurveTargetMesh_3();
+  f2=m1->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  ptr=f2->getArray()->getConstPointer();
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected2[i],ptr[i],1e-12);
+  f2->decrRef();
+  f2=m1->getMeasureField(true);
+  CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  ptr=f2->getArray()->getConstPointer();
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i]*sqrt(2.),ptr[i],1e-12);
+  f2->decrRef();
+  //bary
+  f3=m1->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f3->getNumberOfComponents());
+  double expected10[8]={0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155};
+  ptr=f3->getConstPointer();
+   for(int i=0;i<8;i++)
+     CPPUNIT_ASSERT_DOUBLES_EQUAL(expected10[i],ptr[i],1e-12);
+  f3->decrRef();
+  //
+  f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(m1);
+  array=DataArrayDouble::New();
+  array->alloc(m1->getNumberOfCells(),3);
+  std::copy(arr,arr+12,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->integral(false,res);
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12);
+  f1->integral(true,res);
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12);
+  f1->normL1(res);
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected5[i],res[i],1e-12);
+  f1->normL2(res);
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(sqrt(2.))*expected7[i],res[i],1e-12);
+  //
+  f1->decrRef();
+  m1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testAreaBary2D()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=m1->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  double expected1[10]={-0.5,-1,-1.5,-0.5,-1,  0.5,1,1.5,0.5,1};
+  const double *ptr=f1->getArray()->getConstPointer();
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12);
+  f1->decrRef();
+  f1=m1->getMeasureField(true);
+  ptr=f1->getArray()->getConstPointer();
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12);
+  f1->decrRef();
+  DataArrayDouble *f2=m1->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents());
+  double expected2[20]={
+    0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5,
+    0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5,
+  };
+  ptr=f2->getConstPointer();
+  for(int i=0;i<20;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12);
+  f2->decrRef();
+  m1->changeSpaceDimension(3);
+  f1=m1->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  ptr=f1->getArray()->getConstPointer();
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12);
+  f1->decrRef();
+  f2=m1->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents());
+  ptr=f2->getConstPointer();
+  double expected3[30]={
+    0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0.,
+    0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0.
+  };
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12);
+  f2->decrRef();
+  m1->decrRef();
+}
+
+/*!
+ * This test check polyhedron true barycenter computation 2. 
+ */
+void MEDCouplingBasicsTest::testAreaBary3D()
+{
+  double coords [] = { 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 ,
+                       0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 ,
+                       0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 ,
+                       0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 ,
+                       -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 ,
+                       -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 ,
+                       0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 ,
+                       0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 ,
+                       -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 ,
+                       0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 ,
+                       -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 ,
+                       -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 ,
+                       -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 ,
+                       -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 ,
+                       -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 ,
+                       -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 ,
+                       0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 ,
+                       0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 ,
+                       0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 ,
+                       -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 ,
+                       -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 ,
+                       -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 ,
+                       -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 ,
+                       0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 ,
+                       0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 ,
+                       0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 ,
+                       -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 ,
+                       -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 ,
+                       0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 ,
+                       0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 ,
+                       -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 ,
+                       0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 ,
+                       0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 ,
+                       0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 ,
+                       -0.0372812069535 , -0.286740286332 , 0.00963701291166 };
+
+  int connN [] = { /*polyhedron 0*/
+    0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1
+    , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1
+    , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1
+    , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28,
+    /* polyhedron 1*/
+    0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1
+    , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1
+    , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1
+    , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50,
+    /* polyhedron 2*/
+    6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1
+    , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40,
+    /*polyhedron 3*/
+    35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1
+    , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1
+    , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1
+    , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65};
+
+  double barys[]={ -0.0165220465527 , -0.0190922868195 , 0.158882733414 ,
+                   0.0287618656076 , 0.135874379934 , -0.14601588119 ,
+                   -0.147128055553 , 0.0465995097041 , -0.049391174453 ,
+                   -0.00142506732317 , -0.0996953090351 , -0.115159183132 };
+  MEDCouplingUMesh *meshN=MEDCouplingUMesh::New();
+  meshN->setName("ForBary");
+  meshN->setMeshDimension(3);
+  meshN->allocateCells(4);
+  meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,113,connN);
+  meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,99,connN+113);
+  meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,connN+212);
+  meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,92,connN+255);
+  meshN->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(69,3);
+  std::copy(coords,coords+207,myCoords->getPointer());
+  meshN->setCoords(myCoords);
+  myCoords->decrRef();
+  meshN->checkCoherency();
+  std::vector<int> res1;
+  meshN->arePolyhedronsNotCorrectlyOriented(res1);
+  meshN->orientCorrectlyPolyhedrons();
+  res1.clear();
+  meshN->arePolyhedronsNotCorrectlyOriented(res1);
+  CPPUNIT_ASSERT(res1.empty());
+  //
+  DataArrayDouble *da=meshN->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents());
+  const double *daPtr=da->getConstPointer();
+  for(int i=0;i<12;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(barys[i],daPtr[i],1e-12);
+  da->decrRef();
+  //
+  meshN->decrRef();
+}
+
+void MEDCouplingBasicsTest::testRenumberCellsForFields()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f->setMesh(m);
+  DataArrayDouble *arr=DataArrayDouble::New();
+  int nbOfCells=m->getNumberOfCells();
+  arr->alloc(nbOfCells,3);
+  f->setArray(arr);
+  arr->decrRef();
+  const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.};
+  std::copy(values1,values1+15,arr->getPointer());
+  const int renumber1[5]={3,1,0,4,2};
+  double res[3];
+  const double loc[]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45};
+  for(int j=0;j<5;j++)
+    {
+      f->getValueOn(loc+2*j,res);
+      for(int i=0;i<3;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12);
+    }
+  f->renumberCells(renumber1,false);
+  const double *ptr=f->getArray()->getConstPointer();
+  const double expected1[15]={9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.};
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12);
+  //check that fields remains the same geometrically
+  for(int j=0;j<5;j++)
+    {
+      f->getValueOn(loc+2*j,res);
+      for(int i=0;i<3;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12);
+    }
+  f->decrRef();
+  //On gauss
+  f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME);
+  f->setMesh(m);
+  const double _a=0.446948490915965;
+  const double _b=0.091576213509771;
+  const double _p1=0.11169079483905;
+  const double _p2=0.0549758718227661;
+  const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. };
+  const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b,
+                            2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 };
+  const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 };
+  std::vector<double> _refCoo1(refCoo1,refCoo1+6);
+  std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12);
+  std::vector<double> _wg1(wg1,wg1+6);
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+  const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. };
+  std::vector<double> _refCoo2(refCoo2,refCoo2+8);
+  _gsCoo1.resize(4); _wg1.resize(2);
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1);
+  arr=DataArrayDouble::New();
+  arr->alloc(18,2);
+  const double values2[36]={1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.};
+  std::copy(values2,values2+36,arr->getPointer());
+  f->setArray(arr);
+  arr->decrRef();
+  f->checkCoherency();
+  MEDCouplingFieldDouble *fCpy=f->clone(true);
+  CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12));
+  f->renumberCells(renumber1,false);
+  CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12));
+  double expected2[36]={21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.};
+  ptr=f->getArray()->getConstPointer();
+  for(int i=0;i<36;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12);
+  const int renumber2[5]={2,1,4,0,3};//reverse renumber1
+  f->renumberCells(renumber2,false);
+  CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12));
+  fCpy->decrRef();
+  f->decrRef();
+  //GaussNE
+  f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME);
+  f->setMesh(m);
+  arr=DataArrayDouble::New();
+  arr->alloc(18,2);
+  const double values3[36]={1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.};
+  std::copy(values3,values3+36,arr->getPointer());
+  f->setArray(arr);
+  arr->decrRef();
+  f->checkCoherency();
+  fCpy=f->clone(true);
+  CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12));
+  f->renumberCells(renumber1,false);
+  CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12));
+  double expected3[36]={21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.};
+  ptr=f->getArray()->getConstPointer();
+  for(int i=0;i<36;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12);
+  f->renumberCells(renumber2,false);//perform reverse operation of renumbering to check that the resulting field is equal.
+  CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12));
+  fCpy->decrRef();
+  f->decrRef();
+  //
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testRenumberNodesForFields()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME);
+  f->setMesh(m);
+  DataArrayDouble *arr=DataArrayDouble::New();
+  int nbOfNodes=m->getNumberOfNodes();
+  arr->alloc(nbOfNodes,3);
+  f->setArray(arr);
+  arr->decrRef();
+  const double values1[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.};
+  std::copy(values1,values1+27,arr->getPointer());
+  f->checkCoherency();
+  const int renumber1[9]={0,4,1,3,5,2,6,7,8};
+  double res[3];
+  const double loc[]={0.5432,-0.2432, 0.5478,0.1528};
+  const double expected1[6]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124};
+  for(int j=0;j<2;j++)
+    {
+      f->getValueOn(loc+2*j,res);
+      for(int i=0;i<3;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12);
+    }
+  MEDCouplingFieldDouble *fCpy=f->clone(true);
+  CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12));
+  f->renumberNodes(renumber1);
+  CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12));
+  for(int j=0;j<2;j++)
+    {
+      f->getValueOn(loc+2*j,res);
+      for(int i=0;i<3;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12);
+    }
+  const double expected2[27]={7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.};
+  for(int i=0;i<27;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getArray()->getConstPointer()[i],1e-12);
+  const int renumber2[9]={0,2,5,3,1,4,6,7,8};//reverse of renumber2
+  f->renumberNodes(renumber2);
+  CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12));
+  fCpy->decrRef();
+  //
+  m->decrRef();
+  f->decrRef();
+}
+
+void MEDCouplingBasicsTest::testConvertQuadraticCellsToLinear()
+{
+  MEDCouplingUMesh *mesh=build2DTargetMesh_3();
+  mesh->checkCoherency();
+  const std::set<INTERP_KERNEL::NormalizedCellType>& types=mesh->getAllTypes();
+  CPPUNIT_ASSERT_EQUAL(5,(int)types.size());
+  INTERP_KERNEL::NormalizedCellType expected1[5]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QUAD8};
+  std::set<INTERP_KERNEL::NormalizedCellType> expected1Bis(expected1,expected1+5);
+  CPPUNIT_ASSERT(expected1Bis==types);
+  CPPUNIT_ASSERT(mesh->isPresenceOfQuadratic());
+  CPPUNIT_ASSERT_EQUAL(62,mesh->getMeshLength());
+  MEDCouplingFieldDouble *f1=mesh->getMeasureField(false);
+  //
+  mesh->convertQuadraticCellsToLinear();
+  CPPUNIT_ASSERT(!mesh->isPresenceOfQuadratic());
+  //
+  mesh->checkCoherency();
+  MEDCouplingFieldDouble *f2=mesh->getMeasureField(false);
+  CPPUNIT_ASSERT(f1->getArray()->isEqual(*f2->getArray(),1e-12));
+  CPPUNIT_ASSERT_EQUAL(48,mesh->getMeshLength());
+  const std::set<INTERP_KERNEL::NormalizedCellType>& types2=mesh->getAllTypes();
+  CPPUNIT_ASSERT_EQUAL(3,(int)types.size());
+  INTERP_KERNEL::NormalizedCellType expected2[3]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4};
+  std::set<INTERP_KERNEL::NormalizedCellType> expected2Bis(expected2,expected2+3);
+  CPPUNIT_ASSERT(expected2Bis==types2);
+  //
+  f1->decrRef();
+  f2->decrRef();
+  mesh->decrRef();
+}
+
+void MEDCouplingBasicsTest::testCheckGeoEquivalWith()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_3();
+  MEDCouplingUMesh *mesh2=build2DTargetMesh_3();
+  DataArrayInt *cellCor,*nodeCor;
+  //First test mesh1
+  mesh1->checkGeoEquivalWith(mesh1,0,1e-12,cellCor,nodeCor);//deepEqual
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh1,1,1e-12,cellCor,nodeCor);//fastEqual
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  //Second test mesh1 and mesh2 are 2 different meshes instance
+  mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  //Third test : cell permutation by keeping the first the middle and the last as it is.
+  const int renum[]={0,2,1,3,4,5,6,8,7,9};
+  mesh2->renumberCells(renum,false);
+  CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations
+  CPPUNIT_ASSERT(cellCor);
+  CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer()));
+  CPPUNIT_ASSERT(nodeCor==0);
+  cellCor->decrRef();
+  cellCor=0;
+  CPPUNIT_ASSERT(nodeCor==0);
+  //4th test : cell and node permutation by keeping the first the middle and the last as it is.
+  mesh2->decrRef();
+  mesh2=build2DTargetMesh_3();
+  const int renum2[]={0,2,1,3,4,5,6,8,7,9,10};
+  mesh2->renumberCells(renum,false);
+  mesh2->renumberNodes(renum2,11);
+  CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations
+  CPPUNIT_ASSERT(cellCor);
+  CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer()));
+  CPPUNIT_ASSERT(nodeCor);
+  CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer()));
+  cellCor->decrRef();
+  cellCor=0;
+  nodeCor->decrRef();
+  nodeCor=0;
+  //5th test : modification of the last cell to check fastCheck detection.
+  mesh2->decrRef();
+  mesh2=build2DTargetMesh_3();
+  const int renum3[]={0,2,1,3,4,5,6,8,9,7};
+  mesh2->renumberCells(renum3,false);
+  mesh2->renumberNodes(renum2,11);
+  bool isExcep=false;
+  try { mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual fails
+  }
+  catch(INTERP_KERNEL::Exception& e) { isExcep=true; }
+  CPPUNIT_ASSERT(isExcep); isExcep=false;
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  try { mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual has detected something
+  }
+  catch(INTERP_KERNEL::Exception& e) { isExcep=true; }
+  CPPUNIT_ASSERT(isExcep); isExcep=false;
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor==0);
+  mesh2->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations
+  CPPUNIT_ASSERT(cellCor);
+  CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(renum3,renum3+10,cellCor->getConstPointer()));
+  CPPUNIT_ASSERT(nodeCor);
+  CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer()));
+  cellCor->decrRef();
+  cellCor=0;
+  nodeCor->decrRef();
+  nodeCor=0;
+  //
+  mesh1->decrRef();
+  mesh2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testCheckGeoEquivalWith2()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_4();
+  MEDCouplingUMesh *mesh2=build2DTargetMesh_1();
+  DataArrayInt *cellCor,*nodeCor;
+  mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);
+  CPPUNIT_ASSERT(cellCor==0);
+  CPPUNIT_ASSERT(nodeCor!=0);
+  const int expected1[9]={0, 1, 3, 4, 5, 6, 7, 8, 9};
+  for(int i=0;i<9;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],nodeCor->getIJ(i,0));
+  nodeCor->decrRef();
+  //
+  mesh1->decrRef();
+  mesh2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testCopyTinyStringsFromOnFields()
+{
+  MEDCouplingUMesh *m=build3DSurfTargetMesh_1();
+  int nbOfCells=m->getNumberOfCells();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME);
+  f->setMesh(m);
+  f->setName("a");
+  f->setDescription("b");
+  DataArrayDouble *a1=DataArrayDouble::New();
+  a1->alloc(nbOfCells,2);
+  a1->fillWithZero();
+  a1->setInfoOnComponent(0,"c");
+  a1->setInfoOnComponent(1,"d");
+  DataArrayDouble *a2=a1->deepCopy();
+  a2->setInfoOnComponent(0,"e");
+  a2->setInfoOnComponent(1,"f");
+  f->setArray(a1);
+  f->setEndArray(a2);
+  f->setEndTime(3.,3,4);
+  a2->decrRef();
+  a1->decrRef();
+  m->setName("g");
+  m->getCoords()->setInfoOnComponent(0,"h");
+  m->getCoords()->setInfoOnComponent(1,"i");
+  m->getCoords()->setInfoOnComponent(2,"j");
+  //
+  f->checkCoherency();
+  MEDCouplingFieldDouble *f2=f->clone(true);
+  CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12));
+  f2->setName("smth");
+  CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12));
+  f2->copyTinyStringsFrom(f);
+  CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12));
+  f2->setDescription("GGG");
+  CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12));
+  f2->copyTinyStringsFrom(f);
+  CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12));
+  f2->getArray()->setInfoOnComponent(0,"mmmm");
+  CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12));
+  f2->copyTinyStringsFrom(f);
+  CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12));
+  f2->getEndArray()->setInfoOnComponent(1,"mmmm");
+  CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12));
+  f2->copyTinyStringsFrom(f);
+  CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12));
+  f2->decrRef();
+  MEDCouplingUMesh *m2=m->clone(true);
+  CPPUNIT_ASSERT(m2->isEqual(m,1e-12));
+  m2->setName("123");
+  CPPUNIT_ASSERT(!m2->isEqual(m,1e-12));
+  m2->copyTinyStringsFrom(m);
+  CPPUNIT_ASSERT(m2->isEqual(m,1e-12));
+  m2->getCoords()->setInfoOnComponent(1,"eee");
+  CPPUNIT_ASSERT(!m2->isEqual(m,1e-12));
+  m2->copyTinyStringsFrom(m);
+  CPPUNIT_ASSERT(m2->isEqual(m,1e-12));
+  m2->decrRef();
+  //
+  f->decrRef();
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testTryToShareSameCoordsPermute()
+{
+  MEDCouplingUMesh *m=build3DSurfTargetMesh_1();
+  MEDCouplingUMesh *m2=build3DSurfTargetMesh_1();
+  CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords());
+  m->tryToShareSameCoordsPermute(*m2,1e-12);
+  CPPUNIT_ASSERT(m->getCoords()==m2->getCoords());
+  CPPUNIT_ASSERT(m2->isEqual(m,1e-12));
+  const int renum1[9]={1,2,0,5,8,7,4,3,6};
+  m->renumberNodes(renum1,9);
+  CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords());
+  CPPUNIT_ASSERT(!m2->isEqual(m,1e-12));
+  m->tryToShareSameCoordsPermute(*m2,1e-12);
+  CPPUNIT_ASSERT(m->getCoords()==m2->getCoords());
+  CPPUNIT_ASSERT(m2->isEqual(m,1e-12));
+  m2->decrRef();
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testTryToShareSameCoordsPermute2()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_4();
+  double targetCoords[8]={-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 };
+  int targetConn[4]={0,2,3,1};
+  MEDCouplingUMesh *m2=MEDCouplingUMesh::New();
+  m2->setMeshDimension(2);
+  m2->allocateCells(1);
+  m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn);
+  m2->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(4,2);
+  std::copy(targetCoords,targetCoords+8,myCoords->getPointer());
+  m2->setCoords(myCoords);
+  myCoords->decrRef();
+  m2->checkCoherency();
+  m1->checkCoherency();
+  //
+  const double expected1[5]={0.25,0.125,0.125,0.25,0.25};
+  MEDCouplingFieldDouble *f1=m1->getMeasureField(false);
+  MEDCouplingFieldDouble *f2=m2->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12);
+  f2->decrRef();
+  f1->decrRef();
+  CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoordsPermute(*m2,1e-12),INTERP_KERNEL::Exception);// <- here in this order the sharing is impossible.
+  // Let's go for deeper test of tryToShareSameCoordsPermute
+  m2->tryToShareSameCoordsPermute(*m1,1e-12);
+  f1=m1->getMeasureField(false);
+  f2=m2->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12);
+  //
+  f2->decrRef();
+  f1->decrRef();
+  //
+  m1->decrRef();
+  m2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testChangeUnderlyingMesh1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_3();
+  MEDCouplingUMesh *mesh2=build2DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),2);
+  const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.};
+  std::copy(arr,arr+20,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  const int renum[]={0,2,1,3,4,5,6,8,7,9};
+  mesh2->renumberCells(renum,false);
+  CPPUNIT_ASSERT(f1->getMesh()==mesh1);
+  f1->changeUnderlyingMesh(mesh1,10,1e-12);// nothing done only to check that nothing done.
+  CPPUNIT_ASSERT(f1->getMesh()==mesh1);
+  f1->changeUnderlyingMesh(mesh2,10,1e-12);
+  CPPUNIT_ASSERT(f1->getMesh()==mesh2);
+  const double expected1[20]={7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.};
+  for(int i=0;i<20;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12);
+  f1->decrRef();
+  //
+  f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME);
+  f1->setMesh(mesh1);
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfNodes(),2);
+  const double arr2[22]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.};
+  std::copy(arr2,arr2+22,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  const int renum2[]={0,2,10,3,4,5,6,8,7,9,1};
+  mesh2->renumberNodes(renum2,11);
+  CPPUNIT_ASSERT(f1->getMesh()==mesh1);
+  f1->changeUnderlyingMesh(mesh2,10,1e-12);
+  CPPUNIT_ASSERT(f1->getMesh()==mesh2);
+  const double expected2[22]={7.,107.,9.,109.,17.,117.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,8.,108.};
+  for(int i=0;i<22;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getArray()->getIJ(0,i),1e-12);
+  f1->decrRef();
+  //
+  mesh1->decrRef();
+  mesh2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testGetMaxValue1()
+{
+  MEDCouplingUMesh *m=build3DSurfTargetMesh_1();
+  int nbOfCells=m->getNumberOfCells();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME);
+  f->setMesh(m);
+  DataArrayDouble *a1=DataArrayDouble::New();
+  a1->alloc(nbOfCells,1);
+  const double val1[5]={3.,4.,5.,6.,7.};
+  std::copy(val1,val1+5,a1->getPointer());
+  DataArrayDouble *a2=DataArrayDouble::New();
+  a2->alloc(nbOfCells,1);
+  const double val2[5]={0.,1.,2.,8.,7.};
+  std::copy(val2,val2+5,a2->getPointer());
+  f->setArray(a1);
+  f->setEndArray(a2);
+  f->setEndTime(3.,3,4);
+  f->checkCoherency();
+  //
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,f->getMaxValue(),1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,f->getAverageValue(),1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(5.125,f->getWeightedAverageValue(),1e-14);
+  a1->setIJ(0,2,9.5);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14);
+  a2->setIJ(0,0,9.);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,f->getMinValue(),1e-14);
+  //
+  a2->decrRef();
+  a1->decrRef();
+  m->decrRef();
+  f->decrRef();
+}
+
+void MEDCouplingBasicsTest::testSubstractInPlaceDM1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_3();
+  MEDCouplingUMesh *mesh2=build2DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),2);
+  const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.};
+  std::copy(arr,arr+20,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  CPPUNIT_ASSERT_EQUAL(10,f1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(20,f1->getNumberOfValues());
+  //
+  const int renum[]={0,2,1,3,4,5,6,8,7,9};
+  mesh2->renumberCells(renum,false);
+  //
+  MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f2->setMesh(mesh2);
+  array=DataArrayDouble::New();
+  array->alloc(mesh2->getNumberOfCells(),2);
+  const double arr2[20]={7.1,107.1,9.1,109.1,8.1,108.1,10.1,110.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1};
+  std::copy(arr2,arr2+20,array->getPointer());
+  f2->setArray(array);
+  array->decrRef();
+  //
+  f1->substractInPlaceDM(f2,10,1e-12);
+  f1->applyFunc(1,"abs(x+y+0.2)");
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f1->getMaxValue(),1e-14);
+  //
+  f1->decrRef();
+  f2->decrRef();
+  mesh1->decrRef();
+  mesh2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDotCrossProduct1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setTime(2.3,5,6);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),3);
+  const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.};
+  std::copy(arr1,arr1+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f2->setTime(7.8,4,5);
+  f2->setMesh(mesh1);
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),3);
+  const double arr2[30]={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.};
+  std::copy(arr2,arr2+30,array->getPointer());
+  f2->setArray(array);
+  array->decrRef();
+  //
+  MEDCouplingFieldDouble *f3=f1->dot(*f2);
+  const double expected1[10]={842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.};
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(i,0),1e-9);
+  f3->decrRef();
+  //
+  MEDCouplingFieldDouble *f4=f1->crossProduct(*f2);
+  const double expected2[30]={-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9);
+  f4->decrRef();
+  //
+  f2->decrRef();
+  f1->decrRef();
+  mesh1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testMinMaxFields1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setTime(2.3,5,6);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),3);
+  const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.};
+  std::copy(arr1,arr1+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f2->setTime(7.8,4,5);
+  f2->setMesh(mesh1);
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),3);
+  const double arr2[30]={6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.};
+  std::copy(arr2,arr2+30,array->getPointer());
+  f2->setArray(array);
+  array->decrRef();
+  //
+  MEDCouplingFieldDouble *f3=f1->max(*f2);
+  const double expected1[30]={7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-9);
+  f3->decrRef();
+  //
+  MEDCouplingFieldDouble *f4=f1->min(*f2);
+  const double expected2[30]={6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9);
+  f4->decrRef();
+  //
+  f2->decrRef();
+  f1->decrRef();
+  mesh1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testApplyLin1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),2);
+  const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.};
+  std::copy(arr,arr+20,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  f1->applyLin(2.,3.,0);
+  const double expected1[20]={17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.};
+  for(int i=0;i<20;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-9);
+  //
+  const double arr2[20]={2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.};
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),2);
+  std::copy(arr2,arr2+20,array->getPointer());
+  f1->setEndArray(array);
+  array->decrRef();
+  //
+  f1->applyLin(4.,5.,1);
+  //
+  const double expected2[20]={17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.};
+  for(int i=0;i<20;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-9);
+  const double expected3[20]={2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.};
+  for(int i=0;i<20;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f1->getEndArray()->getIJ(0,i),1e-9);
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testGetIdsInRange1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_3();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setTime(2.3,5,6);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),1);
+  const double arr1[10]={2.,8.,6.,5.,11.,7.,9.,3.,10.,4.};
+  std::copy(arr1,arr1+10,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  f1->checkCoherency();
+  DataArrayInt *da=f1->getIdsInRange(2.9,7.1);
+  CPPUNIT_ASSERT_EQUAL(5,da->getNbOfElems());
+  const int expected1[5]={2,3,5,7,9};
+  CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer()));
+  da->decrRef();
+  da=f1->getIdsInRange(8.,12.);
+  CPPUNIT_ASSERT_EQUAL(4,da->getNbOfElems());
+  const int expected2[4]={1,4,6,8};
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+4,da->getConstPointer()));
+  da->decrRef();
+  //
+  f1->decrRef();
+  mesh1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testBuildSubPart1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setTime(2.3,5,6);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),2);
+  const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.};
+  std::copy(arr1,arr1+10,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  const int part1[3]={2,1,4};
+  MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3);
+  CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents());
+  const double expected1[6]={5.,105.,4.,104.,7.,107.};
+  for(int i=0;i<6;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected1[i],1e-12);
+  CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension());
+  MEDCouplingUMesh *m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh()));
+  CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength());
+  const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7};
+  for(int i=0;i<12;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12);
+  const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2};
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer()));
+  const double expected4[4]={0,4,8,13};
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer()));
+  f2->decrRef();
+  f1->decrRef();
+  // Test with field on nodes.
+  f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
+  f1->setTime(2.3,5,6);
+  f1->setMesh(mesh1);
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfNodes(),2);
+  const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.};
+  std::copy(arr2,arr2+18,array->getPointer());  
+  f1->setArray(array);
+  array->decrRef();
+  const int part2[4]={1,4,2,5};
+  f2=f1->buildSubPart(part2,part2+4);
+  CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents());
+  const double expected5[8]={4.,104.,5.,105.,7.,107.,8.,108.};
+  for(int i=0;i<8;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12);
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension());
+  m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh()));
+  CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength());
+  for(int i=0;i<8;i++)//8 is not an error
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12);
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4));
+  CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer()));
+  f2->decrRef();
+  //idem previous because nodes of cell#4 are not fully present in part3 
+  const int part3[5]={1,4,2,5,7};
+  DataArrayInt *arrr=DataArrayInt::New();
+  arrr->alloc(5,1);
+  std::copy(part3,part3+5,arrr->getPointer());
+  f2=f1->buildSubPart(arrr);
+  arrr->decrRef();
+  CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents());
+  for(int i=0;i<8;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12);
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension());
+  m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh()));
+  CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength());
+  for(int i=0;i<8;i++)//8 is not an error
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12);
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4));
+  CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer()));
+  f2->decrRef();
+  //
+  const int part4[6]={1,4,2,5,7,8};
+  f2=f1->buildSubPart(part4,part4+6);
+  CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents());
+  const double expected6[12]={4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.};
+  for(int i=0;i<12;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected6[i],1e-12);
+  CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension());
+  m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh()));
+  CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength());
+  for(int i=0;i<12;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12);
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4));
+  CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected3+8,expected3+13,m2C->getNodalConnectivity()->getConstPointer()+8));
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer()));
+  f2->decrRef();
+  //
+  f1->decrRef();
+  mesh1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDoublyContractedProduct1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),6);
+  const double arr1[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5};
+  std::copy(arr1,arr1+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->doublyContractedProduct();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(3906.56,f2->getIJ(i,0),1e-9);
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDeterminant1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL);
+  f1->setTime(2.3,5,6);
+  f1->setEndTime(3.8,7,3);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),4);
+  const double arr1[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5};
+  std::copy(arr1,arr1+20,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //4 components
+  f1->checkCoherency();
+  MEDCouplingFieldDouble *f2=f1->determinant();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(CONST_ON_TIME_INTERVAL,f2->getTimeDiscretization());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfValues());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.42,f2->getIJ(i,0),1e-13);
+  f2->decrRef();
+  f1->decrRef();
+  //6 components multi arrays with end array not defined
+  f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME);
+  f1->setTime(2.3,5,6);
+  f1->setEndTime(3.8,7,3);
+  f1->setMesh(mesh1);
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfNodes(),6);
+  const double arr2[54]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7,
+                         1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7};
+  std::copy(arr2,arr2+54,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  CPPUNIT_ASSERT_THROW(f1->checkCoherency(),INTERP_KERNEL::Exception);//no end array specified !
+  //
+  f2=f1->determinant();
+  CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples());
+  for(int i=0;i<9;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10);
+  f2->decrRef();
+  //6 components multi arrays with end array defined
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfNodes(),6);
+  const double arr3[54]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5,
+                         7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5};
+  std::copy(arr3,arr3+54,array->getPointer());
+  f1->setEndArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  f2=f1->determinant();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples());
+  int it,order;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(it,order),1e-12);
+  CPPUNIT_ASSERT_EQUAL(5,it); CPPUNIT_ASSERT_EQUAL(6,order);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.8,f2->getEndTime(it,order),1e-12);
+  CPPUNIT_ASSERT_EQUAL(7,it); CPPUNIT_ASSERT_EQUAL(3,order);
+  for(int i=0;i<9;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(1289.685,f2->getEndArray()->getIJ(i,0),1e-9);
+    }
+  f2->decrRef();
+  f1->decrRef();
+  //9 components
+  f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setTime(7.8,10,2);
+  f1->setMesh(mesh1);
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),9);
+  const double arr4[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1};
+  std::copy(arr4,arr4+45,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  //
+  f1->checkCoherency();
+  f2=f1->determinant();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(ONE_TIME,f2->getTimeDiscretization());
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f2->getTime(it,order),1e-12);
+  CPPUNIT_ASSERT_EQUAL(10,it); CPPUNIT_ASSERT_EQUAL(2,order);
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(3.267,f2->getIJ(i,0),1e-13);
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testEigenValues1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),6);
+  const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7};
+  std::copy(arr1,arr1+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->eigenValues();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  const double expected1[3]={13.638813677891717,-4.502313844635971,-2.2364998332557486};
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13);
+    }
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testEigenVectors1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),6);
+  const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7};
+  std::copy(arr1,arr1+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->eigenVectors();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  const double expected1[9]={
+    0.5424262364180696, 0.5351201064614425, 0.6476266283176001,//eigenvect 0
+    0.7381111277307373, 0.06458838384003074, -0.6715804522117897,//eigenvect 1
+    -0.4012053603397987, 0.8423032781211455, -0.3599436712889738//eigenvect 2
+  };
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13);
+    }
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testInverse1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),9);
+  const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1};
+  std::copy(arr1,arr1+45,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->inverse();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  const double expected1[9]={-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072};
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13);
+    }
+  f2->decrRef();
+  //
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),6);
+  const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5};
+  std::copy(arr3,arr3+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  f2=f1->inverse();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  const double expected3[6]={-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887};
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f2->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f2->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f2->getIJ(i,2),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[3],f2->getIJ(i,3),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[4],f2->getIJ(i,4),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[5],f2->getIJ(i,5),1e-13);
+    }
+  f2->decrRef();
+  //
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),4);
+  const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5};
+  std::copy(arr2,arr2+20,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  f2=f1->inverse();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  const double expected2[4]={-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156};
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[0],f2->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[1],f2->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[2],f2->getIJ(i,2),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[3],f2->getIJ(i,3),1e-13);
+    }
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testTrace1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),9);
+  const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1};
+  std::copy(arr1,arr1+45,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->trace();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(15.9,f2->getIJ(i,0),1e-13);
+  f2->decrRef();
+  //
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),6);
+  const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5};
+  std::copy(arr3,arr3+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  f2=f1->trace();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(25.8,f2->getIJ(i,0),1e-13);
+  f2->decrRef();
+  //
+  array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),4);
+  const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5};
+  std::copy(arr2,arr2+20,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  f2=f1->trace();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7,f2->getIJ(i,0),1e-13);
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDeviator1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),6);
+  const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7};
+  std::copy(arr1,arr1+30,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->deviator();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  const double expected1[6]={-1.1,0.,1.1,4.5,5.6,6.7};
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13);
+    }
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testMagnitude1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),5);
+  const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6};
+  std::copy(arr1,arr1+25,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->magnitude();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(8.3606219864313918,f2->getIJ(i,0),1e-13);
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testMaxPerTuple1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),5);
+  const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4};
+  std::copy(arr1,arr1+25,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->maxPerTuple();
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,f2->getIJ(i,0),1e-13);
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testChangeNbOfComponents()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),5);
+  const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4};
+  std::copy(arr1,arr1+25,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  f1->changeNbOfComponents(3,7.77);
+  f1->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  const double expected1[15]={1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2};
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-13);
+  f1->changeNbOfComponents(4,7.77);
+  f1->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(4,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  const double expected2[20]={1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77};
+  for(int i=0;i<20;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-13);
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testSortPerTuple1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  f1->setMesh(mesh1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(mesh1->getNumberOfCells(),5);
+  const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4};
+  std::copy(arr1,arr1+25,array->getPointer());
+  f1->setArray(array);
+  array->decrRef();
+  f1->checkCoherency();
+  //
+  f1->sortPerTuple(true);
+  f1->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,3),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,4),1e-13);
+    }
+  //
+  f1->sortPerTuple(false);
+  f1->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,0),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,1),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,3),1e-13);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,4),1e-13);
+    }
+  //
+  mesh1->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testIsEqualWithoutConsideringStr1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  MEDCouplingUMesh *mesh2=build2DTargetMesh_1();
+  DataArrayInt *da1,*da2;
+  //
+  CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh2->setName("rr");
+  CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh1->checkDeepEquivalWith(mesh2,2,1e-12,da1,da2);
+  CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,da1,da2),INTERP_KERNEL::Exception);
+  mesh2->setName("");
+  CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh2->getCoords()->setInfoOnComponent(0,"tty");
+  CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh2->getCoords()->setInfoOnComponent(0,"");
+  CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh2->getCoords()->setInfoOnComponent(1,"tty");
+  CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh2->getCoords()->setInfoOnComponent(1,"");
+  CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  double tmp=mesh2->getCoords()->getIJ(0,3);
+  mesh2->getCoords()->setIJ(0,3,9999.);
+  CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh2->getCoords()->setIJ(0,3,tmp);
+  CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  int tmp2=mesh2->getNodalConnectivity()->getIJ(0,4);
+  mesh2->getNodalConnectivity()->setIJ(0,4,0);
+  CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  mesh2->getNodalConnectivity()->setIJ(0,4,tmp2);
+  CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12));
+  CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12));
+  //
+  MEDCouplingFieldDouble *f1=mesh1->getMeasureField(true);
+  MEDCouplingFieldDouble *f2=mesh2->getMeasureField(true);
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+  f2->setName("ftest");
+  CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12));
+  CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+  f1->setName("ftest");
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+  //
+  f2->getArray()->setInfoOnComponent(0,"eee");
+  CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12));
+  CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+  f2->getArray()->setInfoOnComponent(0,"");
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+  //
+  f2->getArray()->setIJ(1,0,0.123);
+  CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12));
+  CPPUNIT_ASSERT(!f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+  f2->getArray()->setIJ(1,0,0.125);
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+  //
+  f1->decrRef();
+  f2->decrRef();
+  //
+  mesh1->decrRef();
+  mesh2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testGetNodeIdsOfCell1()
+{
+  MEDCouplingUMesh *mesh1=build2DTargetMesh_1();
+  std::vector<int> nodeIds;
+  mesh1->getNodeIdsOfCell(1,nodeIds);
+  CPPUNIT_ASSERT_EQUAL(3,(int)nodeIds.size());
+  CPPUNIT_ASSERT_EQUAL(1,nodeIds[0]);
+  CPPUNIT_ASSERT_EQUAL(4,nodeIds[1]);
+  CPPUNIT_ASSERT_EQUAL(2,nodeIds[2]);
+  std::vector<double> coords;
+  mesh1->getCoordinatesOfNode(4,coords);
+  CPPUNIT_ASSERT_EQUAL(2,(int)coords.size());
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[0],1e-13);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[1],1e-13);
+  mesh1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testGetEdgeRatioField1()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=m1->getEdgeRatioField();
+  CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  const double expected1[5]={1.,1.4142135623730951, 1.4142135623730951,1.,1.};
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-14);
+  f1->decrRef();
+  m1->decrRef();
+  //
+  m1=build3DSurfTargetMesh_1();
+  f1=m1->getEdgeRatioField();
+  CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  const double expected2[5]={1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951};
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(i,0),1e-14);
+  f1->decrRef();
+  m1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFillFromAnalytic3()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"y+x"),INTERP_KERNEL::Exception);
+  f1->setMesh(m);
+  f1->setName("myField");
+  f1->fillFromAnalytic(1,"y+x");
+  f1->checkCoherency();
+  CPPUNIT_ASSERT(std::string(f1->getName())=="myField");
+  CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS);
+  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};
+  const double *tmp=f1->getArray()->getConstPointer();
+  std::transform(tmp,tmp+5,values1,values1,std::minus<double>());
+  std::transform(values1,values1+5,values1,std::ptr_fun<double,double>(fabs));
+  double max=*std::max_element(values1,values1+5);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12);
+  f1->decrRef();
+  //
+  f1=MEDCouplingFieldDouble::New(ON_NODES,CONST_ON_TIME_INTERVAL);
+  f1->setMesh(m);
+  f1->setEndTime(1.2,3,4);
+  f1->fillFromAnalytic(1,"y+2*x");
+  f1->checkCoherency();
+  CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==CONST_ON_TIME_INTERVAL);
+  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};
+  tmp=f1->getArray()->getConstPointer();
+  std::transform(tmp,tmp+9,values2,values2,std::minus<double>());
+  std::transform(values2,values2+9,values2,std::ptr_fun<double,double>(fabs));
+  max=*std::max_element(values2,values2+9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12);
+  f1->decrRef();
+  f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME);
+  f1->setMesh(m);
+  f1->setEndTime(1.2,3,4);
+  f1->fillFromAnalytic(1,"2.*x+y");
+  f1->checkCoherency();
+  CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==LINEAR_TIME);
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
+  tmp=f1->getArray()->getConstPointer();
+  double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1};
+  double values2BisBis[9];
+  std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus<double>());
+  std::transform(values2,values2+9,values2BisBis,std::ptr_fun<double,double>(fabs));
+  max=*std::max_element(values2BisBis,values2BisBis+9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12);
+  tmp=f1->getEndArray()->getConstPointer();
+  std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus<double>());
+  std::transform(values2,values2+9,values2BisBis,std::ptr_fun<double,double>(fabs));
+  max=*std::max_element(values2BisBis,values2BisBis+9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12);
+  f1->decrRef();
+  //
+  f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME);
+  f1->setMesh(m);
+  f1->fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec");
+  f1->checkCoherency();
+  CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES);
+  CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_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};
+  tmp=f1->getArray()->getConstPointer();
+  std::transform(tmp,tmp+18,values3,values3,std::minus<double>());
+  std::transform(values3,values3+18,values3,std::ptr_fun<double,double>(fabs));
+  max=*std::max_element(values3,values3+18);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12);
+  double values4[2];
+  f1->accumulate(values4);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12);
+  f1->integral(true,values4);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12);
+  f1->decrRef();
+  //
+  f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME);
+  f1->setMesh(m);
+  CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"1./(x-0.2)"),INTERP_KERNEL::Exception);
+  //
+  m->decrRef();
+  f1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFieldDoubleOpEqual1()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  CPPUNIT_ASSERT_THROW((*f1)=0.07,INTERP_KERNEL::Exception);
+  f1->setMesh(m);
+  (*f1)=0.07;
+  f1->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.07,f1->getIJ(i,0),1e-16);
+  (*f1)=0.09;
+  f1->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples());
+  for(int i=0;i<5;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09,f1->getIJ(i,0),1e-16);
+  f1->decrRef();
+  //
+  f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME);
+  f1->setEndTime(4.5,2,3);
+  f1->setMesh(m);
+  (*f1)=0.08;
+  f1->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples());
+  for(int i=0;i<9;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getIJ(i,0),1e-16);
+  CPPUNIT_ASSERT_EQUAL(1,f1->getEndArray()->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(9,f1->getEndArray()->getNumberOfTuples());
+  for(int i=0;i<9;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getEndArray()->getIJ(i,0),1e-16);
+  f1->decrRef();
+  //
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testAreaBary3D2()
+{
+  const double coordsForHexa8[24]={
+    -75.45749305371, 180.95495078401, 39.515472018008,
+    -9.755591679144, 23.394927935279, 5.108794294848,
+    14.337630157832, 61.705351002702, 160.42422501908,
+    -27.273893776752, 167.567731083961, 192.830034145464,
+    //
+    99.857193154796,264.499264735586,-8.287335493412,
+    144.939882761126,156.38626563134,-31.896173894226,
+    161.34096835726,182.4654895809,73.832387065572,
+    132.680430393685,255.37973247196,96.15235602819
+  };
+  const double volHexa8=3258520.29637466;
+  const double baryHexa8[3]={43.925705821778, 155.31893955289, 65.874418109644};
+
+  const double coordsForPenta6[18]={
+    -68.199829618726,178.938498373416,62.608505919588,
+    8.461744647847,76.653979804423,165.00018874933,
+    -27.273893776752,167.567731083961,192.830034145464,
+    //
+    106.586501038965,262.629609408327,13.124533008813,
+    155.465082847275,197.414118382622,78.408350795821,
+    132.680430393685,255.37973247196,96.15235602819
+  };
+  const double volPenta6=944849.868507338;
+  const double baryPenta6[3]={39.631002313543,182.692711783428,106.98540473964};
+  
+  const double coordsForPyra5[15]={
+    132.680430393685,255.37973247196,96.15235602819,
+    -27.273893776752,167.567731083961,192.830034145464,
+    8.461744647847,76.653979804423,165.00018874933,
+    155.465082847275,197.414118382622,78.408350795821,
+    //
+    -68.199829618726,178.938498373416,62.608505919588
+  };
+  const double volPyra5=756943.92980254;
+  const double baryPyra5[3]={29.204294116618,172.540129749156,118.01035951483};
+  MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Bary3D2",3);
+  DataArrayDouble *coo=DataArrayDouble::New();
+  coo->alloc(19,3);
+  double *tmp=std::copy(coordsForHexa8,coordsForHexa8+24,coo->getPointer());
+  tmp=std::copy(coordsForPenta6,coordsForPenta6+18,tmp);
+  std::copy(coordsForPyra5,coordsForPyra5+15,tmp);
+  mesh->setCoords(coo);
+  coo->decrRef();
+  //
+  int tmpConn[8]={0,1,2,3,4,5,6,7};
+  mesh->allocateCells(3);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,tmpConn);
+  std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus<int>(),8));
+  mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,tmpConn);
+  std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus<int>(),6));
+  mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,tmpConn);
+  mesh->finishInsertingCells();
+  mesh->checkCoherency();
+  bool isMerged;
+  int newNebOfNodes;
+  DataArrayInt *da=mesh->mergeNodes(1e-7,isMerged,newNebOfNodes);
+  da->decrRef();
+  CPPUNIT_ASSERT_EQUAL(12,newNebOfNodes);
+  MEDCouplingFieldDouble *vols=mesh->getMeasureField(true);
+  CPPUNIT_ASSERT_EQUAL(3,vols->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents());
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(volHexa8,vols->getIJ(0,0),1e-6);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(volPenta6,vols->getIJ(1,0),1e-7);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(volPyra5,vols->getIJ(2,0),1e-7);
+  vols->decrRef();
+  DataArrayDouble *bary=mesh->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents());
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[0],bary->getIJ(0,0),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[1],bary->getIJ(0,1),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[2],bary->getIJ(0,2),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[0],bary->getIJ(1,0),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[1],bary->getIJ(1,1),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[2],bary->getIJ(1,2),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[0],bary->getIJ(2,0),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[1],bary->getIJ(2,1),1e-11);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[2],bary->getIJ(2,2),1e-11);
+  bary->decrRef();
+  //
+  mesh->decrRef();
+}
+
+void MEDCouplingBasicsTest::testGetMeasureFieldCMesh1()
+{
+  MEDCouplingCMesh *m=MEDCouplingCMesh::New();
+  DataArrayDouble *da=DataArrayDouble::New();
+  const double discX[4]={2.3,3.4,5.8,10.2};
+  const double discY[3]={12.3,23.4,45.8};
+  const double discZ[5]={-0.7,1.2,1.25,2.13,2.67};
+  da->alloc(4,1);
+  std::copy(discX,discX+4,da->getPointer());
+  m->setCoordsAt(0,da);
+  da->decrRef();
+  m->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(3,m->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(1,m->getSpaceDimension());
+  MEDCouplingFieldDouble *f=m->getMeasureField(true);
+  CPPUNIT_ASSERT_EQUAL(3,f->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents());
+  const double expected1[3]={1.1,2.4,4.4};
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(i,0),1e-12);
+  f->decrRef();
+  DataArrayDouble *coords=m->getCoordinatesAndOwner();
+  CPPUNIT_ASSERT_EQUAL(4,coords->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents());
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(discX[i],coords->getIJ(i,0),1e-12);
+  coords->decrRef();
+  coords=m->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents());
+  const double expected1_3[3]={2.85,4.6,8.};
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1_3[i],coords->getIJ(i,0),1e-12);
+  coords->decrRef();
+  //
+  da=DataArrayDouble::New();
+  da->alloc(3,1);
+  std::copy(discY,discY+3,da->getPointer());
+  m->setCoordsAt(1,da);
+  da->decrRef();
+  m->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(12,m->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(6,m->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(2,m->getSpaceDimension());
+  f=m->getMeasureField(true);
+  CPPUNIT_ASSERT_EQUAL(6,f->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents());
+  const double expected2[6]={12.21,26.64,48.84,24.64,53.76,98.56};
+  for(int i=0;i<6;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(i,0),1e-12);
+  f->decrRef();
+  coords=m->getCoordinatesAndOwner();
+  CPPUNIT_ASSERT_EQUAL(12,coords->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents());
+  const double expected2_2[24]={2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8};
+  for(int i=0;i<24;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_2[i],coords->getIJ(0,i),1e-12);
+  coords->decrRef();
+  coords=m->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(6,coords->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents());
+  const double expected2_3[12]={2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6};
+  for(int i=0;i<12;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_3[i],coords->getIJ(0,i),1e-12);
+  coords->decrRef();
+  //
+  da=DataArrayDouble::New();
+  da->alloc(5,1);
+  std::copy(discZ,discZ+5,da->getPointer());
+  m->setCoordsAt(2,da);
+  da->decrRef();
+  m->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(60,m->getNumberOfNodes());
+  CPPUNIT_ASSERT_EQUAL(24,m->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension());
+  f=m->getMeasureField(true);
+  CPPUNIT_ASSERT_EQUAL(24,f->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents());
+  const double expected3[24]={23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224};
+  for(int i=0;i<24;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f->getIJ(i,0),1e-12);
+  f->decrRef();
+  coords=m->getCoordinatesAndOwner();
+  CPPUNIT_ASSERT_EQUAL(60,coords->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents());
+  const double expected3_2[180]={
+    2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7,
+    2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2,
+    2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25,
+    2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13,
+    2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67
+  };
+  for(int i=0;i<180;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_2[i],coords->getIJ(0,i),1e-12);
+  coords->decrRef();
+  coords=m->getBarycenterAndOwner();
+  CPPUNIT_ASSERT_EQUAL(24,coords->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents());
+  const double expected3_3[72]={
+    2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25,
+    2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225,
+    2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69,
+    2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4
+  };
+  for(int i=0;i<72;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_3[i],coords->getIJ(0,i),1e-12);
+  coords->decrRef();
+  //
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFieldDoubleZipCoords1()
+{
+  MEDCouplingUMesh *m=build2DTargetMeshMergeNode_1();
+  MEDCouplingFieldDouble *f=m->fillFromAnalytic(ON_NODES,2,"x*2.");
+  f->getArray()->setInfoOnComponent(0,"titi");
+  f->getArray()->setInfoOnComponent(1,"tutu");
+  f->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(18,f->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents());
+  const double expected1[36]={-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4};
+  for(int i=0;i<36;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12);
+  CPPUNIT_ASSERT(f->zipCoords());
+  f->checkCoherency();
+  const double expected2[30]={-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12);
+  CPPUNIT_ASSERT(!f->zipCoords());
+  f->checkCoherency();
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12);
+  CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi");
+  CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu");
+  f->decrRef();
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFieldDoubleZipConnectivity1()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  MEDCouplingUMesh *m2=build2DTargetMesh_1();
+  const int cells1[3]={2,3,4};
+  MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true);
+  MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1);
+  CPPUNIT_ASSERT(m3);
+  m2->decrRef();
+  MEDCouplingUMesh *m4=build2DSourceMesh_1();
+  MEDCouplingUMesh *m5=MEDCouplingUMesh::mergeUMeshes(m1,m3);
+  m1->decrRef();
+  m3->decrRef();
+  MEDCouplingUMesh *m6=MEDCouplingUMesh::mergeUMeshes(m5,m4);
+  m4->decrRef();
+  m5->decrRef();
+  //
+  CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes());
+  bool areNodesMerged;
+  int newNbOfNodes;
+  DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes);
+  CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes());
+  arr->decrRef();
+  MEDCouplingFieldDouble *f=m6->fillFromAnalytic(ON_CELLS,2,"x");
+  MEDCouplingFieldDouble *f2=m6->fillFromAnalytic(ON_NODES,2,"x");
+  CPPUNIT_ASSERT_EQUAL(10,f->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents());
+  const double expected1[20]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321,
+                              -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45,
+                              0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326};
+  for(int i=0;i<20;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12);
+  f->getArray()->setInfoOnComponent(0,"titi");
+  f->getArray()->setInfoOnComponent(1,"tutu");
+  f->checkCoherency();
+  CPPUNIT_ASSERT(f->zipConnectivity(0));
+  const double expected2[14]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321,
+                              -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326};
+  CPPUNIT_ASSERT_EQUAL(7,f->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents());
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12);
+  CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi");
+  CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu");
+  CPPUNIT_ASSERT(!f->zipConnectivity(0));
+  f->decrRef();
+  //
+  const double expected3[18]={-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, 
+                              -0.3, -0.3, 0.2, 0.2, 0.7, 0.7};
+  CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents());
+  for(int i=0;i<18;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12);
+  CPPUNIT_ASSERT(f2->zipConnectivity(0));
+  CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents());
+  for(int i=0;i<18;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12);
+  f2->decrRef();
+  //
+  m6->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDaDoubleRenumber1()
+{
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(7,2);
+  a->setInfoOnComponent(0,"toto");
+  a->setInfoOnComponent(1,"tata");
+  const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1};
+  std::copy(arr1,arr1+14,a->getPointer());
+  //
+  const int arr2[7]={3,1,0,6,5,4,2};
+  DataArrayDouble *b=a->renumber(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata");
+  const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14);
+  b->decrRef();
+  a->decrRef();
+  //
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(7,2);
+  c->setInfoOnComponent(0,"toto");
+  c->setInfoOnComponent(1,"tata");
+  const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17};
+  std::copy(arr3,arr3+14,c->getPointer());
+  DataArrayInt *d=c->renumber(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata");
+  const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i));
+  c->decrRef();
+  d->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDaDoubleRenumberAndReduce1()
+{
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(7,2);
+  a->setInfoOnComponent(0,"toto");
+  a->setInfoOnComponent(1,"tata");
+  const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1};
+  std::copy(arr1,arr1+14,a->getPointer());
+  //
+  const int arr2[7]={2,-1,1,-1,0,4,3};
+  DataArrayDouble *b=a->renumberAndReduce(arr2,5);
+  CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata");
+  const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1};
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14);
+  b->decrRef();
+  a->decrRef();
+  //
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(7,2);
+  c->setInfoOnComponent(0,"toto");
+  c->setInfoOnComponent(1,"tata");
+  const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17};
+  std::copy(arr3,arr3+14,c->getPointer());
+  DataArrayInt *d=c->renumberAndReduce(arr2,5);
+  CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata");
+  const int expected2[10]={5,15,3,13,1,11,7,17,6,16};
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i));
+  c->decrRef();
+  d->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDaDoubleRenumberInPlace1()
+{
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(7,2);
+  const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1};
+  std::copy(arr1,arr1+14,a->getPointer());
+  //
+  const int arr2[7]={3,1,0,6,5,4,2};
+  a->renumberInPlace(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents());
+  const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14);
+  a->decrRef();
+  //
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(7,2);
+  const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17};
+  std::copy(arr3,arr3+14,c->getPointer());
+  c->renumberInPlace(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents());
+  const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i));
+  c->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDaDoubleRenumberR1()
+{
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(7,2);
+  a->setInfoOnComponent(0,"toto");
+  a->setInfoOnComponent(1,"tata");
+  const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1};
+  std::copy(arr1,arr1+14,a->getPointer());
+  //
+  const int arr2[7]={3,1,0,6,5,4,2};
+  DataArrayDouble *b=a->renumberR(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata");
+  const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14);
+  b->decrRef();
+  a->decrRef();
+  //
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(7,2);
+  c->setInfoOnComponent(0,"toto");
+  c->setInfoOnComponent(1,"tata");
+  const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17};
+  std::copy(arr3,arr3+14,c->getPointer());
+  DataArrayInt *d=c->renumberR(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata");
+  const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i));
+  c->decrRef();
+  d->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDaDoubleRenumberInPlaceR1()
+{
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(7,2);
+  const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1};
+  std::copy(arr1,arr1+14,a->getPointer());
+  //
+  const int arr2[7]={3,1,0,6,5,4,2};
+  a->renumberInPlaceR(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents());
+  const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14);
+  a->decrRef();
+  //
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(7,2);
+  const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17};
+  std::copy(arr3,arr3+14,c->getPointer());
+  c->renumberInPlaceR(arr2);
+  CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents());
+  const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13};
+  for(int i=0;i<14;i++)
+    CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i));
+  c->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDaDoubleSelectByTupleId1()
+{
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(7,2);
+  a->setInfoOnComponent(0,"toto");
+  a->setInfoOnComponent(1,"tata");
+  const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1};
+  std::copy(arr1,arr1+14,a->getPointer());
+  //
+  const int arr2[7]={4,2,0,6,5};
+  DataArrayDouble *b=a->selectByTupleId(arr2,arr2+5);
+  CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata");
+  const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1};
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14);
+  b->decrRef();
+  a->decrRef();
+  //
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(7,2);
+  c->setInfoOnComponent(0,"toto");
+  c->setInfoOnComponent(1,"tata");
+  const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17};
+  std::copy(arr3,arr3+14,c->getPointer());
+  DataArrayInt *d=c->selectByTupleId(arr2,arr2+5);
+  CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto");
+  CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata");
+  const int expected2[10]={5,15,3,13,1,11,7,17,6,16};
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i));
+  c->decrRef();
+  d->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDaDoubleGetMinMaxValues1()
+{
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(9,1);
+  const double arr1[9]={2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56};
+  std::copy(arr1,arr1+9,a->getPointer());
+  int where;
+  double m=a->getMaxValue(where);
+  CPPUNIT_ASSERT_EQUAL(1,where);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12);
+  DataArrayInt *ws;
+  m=a->getMaxValue2(ws);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12);
+  CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents());
+  const int expected1[3]={1,4,8};
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0));
+  ws->decrRef();
+  a->decrRef();
+  a=DataArrayDouble::New();
+  const double arr2[9]={-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56};
+  a->alloc(9,1);
+  std::copy(arr2,arr2+9,a->getPointer());
+  where=-2;
+  m=a->getMinValue(where);
+  CPPUNIT_ASSERT_EQUAL(1,where);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12);
+  m=a->getMinValue2(ws);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12);
+  CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents());
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0));
+  ws->decrRef();
+  a->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFieldDoubleGetMinMaxValues2()
+{
+  MEDCouplingUMesh *m1=0;
+  MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1);
+  m1->decrRef();
+  CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells());
+  const double arr1[18]={8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71};
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  DataArrayDouble *a=DataArrayDouble::New();
+  a->alloc(18,1);
+  std::copy(arr1,arr1+18,a->getPointer());
+  f->setArray(a);
+  a->decrRef();
+  f->setMesh(m2);
+  //
+  f->checkCoherency();
+  double m=f->getMaxValue();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12);
+  DataArrayInt *ws;
+  m=f->getMaxValue2(ws);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12);
+  CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents());
+  const int expected1[4]={0,3,7,17};
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0));
+  ws->decrRef();
+  //
+  const double arr2[18]={-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71};
+  std::copy(arr2,arr2+18,a->getPointer());
+  f->checkCoherency();
+  m=f->getMinValue();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12);
+  m=f->getMinValue2(ws);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12);
+  CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents());
+  for(int i=0;i<4;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0));
+  ws->decrRef();
+  //
+  f->decrRef();
+  m2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testBuildUnstructuredCMesh1()
+{
+  MEDCouplingCMesh *m=MEDCouplingCMesh::New();
+  DataArrayDouble *da=DataArrayDouble::New();
+  const double discX[4]={2.3,3.4,5.8,10.2};
+  const double discY[3]={12.3,23.4,45.8};
+  const double discZ[5]={-0.7,1.2,1.25,2.13,2.67};
+  da->alloc(4,1);
+  std::copy(discX,discX+4,da->getPointer());
+  m->setCoordsAt(0,da);
+  da->decrRef();
+  m->checkCoherency();
+  double pos=2.4;
+  CPPUNIT_ASSERT_EQUAL(0,m->getCellContainingPoint(&pos,1e-12));
+  pos=3.7;
+  CPPUNIT_ASSERT_EQUAL(1,m->getCellContainingPoint(&pos,1e-12));
+  pos=5.9;
+  CPPUNIT_ASSERT_EQUAL(2,m->getCellContainingPoint(&pos,1e-12));
+  pos=10.3;
+  CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12));
+  pos=1.3;
+  CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12));
+  //
+  MEDCouplingUMesh *m2=m->buildUnstructured();
+  m2->checkCoherency();
+  MEDCouplingFieldDouble *f1=m->getMeasureField(false);
+  MEDCouplingFieldDouble *f2=m2->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),3);
+  CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),3);
+  CPPUNIT_ASSERT_EQUAL(1,m2->getMeshDimension());
+  CPPUNIT_ASSERT_EQUAL(1,m2->getSpaceDimension());
+  for(int i=0;i<3;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10);
+  da=DataArrayDouble::New();
+  da->alloc(3,1);
+  std::copy(discY,discY+3,da->getPointer());
+  m->setCoordsAt(1,da);
+  da->decrRef();
+  m2->decrRef();
+  f1->decrRef();
+  f2->decrRef();
+  //
+  m2=m->buildUnstructured();
+  m2->checkCoherency();
+  f1=m->getMeasureField(false);
+  f2=m2->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),6);
+  CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),6);
+  CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension());
+  CPPUNIT_ASSERT_EQUAL(2,m2->getSpaceDimension());
+  for(int i=0;i<6;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10);
+  f1->decrRef();
+  f2->decrRef();
+  m2->decrRef();
+  //
+  da=DataArrayDouble::New();
+  da->alloc(5,1);
+  std::copy(discZ,discZ+5,da->getPointer());
+  m->setCoordsAt(2,da);
+  da->decrRef();
+  m2=m->buildUnstructured();
+  m2->checkCoherency();
+  f1=m->getMeasureField(false);
+  f2=m2->getMeasureField(false);
+  CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),24);
+  CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),24);
+  CPPUNIT_ASSERT_EQUAL(3,m2->getMeshDimension());
+  CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension());
+  for(int i=0;i<24;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10);
+  f1->decrRef();
+  f2->decrRef();
+  //
+  double pos1[3]={5.,30.,2.};
+  CPPUNIT_ASSERT_EQUAL(16,m->getCellContainingPoint(pos1,1e-12));
+  //
+  const double pt[3]={2.4,12.7,-3.4};
+  m->scale(pt,3.7);
+  MEDCouplingUMesh *m3=m->buildUnstructured();
+  m2->scale(pt,3.7);
+  CPPUNIT_ASSERT(m3->isEqual(m2,1e-12));
+  m2->decrRef();
+  m3->decrRef();
+  //
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testDataArrayIntInvertO2NNO21()
+{
+  const int arr1[6]={2,0,4,1,5,3};
+  DataArrayInt *da=DataArrayInt::New();
+  da->alloc(6,1);
+  std::copy(arr1,arr1+6,da->getPointer());
+  DataArrayInt *da2=da->invertArrayO2N2N2O(6);
+  CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents());
+  const int expected1[6]={1,3,0,5,2,4};
+  for(int i=0;i<6;i++)
+    CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0));
+  DataArrayInt *da3=da2->invertArrayN2O2O2N(6);
+  for(int i=0;i<6;i++)
+    CPPUNIT_ASSERT_EQUAL(arr1[i],da3->getIJ(i,0));
+  da3->decrRef();
+  da2->decrRef();
+  da->decrRef();
+  //
+  const int arr2[10]={3,-1,5,4,-1,0,-1,1,2,-1};
+  da=DataArrayInt::New();
+  da->alloc(10,1);
+  std::copy(arr2,arr2+10,da->getPointer());
+  da2=da->invertArrayO2N2N2O(6);
+  CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents());
+  const int expected2[10]={5,7,8,0,3,2};
+  for(int i=0;i<6;i++)
+    CPPUNIT_ASSERT_EQUAL(expected2[i],da2->getIJ(i,0));
+  da3=da2->invertArrayN2O2O2N(10);
+  for(int i=0;i<10;i++)
+    CPPUNIT_ASSERT_EQUAL(arr2[i],da3->getIJ(i,0));
+  da3->decrRef();
+  da2->decrRef();
+  da->decrRef();
+}
+
+void MEDCouplingBasicsTest::testKeepSetSelectedComponent1()
+{
+  const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.};
+  DataArrayDouble *a1=DataArrayDouble::New();
+  a1->alloc(5,4);
+  std::copy(arr1,arr1+20,a1->getPointer());
+  a1->setInfoOnComponent(0,"aaaa");
+  a1->setInfoOnComponent(1,"bbbb");
+  a1->setInfoOnComponent(2,"cccc");
+  a1->setInfoOnComponent(3,"dddd");
+  const int arr2[6]={1,2,1,2,0,0};
+  std::vector<int> arr2V(arr2,arr2+6);
+  DataArrayDouble *a2=a1->keepSelectedComponents(arr2V);
+  CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="cccc");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="bbbb");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa");
+  const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a2->getIJ(0,i),1e-14);
+  DataArrayInt *a3=a1->convertToIntArr();
+  DataArrayInt *a4=a3->keepSelectedComponents(arr2V);
+  CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="cccc");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="bbbb");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa");
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_EQUAL(int(expected1[i]),a4->getIJ(0,i));
+  // setSelectedComponents
+  const int arr3[2]={3,2};
+  std::vector<int> arr3V(arr3,arr3+2);
+  DataArrayDouble *a5=a1->keepSelectedComponents(arr3V);
+  a5->setInfoOnComponent(0,"eeee");
+  a5->setInfoOnComponent(1,"ffff");
+  const int arr4[2]={1,2};
+  std::vector<int> arr4V(arr4,arr4+2);
+  a2->setSelectedComponents(a5,arr4V);
+  CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="eeee");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="ffff");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa");
+  CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa");
+  const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],a2->getIJ(0,i),1e-14);
+  DataArrayInt *a6=a5->convertToIntArr();
+  a6->setInfoOnComponent(0,"eeee");
+  a6->setInfoOnComponent(1,"ffff");
+  a4->setSelectedComponents(a6,arr4V);
+  CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="eeee");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="ffff");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa");
+  CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa");
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_EQUAL(int(expected2[i]),a4->getIJ(0,i));
+  // test of throw
+  const int arr5[3]={2,3,6};
+  const int arr6[3]={2,7,5};
+  const int arr7[4]={2,1,4,6};
+  std::vector<int> arr5V(arr5,arr5+3);
+  std::vector<int> arr6V(arr6,arr6+3);
+  std::vector<int> arr7V(arr7,arr7+4);
+  CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr5V),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr6V),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception);
+  arr7V.resize(3);
+  CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception);
+  //
+  a6->decrRef();
+  a5->decrRef();
+  a4->decrRef();
+  a3->decrRef();
+  a2->decrRef();
+  a1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testKeepSetSelectedComponent2()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.};
+  DataArrayDouble *a1=DataArrayDouble::New();
+  a1->alloc(5,4);
+  std::copy(arr1,arr1+20,a1->getPointer());
+  a1->setInfoOnComponent(0,"aaaa");
+  a1->setInfoOnComponent(1,"bbbb");
+  a1->setInfoOnComponent(2,"cccc");
+  a1->setInfoOnComponent(3,"dddd");
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setTime(2.3,4,5);
+  f1->setMesh(m1);
+  f1->setName("f1");
+  f1->setArray(a1);
+  f1->checkCoherency();
+  //
+  const int arr2[6]={1,2,1,2,0,0};
+  std::vector<int> arr2V(arr2,arr2+6);
+  MEDCouplingFieldDouble *f2=f1->keepSelectedComponents(arr2V);
+  CPPUNIT_ASSERT(f2->getMesh()==f1->getMesh());
+  CPPUNIT_ASSERT(f2->getTimeDiscretization()==ONE_TIME);
+  int dt,it;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13);
+  CPPUNIT_ASSERT_EQUAL(4,dt);
+  CPPUNIT_ASSERT_EQUAL(5,it);
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="cccc");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="bbbb");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa");
+  const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f2->getIJ(0,i),1e-14);
+  //setSelectedComponents
+  const int arr3[2]={3,2};
+  std::vector<int> arr3V(arr3,arr3+2);
+  MEDCouplingFieldDouble *f5=f1->keepSelectedComponents(arr3V);
+  f5->setTime(6.7,8,9);
+  f5->getArray()->setInfoOnComponent(0,"eeee");
+  f5->getArray()->setInfoOnComponent(1,"ffff");
+  f5->checkCoherency();
+  const int arr4[2]={1,2};
+  std::vector<int> arr4V(arr4,arr4+2);
+  f2->setSelectedComponents(f5,arr4V);
+  CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples());
+  f2->checkCoherency();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13);
+  CPPUNIT_ASSERT_EQUAL(4,dt);
+  CPPUNIT_ASSERT_EQUAL(5,it);
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="eeee");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="ffff");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa");
+  CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa");
+  const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-14);
+  f5->decrRef();
+  f1->decrRef();
+  f2->decrRef();
+  a1->decrRef();
+  m1->decrRef();
+}
index b7c30b71262302df4672f5b61c1c92584fdf0b7a..1050f75ce5735cad96707d1edcc9e57d73cf34fe 100644 (file)
@@ -158,6 +158,119 @@ void MEDCouplingRemapperTest::test2DInterpP0P0R_1()
   targetMesh->decrRef();
 }
 
+void MEDCouplingRemapperTest::test1DInterp_1()
+{
+  MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build1DSourceMesh_2();
+  MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_2();
+  //
+  MEDCouplingRemapper remapper;
+  CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0"));
+  MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS);
+  srcField->setNature(ConservativeVolumic);
+  srcField->setMesh(sourceMesh);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(sourceMesh->getNumberOfCells(),1);
+  srcField->setArray(array);
+  double *ptr=array->getPointer();
+  for(int i=0;i<sourceMesh->getNumberOfCells();i++)
+    ptr[i]=(double)(i+7);
+  array->decrRef();
+  //
+  MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57);
+  const double *values=trgfield->getArray()->getConstPointer();
+  const double valuesExpected1[2]={9.0540540540540526,7.4};
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  const double valuesExpected2[2]={24.75,5.75};
+  srcField->setNature(Integral);
+  trgfield=remapper.transferField(srcField,4.57);
+  values=trgfield->getArray()->getConstPointer();
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  //
+  const double valuesExpected3[2]={24.75,9.25};
+  srcField->setNature(IntegralGlobConstraint);
+  trgfield=remapper.transferField(srcField,4.57);
+  values=trgfield->getArray()->getConstPointer();
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  //
+  const double valuesExpected4[2]={7.4444444444444446,7.4};
+  srcField->setNature(RevIntegral);
+  trgfield=remapper.transferField(srcField,4.57);
+  values=trgfield->getArray()->getConstPointer();
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  //
+  srcField->decrRef();
+  sourceMesh->decrRef();
+  targetMesh->decrRef();
+  //2D Curve
+  sourceMesh=MEDCouplingBasicsTest::build2DCurveSourceMesh_2();
+  targetMesh=MEDCouplingBasicsTest::build2DCurveTargetMesh_2();
+  CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0"));
+  srcField=MEDCouplingFieldDouble::New(ON_CELLS);
+  srcField->setNature(ConservativeVolumic);
+  srcField->setMesh(sourceMesh);
+  array=DataArrayDouble::New();
+  array->alloc(sourceMesh->getNumberOfCells(),1);
+  srcField->setArray(array);
+  ptr=array->getPointer();
+  for(int i=0;i<sourceMesh->getNumberOfCells();i++)
+    ptr[i]=(double)(i+7);
+  array->decrRef();
+  //
+  trgfield=remapper.transferField(srcField,4.57);
+  values=trgfield->getArray()->getConstPointer();
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  srcField->setNature(Integral);
+  trgfield=remapper.transferField(srcField,4.57);
+  values=trgfield->getArray()->getConstPointer();
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  //
+  srcField->setNature(IntegralGlobConstraint);
+  trgfield=remapper.transferField(srcField,4.57);
+  values=trgfield->getArray()->getConstPointer();
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  //
+  srcField->setNature(RevIntegral);
+  trgfield=remapper.transferField(srcField,4.57);
+  values=trgfield->getArray()->getConstPointer();
+  CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents());
+  for(int i0=0;i0<2;i0++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12);
+  trgfield->decrRef();
+  //
+  srcField->decrRef();
+  sourceMesh->decrRef();
+  targetMesh->decrRef();
+}
+
 void MEDCouplingRemapperTest::test2DInterpMultiMethods()
 {
   MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1();
@@ -709,7 +822,8 @@ void MEDCouplingRemapperTest::testExtruded2()
   MEDCouplingUMesh *meshN2D=(MEDCouplingUMesh *)meshN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true);
   n.clear();
   bool b=false;
-  DataArrayInt *da=meshTT->mergeNodes(1e-12,b);
+  int newNbOfNodes;
+  DataArrayInt *da=meshTT->mergeNodes(1e-12,b,newNbOfNodes);
   CPPUNIT_ASSERT(b);
   da->decrRef();
   meshTT->findNodesOnPlane(pt,v,1e-12,n);
index 61dc0e70141b39b2aa0e82226e0d8b622f38b4c7..2b45b4b0665d2b31e60c78cfc333ccec0796fb8d 100644 (file)
@@ -34,6 +34,7 @@ namespace ParaMEDMEM
     CPPUNIT_TEST_SUITE(MEDCouplingRemapperTest);
     CPPUNIT_TEST( test2DInterpP0P0_1 );
     CPPUNIT_TEST( test2DInterpP0P0R_1 );
+    CPPUNIT_TEST( test1DInterp_1 );
     CPPUNIT_TEST( test2DInterpMultiMethods );
     CPPUNIT_TEST( testMultiDimCombi );
     CPPUNIT_TEST( testNatureOfField );
@@ -43,6 +44,7 @@ namespace ParaMEDMEM
   public:
     void test2DInterpP0P0_1();
     void test2DInterpP0P0R_1();
+    void test1DInterp_1();
     void test2DInterpMultiMethods();
     void testMultiDimCombi();
     void testNatureOfField();
index 045a74953d2cf0312012eb11c91035ea36ff2e1d..875fcf4ae9ade168106b9f0d22c54d96948c1246 100755 (executable)
@@ -26,10 +26,17 @@ TestMEDCoupling_CPPFLAGS=@CPPUNIT_INCLUDES@ @PTHREAD_CFLAGS@ -I$(srcdir)/.. -I$(
 TestMEDCoupling_LDFLAGS = @CPPUNIT_LIBS@ ../libmedcoupling.la ../../INTERP_KERNEL/libinterpkernel.la
 
 dist_TestMEDCoupling_SOURCES = TestMEDCoupling.cxx MEDCouplingBasicsTest.hxx MEDCouplingBasicsTest0.cxx MEDCouplingBasicsTest1.cxx \
-       MEDCouplingBasicsTestInterp.cxx MEDCouplingBasicsTestData1.hxx
+       MEDCouplingBasicsTest2.cxx MEDCouplingBasicsTestInterp.cxx MEDCouplingBasicsTestData1.hxx
 
 TestMEDCouplingRemapper_CPPFLAGS=@CPPUNIT_INCLUDES@ @PTHREAD_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../../INTERP_KERNEL/Bases -I$(srcdir)/../../INTERP_KERNELTest -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../INTERP_KERNEL/Geometric2D
 
 TestMEDCouplingRemapper_LDFLAGS = @CPPUNIT_LIBS@ ../libmedcouplingremapper.la ../../INTERP_KERNEL/libinterpkernel.la ../libmedcoupling.la
 
 dist_TestMEDCouplingRemapper_SOURCES = TestMEDCouplingRemapper.cxx MEDCouplingRemapperTest.hxx MEDCouplingRemapperTest.cxx MEDCouplingBasicsTest0.cxx
+
+UNIT_TEST_PROG = TestMEDCoupling TestMEDCouplingRemapper
+
+check : tests
+
+CLEANFILES = \
+        UnitTestsResult
index 98db6b0d5251dd5bea727f6f7454c482af034232..a8e328c08d23e39c6be0583c955f109a6cf72a54 100644 (file)
 
 from libMEDCoupling_Swig import *
 import unittest
+from math import pi,e,sqrt
+from MEDCouplingDataForTest import MEDCouplingDataForTest
 
 class MEDCouplingBasicsTest(unittest.TestCase):
+    def testArray2(self):
+        arr=DataArrayDouble.New()
+        arr.setValues([12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.],3,4)
+        arr.setInfoOnComponent(0,"ggg");
+        arr.setInfoOnComponent(1,"hhhh");
+        arr.setInfoOnComponent(2,"jj");
+        arr.setInfoOnComponent(3,"kkkkkk");
+        arr2=arr.convertToIntArr();
+        arr3=arr2.convertToDblArr();
+        self.assertTrue(arr.isEqual(arr3,1e-14))
+        pass
+
+    def testArray3(self):
+        arr1=DataArrayInt.New();
+        arr1Ref=[0,10,1,11,2,12,3,13,4,14,5,15,6,16]
+        arr1.setValues(arr1Ref,7,2);
+        self.assertEqual(7,arr1.getNumberOfTuples());
+        self.assertEqual(2,arr1.getNumberOfComponents());
+        self.assertEqual(arr1Ref,list(arr1.getValues()));
+        arr2=arr1.substr(3);
+        self.assertEqual(4,arr2.getNumberOfTuples());
+        self.assertEqual(2,arr2.getNumberOfComponents());
+        self.assertEqual(arr1Ref[6:],list(arr2.getValues()));
+        arr3=arr1.substr(2,5);
+        self.assertEqual(3,arr3.getNumberOfTuples());
+        self.assertEqual(2,arr3.getNumberOfComponents());
+        self.assertEqual(arr1Ref[4:10],list(arr3.getValues()));
+        #
+        arr4=DataArrayDouble.New();
+        arr4Ref=[0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5]
+        arr4.setValues(arr4Ref,7,2);
+        self.assertEqual(7,arr4.getNumberOfTuples());
+        self.assertEqual(2,arr4.getNumberOfComponents());
+        tmp=arr4.getValues()
+        for i in xrange(14):
+            self.assertTrue(abs(arr4Ref[i]-tmp[i])<1e-14);
+            pass
+        arr5=arr4.substr(3);
+        self.assertEqual(4,arr5.getNumberOfTuples());
+        self.assertEqual(2,arr5.getNumberOfComponents());
+        tmp=arr5.getValues()
+        for i in xrange(8):
+            self.assertTrue(abs(arr4Ref[6+i]-tmp[i])<1e-14);
+            pass
+        arr6=arr4.substr(2,5);
+        self.assertEqual(3,arr6.getNumberOfTuples());
+        self.assertEqual(2,arr6.getNumberOfComponents());
+        tmp=arr6.getValues()
+        for i in xrange(6):
+            self.assertTrue(abs(arr4Ref[4+i]-tmp[i])<1e-14);
+            pass
+        pass
+
     def testMesh(self):
         tab4=[1, 2, 8, 7, 2, 3, 9, 8, 3,
               4, 10, 9, 4, 5, 11, 10, 5,
@@ -38,23 +93,23 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         mesh.setMeshDimension(2)
         mesh.allocateCells(8);
         mesh.setName("mesh1")
-        self.failUnless(mesh.getName()=="mesh1")
+        self.assertTrue(mesh.getName()=="mesh1")
         for i in range(nbOfCells):
             mesh.insertNextCell(NORM_QUAD4,4,tab4[4*i:4*(i+1)]);
             pass
         mesh.finishInsertingCells()
-        self.failUnless(mesh.getNumberOfCells()==nbOfCells)
-        self.failUnless(mesh.getNodalConnectivity().getNbOfElems()==30)
-        self.failUnless(mesh.getNodalConnectivityIndex().getNbOfElems()==nbOfCells+1)
+        self.assertTrue(mesh.getNumberOfCells()==nbOfCells)
+        self.assertTrue(mesh.getNodalConnectivity().getNbOfElems()==30)
+        self.assertTrue(mesh.getNodalConnectivityIndex().getNbOfElems()==nbOfCells+1)
         myCoords=DataArrayDouble.New()
         myCoords.setValues(coords,nbOfNodes,3);
-        self.failUnless(myCoords.getIJ(3,2)==-0.305)
+        self.assertTrue(myCoords.getIJ(3,2)==-0.305)
         mesh.setCoords(myCoords);
         mesh.checkCoherency();
-        self.failUnless(mesh.getAllTypes()==[4])
+        self.assertTrue(mesh.getAllTypes()==[4])
         myFalseConn=DataArrayInt.New()
         myFalseConn.setValues(tab4,6,4)
-        self.failUnless(myFalseConn.getIJ(1,1)==3)
+        self.assertTrue(myFalseConn.getIJ(1,1)==3)
         #
         field=MEDCouplingFieldDouble.New(ON_CELLS)
         field.setMesh(mesh)
@@ -65,7 +120,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             sampleTab.append(float(i))
         myCoords.setValues(sampleTab,nbOfCells,9);
         field.setArray(myCoords)
-        self.failUnless(3==mesh.getSpaceDimension())
+        self.assertTrue(3==mesh.getSpaceDimension())
         field.checkCoherency()
         mesh2=mesh.clone(False)
         mesh3=mesh.clone(True)
@@ -78,6 +133,4552 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         field3=mesh3.fillFromAnalytic(ON_CELLS,2,"x*IVec+(y+z)*JVec")
         field3.applyFunc("u*u*u+cos(u)")
         pass
+    def testMeshPointsCloud(self):
+        targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5,
+                      -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(0);
+        targetMesh.allocateCells(8);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.insertNextCell(NORM_POINT0,0,[]);
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,9,3);
+        targetMesh.setCoords(myCoords);
+        self.assertEqual(targetMesh.getSpaceDimension(),3)
+        self.assertEqual(targetMesh.getNumberOfCells(),8)
+        self.assertEqual(targetMesh.getNumberOfNodes(),9)
+        self.assertEqual(targetMesh.getMeshDimension(),0)
+        pass
+    def testMeshM1D(self):
+        meshM1D=MEDCouplingUMesh.New();
+        self.assertRaises(Exception,meshM1D.getMeshDimension);
+        self.assertRaises(Exception,meshM1D.getNumberOfNodes);
+        self.assertRaises(Exception,meshM1D.getNumberOfCells);
+        self.assertRaises(Exception,meshM1D.setMeshDimension,-2)
+        self.assertRaises(Exception,meshM1D.setMeshDimension,-10)
+        meshM1D.setMeshDimension(-1);
+        meshM1D.checkCoherency();
+        self.assertEqual(meshM1D.getMeshDimension(),-1);
+        self.assertEqual(meshM1D.getNumberOfCells(),1);
+        self.assertRaises(Exception,meshM1D.getNumberOfNodes);
+        self.assertRaises(Exception,meshM1D.getSpaceDimension);
+        cpy=meshM1D.clone(True);
+        self.assertTrue(cpy.isEqual(meshM1D,1e-12));
+        fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS);
+        fieldOnCells.setMesh(meshM1D);
+        array=DataArrayDouble.New();
+        array.setValues(6*[7.],1,6);
+        fieldOnCells.setArray(array);
+        fieldOnCells.checkCoherency();
+        pass
+    def testDeepCopy(self):
+        array=DataArrayDouble.New();
+        array.setValues(5*3*[7.],5,3);
+        self.assertEqual(array.getIJ(3,2),7.);
+        array2=array.deepCopy();
+        self.assertEqual(array2.getIJ(3,2),7.)
+        #
+        array3=DataArrayInt.New();
+        array3.setValues(5*3*[17],5,3);
+        self.assertEqual(array3.getIJ(3,2),17);
+        array4=array3.deepCopy();
+        self.assertEqual(array4.getIJ(3,2),17);
+        pass
+    def testRevNodal(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_1()
+        revNodal=DataArrayInt.New();
+        revNodalIndx=DataArrayInt.New();
+        mesh.getReverseNodalConnectivity(revNodal,revNodalIndx);
+        revNodalExpected=[0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4];
+        revNodalIndexExpected=[0,1,3,5,7,12,14,15,17,18];
+        self.assertEqual(revNodal.getNbOfElems(),18)
+        self.assertEqual(revNodalIndx.getNbOfElems(),10)
+        self.assertEqual(list(revNodal.getValues()),revNodalExpected)
+        self.assertEqual(list(revNodalIndx.getValues()),revNodalIndexExpected)
+        pass
+    def testConvertToPolyTypes(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        elts=[1,3];
+        mesh.convertToPolyTypes(elts);
+        mesh.checkCoherency();
+        self.assertEqual(5,mesh.getNumberOfCells());
+        self.assertEqual(23,mesh.getNodalConnectivity().getNumberOfTuples());
+        expected1=[4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4]
+        self.assertEqual(expected1,list(mesh.getNodalConnectivity().getValues()));
+        #
+        mesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        mesh.convertToPolyTypes(elts);
+        mesh.checkCoherency();
+        self.assertEqual(8,mesh.getNumberOfCells());
+        self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples());
+        mesh.convertToPolyTypes(elts);
+        mesh.checkCoherency();
+        self.assertEqual(8,mesh.getNumberOfCells());
+        self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples());
+        pass
+    def testDescConn2D(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        desc=DataArrayInt.New();
+        descIndx=DataArrayInt.New();
+        revDesc=DataArrayInt.New();
+        revDescIndx=DataArrayInt.New();
+        mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+        mesh2.checkCoherency();
+        self.assertEqual(1,mesh2.getMeshDimension());
+        self.assertEqual(13,mesh2.getNumberOfCells());
+        self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples());
+        self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples());
+        self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples());
+        self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples());
+        expected1=[0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9];
+        self.assertEqual(expected1,list(desc.getValues()));
+        expected2=[0,4,7,10,14,18];
+        self.assertEqual(expected2,list(descIndx.getValues()));
+        expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18];
+        self.assertEqual(expected3,list(revDescIndx.getValues()));
+        expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4];
+        self.assertEqual(expected4,list(revDesc.getValues()));
+        conn=mesh2.getNodalConnectivity();
+        connIndex=mesh2.getNodalConnectivityIndex();
+        expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39];
+        self.assertEqual(expected5,list(connIndex.getValues()));
+        expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5];
+        self.assertEqual(expected6,list(conn.getValues()));
+        #
+        eltsV=[1,3];
+        mesh.convertToPolyTypes(eltsV);
+        mesh.checkCoherency();
+        #
+        desc=DataArrayInt.New();
+        descIndx=DataArrayInt.New();
+        revDesc=DataArrayInt.New();
+        revDescIndx=DataArrayInt.New();
+        #
+        mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+        mesh2.checkCoherency();
+        self.assertEqual(1,mesh2.getMeshDimension());
+        self.assertEqual(13,mesh2.getNumberOfCells());
+        self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples());
+        self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples());
+        self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples());
+        self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples());
+        self.assertEqual(expected1,list(desc.getValues()));
+        self.assertEqual(expected2,list(descIndx.getValues()));
+        self.assertEqual(expected3,list(revDescIndx.getValues()));
+        self.assertEqual(expected4,list(revDesc.getValues()));
+        conn=mesh2.getNodalConnectivity();
+        connIndex=mesh2.getNodalConnectivityIndex();
+        self.assertEqual(expected5,list(connIndex.getValues()));
+        self.assertEqual(expected6,list(conn.getValues()));
+        pass
+    def testDescConn3D(self):
+        mesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        desc=DataArrayInt.New();
+        descIndx=DataArrayInt.New();
+        revDesc=DataArrayInt.New();
+        revDescIndx=DataArrayInt.New();
+        #
+        mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+        mesh2.checkCoherency();
+        self.assertEqual(2,mesh2.getMeshDimension());
+        self.assertEqual(36,mesh2.getNumberOfCells());
+        self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples());
+        self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples());
+        self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples());
+        self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples());
+        expected1=[0, 6, 12, 18, 24, 30, 36, 42, 48]
+        expected2=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30]
+        expected3=[0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48]
+        expected4=[0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7]
+        expected5=[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180]
+        expected6=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14,
+                   5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8,
+                   17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4,
+                   14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16]
+        expected7=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14,
+                   5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8,
+                   17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4,
+                   14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16]
+        
+        self.assertEqual(expected1,list(descIndx.getValues()));
+        self.assertEqual(expected2,list(desc.getValues()));
+        self.assertEqual(expected3,list(revDescIndx.getValues()));
+        self.assertEqual(expected4,list(revDesc.getValues()));
+        self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues()));
+        self.assertEqual(expected6,list(mesh2.getNodalConnectivity().getValues()));
+        #
+        eltsV=[1,3]
+        mesh.convertToPolyTypes(eltsV);
+        mesh.checkCoherency();
+        desc=DataArrayInt.New();
+        descIndx=DataArrayInt.New();
+        revDesc=DataArrayInt.New();
+        revDescIndx=DataArrayInt.New();
+        mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+        mesh2.checkCoherency();
+        self.assertEqual(2,mesh2.getMeshDimension());
+        self.assertEqual(36,mesh2.getNumberOfCells());
+        self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples());
+        self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples());
+        self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples());
+        self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples());
+        self.assertEqual(expected1,list(descIndx.getValues()));
+        self.assertEqual(expected2,list(desc.getValues()));
+        self.assertEqual(expected3,list(revDescIndx.getValues()));
+        self.assertEqual(expected4,list(revDesc.getValues()));
+        self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues()));
+        self.assertEqual(expected7,list(mesh2.getNodalConnectivity().getValues()));
+        pass
+    def testFindBoundaryNodes(self):
+        mesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        boundaryNodes=mesh.findBoundaryNodes();
+        expected1=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26];
+        self.assertEqual(expected1,list(boundaryNodes));
+        pass
+    def testBoundaryMesh(self):
+        mesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        mesh2=mesh.buildBoundaryMesh(False);
+        self.assertEqual(24,mesh2.getNumberOfCells());
+        self.assertEqual(26,mesh2.getNumberOfNodes());
+        pass
+    def testBuildPartOfMySelf(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        mesh.setName("Toto");
+        tab1=[0,4]
+        tab2=[0,2,3]
+        #
+        subMesh=mesh.buildPartOfMySelf(tab1,True);
+        self.assertTrue(isinstance(subMesh,MEDCouplingUMesh))
+        name=subMesh.getName();
+        self.assertEqual(2,len(mesh.getAllTypes()));
+        self.assertEqual(NORM_TRI3,mesh.getAllTypes()[0]);
+        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(2,subMesh.getNumberOfCells());
+        subConn=[4,0,3,4,1,4,7,8,5,4];
+        subConnIndex=[0,5,10];
+        self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems());
+        self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems());
+        self.assertEqual(subConn[0:10],list(subMesh.getNodalConnectivity().getValues()));
+        self.assertEqual(subConnIndex[0:3],list(subMesh.getNodalConnectivityIndex().getValues()));
+        #
+        subMesh=mesh.buildPartOfMySelf(tab2[0:3],True);
+        self.assertTrue(isinstance(subMesh,MEDCouplingUMesh));
+        name=subMesh.getName();
+        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(3,subMesh.getNumberOfCells());
+        subConn2=[4,0,3,4,1,3,4,5,2,4,6,7,4,3]
+        subConnIndex2=[0,5,9,14]
+        self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems());
+        self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems());
+        self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues()));
+        self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues()));
+        subMesh=subMesh.buildPartOfMySelf(range(3),True);
+        self.assertEqual("PartOf_Toto",subMesh.getName());
+        pass
+    def testBuildPartOfMySelfNode(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        tab1=[5,7]
+        subMesh=mesh.buildPartOfMySelfNode(tab1[0:2],True);
+        self.assertTrue(isinstance(subMesh,MEDCouplingUMesh))
+        self.assertEqual(1,len(subMesh.getAllTypes()));
+        self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]);
+        self.assertEqual(1,subMesh.getNumberOfCells());
+        self.assertEqual(5,subMesh.getNodalConnectivity().getNbOfElems());
+        self.assertEqual(2,subMesh.getNodalConnectivityIndex().getNbOfElems());
+        subConn=[4,7,8,5,4]
+        subConnIndex=[0,5]
+        self.assertEqual(subConn[0:5],list(subMesh.getNodalConnectivity().getValues()));
+        self.assertEqual(subConnIndex[0:2],list(subMesh.getNodalConnectivityIndex().getValues()));
+        #
+        subMesh=mesh.buildPartOfMySelfNode(tab1[0:2],False);
+        self.assertTrue(isinstance(subMesh,MEDCouplingUMesh))
+        self.assertEqual(2,len(subMesh.getAllTypes()));
+        self.assertEqual(NORM_TRI3,subMesh.getAllTypes()[0]);
+        self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[1]);
+        self.assertEqual(3,subMesh.getNumberOfCells());
+        self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems());
+        self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems());
+        subConn2=[3,4,5,2,4,6,7,4,3,4,7,8,5,4]
+        subConnIndex2=[0,4,9,14]
+        self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues()));
+        self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues()));
+        #testing the case where length of tab2 is greater than max number of node per cell.
+        tab2=[0,3,2,1,4,5,6]
+        subMesh=mesh.buildPartOfMySelfNode(tab2[0:7],True);
+        self.assertTrue(isinstance(subMesh,MEDCouplingUMesh))
+        self.assertEqual(2,len(subMesh.getAllTypes()));
+        self.assertEqual(NORM_TRI3,subMesh.getAllTypes()[0]);
+        self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[1]);
+        self.assertEqual(3,subMesh.getNumberOfCells());
+        pass
+    def testZipCoords(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        self.assertEqual(2,len(mesh.getAllTypes()));
+        self.assertEqual(2,mesh.getSpaceDimension());
+        self.assertEqual(9,mesh.getNumberOfNodes());
+        self.assertEqual(5,mesh.getNumberOfCells());
+        oldConn=mesh.getNodalConnectivity().getValues()[0:mesh.getNodalConnectivity().getNbOfElems()];
+        oldConnIndex=mesh.getNodalConnectivityIndex().getValues()[0:mesh.getNumberOfCells()+1]
+        oldCoords=mesh.getCoords();
+        mesh.zipCoords();
+        self.assertEqual(2,len(mesh.getAllTypes()));
+        self.assertEqual(2,mesh.getSpaceDimension());
+        self.assertEqual(9,mesh.getNumberOfNodes());
+        self.assertEqual(5,mesh.getNumberOfCells());
+        self.assertEqual(mesh.getCoords().getValues()[0:2*9],oldCoords.getValues());
+        self.assertEqual(list(oldConn),list(mesh.getNodalConnectivity().getValues()));
+        self.assertEqual(list(oldConnIndex),list(mesh.getNodalConnectivityIndex().getValues()));
+        #
+        tab1=[0,4]
+        subMesh=mesh.buildPartOfMySelf(tab1,True);
+        self.assertTrue(isinstance(subMesh,MEDCouplingUMesh))
+        traducer=subMesh.zipCoordsTraducer();
+        expectedTraducer=[0, 1, -1, 2, 3, 4, -1, 5, 6]
+        self.assertEqual(expectedTraducer,list(traducer.getValues()));
+        self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]);
+        self.assertEqual(2,subMesh.getNumberOfCells());
+        subConn=[4,0,2,3,1,4,5,6,4,3]
+        subConnIndex=[0,5,10]
+        self.assertEqual(7,subMesh.getNumberOfNodes());
+        self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems());
+        self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems());
+        self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues()));
+        self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues()));
+        #
+        subMesh=mesh.buildPartOfMySelf(tab1,False);
+        self.assertTrue(isinstance(subMesh,MEDCouplingUMesh))
+        self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]);
+        self.assertEqual(2,subMesh.getNumberOfCells());
+        self.assertEqual(7,subMesh.getNumberOfNodes());
+        self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems());
+        self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems());
+        self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues()));
+        self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues()));
+        pass
+    def testZipConnectivity(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cells1=[2,3,4]
+        m3=m2.buildPartOfMySelf(cells1,True);
+        self.assertTrue(isinstance(m3,MEDCouplingUMesh))
+        m4=MEDCouplingDataForTest.build2DSourceMesh_1();
+        m5=MEDCouplingUMesh.mergeUMeshes(m1,m3);
+        m6=MEDCouplingUMesh.mergeUMeshes(m5,m4);
+        #
+        self.assertEqual(10,m6.getNumberOfCells());
+        self.assertEqual(22,m6.getNumberOfNodes());
+        (arr,areNodesMerged,newNbOfNodes)=m6.mergeNodes(1e-13);
+        self.assertTrue(areNodesMerged);
+        self.assertEqual(10,m6.getNumberOfCells());
+        self.assertEqual(9,m6.getNumberOfNodes());
+        #
+        arr=m6.zipConnectivityTraducer(0);
+        self.assertEqual(7,m6.getNumberOfCells());
+        m7=m6.clone(True);
+        arr=m6.zipConnectivityTraducer(0);
+        self.assertTrue(m7.isEqual(m6,1e-12));
+        self.assertEqual(7,m6.getNumberOfCells());
+        pass
+    def testEqualMesh(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        #
+        self.assertTrue(mesh1.isEqual(mesh1,1e-12));
+        #
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh2.isEqual(mesh1,1e-12));
+        pt=mesh2.getCoords().getValues();
+        tmp=pt[1]
+        mesh2.getCoords().setIJ(0,1,5.999);
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(not mesh2.isEqual(mesh1,1e-12));
+        mesh2.getCoords().setIJ(0,1,tmp);
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh2.isEqual(mesh1,1e-12));
+        #
+        pt2=mesh1.getNodalConnectivity().getValues();
+        mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])+1);
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(not mesh2.isEqual(mesh1,1e-12));
+        mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5]));
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh2.isEqual(mesh1,1e-12));
+        #
+        pt2=mesh1.getNodalConnectivityIndex().getValues();
+        mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1]+1));
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(not mesh2.isEqual(mesh1,1e-12));
+        mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1]));
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh2.isEqual(mesh1,1e-12));
+        #
+        tmp3=mesh1.getName();
+        mesh1.setName("lllll");
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(not mesh2.isEqual(mesh1,1e-12));
+        mesh1.setName(tmp3);
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh2.isEqual(mesh1,1e-12));
+        #
+        tmp3=mesh2.getCoords().getInfoOnComponent(1);
+        mesh2.getCoords().setInfoOnComponent(1,"kkkkkk");
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(not mesh2.isEqual(mesh1,1e-12));
+        mesh2.getCoords().setInfoOnComponent(1,tmp3);
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh2.isEqual(mesh1,1e-12));
+        pass
+    def testEqualFieldDouble(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        #
+        fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        fieldOnCells1.setMesh(mesh1);
+        fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        fieldOnCells2.setMesh(mesh2);
+        #
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        #
+        fieldOnNodes1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnNodes1,1e-12,1e-15));
+        self.assertTrue(not fieldOnNodes1.isEqual(fieldOnCells1,1e-12,1e-15));
+        #
+        fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        fieldOnCells1.setTime(4.,6,7);
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        fieldOnCells2.setTime(4.,6,7);
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        fieldOnCells1.setName("Power");
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        fieldOnCells2.setName("Power");
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        #
+        fieldOnCells1.setMesh(mesh1);
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        fieldOnCells2.setMesh(mesh1);
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        arr=DataArrayDouble.New();
+        arr.setName("popo");
+        arr.setValues(mesh1.getNumberOfCells()*3*[6.],mesh1.getNumberOfCells(),3);
+        fieldOnCells1.setArray(arr);
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        fieldOnCells2.setArray(arr);
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        #
+        arr2=arr.deepCopy();
+        fieldOnCells2.setArray(arr2);
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        arr.setIJ(1,2,6.1);
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        arr.setIJ(1,2,6.);
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        arr2.setName("popo2");
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        #
+        arr2.setName("popo");
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        #
+        arr2.setInfoOnComponent(2,"jjj");
+        self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        arr.setInfoOnComponent(2,"jjj");
+        self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15));
+        self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15));
+        pass
+
+    def testNatureChecking(self):
+        field=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        field.setNature(Integral);
+        field.setNature(ConservativeVolumic);
+        field.setNature(IntegralGlobConstraint);
+        field=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME);
+        field.setNature(ConservativeVolumic);
+        self.assertRaises(Exception,field.setNature,Integral);
+        self.assertRaises(Exception,field.setNature,IntegralGlobConstraint);
+        pass
+
+    def testBuildSubMeshData(self):
+        targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1()
+        #check buildSubMesh on field on cells
+        fieldCells=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        fieldCells.setMesh(targetMesh);
+        elts=[1,2,4]
+        ret1,di=fieldCells.buildSubMeshData(elts);
+        self.assertTrue(isinstance(ret1,MEDCouplingUMesh))
+        self.assertEqual(3,ret1.getNumberOfCells());
+        self.assertEqual(6,ret1.getNumberOfNodes());
+        self.assertEqual(3,di.getNumberOfTuples());
+        self.assertEqual(1,di.getNumberOfComponents());
+        toCheck=di.getValues();
+        self.assertTrue(elts,toCheck);
+        #check buildSubMesh on field on nodes
+        fieldNodes=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME);
+        fieldNodes.setMesh(targetMesh);
+        ret2,di=fieldNodes.buildSubMeshData(elts);
+        self.assertTrue(isinstance(ret2,MEDCouplingUMesh))
+        self.assertEqual(3,ret2.getNumberOfCells());
+        self.assertEqual(6,ret2.getNumberOfNodes());
+        self.assertEqual(6,di.getNumberOfTuples());
+        self.assertEqual(1,di.getNumberOfComponents());
+        toCheck=di.getValues();
+        expected=[1,2,4,5,7,8]
+        self.assertEqual(expected,list(toCheck));
+        pass
+    def testExtrudedMesh1(self):
+        mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1();
+        ext=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,1);
+        self.assertEqual(18,ext.getNumberOfCells());
+        self.assertEqual(60,ext.getNumberOfNodes());
+        ids3D=ext.getMesh3DIds();
+        ids3DExpected=[5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12]
+        self.assertEqual(18,ids3D.getNumberOfTuples());
+        self.assertEqual(1,ids3D.getNumberOfComponents());
+        self.assertEqual(ids3DExpected,list(ids3D.getValues()));
+        mesh1D=ext.getMesh1D();
+        self.assertEqual(4,mesh1D.getNumberOfNodes());
+        self.assertEqual(3,mesh1D.getNumberOfCells());
+        mesh1DExpected=[0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663,
+                        1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333,
+                        2, 0.66666666666666663, 1.4583333333333333, 3]
+        mesh1DCoords=mesh1D.getCoords();
+        self.assertEqual(4,mesh1DCoords.getNumberOfTuples());
+        self.assertEqual(3,mesh1DCoords.getNumberOfComponents());
+        self.assertEqual(mesh1DExpected,mesh1DCoords.getValues());
+        conn1D=mesh1D.getNodalConnectivity();
+        self.assertEqual(9,conn1D.getNumberOfTuples());
+        self.assertEqual(1,conn1D.getNumberOfComponents());
+        conn1DExpected=[1,0,1,1,1,2,1,2,3]
+        self.assertEqual(conn1DExpected,list(conn1D.getValues()));
+        pass
+
+    def testExtrudedMesh3(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m1.changeSpaceDimension(3);
+        m2=MEDCouplingDataForTest.buildCU1DMesh_U();
+        m2.changeSpaceDimension(3);
+        center=[0.,0.,0.]
+        vector=[0.,1.,0.]
+        m2.rotate(center,vector,-pi/2.);
+        m3=m1.buildExtrudedMeshFromThis(m2,0);
+        #
+        m4=MEDCouplingExtrudedMesh.New(m3,m1,0);
+        self.assertEqual(15,m4.getNumberOfCells());
+        self.assertEqual(5,m4.getMesh2D().getNumberOfCells());
+        self.assertEqual(3,m4.getMesh1D().getNumberOfCells());
+        m3DIds=m4.getMesh3DIds().getValues();
+        self.assertEqual(range(15),list(m3DIds));
+        #some random in cells to check that extrusion alg find it correctly
+        expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4]
+        m3.renumberCells(expected1,False);
+        m4=MEDCouplingExtrudedMesh.New(m3,m1,0);
+        self.assertEqual(15,m4.getNumberOfCells());
+        self.assertEqual(5,m4.getMesh2D().getNumberOfCells());
+        self.assertEqual(3,m4.getMesh1D().getNumberOfCells());
+        m3DIds=m4.getMesh3DIds().getValues();
+        self.assertEqual(expected1,list(m3DIds));
+        #play with polygons and polyedrons
+        cells=[2,3]
+        m1.convertToPolyTypes(cells);
+        m3=m1.buildExtrudedMeshFromThis(m2,0);
+        self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(0));
+        self.assertEqual(NORM_PENTA6,m3.getTypeOfCell(1));
+        self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(2));
+        self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(3));
+        self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(4));
+        m3.renumberCells(expected1,False);
+        m4=MEDCouplingExtrudedMesh.New(m3,m1,0);
+        self.assertEqual(15,m4.getNumberOfCells());
+        self.assertEqual(5,m4.getMesh2D().getNumberOfCells());
+        self.assertEqual(3,m4.getMesh1D().getNumberOfCells());
+        m3DIds=m4.getMesh3DIds().getValues();
+        self.assertEqual(expected1,list(m3DIds));
+        pass
+
+    def testExtrudedMesh4(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cells=[2,4];
+        m1.convertToPolyTypes(cells);
+        m1.changeSpaceDimension(3);
+        m2=MEDCouplingDataForTest.buildCU1DMesh_U();
+        m2.changeSpaceDimension(3);
+        center=[0.,0.,0.]
+        vector=[0.,1.,0.]
+        m2.rotate(center,vector,-pi/2.);
+        m3=m1.buildExtrudedMeshFromThis(m2,0);
+        expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4]
+        rexpected1=[3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12]
+        m3.renumberCells(expected1,False);
+        m4=MEDCouplingExtrudedMesh.New(m3,m1,0);
+        self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(0));
+        self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(1));
+        self.assertEqual(NORM_POLYHED,m4.getTypeOfCell(2));
+        self.assertEqual(NORM_PENTA6,m4.getTypeOfCell(7));
+        f=m4.getMeasureField(True);
+        arr=f.getArray();
+        self.assertEqual(15,arr.getNumberOfTuples());
+        self.assertEqual(1,arr.getNumberOfComponents());
+        arrPtr=arr.getValues();
+        expected2=[0.075,0.0375,0.0375,0.075,0.075,
+                   0.1125,0.05625,0.05625,0.1125,0.1125,
+                   0.0625,0.03125,0.03125,0.0625,0.0625]
+        for i in xrange(15):
+            self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],16);
+            pass
+        m5=m4.build3DUnstructuredMesh();
+        self.assertTrue(m5.isEqual(m3,1e-12));
+        f=m5.getMeasureField(True);
+        f.setMesh(m4)
+        self.assertTrue(isinstance(f.getMesh(),MEDCouplingExtrudedMesh))
+        arr=f.getArray();
+        arrPtr=arr.getValues();
+        for i in xrange(15):
+            self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],15);
+            pass
+        pass
+
+    def testFindCommonNodes(self):
+        targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        comm,commI=targetMesh.findCommonNodes(-1,1e-10);
+        self.assertEqual(1,commI.getNumberOfTuples());
+        self.assertEqual(0,comm.getNumberOfTuples());
+        o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI);
+        self.assertEqual(27,newNbOfNodes);
+        self.assertEqual(27,o2n.getNumberOfTuples());
+        o2nExp1=range(27)
+        self.assertEqual(o2nExp1,list(o2n.getValues()));
+        #
+        targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
+        self.assertEqual(31,targetMesh.getNumberOfNodes());
+        comm,commI=targetMesh.findCommonNodes(-1,1e-10);
+        self.assertEqual(3,commI.getNumberOfTuples());
+        self.assertEqual(6,comm.getNumberOfTuples());
+        commExpected=[1,27,28,29,23,30]
+        commIExpected=[0,4,6]
+        self.assertEqual(commExpected,list(comm.getValues()));
+        self.assertEqual(commIExpected,list(commI.getValues()));
+        o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI);
+        self.assertEqual(31,o2n.getNumberOfTuples());
+        self.assertEqual(27,newNbOfNodes);
+        o2nExp2=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
+                 21,22,23,24,25,26,1,1,1,23]
+        self.assertEqual(o2nExp2,list(o2n.getValues()));
+        #
+        targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        time=targetMesh.getTimeOfThis();
+        o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10);
+        targetMesh.updateTime();
+        self.assertEqual(time,targetMesh.getTimeOfThis());
+        self.assertTrue(not areNodesMerged);
+        #
+        targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
+        time=targetMesh.getTimeOfThis();
+        o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10);
+        targetMesh.updateTime();
+        self.assertTrue(time!=targetMesh.getTimeOfThis());
+        self.assertTrue(areNodesMerged);
+        connExp=[18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15,
+                 18,4,5,8,7,13,14,17,16,
+                 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24,
+                 18,13,14,17,16,22,23,26,25]
+        self.assertEqual(72,targetMesh.getNodalConnectivity().getNumberOfTuples());
+        self.assertEqual(connExp,list(targetMesh.getNodalConnectivity().getValues()));
+        self.assertEqual(27,targetMesh.getCoords().getNumberOfTuples());
+        coordsExp=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0.  , 0., 50., 0., 50., 50., 0. ,
+                    200., 50., 0.,   0., 200., 0., 50., 200., 0. , 200., 200., 0. ,
+                    0., 0., 50., 50., 0., 50. , 200., 0., 50.  , 0., 50., 50., 50.,
+                    50., 50. , 200., 50., 50.,   0., 200., 50., 50., 200., 50. ,
+                    200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200.  
+                    , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 
+                    0., 200., 200., 50., 200., 200. , 200., 200., 200. ]
+        self.assertEqual(coordsExp,targetMesh.getCoords().getValues());
+        # 2D
+        targetMesh=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1();
+        self.assertEqual(18,targetMesh.getNumberOfNodes());
+        time=targetMesh.getTimeOfThis();
+        o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10);
+        self.assertTrue(time!=targetMesh.getTimeOfThis());
+        self.assertTrue(areNodesMerged);
+        self.assertEqual(9,targetMesh.getNumberOfNodes());
+        connExp2=[4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3]
+        self.assertEqual(23,targetMesh.getNodalConnectivity().getNumberOfTuples());
+        self.assertEqual(connExp2,list(targetMesh.getNodalConnectivity().getValues()));
+        coordsExp2=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7]
+        self.assertEqual(9,targetMesh.getCoords().getNumberOfTuples());
+        self.assertEqual(coordsExp2,targetMesh.getCoords().getValues());
+        pass
+
+    def testCheckButterflyCells(self):
+        sourceMesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cells=sourceMesh.checkButterflyCells();
+        self.assertEqual(0,len(cells));
+        conn=sourceMesh.getNodalConnectivity()
+        tmp=conn.getIJ(15,0)
+        conn.setIJ(15,0,conn.getIJ(16,0))
+        conn.setIJ(16,0,tmp)
+        cells=sourceMesh.checkButterflyCells();
+        self.assertEqual(1,len(cells));
+        self.assertEqual(3,cells[0]);
+        tmp=conn.getIJ(15,0)
+        conn.setIJ(15,0,conn.getIJ(16,0))
+        conn.setIJ(16,0,tmp)
+        cells=sourceMesh.checkButterflyCells();
+        self.assertEqual(0,len(cells));
+        # 3D surf
+        sourceMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        cells=sourceMesh.checkButterflyCells();
+        self.assertEqual(0,len(cells));
+        conn=sourceMesh.getNodalConnectivity()
+        tmp=conn.getIJ(15,0)
+        conn.setIJ(15,0,conn.getIJ(16,0))
+        conn.setIJ(16,0,tmp)
+        cells=sourceMesh.checkButterflyCells();
+        self.assertEqual(1,len(cells));
+        self.assertEqual(3,cells[0]);
+        tmp=conn.getIJ(15,0)
+        conn.setIJ(15,0,conn.getIJ(16,0))
+        conn.setIJ(16,0,tmp)
+        cells=sourceMesh.checkButterflyCells();
+        self.assertEqual(0,len(cells));
+        pass
+
+    def testMergeMesh1(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DSourceMesh_1();
+        vec=[1.,0.]
+        m2.translate(vec);
+        m3=m1.mergeMyselfWith(m2);
+        self.assertTrue(isinstance(m3,MEDCouplingUMesh));
+        m3.checkCoherency();
+        m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1();
+        self.assertTrue(m3.isEqual(m4,1.e-12));
+        da,isMerged,newNbOfNodes=m3.mergeNodes(1.e-12);
+        self.assertEqual(11,m3.getNumberOfNodes());
+        self.assertTrue(isMerged);
+        pass
+
+    def testMergeMeshOnSameCoords1(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cells=range(5);
+        m2.convertToPolyTypes(cells);
+        m1.tryToShareSameCoords(m2,1e-12);
+        m3=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m3.tryToShareSameCoords(m2,1e-12);
+        meshes=[m1,m2,m3]
+        m4=MEDCouplingUMesh.mergeUMeshesOnSameCoords(meshes);
+        m4.checkCoherency();
+        self.assertEqual(15,m4.getNumberOfCells());
+        cells1=[0,1,2,3,4]
+        m1_1=m4.buildPartOfMySelf(cells1,True);
+        m1_1.setName(m1.getName());
+        self.assertTrue(m1.isEqual(m1_1,1e-12));
+        cells2=[5,6,7,8,9]
+        m2_1=m4.buildPartOfMySelf(cells2,True);
+        m2_1.setName(m2.getName());
+        self.assertTrue(m2.isEqual(m2_1,1e-12));
+        cells3=[10,11,12,13,14]
+        m3_1=m4.buildPartOfMySelf(cells3,True);
+        m3_1.setName(m3.getName());
+        self.assertTrue(m3.isEqual(m3_1,1e-12));
+        pass
+
+    def testMergeField1(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DSourceMesh_1();
+        vec=[1.,0.]
+        m2.translate(vec);
+        f1=m1.getMeasureField(True);
+        f2=m2.getMeasureField(True);
+        f3=MEDCouplingFieldDouble.mergeFields(f1,f2);
+        f3.checkCoherency();
+        m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1();
+        self.assertTrue(f3.getMesh().isEqual(m4,1.e-12));
+        name=f3.getName();
+        self.assertEqual(name,"MeasureOfMesh_");
+        self.assertEqual(f3.getTypeOfField(),ON_CELLS);
+        self.assertEqual(f3.getTimeDiscretization(),NO_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]
+        tmp=f3.getArray().getValues();
+        self.assertEqual(len(values),len(tmp))
+        for i in xrange(7):
+            self.assertTrue(abs(values[i]-tmp[i])<1e-12)
+            pass
+        pass
+
+    def testFillFromAnalytic(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();             
+        f1=m.fillFromAnalytic(ON_CELLS,1,"x+y");
+        f1.checkCoherency();                    
+        self.assertEqual(f1.getTypeOfField(),ON_CELLS);
+        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(1,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values1),len(tmp))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values1[i])<1.e-12)
+            pass
+        #
+        f1=m.fillFromAnalytic(ON_NODES,1,"x+y");
+        f1.checkCoherency();
+        self.assertEqual(f1.getTypeOfField(),ON_NODES);
+        self.assertEqual(f1.getTimeDiscretization(),NO_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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values2),len(tmp))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values2[i])<1.e-12)
+            pass
+        #
+        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(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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values3),len(tmp))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values3[i])<1.e-12)
+            pass
+        values4=f1.accumulate();
+        self.assertEqual(2,len(values4))
+        self.assertTrue(abs(3.6-values4[0])<1.e-12);
+        self.assertTrue(abs(7.2-values4[1])<1.e-12);
+        values4=f1.integral(True);
+        self.assertEqual(2,len(values4))
+        self.assertTrue(abs(0.5-values4[0])<1.e-12);
+        self.assertTrue(abs(1.-values4[1])<1.e-12);
+        #
+        self.assertRaises(Exception,m.fillFromAnalytic,ON_NODES,1,"1./(x-0.2)");
+        pass
+
+    def testFillFromAnalytic2(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=m.fillFromAnalytic(ON_CELLS,1,"y+x");
+        f1.checkCoherency();
+        self.assertEqual(f1.getTypeOfField(),ON_CELLS);
+        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(1,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values1),len(tmp))
+        for i in xrange(len(values1)):
+            self.assertTrue(abs(values1[i]-tmp[i])<1.e-12);
+            pass
+        #
+        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(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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values2),len(tmp))
+        for i in xrange(len(values2)):
+            self.assertTrue(abs(values2[i]-tmp[i])<1.e-12);
+            pass
+        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(1,f1.getNumberOfComponents());
+        self.assertEqual(9,f1.getNumberOfTuples());
+        tmp=f1.getArray().getValues();
+        values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1]
+        self.assertEqual(len(values2Bis),len(tmp))
+        for i in xrange(len(values2Bis)):
+            self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12);
+            pass
+        #
+        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(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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values3),len(tmp))
+        for i in xrange(len(values3)):
+            self.assertTrue(abs(values3[i]-tmp[i])<1.e-12);
+            pass
+        values4=f1.accumulate();
+        self.assertTrue(abs(3.6-values4[0])<1.e-12);
+        self.assertTrue(abs(7.2-values4[1])<1.e-12);
+        values4=f1.integral(True);
+        self.assertTrue(abs(0.5-values4[0])<1.e-12);
+        self.assertTrue(abs(1.-values4[1])<1.e-12);
+        pass
+
+    def testApplyFunc(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        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(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(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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values1),len(tmp))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values1[i])<1.e-12)
+            pass
+        pass
+
+    def testApplyFunc2(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        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(2,f1.getNumberOfComponents());
+        self.assertEqual(9,f1.getNumberOfTuples());
+        #
+        f2=f1.clone(True);
+        f2.applyFunc("abs(u)^2.4+2*u");
+        self.assertEqual(f1.getTypeOfField(),ON_NODES);
+        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        self.assertEqual(2,f1.getNumberOfComponents());
+        self.assertEqual(9,f1.getNumberOfTuples());
+        values2=[-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987,
+                 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987,
+                 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295,
+                 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295,
+                 5.0423700574830965, 17.435300118916864]
+        tmp=f2.getArray().getValues();
+        self.assertEqual(len(tmp),len(values2))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values2[i])<1.e-12)
+            pass
+        #
+        f1.applyFunc(1,"x+y");
+        self.assertEqual(f1.getTypeOfField(),ON_NODES);
+        self.assertEqual(f1.getTimeDiscretization(),NO_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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(tmp),len(values1))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values1[i])<1.e-12)
+            pass
+        pass
+
+    def testOperationsOnFields(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=m.fillFromAnalytic(ON_NODES,1,"x+y");
+        f2=m.fillFromAnalytic(ON_NODES,1,"x+y");
+        f1.checkCoherency();
+        f2.checkCoherency();
+        f3=f1+f2;
+        f3.checkCoherency();
+        self.assertEqual(f3.getTypeOfField(),ON_NODES);
+        self.assertEqual(f3.getTimeDiscretization(),NO_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))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values1[i])<1.e-12)
+            pass
+        #
+        f3=f1*f2;
+        f3.checkCoherency();
+        self.assertEqual(f3.getTypeOfField(),ON_NODES);
+        self.assertEqual(f3.getTimeDiscretization(),NO_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))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values2[i])<1.e-12)
+            pass
+        #
+        f3=f1+f2;
+        f4=f1-f3;
+        f4.checkCoherency();
+        self.assertEqual(f4.getTypeOfField(),ON_NODES);
+        self.assertEqual(f4.getTimeDiscretization(),NO_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))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values3[i])<1.e-12)
+            pass
+        #
+        f3=f1+f2;
+        f4=f3/f2;
+        f4.checkCoherency();
+        self.assertEqual(f4.getTypeOfField(),ON_NODES);
+        self.assertEqual(f4.getTimeDiscretization(),NO_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.checkCoherency();
+        self.assertEqual(f4.getTypeOfField(),ON_NODES);
+        self.assertEqual(f4.getTimeDiscretization(),ONE_TIME);
+        self.assertRaises(Exception,f1.__add__,f4);
+        f5=f4.buildNewTimeReprFromThis(NO_TIME,False);
+        self.assertEqual(f5.getTypeOfField(),ON_NODES);
+        self.assertEqual(f5.getTimeDiscretization(),NO_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]
+        self.assertEqual(len(values3),len(tmp))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values4[i])<1.e-12)
+            pass
+        #
+        f4=f2.buildNewTimeReprFromThis(ONE_TIME,True);
+        f4.checkCoherency();
+        self.assertEqual(f4.getTypeOfField(),ON_NODES);
+        self.assertEqual(f4.getTimeDiscretization(),ONE_TIME);
+        self.assertRaises(Exception,f1.__add__,f4);
+        f5=f4.buildNewTimeReprFromThis(NO_TIME,True);
+        self.assertEqual(f5.getTypeOfField(),ON_NODES);
+        self.assertEqual(f5.getTimeDiscretization(),NO_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]
+        self.assertEqual(len(values5),len(tmp))
+        for i in xrange(len(tmp)):
+            self.assertTrue(abs(tmp[i]-values5[i])<1.e-12)
+            pass
+        pass
+
+    def testOperationsOnFields2(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        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);
+        expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391,
+                   0.7407407407407407, 1.129032258064516, 0.81632653061224492,
+                   0.86538461538461531, 1.0919540229885056, 0.84302325581395343]
+        self.assertEqual(1,f3.getNumberOfComponents());
+        self.assertEqual(9,f3.getNumberOfTuples());
+        val=f3.getArray().getValues();
+        for i in xrange(9):
+            self.assertTrue(abs(expected1[i]-val[i])<1.e-12);
+        #
+        f1=m.buildOrthogonalField();
+        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]
+        val=f3.getArray().getValues();
+        for i in xrange(15):
+            self.assertTrue(abs(expected2[i]-val[i])<1.e-12);
+            pass
+        #
+        f3=f2*f1;
+        val=f3.getArray().getValues();
+        for i in xrange(15):
+            self.assertTrue(abs(expected2[i]-val[i])<1.e-12);
+            pass
+        pass
+
+    def testOperationsOnFields3(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z");
+        f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c");
+        f1/=f2
+        f1.checkCoherency();
+        self.assertEqual(f1.getTypeOfField(),ON_NODES);
+        self.assertEqual(f1.getTimeDiscretization(),NO_TIME);
+        expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391,
+                   0.7407407407407407, 1.129032258064516, 0.81632653061224492,
+                   0.86538461538461531, 1.0919540229885056, 0.84302325581395343]
+        self.assertEqual(1,f1.getNumberOfComponents());
+        self.assertEqual(9,f1.getNumberOfTuples());
+        val=f1.getArray().getValues();
+        for i in xrange(9):
+            self.assertTrue(abs(expected1[i]-val[i])<1.e-12);
+            pass
+        #
+        f1=m.buildOrthogonalField();
+        f2=m.fillFromAnalytic(ON_CELLS,1,"x");
+        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]
+        val=f1.getArray().getValues();
+        for i in xrange(15):
+            self.assertTrue(abs(expected2[i]-val[i])<1.e-12);
+            pass
+        #
+        f1=m.buildOrthogonalField();
+        # to avoid valgrind leaks
+        # self.assertRaises(Exception,f2.__imul__,f1);
+        pass
+
+    def testOperationsOnFields4(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        nbOfCells=m.getNumberOfCells();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL);
+        f1.setMesh(m);
+        array=DataArrayDouble.New();
+        f1.setArray(array);
+        self.assertRaises(Exception,f1.setEndArray,array);
+        self.assertRaises(Exception,f1.getEndArray);
+        arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.]
+        arr2=[5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.]
+        array.setValues(arr1,nbOfCells,3);
+        f1.setStartTime(2.,0,0);
+        f1.setEndTime(3.,0,0);
+        f1.checkCoherency();
+        pos=[0.3,-0.2]
+        res=f1.getValueOn(pos);
+        self.assertTrue(abs(arr1[3]-res[0])<1.e-12);
+        self.assertTrue(abs(arr1[4]-res[1])<1.e-12);
+        self.assertTrue(abs(arr1[5]-res[2])<1.e-12);
+        res=None
+        res=f1.getValueOn(pos,2.2);
+        self.assertTrue(abs(arr1[3]-res[0])<1.e-12);
+        self.assertTrue(abs(arr1[4]-res[1])<1.e-12);
+        self.assertTrue(abs(arr1[5]-res[2])<1.e-12);
+        res=None
+        self.assertRaises(Exception,f1.getValueOn,pos,3.2)
+        f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME);
+        f2.setMesh(m);
+        f2.setArray(f1.getArray());
+        f2.setStartTime(2.,3,0);
+        f2.setEndTime(4.,13,0);
+        self.assertRaises(Exception,f2.checkCoherency)
+        array2=DataArrayDouble.New();
+        array2.setValues(arr2,nbOfCells,3);
+        f2.setEndArray(array2);
+        f2.checkCoherency();
+        #
+        res=None
+        res=f2.getValueOn(pos,3.21);
+        self.assertTrue(abs(4.025-res[0])<1.e-12);
+        self.assertTrue(abs(14.025-res[1])<1.e-12);
+        self.assertTrue(abs(24.025-res[2])<1.e-12);
+        f3=f2.clone(True);
+        self.assertTrue(f2.isEqual(f3,1e-12,1e-12));
+        f3.getEndArray().setIJ(0,0,5.001);
+        self.assertTrue(not f2.isEqual(f3,1e-12,1e-12));
+        self.assertTrue(f2.isEqual(f3,1e-12,1e-2));
+        f3.setStartTime(2.1,3,0);
+        self.assertTrue(not f2.isEqual(f3,1e-12,1e-2));
+        f3.setStartTime(2.,3,0);
+        self.assertTrue(f2.isEqual(f3,1e-12,1e-2));
+        f3.setStartTime(2.,4,0);
+        self.assertTrue(not f2.isEqual(f3,1e-12,1e-2));
+        f3.setStartTime(2.,3,1);
+        self.assertTrue(not f2.isEqual(f3,1e-12,1e-2));
+        f3.setStartTime(2.,3,0);
+        self.assertTrue(f2.isEqual(f3,1e-12,1e-2));
+        f3.setEndTime(4.1,13,0);
+        self.assertTrue(not f2.isEqual(f3,1e-12,1e-2));
+        f3.setEndTime(4.,13,0);
+        self.assertTrue(f2.isEqual(f3,1e-12,1e-2));
+        f3.setEndTime(4.,14,0);
+        self.assertTrue(not f2.isEqual(f3,1e-12,1e-2));
+        f3.setEndTime(4.,13,1);
+        self.assertTrue(not f2.isEqual(f3,1e-12,1e-2));
+        f3.setEndTime(4.,13,0);
+        self.assertTrue(f2.isEqual(f3,1e-12,1e-2));
+        f4=f2+f2
+        res=None
+        res=f4.getValueOn(pos,3.21);
+        self.assertTrue(abs(8.05-res[0])<1.e-12);
+        self.assertTrue(abs(28.05-res[1])<1.e-12);
+        self.assertTrue(abs(48.05-res[2])<1.e-12);
+        f4+=f2;
+        res=None
+        res=f4.getValueOn(pos,3.21);
+        self.assertTrue(abs(12.075-res[0])<1.e-12);
+        self.assertTrue(abs(42.075-res[1])<1.e-12);
+        self.assertTrue(abs(72.075-res[2])<1.e-12);
+        pass
+    
+    def testMergeNodesOnField(self):
+        targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
+        f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z");
+        f1.mergeNodes(1e-10);
+        #
+        targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
+        f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z");
+        tmp=f1.getArray()
+        tmp.setIJ(0,0,1000.);
+        f1.mergeNodes(1e-10);
+        #
+        targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
+        f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z");
+        tmp=f1.getArray()
+        tmp.setIJ(1,0,1000.);
+        self.assertRaises(Exception,f1.mergeNodes,1.e-10)
+        pass
+
+    def testCheckConsecutiveCellTypes(self):
+        sourceMesh=MEDCouplingDataForTest.build2DSourceMesh_1();
+        targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        self.assertTrue(sourceMesh.checkConsecutiveCellTypes());
+        order1=[NORM_TRI3,NORM_QUAD4]
+        order2=[NORM_QUAD4,NORM_TRI3]
+        self.assertTrue(not targetMesh.checkConsecutiveCellTypes());
+        self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order1));
+        self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2));
+        da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order1);
+        self.assertEqual(5,da.getNumberOfTuples());
+        self.assertEqual(1,da.getNumberOfComponents());
+        expected1=[2,0,1,3,4]
+        self.assertTrue(expected1==list(da.getValues()));
+        da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order2);
+        self.assertEqual(5,da.getNumberOfTuples());
+        self.assertEqual(1,da.getNumberOfComponents());
+        expected2=[0,3,4,1,2]
+        self.assertTrue(expected2==list(da.getValues()));
+        renumber1=[4,0,1,2,3]
+        targetMesh.renumberCells(renumber1,False);
+        self.assertTrue(targetMesh.checkConsecutiveCellTypes());
+        self.assertTrue(targetMesh.checkConsecutiveCellTypesAndOrder(order1));
+        self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2));
+        pass
+
+    def testRearrange2ConsecutiveCellTypes(self):
+        m1_1=MEDCouplingDataForTest.build2DSourceMesh_1();
+        m2_1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        arr1=m1_1.rearrange2ConsecutiveCellTypes();
+        m1_2=MEDCouplingDataForTest.build2DSourceMesh_1();
+        self.assertTrue(m1_2.isEqual(m1_1,1e-12));
+        expected1=[0,1]
+        self.assertEqual(2,arr1.getNumberOfTuples());
+        self.assertEqual(1,arr1.getNumberOfComponents());
+        self.assertTrue(expected1,arr1.getValues());
+        expected2=[0,3,4,1,2]
+        arr1=m2_1.rearrange2ConsecutiveCellTypes();
+        self.assertEqual(5,arr1.getNumberOfTuples());
+        self.assertEqual(1,arr1.getNumberOfComponents());
+        self.assertEqual(expected2,list(arr1.getValues()));
+        m2_2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        self.assertEqual(5,arr1.getNumberOfTuples());
+        self.assertEqual(1,arr1.getNumberOfComponents());
+        self.assertEqual(expected2,list(arr1.getValues()));
+        self.assertTrue(not m2_2.isEqual(m2_1,1e-12));
+        m2_2.renumberCells(expected2,False);
+        self.assertTrue(m2_2.isEqual(m2_1,1e-12));
+        pass
+
+    def testSplitByType(self):
+        m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        v=m1.splitByType();
+        self.assertEqual(3,len(v));
+        m2=MEDCouplingUMesh.mergeUMeshesOnSameCoords(v);
+        m2.setName(m1.getName());
+        self.assertTrue(m1.isEqual(m2,1.e-12));
+        pass
+
+    def testFuseUMeshesOnSameCoords(self):
+        m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cells1=[2,3,4]
+        m3=m2.buildPartOfMySelf(cells1,True);
+        self.assertTrue(isinstance(m3,MEDCouplingUMesh))
+        cells2=[1,2,4]
+        m4=m2.buildPartOfMySelf(cells2,True);
+        self.assertTrue(isinstance(m4,MEDCouplingUMesh))
+        cells3=[1,2]
+        m5=m2.buildPartOfMySelf(cells3,True);
+        self.assertTrue(isinstance(m5,MEDCouplingUMesh))
+        meshes=[m3,m4,m5]
+        #
+        m7,corr=MEDCouplingUMesh.fuseUMeshesOnSameCoords(meshes,0);
+        self.assertEqual(4,m7.getNumberOfCells());
+        self.assertEqual(3,len(corr));
+        expectedVals1=[3,3,2]
+        expectedVals2=[[0,1,2],[3,0,2],[3,0]]
+        for i in xrange(3):
+            arr=corr[i];
+            self.assertEqual(1,arr.getNumberOfComponents());
+            nbOfVals=expectedVals1[i];
+            self.assertEqual(nbOfVals,arr.getNumberOfTuples());
+            vals=arr.getValues();
+            self.assertEqual(expectedVals2[i],list(vals));
+            pass
+        arr2,fidsOfGroups=DataArrayInt.makePartition(corr,m7.getNumberOfCells());
+        fidExp=[5,1,3,4]
+        fidsGrp=[[1,3,5],[3,4,5],[4,5]]
+        self.assertEqual(3,len(fidsOfGroups));
+        self.assertEqual(1,arr2.getNumberOfComponents());
+        self.assertEqual(4,arr2.getNumberOfTuples());
+        self.assertEqual(fidExp,list(arr2.getValues()));
+        for i in xrange(3):
+            nbOfVals=expectedVals1[i];
+            self.assertEqual(list(fidsOfGroups[i]),fidsGrp[i]);
+            pass
+        pass
+
+    def testFuseUMeshesOnSameCoords2(self):
+        m1,m2=MEDCouplingDataForTest.build3DExtrudedUMesh_1();
+        part1=[2,3,6,4,10]
+        m3=m1.buildPartOfMySelf(part1,True);
+        part2=[5,6,4,7]
+        m4=m1.buildPartOfMySelf(part2,True);
+        meshes=[m1,m3,m3,m4]
+        m5,corr=MEDCouplingUMesh.fuseUMeshesOnSameCoords(meshes,0);
+        self.assertEqual(18,m5.getNumberOfCells());
+        exp2=[
+            [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
+            [2,3,6,4,10],
+            [2,3,6,4,10],
+            [5,6,4,7]]
+        i=0;
+        for it in corr:
+            self.assertEqual(exp2[i],list(it.getValues()));
+            i+=1
+            pass
+        pass
+
+    def testBuildOrthogonalField(self):
+        targetMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        field=targetMesh.buildOrthogonalField();
+        expected=[0.70710678118654746,0.,-0.70710678118654746]
+        self.assertEqual(5,field.getNumberOfTuples());
+        self.assertEqual(3,field.getNumberOfComponents());
+        vals=field.getArray().getValues();
+        for i in xrange(15):
+            self.assertTrue(abs(expected[i%3]-vals[i])<1e-12);
+        # testing
+        targetCoords=[0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.]
+        targetConn=[0,1,2,3]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(1);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,4,3);
+        targetMesh.setCoords(myCoords);
+        field=targetMesh.buildOrthogonalField();
+        self.assertEqual(1,field.getNumberOfTuples());
+        self.assertEqual(3,field.getNumberOfComponents());
+        vals=field.getArray().getValues();
+        self.assertTrue(abs(-0.70710678118654746-vals[0])<1e-12);
+        self.assertTrue(abs(0.-vals[1])<1e-12);
+        self.assertTrue(abs(0.70710678118654746-vals[2])<1e-12);
+        pass
+
+    def testGetCellsContainingPoint(self):
+        targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        pos=[0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.]
+        #2D basic
+        t1,t2=targetMesh.getCellsContainingPoints(pos,6,1e-12);
+        self.assertEqual(6,len(t1));
+        self.assertEqual(7,len(t2));
+        expectedValues1=[0,4,3,0,1,2]
+        expectedValues2=[0,1,2,3,4,5,6]
+        self.assertEqual(list(t1),expectedValues1);
+        self.assertEqual(list(t2),expectedValues2);
+        #2D with no help of bounding box.
+        center=[0.2,0.2]
+        MEDCouplingPointSet.rotate2DAlg(center,0.78539816339744830962,6,pos);
+        targetMesh.rotate(center,[],0.78539816339744830962);
+        t1=None
+        t2=None
+        t1,t2=targetMesh.getCellsContainingPoints(pos,6,1e-12);
+        self.assertEqual(6,len(t1));
+        self.assertEqual(7,len(t2));
+        self.assertEqual(list(t1),expectedValues1);
+        self.assertEqual(list(t2),expectedValues2);
+        #2D outside
+        pos1bis=[-0.3303300858899107,-0.11819805153394641]
+        self.assertEqual(-1,targetMesh.getCellContainingPoint(pos1bis,1e-12));
+        #test limits 2D
+        targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        pos2=[0.2,-0.05]
+        t1=None
+        t1=targetMesh.getCellsContainingPoint(pos2,1e-12)
+        self.assertEqual(2,len(t1));
+        expectedValues3=[0,1]
+        self.assertEqual(list(t1),expectedValues3);
+        pos3=[0.2,0.2]
+        t1=None
+        t1=targetMesh.getCellsContainingPoint(pos3,1e-12);
+        self.assertEqual(5,len(t1));
+        expectedValues4=[0,1,2,3,4]
+        self.assertEqual(list(t1),expectedValues4);
+        self.assertEqual(0,targetMesh.getCellContainingPoint(pos3,1e-12));
+        #3D
+        targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        pos4=[25.,25.,25.]
+        self.assertEqual(0,targetMesh.getCellContainingPoint(pos4,1e-12));
+        pos5=[50.,50.,50.]
+        t1=None
+        t1=targetMesh.getCellsContainingPoint(pos5,1e-12);
+        self.assertEqual(8,len(t1));
+        expectedValues5=[0,1,2,3,4,5,6,7]
+        self.assertEqual(list(t1),expectedValues5);
+        pos6=[0., 50., 0.]
+        t1=None
+        t1=targetMesh.getCellsContainingPoint(pos6,1e-12);
+        self.assertEqual(2,len(t1));
+        expectedValues6=[0,2]
+        self.assertEqual(list(t1),expectedValues6);
+        #3D outside
+        pos7=[-1.0,-1.0,0.]
+        self.assertEqual(-1,targetMesh.getCellContainingPoint(pos7,1e-12));
+        #3D outside 2
+        center2=[0.,0.,0.]
+        vec2=[0.,-1.,0.]
+        targetMesh.rotate(center2,vec2,0.78539816339744830962);
+        pos8=[-25.,25.,12.]
+        self.assertEqual(-1,targetMesh.getCellContainingPoint(pos8,1e-12));
+        pass
+
+    def testGetValueOn1(self):
+        targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS);
+        nbOfCells=targetMesh.getNumberOfCells();
+        fieldOnCells.setMesh(targetMesh);
+        array=DataArrayDouble.New();
+        tmp=2*nbOfCells*[None]
+        for i in xrange(nbOfCells):
+            tmp[2*i]=7.+float(i);
+            tmp[2*i+1]=17.+float(i)
+            pass
+        array.setValues(tmp,nbOfCells,2);
+        fieldOnCells.setArray(array);
+        #
+        pos1=[0.25,0.]
+        res=fieldOnCells.getValueOn(pos1);
+        self.assertEqual(2,len(res))
+        self.assertTrue(abs(8.-res[0])<1e-12);
+        self.assertTrue(abs(18.-res[1])<1e-12);
+        #
+        #
+        targetMesh=MEDCouplingDataForTest.build2DSourceMesh_1();
+        fieldOnNodes=MEDCouplingFieldDouble.New(ON_NODES);
+        nbOfNodes=targetMesh.getNumberOfNodes();
+        fieldOnNodes.setMesh(targetMesh);
+        array=DataArrayDouble.New();
+        tmp=2*nbOfNodes*[None]
+        for i in xrange(nbOfNodes):
+            tmp[2*i]=17.+float(i);
+            tmp[2*i+1]=27.+float(i)
+            pass
+        array.setValues(tmp,nbOfNodes,2);
+        fieldOnNodes.setArray(array);
+        #
+        pos2=[-0.13333333333333333,-0.13333333333333333]
+        res=None
+        res=fieldOnNodes.getValueOn(pos2);
+        self.assertEqual(2,len(res))
+        self.assertTrue(abs(17.5-res[0])<1e-12);
+        self.assertTrue(abs(27.5-res[1])<1e-12);
+        pos3=[0.033333333333333326,0.36666666666666664]
+        res=None
+        res=fieldOnNodes.getValueOn(pos3);
+        self.assertEqual(2,len(res))
+        self.assertTrue(abs(18.666666666666667-res[0])<1e-12);
+        self.assertTrue(abs(28.666666666666667-res[1])<1e-12);
+        pass
+
+    def testCMesh0(self):
+        mesh=MEDCouplingCMesh.New();
+        coordsX=DataArrayDouble.New();
+        arrX=[ -1., 1., 2., 4. ]
+        coordsX.setValues(arrX,4,1);
+        coordsY=DataArrayDouble.New();
+        arrY=[ -2., 2., 4., 8. ]
+        coordsY.setValues(arrY,4,1);
+        coordsZ=DataArrayDouble.New();
+        arrZ=[ -3., 3., 6., 12. ]
+        coordsZ.setValues(arrZ,4,1);
+        mesh.setCoords(coordsX,coordsY,coordsZ);
+        pass
+
+    def testScale(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_1();
+        pos=[0.2,0.2]
+        mesh.scale(pos,0.5);
+        expected1=[-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2,
+                   -0.05,0.45, 0.2,0.45, 0.45,0.45]
+        val=mesh.getCoords().getValues();
+        self.assertEqual(18,len(val))
+        for i in xrange(18):
+            self.assertTrue(abs(expected1[i]-val[i])<1e-12);
+            pass
+        pass
+
+    def testTryToShareSameCoords(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        #self.assertEqual(m1.getCoords()!=m2.getCoords());
+        m1.tryToShareSameCoords(m2,1e-12);
+        #self.assertEqual(m1.getCoords()==m2.getCoords());
+        m1.tryToShareSameCoords(m2,1e-12);
+        #self.assertEqual(m1.getCoords()==m2.getCoords());
+        m2.tryToShareSameCoords(m1,1e-12);
+        #self.assertEqual(m1.getCoords()==m2.getCoords());
+        #
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DTargetMesh_2();
+        #self.assertEqual(m1.getCoords()!=m2.getCoords());
+        m1.tryToShareSameCoords(m2,1e-12);
+        #self.assertEqual(m1.getCoords()==m2.getCoords());
+        m1.tryToShareSameCoords(m2,1e-12);
+        #self.assertEqual(m1.getCoords()==m2.getCoords());
+        m2.tryToShareSameCoords(m1,1e-12);
+        #self.assertEqual(m1.getCoords()==m2.getCoords());
+        #
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DSourceMesh_1();
+        #self.assertEqual(m1.getCoords()!=m2.getCoords());
+        self.assertRaises(Exception,m1.tryToShareSameCoords,m2,1e-12)
+        pass
+
+    def testFindNodeOnPlane(self):
+        mesh=MEDCouplingDataForTest.build3DTargetMesh_1();
+        pt=[300.,300.,0.]
+        v=[0.,0.,2.]
+        n=mesh.findNodesOnPlane(pt,v,1e-12);
+        self.assertEqual(9,len(n));
+        m3dSurf=mesh.buildFacePartOfMySelfNode(n,True);
+        self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh))
+        me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0);
+        da=me.getMesh3DIds();
+        self.assertEqual(8,me.getNumberOfCells());
+        expected=[0,1,2,3,4,5,6,7]
+        val=da.getValues();
+        self.assertEqual(expected,list(val));
+        pass
+
+    def testRenumberCells(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        self.assertTrue(m.isEqual(m2,0));
+        arr=[12,3,25,2,26]
+        m.renumberCells(arr,True);
+        self.assertTrue(not m.isEqual(m2,0));
+        self.assertEqual(NORM_QUAD4,m.getTypeOfCell(0));
+        self.assertEqual(NORM_TRI3,m.getTypeOfCell(1));
+        self.assertEqual(NORM_QUAD4,m.getTypeOfCell(2));
+        self.assertEqual(NORM_TRI3,m.getTypeOfCell(3));
+        self.assertEqual(NORM_QUAD4,m.getTypeOfCell(4));
+        arr2=[5,-1,-5,4,8]
+        m.renumberCells(arr2,True);
+        self.assertTrue(m.isEqual(m2,0));
+        pass
+
+    def testChangeSpaceDimension(self):
+        m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        #
+        self.assertEqual(3,m1.getSpaceDimension());
+        m1.changeSpaceDimension(2);
+        self.assertEqual(2,m1.getSpaceDimension());
+        m1.setName(m2.getName());
+        self.assertTrue(m1.isEqual(m2,1e-12));
+        m1.changeSpaceDimension(3);
+        self.assertEqual(3,m1.getSpaceDimension());
+        expected=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.]
+        val=m1.getCoords().getValues();
+        for i in xrange(27):
+            self.assertTrue(abs(expected[i]-val[i])<1e-14);
+            pass
+        pass
+
+    def testGaussPointField1(self):
+        _a=0.446948490915965;
+        _b=0.091576213509771;
+        _p1=0.11169079483905;
+        _p2=0.0549758718227661;
+        refCoo1=[ 0.,0., 1.,0., 0.,1. ]
+        gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b,
+                 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]
+        wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ]
+        _refCoo1=refCoo1
+        _gsCoo1=gsCoo1
+        _wg1=wg1
+        #
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME);
+        f.setMesh(m);
+        self.assertEqual(0,f.getNbOfGaussLocalization());
+        f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+        self.assertRaises(Exception,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1)
+        self.assertEqual(1,f.getNbOfGaussLocalization());
+        refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ]                                                               
+        _refCoo2=refCoo2                                                 
+        _gsCoo1=_gsCoo1[0:4]
+        _wg1=_wg1[0:2]             
+        f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1);
+        self.assertEqual(2,f.getNbOfGaussLocalization());
+        array=DataArrayDouble.New();
+        ptr=18*2*[None]
+        for i in xrange(18*2):
+            ptr[i]=float(i+1)
+        array.setValues(ptr,18,2);
+        ptr=array.getPointer();
+        f.setArray(array);
+        f.setName("MyFirstFieldOnGaussPoint");                                                               
+        f.checkCoherency();
+        self.assertAlmostEqual(27.,f.getIJK(2,5,0),14);                                       
+        self.assertAlmostEqual(16.,f.getIJK(1,5,1),14);                                       
+        #
+        f.clearGaussLocalizations();
+        self.assertEqual(0,f.getNbOfGaussLocalization());
+        self.assertRaises(Exception,f.checkCoherency);
+        ids1=[0,1,3,4]
+        self.assertRaises(Exception,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1);
+        self.assertEqual(0,f.getNbOfGaussLocalization());
+        ids2=[0,4]
+        f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1);
+        self.assertEqual(1,f.getNbOfGaussLocalization());
+        self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0));
+        self.assertRaises(Exception,f.getGaussLocalizationIdOfOneCell,1);
+        ids3=[1,2]
+        f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1);
+        self.assertEqual(2,f.getNbOfGaussLocalization());
+        self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0));
+        self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1));
+        self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2));
+        self.assertRaises(Exception,f.checkCoherency);#<- cell 3 has no localization
+        ids4=[3]
+        _gsCoo2=_gsCoo1;
+        _wg2=_wg1;
+        _gsCoo2[0]=0.8888777776666;
+        _wg2[0]=0.1234567892377;
+        f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2);
+        self.assertEqual(3,f.getNbOfGaussLocalization());
+        tmpIds=f.getCellIdsHavingGaussLocalization(0);
+        self.assertEqual(ids2,list(tmpIds));
+        self.assertRaises(Exception,f.checkCoherency);#<- it's always not ok because undelying array not with the good size.
+        array2=f.getArray().substr(0,10);
+        f.setArray(array2);
+        f.checkCoherency();#<- here it is OK
+        f2=f.clone(True);
+        self.assertTrue(f.isEqual(f2,1e-14,1e-14));
+        gl1=f2.getGaussLocalization(0);
+        tmp=gl1.getGaussCoord(1,1);
+        self.assertAlmostEqual(2.07*_b-1,tmp,14);
+        gl1.setGaussCoord(1,1,0.07);
+        self.assertTrue(not f.isEqual(f2,1e-14,1e-14));
+        gl1.setGaussCoord(1,1,tmp);
+        self.assertTrue(f.isEqual(f2,1e-14,1e-14));
+        f2.checkCoherency();
+        pass
+
+    def testGaussPointNEField1(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME);
+        f.setMesh(m);
+        f.setName("MyFirstFieldOnNE");
+        f.setDescription("MyDescriptionNE");
+        array=DataArrayDouble.New();
+        tmp=18*2*[None]
+        for i in xrange(18*2):
+            tmp[i]=float(i+7)
+            pass
+        array.setValues(tmp,18,2);
+        ptr=array.getPointer();
+        f.setArray(array);
+        #
+        f.checkCoherency();
+        f2=f.clone(True);
+        self.assertTrue(f.isEqual(f2,1e-14,1e-14));
+        self.assertAlmostEqual(21.,f.getIJK(2,0,0),14);
+        self.assertAlmostEqual(18.,f.getIJK(1,1,1),14);
+        pass
+
+    def testCellOrientation1(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        vec=[0.,0.,1.]
+        self.assertRaises(Exception,m.are2DCellsNotCorrectlyOriented,vec,False);
+        m.changeSpaceDimension(3);
+        res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+        self.assertTrue(len(res1)==0);
+        vec[2]=-1.;
+        res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+        self.assertEqual(5,len(res1));
+        #
+        vec[2]=1.;
+        # connectivity inversion
+        conn=m.getNodalConnectivity().getValues();
+        tmp=conn[11];
+        conn[11]=conn[12];
+        conn[12]=tmp;
+        m.getNodalConnectivity().setValues(conn,len(conn),1)
+        res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+        self.assertEqual(1,len(res1));
+        self.assertEqual(2,res1[0]);
+        m.orientCorrectly2DCells(vec,False);
+        res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+        self.assertTrue(len(res1)==0);
+        m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2.changeSpaceDimension(3);
+        self.assertTrue(m.isEqual(m2,1e-12));
+        pass
+
+    def testCellOrientation2(self):
+        m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1();
+        res1=m2.arePolyhedronsNotCorrectlyOriented();
+        self.assertEqual(6,len(res1));
+        m2.orientCorrectlyPolyhedrons();
+        res1=m2.arePolyhedronsNotCorrectlyOriented();
+        self.assertTrue(len(res1)==0);
+        m2.checkCoherency();
+        self.assertEqual(18,m2.getNumberOfCells());
+        cellIds2=[0,6,12]
+        m2.convertToPolyTypes(cellIds2);
+        m2.orientCorrectlyPolyhedrons();
+        res1=m2.arePolyhedronsNotCorrectlyOriented();
+        self.assertTrue(len(res1)==0);
+        f2=m2.getMeasureField(False);
+        f2Ptr=f2.getArray().getValues();
+        #Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation
+        m3=MEDCouplingDataForTest.build2DTargetMesh_1();
+        vec=[0.,0.,-1.]
+        m3.changeSpaceDimension(3);
+        ids2=[0,1,2,3,4]
+        m3.convertToPolyTypes(ids2);
+        m3.orientCorrectly2DCells(vec,False);
+        m4=MEDCouplingDataForTest.buildCU1DMesh_U();
+        m4.changeSpaceDimension(3);
+        center=[0.,0.,0.]
+        vector=[0.,1.,0.]
+        m4.rotate(center,vector,-pi/2.);
+        m5=m3.buildExtrudedMeshFromThis(m4,0);
+        res1=m5.arePolyhedronsNotCorrectlyOriented();
+        self.assertEqual(15,len(res1));
+        m5.orientCorrectlyPolyhedrons();
+        res1=m5.arePolyhedronsNotCorrectlyOriented();
+        self.assertTrue(len(res1)==0);
+        f3=m5.getMeasureField(False);
+        self.assertEqual(15,f3.getArray().getNumberOfTuples());
+        self.assertEqual(1,f3.getNumberOfComponents());
+        f3Ptr=f3.getArray().getValues();
+        expected1=[0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625];
+        for i in xrange(15):
+            self.assertTrue(abs(expected1[i]-f3Ptr[i])<1e-12);
+            pass
+        f4=m5.getBarycenterAndOwner();
+        self.assertEqual(15,f4.getNumberOfTuples());
+        self.assertEqual(3,f4.getNumberOfComponents());
+        f4Ptr=f4.getValues();
+        expected2=[-0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15,-0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525,-0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875];
+        for i in xrange(45):
+            self.assertTrue(abs(expected2[i]-f4Ptr[i])<1e-12);
+            pass
+        pass
+
+    def testPolyhedronBarycenter(self):
+        connN=[0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0];
+        coords=[0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5];
+        meshN=MEDCouplingUMesh.New();
+        meshN.setName("ForBary");
+        meshN.setMeshDimension(3);
+        meshN.allocateCells(4);
+        meshN.insertNextCell(NORM_POLYHED,29,connN[0:29])
+        meshN.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,9,3);
+        meshN.setCoords(myCoords);
+        meshN.checkCoherency();
+        #
+        res1=meshN.arePolyhedronsNotCorrectlyOriented();
+        meshN.orientCorrectlyPolyhedrons();
+        self.assertTrue(len(res1)==0);
+        da=meshN.getBarycenterAndOwner();
+        self.assertEqual(1,da.getNumberOfTuples());
+        self.assertEqual(3,da.getNumberOfComponents());
+        daPtr=da.getValues();
+        ref=meshN.getCoords().getValues()[24:];
+        for i in xrange(3):
+            self.assertTrue(abs(ref[i]-daPtr[i])<1e-12);
+            pass
+        #
+        center=[0.,0.,0.]
+        vec=[0.,2.78,0.]
+        da=meshN.getBarycenterAndOwner();
+        daPtr=da.getValues();
+        ref=meshN.getCoords().getValues()[24:];
+        for i in xrange(3):
+            self.assertTrue(abs(ref[i]-daPtr[i])<1e-12);
+            pass
+        #
+        meshN.rotate(center,vec,pi/7.);
+        meshN.translate(vec);
+        da=meshN.getBarycenterAndOwner();
+        daPtr=da.getValues();
+        ref=meshN.getCoords().getValues()[24:];
+        for i in xrange(3):
+            self.assertTrue(abs(ref[i]-daPtr[i])<1e-12);
+            pass
+        #
+        center2=[1.12,3.45,6.78]
+        vec2=[4.5,9.3,2.8]
+        meshN.rotate(center2,vec2,e);
+        meshN.translate(vec2);
+        da=meshN.getBarycenterAndOwner();
+        daPtr=da.getValues();
+        ref=meshN.getCoords().getValues()[24:];
+        for i in xrange(3):
+            self.assertTrue(abs(ref[i]-daPtr[i])<1e-10);
+            pass
+        pass
+
+    def testNormL12Integ1D(self):
+        m1=MEDCouplingDataForTest.build1DTargetMesh_3();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(m1);
+        array=DataArrayDouble.New();
+        arr=[-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72]
+        array.setValues(arr,m1.getNumberOfCells(),3);
+        f1.setArray(array);
+        #
+        f3=m1.getBarycenterAndOwner();
+        self.assertEqual(4,f3.getNumberOfTuples());
+        self.assertEqual(1,f3.getNumberOfComponents());
+        expected9=[0.75,5.105,0.8,5.155]
+        ptr=f3.getValues();
+        for i in xrange(4):
+            self.assertTrue(abs(expected9[i]-ptr[i])<1e-12);
+            pass
+        #
+        f2=m1.getMeasureField(False);
+        self.assertEqual(4,f2.getArray().getNumberOfTuples());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        expected1=[0.5,0.21,-0.6,-0.31]
+        ptr=f2.getArray().getValues();
+        for i in xrange(4):
+            self.assertTrue(abs(expected1[i]-ptr[i])<1e-12);
+            pass
+        expected2=[0.5,0.21,0.6,0.31]
+        f2=m1.getMeasureField(True);
+        ptr=f2.getArray().getValues();
+        for i in xrange(4):
+            self.assertTrue(abs(expected2[i]-ptr[i])<1e-12);
+            pass
+        #integral
+        self.assertTrue(4,f1.getNumberOfTuples())
+        res=f1.integral(False);
+        self.assertTrue(3,len(res))
+        expected3=[0.9866,-0.3615,0.4217]
+        for i in xrange(3):
+            self.assertTrue(abs(expected3[i]-res[i])<1e-12);
+            pass
+        self.assertTrue(abs(expected3[0]-f1.integral(0,False))<1e-12);
+        self.assertTrue(abs(expected3[1]-f1.integral(1,False))<1e-12);
+        self.assertTrue(abs(expected3[2]-f1.integral(2,False))<1e-12);
+        res=f1.integral(True);
+        expected4=[-3.4152,8.7639,-14.6879]
+        for i in xrange(3):
+            self.assertTrue(abs(expected4[i]-res[i])<1e-12);
+            pass
+        #normL1
+        res=f1.normL1();
+        self.assertTrue(3,len(res))
+        expected5=[11.3068,27.3621,43.7881]
+        for i in xrange(3):
+            self.assertTrue(abs(expected5[i]-res[i])<1e-12);
+            pass
+        self.assertTrue(abs(expected5[0]-f1.normL1(0))<1e-12);
+        self.assertTrue(abs(expected5[1]-f1.normL1(1))<1e-12);
+        self.assertTrue(abs(expected5[2]-f1.normL1(2))<1e-12);
+        #normL2
+        res=f1.normL2();
+        self.assertTrue(3,len(res))
+        expected7=[9.0252562290496776, 21.545259176904789, 34.433193070059595]
+        for i in xrange(3):
+            self.assertTrue(abs(expected7[i]-res[i])<1e-9);
+            pass
+        self.assertTrue(abs(expected7[0]-f1.normL2(0))<1e-9);
+        self.assertTrue(abs(expected7[1]-f1.normL2(1))<1e-9);
+        self.assertTrue(abs(expected7[2]-f1.normL2(2))<1e-9);
+        #buildMeasureField
+        f4=f1.buildMeasureField(False);
+        self.assertTrue(abs(-0.2-f4.accumulate(0))<1e-12);
+        f4=f1.buildMeasureField(True);
+        self.assertTrue(abs(1.62-f4.accumulate(0))<1e-12);
+        # Testing with 2D Curve
+        m1=MEDCouplingDataForTest.build2DCurveTargetMesh_3();
+        f2=m1.getMeasureField(False);
+        self.assertEqual(4,f2.getArray().getNumberOfTuples());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        ptr=f2.getArray().getValues();
+        for i in xrange(4):
+            self.assertTrue(abs(sqrt(2.)*expected2[i]-ptr[i])<1e-12);
+            pass
+        f2=m1.getMeasureField(True);
+        self.assertEqual(4,f2.getArray().getNumberOfTuples());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        ptr=f2.getArray().getValues();
+        for i in xrange(4):
+            self.assertTrue(abs(expected2[i]*sqrt(2.)-ptr[i])<1e-12);
+            pass
+        #bary
+        f3=m1.getBarycenterAndOwner();
+        self.assertEqual(4,f3.getNumberOfTuples());
+        self.assertEqual(2,f3.getNumberOfComponents());
+        expected10=[0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155]
+        ptr=f3.getValues();
+        for i in xrange(8):
+            self.assertTrue(abs(expected10[i]-ptr[i])<1e-12);
+            pass
+        #
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(m1);
+        array=DataArrayDouble.New();
+        array.setValues(arr,m1.getNumberOfCells(),3);
+        f1.setArray(array);
+        res=f1.integral(False);
+        for i in xrange(3):
+            self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12);
+            pass
+        res=f1.integral(True);
+        for i in xrange(3):
+            self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12);
+            pass
+        res=f1.normL1();
+        for i in xrange(3):
+            self.assertTrue(abs(sqrt(2.)*expected5[i]-res[i])<1e-12);
+            pass
+        res=f1.normL2();
+        for i in xrange(3):
+            self.assertTrue(abs(sqrt(sqrt(2.))*expected7[i]-res[i])<1e-12);
+            pass
+        pass
+
+    def testAreaBary2D(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        f1=m1.getMeasureField(False);
+        self.assertEqual(10,f1.getArray().getNumberOfTuples());
+        self.assertEqual(1,f1.getNumberOfComponents());
+        expected1=[-0.5,-1,-1.5,-0.5,-1,  0.5,1,1.5,0.5,1]
+        ptr=f1.getArray().getValues();
+        for i in xrange(10):
+            self.assertTrue(abs(expected1[i]-ptr[i])<1e-12);
+            pass
+        f1=m1.getMeasureField(True);
+        ptr=f1.getArray().getValues();
+        for i in xrange(10):
+            self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12);
+            pass
+        f2=m1.getBarycenterAndOwner();
+        self.assertEqual(10,f2.getNumberOfTuples());
+        self.assertEqual(2,f2.getNumberOfComponents());
+        expected2=[0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5,0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5]
+        ptr=f2.getValues();
+        for i in xrange(20):
+            self.assertTrue(abs(expected2[i]-ptr[i])<1e-12);
+            pass
+        m1.changeSpaceDimension(3);
+        f1=m1.getMeasureField(False);
+        self.assertEqual(10,f1.getArray().getNumberOfTuples());
+        self.assertEqual(1,f1.getNumberOfComponents());
+        ptr=f1.getArray().getValues();
+        for i in xrange(10):
+            self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12);
+            pass
+        f2=m1.getBarycenterAndOwner();
+        self.assertEqual(10,f2.getNumberOfTuples());
+        self.assertEqual(3,f2.getNumberOfComponents());
+        ptr=f2.getValues();
+        expected3=[0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0.]
+        for i in xrange(30):
+            self.assertTrue(abs(expected3[i]-ptr[i])<1e-12);
+            pass
+        pass
+
+    def testAreaBary3D(self):
+        coords=[ 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 ,
+                 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 ,
+                 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 ,
+                 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 ,
+                 -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 ,
+                 -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 ,
+                 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 ,
+                 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 ,
+                 -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 ,
+                 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 ,
+                -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 ,
+                 -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 ,
+                 -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 ,
+                 -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 ,
+                 -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 ,
+                 -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 ,
+                 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 ,
+                 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 ,
+                 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 ,
+                 -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 ,
+                 -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 ,
+                -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 ,
+                 -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 ,
+                 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 ,
+                 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 ,
+                 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 ,
+                 -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 ,
+                 -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 ,
+                0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 ,
+                 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 ,
+                 -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 ,
+                 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 ,
+                 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 ,
+                 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 ,
+                 -0.0372812069535 , -0.286740286332 , 0.00963701291166 ]
+        
+        connN = [ #polyhedron 0
+            0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1
+            , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1
+            , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1
+            , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28,
+            # polyhedron 1
+            0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1
+            , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1
+            , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1
+            , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50,
+            # polyhedron 2
+            6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1
+            , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40,
+            # polyhedron 3
+            35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1
+            , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1
+            , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1
+            , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65]
+        
+        barys = [ -0.0165220465527 , -0.0190922868195 , 0.158882733414 ,
+                  0.0287618656076 , 0.135874379934 , -0.14601588119 ,
+                  -0.147128055553 , 0.0465995097041 , -0.049391174453 ,
+                  -0.00142506732317 , -0.0996953090351 , -0.115159183132 ]
+        meshN=MEDCouplingUMesh.New();
+        meshN.setName("ForBary");
+        meshN.setMeshDimension(3);
+        meshN.allocateCells(4);
+        meshN.insertNextCell(NORM_POLYHED,113,connN);
+        meshN.insertNextCell(NORM_POLYHED,99,connN[113:]);
+        meshN.insertNextCell(NORM_POLYHED,43,connN[212:]);
+        meshN.insertNextCell(NORM_POLYHED,92,connN[255:]);
+        meshN.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,69,3);
+        meshN.setCoords(myCoords);
+        meshN.checkCoherency();
+        res1=meshN.arePolyhedronsNotCorrectlyOriented();
+        meshN.orientCorrectlyPolyhedrons();
+        res1=meshN.arePolyhedronsNotCorrectlyOriented();
+        self.assertTrue(len(res1)==0);
+        #
+        da=meshN.getBarycenterAndOwner();
+        self.assertEqual(4,da.getNumberOfTuples());
+        self.assertEqual(3,da.getNumberOfComponents());
+        daPtr=da.getValues();
+        for i in xrange(12):
+            self.assertTrue(abs(barys[i]-daPtr[i])<1e-12);
+            pass
+        pass
+
+    def testRenumberCellsForFields(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f.setMesh(m);
+        arr=DataArrayDouble.New();
+        nbOfCells=m.getNumberOfCells();
+        values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.]
+        arr.setValues(values1,nbOfCells,3);
+        f.setArray(arr);
+        renumber1=[3,1,0,4,2]
+        loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45]
+        for j in xrange(5):
+            res=f.getValueOn(loc[2*j:2*j+2]);
+            for i in xrange(3):
+                self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12);
+                pass
+            pass
+        f.renumberCells(renumber1,False);
+        ptr=f.getArray().getValues();
+        expected1=[9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.]
+        for i in xrange(15):
+            self.assertTrue(abs(expected1[i]-ptr[i])<1e-12);
+            pass
+        #check that fields remains the same geometrically
+        for j in xrange(5):
+            res=f.getValueOn(loc[2*j:2*(j+1)]);
+            for i in xrange(3):
+                self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12);
+                pass
+            pass
+        #On gauss
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME);
+        f.setMesh(m);
+        _a=0.446948490915965;
+        _b=0.091576213509771;
+        _p1=0.11169079483905;
+        _p2=0.0549758718227661;
+        refCoo1=[ 0.,0., 1.,0., 0.,1. ]
+        gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ];
+        wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ]
+        _refCoo1=refCoo1[0:6];
+        _gsCoo1=gsCoo1[0:12];
+        _wg1=wg1[0:6];
+        f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+        refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ]
+        _refCoo2=refCoo2[0:8];
+        _gsCoo1=_gsCoo1[0:4]
+        _wg1=_wg1[0:2]
+        f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1);
+        arr=DataArrayDouble.New();
+        values2=[1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.]
+        arr.setValues(values2,18,2);
+        f.setArray(arr);
+        f.checkCoherency();
+        fCpy=f.clone(True);
+        self.assertTrue(f.isEqual(fCpy,1e-12,1e-12));
+        f.renumberCells(renumber1,False);
+        self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12));
+        expected2=[21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.]
+        ptr=f.getArray().getValues();
+        for i in xrange(36):
+            self.assertTrue(abs(expected2[i]-ptr[i])<1e-12);
+            pass
+        renumber2=[2,1,4,0,3]
+        f.renumberCells(renumber2,False);
+        self.assertTrue(f.isEqual(fCpy,1e-12,1e-12));
+        #GaussNE
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME);
+        f.setMesh(m);
+        arr=DataArrayDouble.New();
+        values3=[1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.]
+        arr.setValues(values3,18,2);
+        f.setArray(arr);
+        f.checkCoherency();
+        fCpy=f.clone(True);
+        self.assertTrue(f.isEqual(fCpy,1e-12,1e-12));
+        f.renumberCells(renumber1,False);
+        self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12));
+        expected3=[21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.]
+        ptr=f.getArray().getValues();
+        for i in xrange(36):
+            self.assertTrue(abs(expected3[i]-ptr[i])<1e-12);
+            pass
+        f.renumberCells(renumber2,False);#perform reverse operation of renumbering to check that the resulting field is equal.
+        self.assertTrue(f.isEqual(fCpy,1e-12,1e-12));
+        #
+        pass
+
+    def testRenumberNodesForFields(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME);
+        f.setMesh(m);
+        arr=DataArrayDouble.New();
+        nbOfNodes=m.getNumberOfNodes();
+        values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.]
+        arr.setValues(values1,nbOfNodes,3);
+        f.setArray(arr);
+        f.checkCoherency();
+        renumber1=[0,4,1,3,5,2,6,7,8]
+        loc=[0.5432,-0.2432, 0.5478,0.1528]
+        expected1=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124]
+        for j in xrange(2):
+            res=f.getValueOn(loc[2*j:2*j+2]);
+            for i in xrange(3):
+                self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12);
+                pass
+            pass
+        fCpy=f.clone(True);
+        self.assertTrue(f.isEqual(fCpy,1e-12,1e-12));
+        f.renumberNodes(renumber1);
+        self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12));
+        for j in xrange(2):
+            res=f.getValueOn(loc[2*j:2*j+2]);
+            for i in xrange(3):
+                self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12);
+                pass
+            pass
+        expected2=[7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.]
+        for i in xrange(27):
+            self.assertTrue(abs(expected2[i]-f.getArray().getValues()[i])<1e-12);
+            pass
+        renumber2=[0,2,5,3,1,4,6,7,8]
+        f.renumberNodes(renumber2);
+        self.assertTrue(f.isEqual(fCpy,1e-12,1e-12));
+        pass
+
+    def testConvertQuadraticCellsToLinear(self):
+        mesh=MEDCouplingDataForTest.build2DTargetMesh_3();
+        mesh.checkCoherency();
+        types=mesh.getAllTypes();
+        types.sort()
+        self.assertEqual(5,len(types));
+        expected1=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4, NORM_TRI6, NORM_QUAD8]
+        expected1.sort()
+        self.assertTrue(expected1==types);
+        self.assertTrue(mesh.isPresenceOfQuadratic());
+        self.assertEqual(62,mesh.getMeshLength());
+        f1=mesh.getMeasureField(False);
+        #
+        mesh.convertQuadraticCellsToLinear();
+        self.assertTrue(not mesh.isPresenceOfQuadratic());
+        #
+        mesh.checkCoherency();
+        f2=mesh.getMeasureField(False);
+        self.assertTrue(f1.getArray().isEqual(f2.getArray(),1e-12));
+        self.assertEqual(48,mesh.getMeshLength());
+        types2=mesh.getAllTypes();
+        types2.sort()
+        self.assertEqual(3,len(types2));
+        expected2=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4]
+        expected2.sort()
+        self.assertTrue(expected2==types2);
+        pass
+
+    def testCheckGeoEquivalWith(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        #First test mesh1
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,0,1e-12);#deepEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,1,1e-12);#fastEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        #Second test mesh1 and mesh2 are 2 different meshes instance
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,0,1e-12);#deepEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        #Third test : cell permutation by keeping the first the middle and the last as it is.
+        renum=[0,2,1,3,4,5,6,8,7,9]
+        mesh2.renumberCells(renum,False);
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor);
+        self.assertEqual(10,cellCor.getNumberOfTuples());
+        self.assertEqual(1,cellCor.getNumberOfComponents());
+        self.assertEqual(renum,list(cellCor.getValues()))
+        self.assertTrue(nodeCor==None);
+        cellCor=0;
+        self.assertTrue(nodeCor==None);
+        #4th test : cell and node permutation by keeping the first the middle and the last as it is.
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        renum2=[0,2,1,3,4,5,6,8,7,9,10]
+        mesh2.renumberCells(renum,False);
+        mesh2.renumberNodes(renum2,11);
+        cellCor=None
+        nodeCor=None
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor);
+        self.assertEqual(10,cellCor.getNumberOfTuples());
+        self.assertEqual(1,cellCor.getNumberOfComponents());
+        self.assertEqual(renum,list(cellCor.getValues()))
+        self.assertTrue(nodeCor);
+        self.assertEqual(11,nodeCor.getNumberOfTuples());
+        self.assertEqual(1,nodeCor.getNumberOfComponents());
+        self.assertEqual(renum2,list(nodeCor.getValues()))
+        cellCor=0;
+        nodeCor=0;
+        #5th test : modification of the last cell to check fastCheck detection.
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        renum3=[0,2,1,3,4,5,6,8,9,7]
+        mesh2.renumberCells(renum3,False);
+        mesh2.renumberNodes(renum2,11);
+        cellCor=None
+        nodeCor=None
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12)
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,1,1e-12)
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh2.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor!=None);
+        self.assertEqual(10,cellCor.getNumberOfTuples());
+        self.assertEqual(1,cellCor.getNumberOfComponents());
+        self.assertEqual(renum3,list(cellCor.getValues()))
+        self.assertTrue(nodeCor!=None);
+        self.assertEqual(11,nodeCor.getNumberOfTuples());
+        self.assertEqual(1,nodeCor.getNumberOfComponents());
+        self.assertEqual(renum2,list(nodeCor.getValues()));
+        pass
+
+    def testCheckGeoEquivalWith2(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_4();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);
+        self.assertEqual(None,cellCor);
+        self.assertNotEqual(None,nodeCor);
+        expected1=[0, 1, 3, 4, 5, 6, 7, 8, 9]
+        for i in xrange(9):
+            self.assertEqual(expected1[i],nodeCor.getIJ(i,0));
+            pass
+        pass
+
+    def testCopyTinyStringsFromOnFields(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        nbOfCells=m.getNumberOfCells();
+        f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME);
+        f.setMesh(m);
+        f.setName("a");
+        f.setDescription("b");
+        a1=DataArrayDouble.New();
+        a1.alloc(nbOfCells,2);
+        a1.fillWithZero();
+        a1.setInfoOnComponent(0,"c");
+        a1.setInfoOnComponent(1,"d");
+        a2=a1.deepCopy();
+        a2.setInfoOnComponent(0,"e");
+        a2.setInfoOnComponent(1,"f");
+        f.setArray(a1);
+        f.setEndArray(a2);
+        f.setEndTime(3.,3,4);
+        m.setName("g");
+        m.getCoords().setInfoOnComponent(0,"h");
+        m.getCoords().setInfoOnComponent(1,"i");
+        m.getCoords().setInfoOnComponent(2,"j");
+        #
+        f.checkCoherency();
+        f2=f.clone(True);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.setName("smth");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.setDescription("GGG");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.getArray().setInfoOnComponent(0,"mmmm");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.getEndArray().setInfoOnComponent(1,"mmmm");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        m2=m.clone(True);
+        self.assertTrue(m2.isEqual(m,1e-12));
+        m2.setName("123");
+        self.assertTrue(not m2.isEqual(m,1e-12));
+        m2.copyTinyStringsFrom(m);
+        self.assertTrue(m2.isEqual(m,1e-12));
+        m2.getCoords().setInfoOnComponent(1,"eee");
+        self.assertTrue(not m2.isEqual(m,1e-12));
+        m2.copyTinyStringsFrom(m);
+        self.assertTrue(m2.isEqual(m,1e-12));
+        pass
+
+    def testTryToShareSameCoordsPermute(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        #self.assertTrue(m.getCoords()!=m2.getCoords());
+        m.tryToShareSameCoordsPermute(m2,1e-12);
+        #self.assertTrue(m.getCoords()==m2.getCoords());
+        self.assertTrue(m2.isEqual(m,1e-12));
+        renum1=[1,2,0,5,8,7,4,3,6]
+        m.renumberNodes(renum1,9);
+        #self.assertTrue(m.getCoords()!=m2.getCoords());
+        self.assertTrue(not m2.isEqual(m,1e-12));
+        m.tryToShareSameCoordsPermute(m2,1e-12);
+        #self.assertTrue(m.getCoords()==m2.getCoords());
+        self.assertTrue(m2.isEqual(m,1e-12));
+        pass
+
+    def testTryToShareSameCoordsPermute2(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_4();
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 ]
+        targetConn=[0,2,3,1]
+        m2=MEDCouplingUMesh.New();
+        m2.setMeshDimension(2);
+        m2.allocateCells(1);
+        m2.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        m2.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,4,2);
+        m2.setCoords(myCoords);
+        m2.checkCoherency();
+        m1.checkCoherency();
+        #
+        expected1=[0.25,0.125,0.125,0.25,0.25]
+        f1=m1.getMeasureField(False);
+        f2=m2.getMeasureField(False);
+        self.assertEqual(5,f1.getArray().getNumberOfTuples());
+        self.assertEqual(1,f2.getArray().getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12);
+            pass
+        self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12);
+        self.assertRaises(Exception,m1.tryToShareSameCoordsPermute,m2,1e-12);# <- here in this order the sharing is impossible.
+        # Let's go for deeper test of tryToShareSameCoordsPermute
+        m2.tryToShareSameCoordsPermute(m1,1e-12);
+        f1=m1.getMeasureField(False);
+        f2=m2.getMeasureField(False);
+        self.assertEqual(5,f1.getArray().getNumberOfTuples());
+        self.assertEqual(1,f2.getArray().getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12);
+            pass
+        self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12);
+        pass
+
+    def testChangeUnderlyingMesh1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr=[7., 107., 8., 108., 9., 109., 10., 110., 11., 111., 12., 112., 13., 113., 14., 114., 15., 115., 16., 116.]
+        array.setValues(arr,mesh1.getNumberOfCells(),2);
+        f1.setArray(array);
+        #
+        renum=[0,2,1,3,4,5,6,8,7,9]
+        mesh2.renumberCells(renum,False);
+        #self.assertTrue(f1.getMesh()==mesh1);
+        f1.changeUnderlyingMesh(mesh1,10,1e-12);# nothing done only to check that nothing done.
+        #self.assertTrue(f1.getMesh()==mesh1);
+        f1.changeUnderlyingMesh(mesh2,10,1e-12);
+        #self.assertTrue(f1.getMesh()==mesh2);
+        expected1=[7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.]
+        for i in xrange(20):
+            self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12);
+            pass
+        #
+        f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr2=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.]
+        array.setValues(arr2,mesh1.getNumberOfNodes(),2);
+        f1.setArray(array);
+        #
+        renum2=[0,2,10,3,4,5,6,8,7,9,1]
+        mesh2.renumberNodes(renum2,11);
+        #self.assertTrue(f1.getMesh()==mesh1);
+        f1.changeUnderlyingMesh(mesh2,10,1e-12);
+        #self.assertTrue(f1.getMesh()==mesh2);
+        expected2=[7.,107.,9.,109.,17.,117.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,8.,108.]
+        for i in xrange(22):
+            self.assertAlmostEqual(expected2[i],f1.getArray().getIJ(0,i),12);
+            pass
+        pass
+
+    def testGetMaxValue1(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        nbOfCells=m.getNumberOfCells();
+        f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME);
+        f.setMesh(m);
+        a1=DataArrayDouble.New();
+        val1=[3.,4.,5.,6.,7.]
+        a1.setValues(val1,nbOfCells,1);
+        a2=DataArrayDouble.New();
+        val2=[0.,1.,2.,8.,7.]
+        a2.setValues(val2,nbOfCells,1);
+        f.setArray(a1);
+        f.setEndArray(a2);
+        f.setEndTime(3.,3,4);
+        f.checkCoherency();
+        #
+        self.assertAlmostEqual(8.,f.getMaxValue(),14);
+        self.assertAlmostEqual(0.,f.getMinValue(),14);
+        self.assertAlmostEqual(5.,f.getAverageValue(),14);
+        self.assertAlmostEqual(5.125,f.getWeightedAverageValue(),14);
+        a1.setIJ(0,2,9.5);
+        self.assertAlmostEqual(9.5,f.getMaxValue(),14);
+        self.assertAlmostEqual(0.,f.getMinValue(),14);
+        a2.setIJ(0,0,9.);
+        self.assertAlmostEqual(9.5,f.getMaxValue(),14);
+        self.assertAlmostEqual(1.,f.getMinValue(),14);
+        pass
+
+    def testSubstractInPlaceDM1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.]
+        array.setValues(arr,mesh1.getNumberOfCells(),2);
+        f1.setArray(array);
+        #
+        self.assertEqual(10,f1.getNumberOfTuples());
+        self.assertEqual(2,f1.getNumberOfComponents());
+        self.assertEqual(20,f1.getNumberOfValues());
+        #
+        renum=[0,2,1,3,4,5,6,8,7,9]
+        mesh2.renumberCells(renum,False);
+        #
+        f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f2.setMesh(mesh2);
+        array=DataArrayDouble.New();
+        arr2=[7.1,107.1,9.1,109.1,8.1,108.1,10.1,110.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1]
+        array.setValues(arr2,mesh2.getNumberOfCells(),2);
+        f2.setArray(array);
+        #
+        f1.substractInPlaceDM(f2,10,1e-12);
+        f1.applyFunc(1,"abs(x+y+0.2)");
+        self.assertAlmostEqual(0.,f1.getMaxValue(),13);
+        pass
+
+    def testDotCrossProduct1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setTime(2.3,5,6);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.]
+        array.setValues(arr1,mesh1.getNumberOfCells(),3);
+        f1.setArray(array);
+        f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f2.setTime(7.8,4,5);
+        f2.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr2=[1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.]
+        array.setValues(arr2,mesh1.getNumberOfCells(),3);
+        f2.setArray(array);
+        #
+        f3=f1.dot(f2);
+        expected1=[842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.]
+        for i in xrange(10):
+            self.assertAlmostEqual(expected1[i],f3.getIJ(i,0),9);
+            pass
+        #
+        f4=f1.crossProduct(f2);
+        expected2=[-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9);
+            pass
+        pass
+
+    def testMinMaxFields1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setTime(2.3,5,6);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.]
+        array.setValues(arr1,mesh1.getNumberOfCells(),3);
+        f1.setArray(array);
+        f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f2.setTime(7.8,4,5);
+        f2.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr2=[6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.]
+        array.setValues(arr2,mesh1.getNumberOfCells(),3);
+        f2.setArray(array);
+        #
+        f3=f1.max(f2);
+        expected1=[7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),9);
+            pass
+        #
+        f4=f1.min(f2);
+        expected2=[6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9);
+            pass
+        #
+        pass
+
+    def testApplyLin1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.]
+        array.setValues(arr,mesh1.getNumberOfCells(),2);
+        f1.setArray(array);
+        #
+        f1.applyLin(2.,3.,0);
+        expected1=[17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.]
+        for i in xrange(20):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),9);
+            pass
+        #
+        arr2=[2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.]
+        array=DataArrayDouble.New();
+        array.setValues(arr2,mesh1.getNumberOfCells(),2);
+        f1.setEndArray(array);
+        #
+        f1.applyLin(4.,5.,1);
+        #
+        expected2=[17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.]
+        for i in xrange(20):
+            self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),9);
+            pass
+        expected3=[2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.]
+        for i in xrange(20):
+            self.assertAlmostEqual(expected3[i],f1.getEndArray().getIJ(0,i),9);
+            pass
+        #
+        pass
+
+    def testGetIdsInRange1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setTime(2.3,5,6);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[2.,8.,6.,5.,11.,7.,9.,3.,10.,4.]
+        array.setValues(arr1,mesh1.getNumberOfCells(),1);
+        f1.setArray(array);
+        #
+        f1.checkCoherency();
+        da=f1.getIdsInRange(2.9,7.1);
+        self.failUnlessEqual(5,da.getNbOfElems());
+        expected1=[2,3,5,7,9]
+        self.failUnlessEqual(expected1,list(da.getValues()));
+        da=f1.getIdsInRange(8.,12.);
+        self.failUnlessEqual(4,da.getNbOfElems());
+        expected2=[1,4,6,8]
+        self.failUnlessEqual(expected2,list(da.getValues()));
+        #
+        pass
+
+    def testBuildSubPart1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setTime(2.3,5,6);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.]
+        array.setValues(arr1,mesh1.getNumberOfCells(),2);
+        f1.setArray(array);
+        #
+        part1=[2,1,4]
+        f2=f1.buildSubPart(part1);
+        self.failUnlessEqual(3,f2.getNumberOfTuples());
+        self.failUnlessEqual(2,f2.getNumberOfComponents());
+        expected1=[5.,105.,4.,104.,7.,107.]
+        for i in xrange(6):
+            self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12);
+            pass
+        self.failUnlessEqual(3,f2.getMesh().getNumberOfCells());
+        self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes());
+        self.failUnlessEqual(2,f2.getMesh().getSpaceDimension());
+        self.failUnlessEqual(2,f2.getMesh().getMeshDimension());
+        m2C=f2.getMesh();
+        self.failUnlessEqual(13,m2C.getMeshLength());
+        expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7]
+        for i in xrange(12):
+            self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12);
+            pass
+        expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2]
+        self.failUnlessEqual(expected3,list(m2C.getNodalConnectivity().getValues()));
+        expected4=[0,4,8,13]
+        self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues()));
+        # Test with field on nodes.
+        f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME);
+        f1.setTime(2.3,5,6);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.]
+        array.setValues(arr2,mesh1.getNumberOfNodes(),2);
+        f1.setArray(array);
+        part2=[1,4,2,5]
+        f2=f1.buildSubPart(part2);
+        self.failUnlessEqual(4,f2.getNumberOfTuples());
+        self.failUnlessEqual(2,f2.getNumberOfComponents());
+        expected5=[4.,104.,5.,105.,7.,107.,8.,108.]
+        for i in xrange(8):
+            self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12);
+            pass
+        self.failUnlessEqual(2,f2.getMesh().getNumberOfCells());
+        self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes());
+        self.failUnlessEqual(2,f2.getMesh().getSpaceDimension());
+        self.failUnlessEqual(2,f2.getMesh().getMeshDimension());
+        m2C=f2.getMesh();
+        self.failUnlessEqual(8,m2C.getMeshLength());
+        for i in xrange(8):#8 is not an error
+            self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12);
+            pass
+        self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:]);
+        self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]);
+        self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues()));
+        #idem previous because nodes of cell#4 are not fully present in part3
+        part3=[1,4,2,5,7]
+        arrr=DataArrayInt.New();
+        arrr.setValues(part3,5,1);
+        f2=f1.buildSubPart(arrr);
+        self.failUnlessEqual(4,f2.getNumberOfTuples());
+        self.failUnlessEqual(2,f2.getNumberOfComponents());
+        for i in xrange(8):
+            self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12);
+            pass
+        self.failUnlessEqual(2,f2.getMesh().getNumberOfCells());
+        self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes());
+        self.failUnlessEqual(2,f2.getMesh().getSpaceDimension());
+        self.failUnlessEqual(2,f2.getMesh().getMeshDimension());
+        m2C=f2.getMesh();
+        self.failUnlessEqual(8,m2C.getMeshLength());
+        for i in xrange(8):#8 is not an error
+            self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12);
+            pass
+        self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:8]);
+        self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]);
+        self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues()));
+        #
+        part4=[1,4,2,5,7,8]
+        f2=f1.buildSubPart(part4);
+        self.failUnlessEqual(6,f2.getNumberOfTuples());
+        self.failUnlessEqual(2,f2.getNumberOfComponents());
+        expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.]
+        for i in xrange(12):
+            self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12);
+            pass
+        self.failUnlessEqual(3,f2.getMesh().getNumberOfCells());
+        self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes());
+        self.failUnlessEqual(2,f2.getMesh().getSpaceDimension());
+        self.failUnlessEqual(2,f2.getMesh().getMeshDimension());
+        m2C=f2.getMesh();
+        self.failUnlessEqual(13,m2C.getMeshLength());
+        for i in xrange(12):
+            self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12);
+            pass
+        self.failUnlessEqual(expected3[0:4],list(m2C.getNodalConnectivity().getValues())[4:8]);
+        self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[0:4]);
+        self.failUnlessEqual(expected3[8:13],list(m2C.getNodalConnectivity().getValues())[8:13]);
+        self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues()));
+        pass
+
+    def testDoublyContractedProduct1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.doublyContractedProduct();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(3906.56,f2.getIJ(i,0),9);
+            pass
+        #
+        pass
+
+    def testDeterminant1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL);
+        f1.setTime(2.3,5,6);
+        f1.setEndTime(3.8,7,3);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5]
+        array.setValues(arr1,mesh1.getNumberOfCells(),4);
+        f1.setArray(array);
+        #4 components
+        f1.checkCoherency();
+        f2=f1.determinant();
+        f2.checkCoherency();
+        self.assertEqual(CONST_ON_TIME_INTERVAL,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfValues());
+        for i in xrange(5):
+            self.assertAlmostEqual(-2.42,f2.getIJ(i,0),13);
+            pass
+        #6 components multi arrays with end array not defined
+        f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME);
+        f1.setTime(2.3,5,6);
+        f1.setEndTime(3.8,7,3);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr2=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7,
+              1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr2,mesh1.getNumberOfNodes(),6);
+        f1.setArray(array);
+        self.assertRaises(Exception,f1.checkCoherency);#no end array specified !
+        #
+        f2=f1.determinant();
+        self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getArray().getNumberOfComponents());
+        self.assertEqual(9,f2.getNumberOfTuples());
+        for i in xrange(9):
+            self.assertAlmostEqual(137.335,f2.getIJ(i,0),10);
+            pass
+        #6 components multi arrays with end array defined
+        array=DataArrayDouble.New();
+        arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5,
+              7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr3,mesh1.getNumberOfNodes(),6);
+        f1.setEndArray(array);
+        f1.checkCoherency();
+        f2=f1.determinant();
+        f2.checkCoherency();
+        self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(9,f2.getNumberOfTuples());
+        time2,it,order=f2.getTime()
+        self.assertAlmostEqual(2.3,time2,12);
+        self.assertEqual(5,it);
+        self.assertEqual(6,order);
+        time2,it,order=f2.getEndTime()
+        self.assertAlmostEqual(3.8,time2,12);
+        self.assertEqual(7,it);
+        self.assertEqual(3,order);
+        for i in xrange(9):
+            self.assertAlmostEqual(137.335,f2.getIJ(i,0),10);
+            self.assertAlmostEqual(1289.685,f2.getEndArray().getIJ(i,0),9);
+            pass
+        #9 components
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setTime(7.8,10,2);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr4=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1]
+        array.setValues(arr4,mesh1.getNumberOfCells(),9);
+        f1.setArray(array);
+        #
+        f1.checkCoherency();
+        f2=f1.determinant();
+        f2.checkCoherency();
+        self.assertEqual(ONE_TIME,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        time2,it,order=f2.getTime()
+        self.assertAlmostEqual(7.8,time2,12);
+        self.assertEqual(10,it);
+        self.assertEqual(2,order);
+        for i in xrange(5):
+            self.assertAlmostEqual(3.267,f2.getIJ(i,0),13);
+            pass
+        pass
+
+    def testEigenValues1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.eigenValues();
+        f2.checkCoherency();
+        self.assertEqual(3,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[13.638813677891717,-4.502313844635971,-2.2364998332557486]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13);
+            pass
+        pass
+
+    def testEigenVectors1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.eigenVectors();
+        f2.checkCoherency();
+        self.assertEqual(9,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[0.5424262364180696, 0.5351201064614425, 0.6476266283176001,#eigenvect 0
+                   0.7381111277307373, 0.06458838384003074, -0.6715804522117897,#eigenvect 1
+                   -0.4012053603397987, 0.8423032781211455, -0.3599436712889738#eigenvect 2
+                   ]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13);
+            self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13);
+            self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13);
+            self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13);
+            self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13);
+            self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13);
+            pass
+        #
+        pass
+
+    def testInverse1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1]
+        array.setValues(arr1,mesh1.getNumberOfCells(),9);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.inverse();
+        f2.checkCoherency();
+        self.assertEqual(9,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13);
+            self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13);
+            self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13);
+            self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13);
+            self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13);
+            self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr3,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.inverse();
+        f2.checkCoherency();
+        self.assertEqual(6,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected3=[-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected3[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected3[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected3[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected3[3],f2.getIJ(i,3),13);
+            self.assertAlmostEqual(expected3[4],f2.getIJ(i,4),13);
+            self.assertAlmostEqual(expected3[5],f2.getIJ(i,5),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5]
+        array.setValues(arr2,mesh1.getNumberOfCells(),4);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.inverse();
+        f2.checkCoherency();
+        self.assertEqual(4,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected2=[-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected2[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected2[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected2[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected2[3],f2.getIJ(i,3),13);
+            pass
+        #
+        pass
+
+    def testTrace1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1]
+        array.setValues(arr1,mesh1.getNumberOfCells(),9);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.trace();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(15.9,f2.getIJ(i,0),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr3,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.trace();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(25.8,f2.getIJ(i,0),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5]
+        array.setValues(arr2,mesh1.getNumberOfCells(),4);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.trace();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(5.7,f2.getIJ(i,0),13);
+            pass
+        #
+        pass
+
+    def testDeviator1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.deviator();
+        f2.checkCoherency();
+        self.assertEqual(6,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[-1.1,0.,1.1,4.5,5.6,6.7]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13);
+            self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13);
+            self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13);
+            pass
+        #
+        pass
+
+    def testMagnitude1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.magnitude();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(8.3606219864313918,f2.getIJ(i,0),13);
+            pass
+        #
+        pass
+
+    def testMaxPerTuple1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.maxPerTuple();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(5.6,f2.getIJ(i,0),13);
+            pass
+        #
+        pass
+
+    def testChangeNbOfComponents(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f1.changeNbOfComponents(3,7.77);
+        f1.checkCoherency();
+        self.assertEqual(3,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        expected1=[1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2]
+        for i in xrange(15):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),13);
+            pass
+        f1.changeNbOfComponents(4,7.77);
+        f1.checkCoherency();
+        self.assertEqual(4,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        expected2=[1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77]
+        for i in xrange(20):
+            self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),13);
+            pass
+        #
+        pass
+
+    def testSortPerTuple1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f1.sortPerTuple(True);
+        f1.checkCoherency();
+        self.assertEqual(5,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(arr1[0],f1.getIJ(i,0),13);
+            self.assertAlmostEqual(arr1[1],f1.getIJ(i,1),13);
+            self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13);
+            self.assertAlmostEqual(arr1[3],f1.getIJ(i,3),13);
+            self.assertAlmostEqual(arr1[4],f1.getIJ(i,4),13);
+            pass
+        #
+        f1.sortPerTuple(False);
+        f1.checkCoherency();
+        self.assertEqual(5,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(arr1[4],f1.getIJ(i,0),13);
+            self.assertAlmostEqual(arr1[3],f1.getIJ(i,1),13);
+            self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13);
+            self.assertAlmostEqual(arr1[1],f1.getIJ(i,3),13);
+            self.assertAlmostEqual(arr1[0],f1.getIJ(i,4),13);
+            pass
+        #
+        pass
+
+    def testIsEqualWithoutConsideringStr1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        #
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        mesh2.setName("rr");
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        da1,da2=mesh1.checkGeoEquivalWith(mesh2,2,1e-12);
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);
+        mesh2.setName("");
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        mesh2.getCoords().setInfoOnComponent(0,"tty");
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        mesh2.getCoords().setInfoOnComponent(0,"");
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        mesh2.getCoords().setInfoOnComponent(1,"tty");
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        mesh2.getCoords().setInfoOnComponent(1,"");
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        tmp=mesh2.getCoords().getIJ(0,3);
+        mesh2.getCoords().setIJ(0,3,9999.);
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        mesh2.getCoords().setIJ(0,3,tmp);
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        tmp2=mesh2.getNodalConnectivity().getIJ(0,4);
+        mesh2.getNodalConnectivity().setIJ(0,4,0);
+        self.assertTrue(not mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        mesh2.getNodalConnectivity().setIJ(0,4,tmp2);
+        self.assertTrue(mesh1.isEqual(mesh2,1e-12));
+        self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12));
+        #
+        f1=mesh1.getMeasureField(True);
+        f2=mesh2.getMeasureField(True);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+        f2.setName("ftest");
+        self.assertTrue(not f1.isEqual(f2,1e-12,1e-12));
+        self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+        f1.setName("ftest");
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+        #
+        f2.getArray().setInfoOnComponent(0,"eee");
+        self.assertTrue(not f1.isEqual(f2,1e-12,1e-12));
+        self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+        f2.getArray().setInfoOnComponent(0,"");
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+        #
+        f2.getArray().setIJ(1,0,0.123);
+        self.assertTrue(not f1.isEqual(f2,1e-12,1e-12));
+        self.assertTrue(not f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+        f2.getArray().setIJ(1,0,0.125);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12));
+        #
+        pass
+    def testGetNodeIdsOfCell1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        li=mesh1.getNodeIdsOfCell(1)
+        expected1=[1, 4, 2]
+        self.assertEqual(expected1,list(li))
+        li=mesh1.getCoordinatesOfNode(4)
+        self.assertEqual(2,len(li))
+        self.assertAlmostEqual(0.2,li[0],13);
+        self.assertAlmostEqual(0.2,li[1],13);
+        li=mesh1.getCoords().getValuesAsTuple()
+        self.assertEqual(9,len(li))
+        li2=mesh1.getNodalConnectivityIndex().getValuesAsTuple()
+        self.assertEqual(6,len(li2))
+        pass
+
+    def testGetEdgeRatioField1(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=m1.getEdgeRatioField();
+        self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        self.assertEqual(1,f1.getNumberOfComponents());
+        expected1=[1.,1.4142135623730951, 1.4142135623730951,1.,1.]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),14);
+            pass
+        #
+        m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        f1=m1.getEdgeRatioField();
+        self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        self.assertEqual(1,f1.getNumberOfComponents());
+        expected2=[1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected2[i],f1.getIJ(i,0),14);
+            pass
+        pass
+
+    def testFillFromAnalytic3(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1()
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME)
+        self.assertRaises(Exception,f1.fillFromAnalytic,1,"y+x");
+        f1.setMesh(m)
+        f1.setName("myField");
+        f1.fillFromAnalytic(1,"y+x");
+        f1.checkCoherency();
+        self.assertEqual(f1.getName(),"myField");
+        self.assertEqual(f1.getTypeOfField(),ON_CELLS);
+        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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values1),len(tmp))
+        for i in xrange(len(values1)):
+            self.assertTrue(abs(values1[i]-tmp[i])<1.e-12);
+            pass
+        #
+        f1=MEDCouplingFieldDouble.New(ON_NODES,CONST_ON_TIME_INTERVAL)
+        f1.setMesh(m)
+        f1.fillFromAnalytic(1,"y+2*x");
+        f1.setEndTime(1.2,3,4);
+        f1.checkCoherency();
+        self.assertEqual(f1.getTypeOfField(),ON_NODES);
+        self.assertEqual(f1.getTimeDiscretization(),CONST_ON_TIME_INTERVAL);
+        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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values2),len(tmp))
+        for i in xrange(len(values2)):
+            self.assertTrue(abs(values2[i]-tmp[i])<1.e-12);
+            pass
+        f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME);
+        f1.setMesh(m)
+        f1.fillFromAnalytic(1,"2.*x+y");
+        f1.setEndTime(1.2,3,4);
+        f1.checkCoherency();
+        self.assertEqual(f1.getTypeOfField(),ON_NODES);
+        self.assertEqual(f1.getTimeDiscretization(),LINEAR_TIME);
+        self.assertEqual(1,f1.getNumberOfComponents());
+        self.assertEqual(9,f1.getNumberOfTuples());
+        tmp=f1.getArray().getValues();
+        values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1]
+        self.assertEqual(len(values2Bis),len(tmp))
+        for i in xrange(len(values2Bis)):
+            self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12);
+            pass
+        tmp=f1.getEndArray().getValues();
+        self.assertEqual(len(values2Bis),len(tmp))
+        for i in xrange(len(values2Bis)):
+            self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12);
+            pass
+        #
+        f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME);
+        f1.setMesh(m)
+        f1.fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec");
+        f1.checkCoherency();
+        self.assertEqual(f1.getTypeOfField(),ON_NODES);
+        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]
+        tmp=f1.getArray().getValues();
+        self.assertEqual(len(values3),len(tmp))
+        for i in xrange(len(values3)):
+            self.assertTrue(abs(values3[i]-tmp[i])<1.e-12);
+            pass
+        values4=f1.accumulate();
+        self.assertTrue(abs(3.6-values4[0])<1.e-12);
+        self.assertTrue(abs(7.2-values4[1])<1.e-12);
+        values4=f1.integral(True);
+        self.assertTrue(abs(0.5-values4[0])<1.e-12);
+        self.assertTrue(abs(1.-values4[1])<1.e-12);
+        #
+        f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME);
+        f1.setMesh(m);
+        self.assertRaises(Exception,f1.fillFromAnalytic,1,"1./(x-0.2)");
+        pass
+
+    def testFieldDoubleOpEqual1(self):
+        m=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        self.assertRaises(Exception,f1.assign,0.07);
+        f1.setMesh(m);
+        f1.assign(0.07);
+        f1.checkCoherency();
+        self.assertEqual(1,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(0.07,f1.getIJ(i,0),16);
+            pass
+        f1.assign(0.09);
+        f1.checkCoherency();
+        self.assertEqual(1,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(0.09,f1.getIJ(i,0),16);
+            pass
+        #
+        f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME);
+        f1.setEndTime(4.5,2,3);
+        f1.setMesh(m);
+        f1.assign(0.08);
+        f1.checkCoherency();
+        self.assertEqual(1,f1.getNumberOfComponents());
+        self.assertEqual(9,f1.getNumberOfTuples());
+        for i in xrange(9):
+            self.assertAlmostEqual(0.08,f1.getIJ(i,0),16);
+            pass
+        self.assertEqual(1,f1.getEndArray().getNumberOfComponents());
+        self.assertEqual(9,f1.getEndArray().getNumberOfTuples());
+        for i in xrange(9):
+            self.assertAlmostEqual(0.08,f1.getEndArray().getIJ(i,0),16);
+            pass
+        pass
+
+    def testAreaBary3D2(self):
+        coordsForHexa8=[-75.45749305371, 180.95495078401, 39.515472018008,
+                        -9.755591679144, 23.394927935279, 5.108794294848,
+                        14.337630157832, 61.705351002702, 160.42422501908,
+                        -27.273893776752, 167.567731083961, 192.830034145464,
+                        99.857193154796,264.499264735586,-8.287335493412,
+                        144.939882761126,156.38626563134,-31.896173894226,
+                        161.34096835726,182.4654895809,73.832387065572,
+                        132.680430393685,255.37973247196,96.15235602819];
+        volHexa8=3258520.29637466;
+        baryHexa8=[43.925705821778, 155.31893955289, 65.874418109644]
+        
+        coordsForPenta6=[-68.199829618726,178.938498373416,62.608505919588,
+                         8.461744647847,76.653979804423,165.00018874933,
+                         -27.273893776752,167.567731083961,192.830034145464,
+                         106.586501038965,262.629609408327,13.124533008813,
+                         155.465082847275,197.414118382622,78.408350795821,
+                         132.680430393685,255.37973247196,96.15235602819];
+        volPenta6=944849.868507338;
+        baryPenta6=[39.631002313543,182.692711783428,106.98540473964]
+        
+        coordsForPyra5=[132.680430393685,255.37973247196,96.15235602819,
+                        -27.273893776752,167.567731083961,192.830034145464,
+                        8.461744647847,76.653979804423,165.00018874933,
+                        155.465082847275,197.414118382622,78.408350795821,
+                        -68.199829618726,178.938498373416,62.608505919588];
+        volPyra5=756943.92980254;
+        baryPyra5=[29.204294116618,172.540129749156,118.01035951483]
+        mesh=MEDCouplingUMesh.New("Bary3D2",3);
+        coo=DataArrayDouble.New();
+        tmp=coordsForHexa8+coordsForPenta6+coordsForPyra5
+        coo.setValues(tmp,19,3);
+        mesh.setCoords(coo);
+        #
+        tmpConn=[0,1,2,3,4,5,6,7]
+        mesh.allocateCells(3);
+        mesh.insertNextCell(NORM_HEXA8,8,tmpConn[0:8])
+        mesh.insertNextCell(NORM_PENTA6,6,[i+8 for i in tmpConn])
+        mesh.insertNextCell(NORM_PYRA5,5,[i+14 for i in tmpConn])
+        mesh.finishInsertingCells();
+        mesh.checkCoherency();
+        mesh.mergeNodes(1e-7)
+        self.assertEqual(12,mesh.getNumberOfNodes());
+        vols=mesh.getMeasureField(True);
+        self.assertEqual(3,vols.getNumberOfTuples());
+        self.assertEqual(1,vols.getNumberOfComponents());
+        self.assertAlmostEqual(volHexa8,vols.getIJ(0,0),6);
+        self.assertAlmostEqual(volPenta6,vols.getIJ(1,0),7);
+        self.assertAlmostEqual(volPyra5,vols.getIJ(2,0),7);
+        bary=mesh.getBarycenterAndOwner();
+        self.assertEqual(3,bary.getNumberOfTuples());
+        self.assertEqual(3,bary.getNumberOfComponents());
+        self.assertAlmostEqual(baryHexa8[0],bary.getIJ(0,0),11);
+        self.assertAlmostEqual(baryHexa8[1],bary.getIJ(0,1),11);
+        self.assertAlmostEqual(baryHexa8[2],bary.getIJ(0,2),11);
+        self.assertAlmostEqual(baryPenta6[0],bary.getIJ(1,0),11);
+        self.assertAlmostEqual(baryPenta6[1],bary.getIJ(1,1),11);
+        self.assertAlmostEqual(baryPenta6[2],bary.getIJ(1,2),11);
+        self.assertAlmostEqual(baryPyra5[0],bary.getIJ(2,0),11);
+        self.assertAlmostEqual(baryPyra5[1],bary.getIJ(2,1),11);
+        self.assertAlmostEqual(baryPyra5[2],bary.getIJ(2,2),11);
+        pass
+
+    def testGetMeasureFieldCMesh1(self):
+        m=MEDCouplingCMesh.New();
+        da=DataArrayDouble.New();
+        discX=[2.3,3.4,5.8,10.2]
+        discY=[12.3,23.4,45.8]
+        discZ=[-0.7,1.2,1.25,2.13,2.67]
+        da.setValues(discX,4,1);
+        m.setCoordsAt(0,da);
+        m.checkCoherency();
+        self.assertEqual(4,m.getNumberOfNodes());
+        self.assertEqual(3,m.getNumberOfCells());
+        self.assertEqual(1,m.getSpaceDimension());
+        f=m.getMeasureField(True);
+        self.assertEqual(3,f.getNumberOfTuples());
+        self.assertEqual(1,f.getNumberOfComponents());
+        expected1=[1.1,2.4,4.4]
+        for i in xrange(3):
+            self.assertAlmostEqual(expected1[i],f.getIJ(i,0),12);
+            pass
+        coords=m.getCoordinatesAndOwner();
+        self.assertEqual(4,coords.getNumberOfTuples());
+        self.assertEqual(1,coords.getNumberOfComponents());
+        for i in xrange(4):
+            self.assertAlmostEqual(discX[i],coords.getIJ(i,0),12);
+            pass
+        coords=m.getBarycenterAndOwner();
+        self.assertEqual(3,coords.getNumberOfTuples());
+        self.assertEqual(1,coords.getNumberOfComponents());
+        expected1_3=[2.85,4.6,8.]
+        for i in xrange(3):
+            self.assertAlmostEqual(expected1_3[i],coords.getIJ(i,0),12);
+            pass
+        #
+        da=DataArrayDouble.New();
+        da.setValues(discY,3,1);
+        m.setCoordsAt(1,da);
+        m.checkCoherency();
+        self.assertEqual(12,m.getNumberOfNodes());
+        self.assertEqual(6,m.getNumberOfCells());
+        self.assertEqual(2,m.getSpaceDimension());
+        f=m.getMeasureField(True);
+        self.assertEqual(6,f.getNumberOfTuples());
+        self.assertEqual(1,f.getNumberOfComponents());
+        expected2=[12.21,26.64,48.84,24.64,53.76,98.56]
+        for i in xrange(6):
+            self.assertAlmostEqual(expected2[i],f.getIJ(i,0),12);
+            pass
+        coords=m.getCoordinatesAndOwner();
+        self.assertEqual(12,coords.getNumberOfTuples());
+        self.assertEqual(2,coords.getNumberOfComponents());
+        expected2_2=[2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8]
+        for i in xrange(24):
+            self.assertAlmostEqual(expected2_2[i],coords.getIJ(0,i),12);
+            pass
+        coords=m.getBarycenterAndOwner();
+        self.assertEqual(6,coords.getNumberOfTuples());
+        self.assertEqual(2,coords.getNumberOfComponents());
+        expected2_3=[2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6]
+        for i in xrange(12):
+            self.assertAlmostEqual(expected2_3[i],coords.getIJ(0,i),12);
+            pass
+        #
+        da=DataArrayDouble.New();
+        da.setValues(discZ,5,1);
+        m.setCoordsAt(2,da);
+        m.checkCoherency();
+        self.assertEqual(60,m.getNumberOfNodes());
+        self.assertEqual(24,m.getNumberOfCells());
+        self.assertEqual(3,m.getSpaceDimension());
+        f=m.getMeasureField(True);
+        self.assertEqual(24,f.getNumberOfTuples());
+        self.assertEqual(1,f.getNumberOfComponents());
+        expected3=[23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224]
+        for i in xrange(24):
+            self.assertAlmostEqual(expected3[i],f.getIJ(i,0),12);
+            pass
+        coords=m.getCoordinatesAndOwner();
+        self.assertEqual(60,coords.getNumberOfTuples());
+        self.assertEqual(3,coords.getNumberOfComponents());
+        expected3_2=[
+            2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7,
+            2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2,
+            2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25,
+            2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13,
+            2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67];
+        for i in xrange(180):
+            self.assertAlmostEqual(expected3_2[i],coords.getIJ(0,i),12);
+            pass
+        coords=m.getBarycenterAndOwner();
+        self.assertEqual(24,coords.getNumberOfTuples());
+        self.assertEqual(3,coords.getNumberOfComponents());
+        expected3_3=[
+            2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25,
+            2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225,
+            2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69,
+            2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4];
+        for i in xrange(72):
+            self.assertAlmostEqual(expected3_3[i],coords.getIJ(0,i),12);
+            pass
+        pass
+
+    def testFieldDoubleZipCoords1(self):
+        m=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1();
+        f=m.fillFromAnalytic(ON_NODES,2,"x*2.");
+        f.getArray().setInfoOnComponent(0,"titi");
+        f.getArray().setInfoOnComponent(1,"tutu");
+        f.checkCoherency();
+        self.assertEqual(18,f.getNumberOfTuples());
+        self.assertEqual(2,f.getNumberOfComponents());
+        expected1=[-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4]
+        for i in xrange(36):
+            self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12);
+            pass
+        self.assertTrue(f.zipCoords());
+        f.checkCoherency();
+        expected2=[-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12);
+            pass
+        self.assertTrue(not f.zipCoords());
+        f.checkCoherency();
+        for i in xrange(30):
+            self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12);
+            pass
+        self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi");
+        self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu");
+        pass
+
+    def testFieldDoubleZipConnectivity1(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cells1=[2,3,4]
+        m3_1=m2.buildPartOfMySelf(cells1,True);
+        m3=m3_1;
+        m4=MEDCouplingDataForTest.build2DSourceMesh_1();
+        m5=MEDCouplingUMesh.mergeUMeshes(m1,m3);
+        m6=MEDCouplingUMesh.mergeUMeshes(m5,m4);
+        #
+        self.assertEqual(10,m6.getNumberOfCells());
+        self.assertEqual(22,m6.getNumberOfNodes());
+        arr,areNodesMerged,newNbOfNodes=m6.mergeNodes(1e-13);
+        self.assertEqual(9,m6.getNumberOfNodes());
+        f=m6.fillFromAnalytic(ON_CELLS,2,"x");
+        f2=m6.fillFromAnalytic(ON_NODES,2,"x");
+        self.assertEqual(10,f.getNumberOfTuples());
+        self.assertEqual(2,f.getNumberOfComponents());
+        expected1=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321,
+                   -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45,
+                   0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326];
+        for i in xrange(20):
+            self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12);
+            pass
+        f.getArray().setInfoOnComponent(0,"titi");
+        f.getArray().setInfoOnComponent(1,"tutu");
+        f.checkCoherency();
+        self.assertTrue(f.zipConnectivity(0));
+        expected2=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321,
+                   -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326];
+        self.assertEqual(7,f.getNumberOfTuples());
+        self.assertEqual(2,f.getNumberOfComponents());
+        for i in xrange(14):
+            self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12);
+            pass
+        self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi");
+        self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu");
+        self.assertTrue(not f.zipConnectivity(0));
+        #
+        expected3=[-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7,
+                   -0.3, -0.3, 0.2, 0.2, 0.7, 0.7];
+        self.assertEqual(9,f2.getNumberOfTuples());
+        self.assertEqual(2,f2.getNumberOfComponents());
+        for i in xrange(18):
+            self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12);
+            pass
+        self.assertTrue(f2.zipConnectivity(0));
+        self.assertEqual(9,f2.getNumberOfTuples());
+        self.assertEqual(2,f2.getNumberOfComponents());
+        for i in xrange(18):
+            self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12);
+            pass
+        pass
+
+    def testDaDoubleRenumber1(self):
+        a=DataArrayDouble.New();
+        arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1]
+        a.setValues(arr1,7,2);
+        a.setInfoOnComponent(0,"toto");
+        a.setInfoOnComponent(1,"tata");
+        #
+        arr2=[3,1,0,6,5,4,2]
+        b=a.renumber(arr2);
+        self.assertEqual(7,b.getNumberOfTuples());
+        self.assertEqual(2,b.getNumberOfComponents());
+        self.assertTrue(b.getInfoOnComponent(0)=="toto");
+        self.assertTrue(b.getInfoOnComponent(1)=="tata");
+        expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1]
+        for i in xrange(14):
+            self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14);
+            pass
+        #
+        c=DataArrayInt.New();
+        arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17]
+        c.setValues(arr3,7,2);
+        c.setInfoOnComponent(0,"toto");
+        c.setInfoOnComponent(1,"tata");
+        d=c.renumber(arr2);
+        self.assertEqual(7,d.getNumberOfTuples());
+        self.assertEqual(2,d.getNumberOfComponents());
+        self.assertTrue(d.getInfoOnComponent(0)=="toto");
+        self.assertTrue(d.getInfoOnComponent(1)=="tata");
+        expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14]
+        for i in xrange(14):
+            self.assertEqual(expected2[i],d.getIJ(0,i));
+            pass
+        pass
+
+    def testDaDoubleRenumberAndReduce1(self):
+        a=DataArrayDouble.New();
+        arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1]
+        a.setValues(arr1,7,2);
+        a.setInfoOnComponent(0,"toto");
+        a.setInfoOnComponent(1,"tata");
+        #
+        arr2=[2,-1,1,-1,0,4,3]
+        b=a.renumberAndReduce(arr2,5);
+        self.assertEqual(5,b.getNumberOfTuples());
+        self.assertEqual(2,b.getNumberOfComponents());
+        self.assertTrue(b.getInfoOnComponent(0)=="toto");
+        self.assertTrue(b.getInfoOnComponent(1)=="tata");
+        expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1]
+        for i in xrange(10):
+            self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14);
+            pass
+        #
+        c=DataArrayInt.New();
+        arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17]
+        c.setValues(arr3,7,2);
+        c.setInfoOnComponent(0,"toto");
+        c.setInfoOnComponent(1,"tata");
+        d=c.renumberAndReduce(arr2,5);
+        self.assertEqual(5,d.getNumberOfTuples());
+        self.assertEqual(2,d.getNumberOfComponents());
+        self.assertTrue(d.getInfoOnComponent(0)=="toto");
+        self.assertTrue(d.getInfoOnComponent(1)=="tata");
+        expected2=[5,15,3,13,1,11,7,17,6,16]
+        for i in xrange(10):
+            self.assertEqual(expected2[i],d.getIJ(0,i));
+            pass
+        pass
+
+    def testDaDoubleRenumberInPlace1(self):
+        a=DataArrayDouble.New();
+        arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1]
+        a.setValues(arr1,7,2);
+        #
+        arr2=[3,1,0,6,5,4,2]
+        a.renumberInPlace(arr2);
+        self.assertEqual(7,a.getNumberOfTuples());
+        self.assertEqual(2,a.getNumberOfComponents());
+        expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1]
+        for i in xrange(14):
+            self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14);
+            pass
+        #
+        c=DataArrayInt.New();
+        arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17]
+        c.setValues(arr3,7,2);
+        c.renumberInPlace(arr2);
+        self.assertEqual(7,c.getNumberOfTuples());
+        self.assertEqual(2,c.getNumberOfComponents());
+        expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14]
+        for i in xrange(14):
+            self.assertEqual(expected2[i],c.getIJ(0,i));
+            pass
+        pass
+
+    def testDaDoubleRenumberR1(self):
+        a=DataArrayDouble.New();
+        arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1]
+        a.setValues(arr1,7,2);
+        a.setInfoOnComponent(0,"toto");
+        a.setInfoOnComponent(1,"tata");
+        #
+        arr2=[3,1,0,6,5,4,2]
+        b=a.renumberR(arr2);
+        self.assertEqual(7,b.getNumberOfTuples());
+        self.assertEqual(2,b.getNumberOfComponents());
+        self.assertTrue(b.getInfoOnComponent(0)=="toto");
+        self.assertTrue(b.getInfoOnComponent(1)=="tata");
+        expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1]
+        for i in xrange(14):
+            self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14);
+            pass
+        #
+        c=DataArrayInt.New();
+        arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17]
+        c.setValues(arr3,7,2);
+        c.setInfoOnComponent(0,"toto");
+        c.setInfoOnComponent(1,"tata");
+        d=c.renumberR(arr2);
+        self.assertEqual(7,d.getNumberOfTuples());
+        self.assertEqual(2,d.getNumberOfComponents());
+        self.assertTrue(d.getInfoOnComponent(0)=="toto");
+        self.assertTrue(d.getInfoOnComponent(1)=="tata");
+        expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13]
+        for i in xrange(14):
+            self.assertEqual(expected2[i],d.getIJ(0,i));
+            pass
+        pass
+
+    def testDaDoubleRenumberInPlaceR1(self):
+        a=DataArrayDouble.New();
+        arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1]
+        a.setValues(arr1,7,2);
+        #
+        arr2=[3,1,0,6,5,4,2]
+        a.renumberInPlaceR(arr2);
+        self.assertEqual(7,a.getNumberOfTuples());
+        self.assertEqual(2,a.getNumberOfComponents());
+        expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1]
+        for i in xrange(14):
+            self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14);
+            pass
+        #
+        c=DataArrayInt.New();
+        arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17]
+        c.setValues(arr3,7,2);
+        c.renumberInPlaceR(arr2);
+        self.assertEqual(7,c.getNumberOfTuples());
+        self.assertEqual(2,c.getNumberOfComponents());
+        expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13]
+        for i in xrange(14):
+            self.assertEqual(expected2[i],c.getIJ(0,i));
+            pass
+        pass
+
+    def testDaDoubleSelectByTupleId1(self):
+        a=DataArrayDouble.New();
+        arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1]
+        a.setValues(arr1,7,2);
+        a.setInfoOnComponent(0,"toto");
+        a.setInfoOnComponent(1,"tata");
+        #
+        arr2=[4,2,0,6,5]
+        b=a.selectByTupleId(arr2);
+        self.assertEqual(5,b.getNumberOfTuples());
+        self.assertEqual(2,b.getNumberOfComponents());
+        self.assertTrue(b.getInfoOnComponent(0)=="toto");
+        self.assertTrue(b.getInfoOnComponent(1)=="tata");
+        expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1]
+        for i in xrange(10):
+            self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14);
+            pass
+        #
+        c=DataArrayInt.New();
+        arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17]
+        c.setValues(arr3,7,2);
+        c.setInfoOnComponent(0,"toto");
+        c.setInfoOnComponent(1,"tata");
+        d=c.selectByTupleId(arr2);
+        self.assertEqual(5,d.getNumberOfTuples());
+        self.assertEqual(2,d.getNumberOfComponents());
+        self.assertTrue(d.getInfoOnComponent(0)=="toto");
+        self.assertTrue(d.getInfoOnComponent(1)=="tata");
+        expected2=[5,15,3,13,1,11,7,17,6,16]
+        for i in xrange(10):
+            self.assertEqual(expected2[i],d.getIJ(0,i));
+            pass
+        pass
+
+    def testDaDoubleGetMinMaxValues1(self):
+        a=DataArrayDouble.New();
+        arr1=[2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56]
+        a.setValues(arr1,9,1);
+        m,where=a.getMaxValue();
+        self.assertEqual(1,where);
+        self.assertAlmostEqual(4.56,m,12);
+        m,ws=a.getMaxValue2();
+        self.assertAlmostEqual(4.56,m,12);
+        self.assertEqual(3,ws.getNumberOfTuples());
+        self.assertEqual(1,ws.getNumberOfComponents());
+        expected1=[1,4,8]
+        for i in xrange(3):
+            self.assertEqual(expected1[i],ws.getIJ(i,0));
+            pass
+        a=DataArrayDouble.New();
+        arr2=[-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56]
+        a.setValues(arr2,9,1);
+        m,where=a.getMinValue();
+        self.assertEqual(1,where);
+        self.assertAlmostEqual(-4.56,m,12);
+        m,ws=a.getMinValue2();
+        self.assertAlmostEqual(-4.56,m,12);
+        self.assertEqual(3,ws.getNumberOfTuples());
+        self.assertEqual(1,ws.getNumberOfComponents());
+        for i in xrange(3):
+            self.assertEqual(expected1[i],ws.getIJ(i,0));
+            pass
+        pass
+
+    def testFieldDoubleGetMinMaxValues2(self):
+        m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1();
+        self.assertEqual(18,m2.getNumberOfCells());
+        arr1=[8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71]
+        f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        a=DataArrayDouble.New();
+        a.setValues(arr1,18,1);
+        f.setArray(a);
+        f.setMesh(m2);
+        #
+        f.checkCoherency();
+        m=f.getMaxValue();
+        self.assertAlmostEqual(8.71,m,12);
+        m,ws=f.getMaxValue2();
+        self.assertAlmostEqual(8.71,m,12);
+        self.assertEqual(4,ws.getNumberOfTuples());
+        self.assertEqual(1,ws.getNumberOfComponents());
+        expected1=[0,3,7,17]
+        for i in xrange(4):
+            self.assertEqual(expected1[i],ws.getIJ(i,0));
+            pass
+        #
+        arr2=[-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71]
+        a.setValues(arr2,18,1);
+        f.checkCoherency();
+        m=f.getMinValue();
+        self.assertAlmostEqual(-8.71,m,12);
+        m,ws=f.getMinValue2();
+        self.assertAlmostEqual(-8.71,m,12);
+        self.assertEqual(4,ws.getNumberOfTuples());
+        self.assertEqual(1,ws.getNumberOfComponents());
+        for i in xrange(4):
+            self.assertEqual(expected1[i],ws.getIJ(i,0));
+            pass
+        pass
+
+    def testBuildUnstructuredCMesh1(self):
+        m=MEDCouplingCMesh.New();
+        da=DataArrayDouble.New();
+        discX=[2.3,3.4,5.8,10.2]
+        discY=[12.3,23.4,45.8]
+        discZ=[-0.7,1.2,1.25,2.13,2.67]
+        da.setValues(discX,4,1);
+        m.setCoordsAt(0,da);
+        m.checkCoherency();
+        self.assertEqual(0,m.getCellContainingPoint([2.4],12));
+        self.assertEqual(1,m.getCellContainingPoint([3.7],12));
+        self.assertEqual(2,m.getCellContainingPoint([5.9],12));
+        self.assertEqual(-1,m.getCellContainingPoint([10.3],12));
+        self.assertEqual(-1,m.getCellContainingPoint([1.3],12));
+        #
+        m2=m.buildUnstructured();
+        m2.checkCoherency();
+        f1=m.getMeasureField(False);
+        f2=m2.getMeasureField(False);
+        self.assertTrue(isinstance(f1.getMesh(),MEDCouplingCMesh))
+        self.assertEqual(f1.getNumberOfTuples(),3);
+        self.assertEqual(f2.getNumberOfTuples(),3);
+        self.assertEqual(1,m2.getMeshDimension());
+        self.assertEqual(1,m2.getSpaceDimension());
+        for i in xrange(3):
+            self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10);
+            pass
+        da=DataArrayDouble.New();
+        da.setValues(discY,3,1);
+        m.setCoordsAt(1,da);
+        #
+        m2=m.buildUnstructured();
+        m2.checkCoherency();
+        f1=m.getMeasureField(False);
+        f2=m2.getMeasureField(False);
+        self.assertEqual(f1.getNumberOfTuples(),6);
+        self.assertEqual(f2.getNumberOfTuples(),6);
+        self.assertEqual(2,m2.getMeshDimension());
+        self.assertEqual(2,m2.getSpaceDimension());
+        for i in xrange(6):
+            self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10);
+            pass
+        #
+        da=DataArrayDouble.New();
+        da.setValues(discZ,5,1);
+        m.setCoordsAt(2,da);
+        m2=m.buildUnstructured();
+        m2.checkCoherency();
+        f1=m.getMeasureField(False);
+        f2=m2.getMeasureField(False);
+        self.assertEqual(f1.getNumberOfTuples(),24);
+        self.assertEqual(f2.getNumberOfTuples(),24);
+        self.assertEqual(3,m2.getMeshDimension());
+        self.assertEqual(3,m2.getSpaceDimension());
+        for i in xrange(24):
+            self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10);
+            pass
+        #
+        pos1=[5.,30.,2.]
+        self.assertEqual(16,m.getCellContainingPoint(pos1,1e-12));
+        #
+        pt=[2.4,12.7,-3.4]
+        m.scale(pt,3.7);
+        m3=m.buildUnstructured();
+        m2.scale(pt,3.7);
+        self.assertTrue(m3.isEqual(m2,1e-12));
+        pass
+
+    def testDataArrayIntInvertO2NNO21(self):
+        arr1=[2,0,4,1,5,3]
+        da=DataArrayInt.New();
+        da.setValues(arr1,6,1);
+        da2=da.invertArrayO2N2N2O(6);
+        self.assertEqual(6,da2.getNumberOfTuples());
+        self.assertEqual(1,da2.getNumberOfComponents());
+        expected1=[1,3,0,5,2,4]
+        for i in xrange(6):
+            self.assertEqual(expected1[i],da2.getIJ(i,0));
+            pass
+        da3=da2.invertArrayN2O2O2N(6);
+        for i in xrange(6):
+            self.assertEqual(arr1[i],da3.getIJ(i,0));
+            pass
+        #
+        arr2=[3,-1,5,4,-1,0,-1,1,2,-1]
+        da=DataArrayInt.New();
+        da.setValues(arr2,10,1);
+        da2=da.invertArrayO2N2N2O(6);
+        self.assertEqual(6,da2.getNumberOfTuples());
+        self.assertEqual(1,da2.getNumberOfComponents());
+        expected2=[5,7,8,0,3,2]
+        for i in xrange(6):
+            self.assertEqual(expected2[i],da2.getIJ(i,0));
+            pass
+        da3=da2.invertArrayN2O2O2N(10);
+        for i in xrange(10):
+            self.assertEqual(arr2[i],da3.getIJ(i,0));
+            pass
+        pass
+
+    def testDoublyContractedProduct1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.doublyContractedProduct();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(3906.56,f2.getIJ(i,0),9);
+            pass
+        #
+        pass
+
+    def testDeterminant1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL);
+        f1.setTime(2.3,5,6);
+        f1.setEndTime(3.8,7,3);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5]
+        array.setValues(arr1,mesh1.getNumberOfCells(),4);
+        f1.setArray(array);
+        #4 components
+        f1.checkCoherency();
+        f2=f1.determinant();
+        f2.checkCoherency();
+        self.assertEqual(CONST_ON_TIME_INTERVAL,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfValues());
+        for i in xrange(5):
+            self.assertAlmostEqual(-2.42,f2.getIJ(i,0),13);
+            pass
+        #6 components multi arrays with end array not defined
+        f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME);
+        f1.setTime(2.3,5,6);
+        f1.setEndTime(3.8,7,3);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr2=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7,
+              1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr2,mesh1.getNumberOfNodes(),6);
+        f1.setArray(array);
+        self.assertRaises(Exception,f1.checkCoherency);#no end array specified !
+        #
+        f2=f1.determinant();
+        self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getArray().getNumberOfComponents());
+        self.assertEqual(9,f2.getNumberOfTuples());
+        for i in xrange(9):
+            self.assertAlmostEqual(137.335,f2.getIJ(i,0),10);
+            pass
+        #6 components multi arrays with end array defined
+        array=DataArrayDouble.New();
+        arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5,
+              7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr3,mesh1.getNumberOfNodes(),6);
+        f1.setEndArray(array);
+        f1.checkCoherency();
+        f2=f1.determinant();
+        f2.checkCoherency();
+        self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(9,f2.getNumberOfTuples());
+        time2,it,order=f2.getTime()
+        self.assertAlmostEqual(2.3,time2,12);
+        self.assertEqual(5,it);
+        self.assertEqual(6,order);
+        time2,it,order=f2.getEndTime()
+        self.assertAlmostEqual(3.8,time2,12);
+        self.assertEqual(7,it);
+        self.assertEqual(3,order);
+        for i in xrange(9):
+            self.assertAlmostEqual(137.335,f2.getIJ(i,0),10);
+            self.assertAlmostEqual(1289.685,f2.getEndArray().getIJ(i,0),9);
+            pass
+        #9 components
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setTime(7.8,10,2);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr4=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1]
+        array.setValues(arr4,mesh1.getNumberOfCells(),9);
+        f1.setArray(array);
+        #
+        f1.checkCoherency();
+        f2=f1.determinant();
+        f2.checkCoherency();
+        self.assertEqual(ONE_TIME,f2.getTimeDiscretization());
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        time2,it,order=f2.getTime()
+        self.assertAlmostEqual(7.8,time2,12);
+        self.assertEqual(10,it);
+        self.assertEqual(2,order);
+        for i in xrange(5):
+            self.assertAlmostEqual(3.267,f2.getIJ(i,0),13);
+            pass
+        pass
+
+    def testEigenValues1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.eigenValues();
+        f2.checkCoherency();
+        self.assertEqual(3,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[13.638813677891717,-4.502313844635971,-2.2364998332557486]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13);
+            pass
+        pass
+
+    def testEigenVectors1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.eigenVectors();
+        f2.checkCoherency();
+        self.assertEqual(9,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[0.5424262364180696, 0.5351201064614425, 0.6476266283176001,#eigenvect 0
+                   0.7381111277307373, 0.06458838384003074, -0.6715804522117897,#eigenvect 1
+                   -0.4012053603397987, 0.8423032781211455, -0.3599436712889738#eigenvect 2
+                   ]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),1e-13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),1e-13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),1e-13);
+            self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),1e-13);
+            self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),1e-13);
+            self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),1e-13);
+            self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),1e-13);
+            self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),1e-13);
+            self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),1e-13);
+            pass
+        #
+        pass
+
+    def testInverse1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1]
+        array.setValues(arr1,mesh1.getNumberOfCells(),9);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.inverse();
+        f2.checkCoherency();
+        self.assertEqual(9,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13);
+            self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13);
+            self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13);
+            self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13);
+            self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13);
+            self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr3,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.inverse();
+        f2.checkCoherency();
+        self.assertEqual(6,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected3=[-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected3[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected3[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected3[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected3[3],f2.getIJ(i,3),13);
+            self.assertAlmostEqual(expected3[4],f2.getIJ(i,4),13);
+            self.assertAlmostEqual(expected3[5],f2.getIJ(i,5),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5]
+        array.setValues(arr2,mesh1.getNumberOfCells(),4);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.inverse();
+        f2.checkCoherency();
+        self.assertEqual(4,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected2=[-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected2[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected2[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected2[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected2[3],f2.getIJ(i,3),13);
+            pass
+        #
+        pass
+
+    def testTrace1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1]
+        array.setValues(arr1,mesh1.getNumberOfCells(),9);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.trace();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(15.9,f2.getIJ(i,0),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5]
+        array.setValues(arr3,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.trace();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(25.8,f2.getIJ(i,0),13);
+            pass
+        #
+        array=DataArrayDouble.New();
+        arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5]
+        array.setValues(arr2,mesh1.getNumberOfCells(),4);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.trace();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(5.7,f2.getIJ(i,0),13);
+            pass
+        #
+        pass
+
+    def testDeviator1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7]
+        array.setValues(arr1,mesh1.getNumberOfCells(),6);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.deviator();
+        f2.checkCoherency();
+        self.assertEqual(6,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        expected1=[-1.1,0.,1.1,4.5,5.6,6.7]
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13);
+            self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13);
+            self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13);
+            self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13);
+            self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13);
+            self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13);
+            pass
+        #
+        pass
+
+    def testMagnitude1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.magnitude();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(8.3606219864313918,f2.getIJ(i,0),13);
+            pass
+        #
+        pass
+
+    def testMaxPerTuple1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f2=f1.maxPerTuple();
+        f2.checkCoherency();
+        self.assertEqual(1,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(5.6,f2.getIJ(i,0),13);
+            pass
+        #
+        pass
+
+    def testChangeNbOfComponents(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f1.changeNbOfComponents(3,7.77);
+        f1.checkCoherency();
+        self.assertEqual(3,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        expected1=[1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2]
+        for i in xrange(15):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),13);
+            pass
+        f1.changeNbOfComponents(4,7.77);
+        f1.checkCoherency();
+        self.assertEqual(4,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        expected2=[1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77]
+        for i in xrange(20):
+            self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),13);
+            pass
+        #
+        pass
+
+    def testSortPerTuple1(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME);
+        f1.setMesh(mesh1);
+        array=DataArrayDouble.New();
+        arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4]
+        array.setValues(arr1,mesh1.getNumberOfCells(),5);
+        f1.setArray(array);
+        f1.checkCoherency();
+        #
+        f1.sortPerTuple(True);
+        f1.checkCoherency();
+        self.assertEqual(5,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(arr1[0],f1.getIJ(i,0),13);
+            self.assertAlmostEqual(arr1[1],f1.getIJ(i,1),13);
+            self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13);
+            self.assertAlmostEqual(arr1[3],f1.getIJ(i,3),13);
+            self.assertAlmostEqual(arr1[4],f1.getIJ(i,4),13);
+            pass
+        #
+        f1.sortPerTuple(False);
+        f1.checkCoherency();
+        self.assertEqual(5,f1.getNumberOfComponents());
+        self.assertEqual(5,f1.getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(arr1[4],f1.getIJ(i,0),13);
+            self.assertAlmostEqual(arr1[3],f1.getIJ(i,1),13);
+            self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13);
+            self.assertAlmostEqual(arr1[1],f1.getIJ(i,3),13);
+            self.assertAlmostEqual(arr1[0],f1.getIJ(i,4),13);
+            pass
+        #
+        pass
+    
+    def testKeepSetSelectedComponent1(self):
+        arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.]
+        a1=DataArrayDouble.New();
+        a1.setValues(arr1,5,4);
+        a1.setInfoOnComponent(0,"aaaa");
+        a1.setInfoOnComponent(1,"bbbb");
+        a1.setInfoOnComponent(2,"cccc");
+        a1.setInfoOnComponent(3,"dddd");
+        arr2V=[1,2,1,2,0,0]
+        a2=a1.keepSelectedComponents(arr2V);
+        self.assertEqual(6,a2.getNumberOfComponents());
+        self.assertEqual(5,a2.getNumberOfTuples());
+        self.assertTrue(a2.getInfoOnComponent(0)=="bbbb");
+        self.assertTrue(a2.getInfoOnComponent(1)=="cccc");
+        self.assertTrue(a2.getInfoOnComponent(2)=="bbbb");
+        self.assertTrue(a2.getInfoOnComponent(3)=="cccc");
+        self.assertTrue(a2.getInfoOnComponent(4)=="aaaa");
+        self.assertTrue(a2.getInfoOnComponent(5)=="aaaa");
+        expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected1[i],a2.getIJ(0,i),14);
+            pass
+        a3=a1.convertToIntArr();
+        a4=a3.keepSelectedComponents(arr2V);
+        self.assertEqual(6,a4.getNumberOfComponents());
+        self.assertEqual(5,a4.getNumberOfTuples());
+        self.assertTrue(a4.getInfoOnComponent(0)=="bbbb");
+        self.assertTrue(a4.getInfoOnComponent(1)=="cccc");
+        self.assertTrue(a4.getInfoOnComponent(2)=="bbbb");
+        self.assertTrue(a4.getInfoOnComponent(3)=="cccc");
+        self.assertTrue(a4.getInfoOnComponent(4)=="aaaa");
+        self.assertTrue(a4.getInfoOnComponent(5)=="aaaa");
+        for i in xrange(30):
+            self.assertEqual(int(expected1[i]),a4.getIJ(0,i));
+            pass
+        # setSelectedComponents
+        arr3V=[3,2]
+        a5=a1.keepSelectedComponents(arr3V);
+        a5.setInfoOnComponent(0,"eeee");
+        a5.setInfoOnComponent(1,"ffff");
+        arr4V=[1,2]
+        a2.setSelectedComponents(a5,arr4V);
+        self.assertEqual(6,a2.getNumberOfComponents());
+        self.assertEqual(5,a2.getNumberOfTuples());
+        self.assertTrue(a2.getInfoOnComponent(0)=="bbbb");
+        self.assertTrue(a2.getInfoOnComponent(1)=="eeee");
+        self.assertTrue(a2.getInfoOnComponent(2)=="ffff");
+        self.assertTrue(a2.getInfoOnComponent(3)=="cccc");
+        self.assertTrue(a2.getInfoOnComponent(4)=="aaaa");
+        self.assertTrue(a2.getInfoOnComponent(5)=="aaaa");
+        expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected2[i],a2.getIJ(0,i),14);
+            pass
+        a6=a5.convertToIntArr();
+        a6.setInfoOnComponent(0,"eeee");
+        a6.setInfoOnComponent(1,"ffff");
+        a4.setSelectedComponents(a6,arr4V);
+        self.assertEqual(6,a4.getNumberOfComponents());
+        self.assertEqual(5,a4.getNumberOfTuples());
+        self.assertTrue(a4.getInfoOnComponent(0)=="bbbb");
+        self.assertTrue(a4.getInfoOnComponent(1)=="eeee");
+        self.assertTrue(a4.getInfoOnComponent(2)=="ffff");
+        self.assertTrue(a4.getInfoOnComponent(3)=="cccc");
+        self.assertTrue(a4.getInfoOnComponent(4)=="aaaa");
+        self.assertTrue(a4.getInfoOnComponent(5)=="aaaa");
+        for i in xrange(30):
+            self.assertEqual(int(expected2[i]),a4.getIJ(0,i));
+            pass
+        # test of throw
+        arr5V=[2,3,6]
+        arr6V=[2,7,5]
+        arr7V=[2,1,4,6]
+        self.assertRaises(Exception,a2.keepSelectedComponents,arr5V);
+        self.assertRaises(Exception,a2.keepSelectedComponents,arr6V);
+        self.assertRaises(Exception,a2.setSelectedComponents,a1,arr7V);
+        arr7V=arr7V[0:3]
+        self.assertRaises(Exception,a2.setSelectedComponents,a1,arr7V);
+        #
+        pass
+
+    def testKeepSetSelectedComponent2(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+        arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.]
+        a1=DataArrayDouble.New();
+        a1.setValues(arr1,5,4);
+        a1.setInfoOnComponent(0,"aaaa");
+        a1.setInfoOnComponent(1,"bbbb");
+        a1.setInfoOnComponent(2,"cccc");
+        a1.setInfoOnComponent(3,"dddd");
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setTime(2.3,4,5);
+        f1.setMesh(m1);
+        f1.setName("f1");
+        f1.setArray(a1);
+        f1.checkCoherency();
+        #
+        arr2V=[1,2,1,2,0,0]
+        f2=f1.keepSelectedComponents(arr2V);
+        self.assertTrue(f2.getTimeDiscretization()==ONE_TIME);
+        t,dt,it=f2.getTime()
+        self.assertAlmostEqual(2.3,t,13);
+        self.assertEqual(4,dt);
+        self.assertEqual(5,it);
+        f2.checkCoherency();
+        self.assertEqual(6,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb");
+        self.assertTrue(f2.getArray().getInfoOnComponent(1)=="cccc");
+        self.assertTrue(f2.getArray().getInfoOnComponent(2)=="bbbb");
+        self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc");
+        self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa");
+        self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa");
+        expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected1[i],f2.getIJ(0,i),14);
+            pass
+        #setSelectedComponents
+        arr3V=[3,2]
+        f5=f1.keepSelectedComponents(arr3V);
+        f5.setTime(6.7,8,9);
+        f5.getArray().setInfoOnComponent(0,"eeee");
+        f5.getArray().setInfoOnComponent(1,"ffff");
+        f5.checkCoherency();
+        arr4V=[1,2]
+        f2.setSelectedComponents(f5,arr4V);
+        self.assertEqual(6,f2.getNumberOfComponents());
+        self.assertEqual(5,f2.getNumberOfTuples());
+        f2.checkCoherency();
+        t,dt,it=f2.getTime()
+        self.assertAlmostEqual(2.3,t,13);
+        self.assertEqual(4,dt);
+        self.assertEqual(5,it);
+        self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb");
+        self.assertTrue(f2.getArray().getInfoOnComponent(1)=="eeee");
+        self.assertTrue(f2.getArray().getInfoOnComponent(2)=="ffff");
+        self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc");
+        self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa");
+        self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa");
+        expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.]
+        for i in xrange(30):
+            self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),14);
+            pass
+        #
+        pass
+    
     def setUp(self):
         pass
     pass
diff --git a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py
new file mode 100644 (file)
index 0000000..d152e2a
--- /dev/null
@@ -0,0 +1,338 @@
+#  -*- coding: iso-8859-1 -*-
+#  Copyright (C) 2007-2010  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
+#
+
+from libMEDCoupling_Swig import *
+
+class MEDCouplingDataForTest:
+    def build2DTargetMesh_1(cls):
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ];
+        targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4];
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(5);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]);
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]);
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]);
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,9,2);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+    def build2DSourceMesh_1(cls):
+        sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7]
+        sourceConn=[0,3,1,0,2,3]
+        sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2);
+        sourceMesh.allocateCells(2);
+        sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]);
+        sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]);
+        sourceMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(sourceCoords,4,2);
+        sourceMesh.setCoords(myCoords);
+        return sourceMesh;
+        
+    def build3DTargetMesh_1(cls):
+        targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0.  , 0., 50., 0., 50., 50., 0. , 200., 50., 0.,   0., 200., 0., 50., 200., 0. , 200., 200., 0. ,
+                       0., 0., 50., 50., 0., 50. , 200., 0., 50.  , 0., 50., 50., 50., 50., 50. , 200., 50., 50.,   0., 200., 50., 50., 200., 50. , 200., 200., 50. ,
+                       0., 0., 200., 50., 0., 200. , 200., 0., 200.  , 0., 50., 200., 50., 50., 200. , 200., 50., 200.,   0., 200., 200., 50., 200., 200. , 200., 200., 200. ];
+        targetConn=[0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16,
+                    9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25];
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(3);
+        targetMesh.allocateCells(12);
+        for i in xrange(8):
+            targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*i+8]);
+            pass
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,27,3);
+        targetMesh.setCoords(myCoords);
+        return targetMesh
+
+    def build3DSurfTargetMesh_1(self):
+        targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5]
+        targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(5);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,9,3);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
+    def build3DExtrudedUMesh_1(self):
+        coords=[
+            0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0.,
+            3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0.,
+            0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1.,
+            3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1.,
+            0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2.,
+            3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2.,
+            0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3.,
+            3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.]
+
+        conn=[
+            # 0
+            0,11,1,3,15,26,16,18,   1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17,
+            1,6,5,3,16,21,20,18,   13,10,9,6,28,25,24,21,
+            11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23,
+            7,12,14,13,22,27,29,28,
+            # 1
+            15,26,16,18,30,41,31,33,   16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32,
+            16,21,20,18,31,36,35,33,   28,25,24,21,43,40,39,36,
+            26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38,
+            22,27,29,28,37,42,44,43,
+            # 2
+            30,41,31,33,45,56,46,48,  31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47,
+            31,36,35,33,46,51,50,48,  43,40,39,36,58,55,54,51,
+            41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53,
+            37,42,44,43,52,57,59,58]            
+        conn2=[7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3]
+        #
+        ret=MEDCouplingUMesh.New();
+        ret.setMeshDimension(3);
+        ret.allocateCells(18);
+        #
+        ret.insertNextCell(NORM_HEXA8,8,conn[0:8]);
+        ret.insertNextCell(NORM_POLYHED,43,conn[8:51]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[51:59]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[59:67]);
+        ret.insertNextCell(NORM_POLYHED,43,conn[67:110]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[110:118]);
+        #
+        ret.insertNextCell(NORM_HEXA8,8,conn[118:126]);
+        ret.insertNextCell(NORM_POLYHED,43,conn[126:169]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[169:177]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[177:185]);
+        ret.insertNextCell(NORM_POLYHED,43,conn[185:228]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[228:236]);
+        #
+        ret.insertNextCell(NORM_HEXA8,8,conn[236:244]);
+        ret.insertNextCell(NORM_POLYHED,43,conn[244:287]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[287:295]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[295:303]);
+        ret.insertNextCell(NORM_POLYHED,43,conn[303:346]);
+        ret.insertNextCell(NORM_HEXA8,8,conn[346:354]);
+        #
+        ret.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,60,3);
+        ret.setCoords(myCoords);
+        #
+        mesh2D=MEDCouplingUMesh.New();
+        mesh2D.setMeshDimension(2);
+        mesh2D.allocateCells(6);
+        mesh2D.insertNextCell(NORM_QUAD4,4,conn2[0:4]);
+        mesh2D.insertNextCell(NORM_POLYGON,6,conn2[4:10]);
+        mesh2D.insertNextCell(NORM_QUAD4,4,conn2[10:14]);
+        mesh2D.insertNextCell(NORM_QUAD4,4,conn2[14:18]);
+        mesh2D.insertNextCell(NORM_POLYGON,6,conn2[18:24]);
+        mesh2D.insertNextCell(NORM_QUAD4,4,conn2[24:28]);
+        mesh2D.setCoords(myCoords);
+        return ret,mesh2D
+    
+    def buildCU1DMesh_U(self):
+        coords=[ 0.0, 0.3, 0.75, 1.0 ]
+        conn=[ 0,1, 1,2, 2,3 ]
+        mesh=MEDCouplingUMesh.New();
+        mesh.setMeshDimension(1);
+        mesh.allocateCells(3);
+        mesh.insertNextCell(NORM_SEG2,2,conn[0:2]);
+        mesh.insertNextCell(NORM_SEG2,2,conn[2:4]);
+        mesh.insertNextCell(NORM_SEG2,2,conn[4:6]);
+        mesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,4,1);
+        mesh.setCoords(myCoords);
+        return mesh;
+
+    def build2DTargetMeshMergeNode_1(self):
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 ]
+        targetConn=[0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(5);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]);
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]);
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]);
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,18,2);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
+    def build3DTargetMeshMergeNode_1(self):
+        targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0.  , 0., 50., 0., 50., 50., 0. , 200., 50., 0.,   0., 200., 0., 50., 200., 0. , 200., 200., 0. ,
+                       0., 0., 50., 50., 0., 50. , 200., 0., 50.  , 0., 50., 50., 50., 50., 50. , 200., 50., 50.,   0., 200., 50., 50., 200., 50. , 200., 200., 50. ,
+                       0., 0., 200., 50., 0., 200. , 200., 0., 200.  , 0., 50., 200., 50., 50., 200. , 200., 50., 200.,   0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0.,  200., 50., 200.]
+        targetConn=[0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16,
+                    9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(3);
+        targetMesh.allocateCells(12);
+        for i in xrange(8):
+            targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*(i+1)]);
+            pass
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,31,3);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
+    def build2DTargetMeshMerged_1(self):
+        targetCoords=[
+            -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7,
+            0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7
+            ]
+        targetConn=[
+            0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4,
+            9,12,10,9,11,12
+            ]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setName("merge");
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(10);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,13,2);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
+    def build2DTargetMesh_2(cls):
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]
+        targetConn=[0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 ]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(8);
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[6:9])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[9:12])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[12:15])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[15:18])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,9,2);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
+    def build1DTargetMesh_3(cls):
+        ret=MEDCouplingUMesh.New("1DMesh_3",1);
+        ret.allocateCells(4);
+        conn=[0,1,2, 3,4, 6,5,7 ,9,8]
+        ret.insertNextCell(NORM_SEG3,3,conn[0:3])
+        ret.insertNextCell(NORM_SEG2,2,conn[3:5])
+        ret.insertNextCell(NORM_SEG3,3,conn[5:8])
+        ret.insertNextCell(NORM_SEG2,2,conn[8:10])
+        ret.finishInsertingCells();
+        coords=[0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31]
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,10,1);
+        ret.setCoords(myCoords);
+        return ret;
+
+    def build2DCurveTargetMesh_3(cls):
+        ret=MEDCouplingUMesh.New("2DCurveMesh_3",1);
+        ret.allocateCells(4);
+        conn=[0,1,2, 3,4, 6,5,7 ,9,8]
+        ret.insertNextCell(NORM_SEG3,3,conn[0:3])
+        ret.insertNextCell(NORM_SEG2,2,conn[3:5])
+        ret.insertNextCell(NORM_SEG3,3,conn[5:8])
+        ret.insertNextCell(NORM_SEG2,2,conn[8:10])
+        ret.finishInsertingCells();
+        coords=[0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31]
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,10,2);
+        ret.setCoords(myCoords);
+        return ret;
+
+    def build2DTargetMesh_3(cls):
+        ret=MEDCouplingUMesh.New("2DMesh_3",2);
+        ret.allocateCells(10);
+        conn=[0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6]
+        ret.insertNextCell(NORM_TRI3,3,conn[0:3])
+        ret.insertNextCell(NORM_QUAD4,4,conn[3:7])
+        ret.insertNextCell(NORM_POLYGON,5,conn[7:12])
+        ret.insertNextCell(NORM_TRI6,6,conn[12:18])
+        ret.insertNextCell(NORM_QUAD8,8,conn[18:26])
+        ret.insertNextCell(NORM_TRI3,3,conn[26:29])
+        ret.insertNextCell(NORM_QUAD4,4,conn[29:33])
+        ret.insertNextCell(NORM_POLYGON,5,conn[33:38])
+        ret.insertNextCell(NORM_TRI6,6,conn[38:44])
+        ret.insertNextCell(NORM_QUAD8,8,conn[44:52])
+        ret.finishInsertingCells();
+        coords=[0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5]
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,11,2);
+        ret.setCoords(myCoords);
+        ret.checkCoherency();
+        return ret;
+
+    def build2DTargetMesh_4(cls):
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]
+        targetConn=[0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(5);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,10,2);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
+    build2DTargetMesh_1=classmethod(build2DTargetMesh_1)
+    build2DSourceMesh_1=classmethod(build2DSourceMesh_1)
+    build3DTargetMesh_1=classmethod(build3DTargetMesh_1)
+    build3DSurfTargetMesh_1=classmethod(build3DSurfTargetMesh_1)
+    build3DExtrudedUMesh_1=classmethod(build3DExtrudedUMesh_1)
+    buildCU1DMesh_U=classmethod(buildCU1DMesh_U)
+    build2DTargetMeshMergeNode_1=classmethod(build2DTargetMeshMergeNode_1)
+    build3DTargetMeshMergeNode_1=classmethod(build3DTargetMeshMergeNode_1)
+    build2DTargetMeshMerged_1=classmethod(build2DTargetMeshMerged_1)
+    build2DTargetMesh_2=classmethod(build2DTargetMesh_2)
+    build1DTargetMesh_3=classmethod(build1DTargetMesh_3)
+    build2DCurveTargetMesh_3=classmethod(build2DCurveTargetMesh_3)
+    build2DTargetMesh_3=classmethod(build2DTargetMesh_3)
+    build2DTargetMesh_4=classmethod(build2DTargetMesh_4)
+    pass
index 4b8e950b2e1e0e12a84bb1abc0a29d4d607eb32f..d1af65ba8c5de44a72e184d3b96bf33215cc5320 100644 (file)
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
+#ifdef WITH_NUMPY2
+#include <numpy/arrayobject.h>
+#endif
+
 static PyObject* convertMesh(ParaMEDMEM::MEDCouplingMesh* mesh, int owner)
 {
-  PyObject *ret;
+  PyObject *ret=0;
   if(dynamic_cast<ParaMEDMEM::MEDCouplingUMesh *>(mesh))
     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,owner);
+  if(dynamic_cast<ParaMEDMEM::MEDCouplingExtrudedMesh *>(mesh))
+    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(!ret)
+    {
+      PyErr_SetString(PyExc_TypeError,"Not recognized type of mesh on downcast !");
+      PyErr_Print();
+    }
   return ret;
 }
 
 static PyObject *convertIntArrToPyList(const int *ptr, int size)
 {
+#ifndef WITH_NUMPY2
   PyObject *ret=PyList_New(size);
   for(int i=0;i<size;i++)
     PyList_SetItem(ret,i,PyInt_FromLong(ptr[i]));
   return ret;
+#else
+  npy_intp dim = (npy_intp) size;
+  int *tmp=new int[size];
+  std::copy(ptr,ptr+size,tmp);
+  return PyArray_SimpleNewFromData(1,&dim,NPY_INT,const_cast<int *>(tmp));
+#endif
+}
+
+static PyObject *convertIntArrToPyList2(const std::vector<int>& v)
+{
+#ifndef WITH_NUMPY2
+  int size=v.size();
+  PyObject *ret=PyList_New(size);
+  for(int i=0;i<size;i++)
+    PyList_SetItem(ret,i,PyInt_FromLong(v[i]));
+  return ret;
+#else
+  npy_intp dim = (npy_intp) v.size();
+  int *tmp=new int[v.size()];
+  std::copy(v.begin(),v.end(),tmp);
+  return PyArray_SimpleNewFromData(1,&dim,NPY_INT,tmp);
+#endif
 }
 
-static int *convertPyToNewIntArr(PyObject *pyLi, int size)
+static PyObject *convertIntArrToPyListOfTuple(const int *vals, int nbOfComp, int nbOfTuples)
+{
+  PyObject *ret=PyList_New(nbOfTuples);
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      PyObject *t=PyTuple_New(nbOfComp);
+      for(int j=0;j<nbOfComp;j++)
+        PyTuple_SetItem(t,j,PyInt_FromLong(vals[i*nbOfComp+j]));
+      PyList_SetItem(ret,i,t);
+    }
+  return ret;
+}
+
+static int *convertPyToNewIntArr2(PyObject *pyLi, int *size)
 {
   if(PyList_Check(pyLi))
     {
-      int *tmp=new int[size];
-      for(int i=0;i<size;i++)
+      *size=PyList_Size(pyLi);
+      int *tmp=new int[*size];
+      for(int i=0;i<*size;i++)
         {
           PyObject *o=PyList_GetItem(pyLi,i);
           if(PyInt_Check(o))
@@ -48,7 +98,9 @@ static int *convertPyToNewIntArr(PyObject *pyLi, int size)
             }
           else
             {
+              delete [] tmp;
               PyErr_SetString(PyExc_TypeError,"list must contain integers only");
+              PyErr_Print();
               return NULL;
             }
         }
@@ -56,37 +108,71 @@ static int *convertPyToNewIntArr(PyObject *pyLi, int size)
     }
   else
     {
-      PyErr_SetString(PyExc_TypeError,"convertPyToNewIntArr : not a list");
+#ifndef WITH_NUMPY2
+      PyErr_SetString(PyExc_TypeError,"convertPyToNewIntArr2 : not a list");
+      PyErr_Print();
       return 0;
+#else
+      if(PyArray_Check(pyLi))
+        {
+          npy_intp mySize = PyArray_SIZE(pyLi);
+          int *ret=(int *)PyArray_BYTES(pyLi);
+          *size=mySize;
+          return ret;
+        }
+      else
+        {
+          PyErr_SetString(PyExc_TypeError,"convertPyToNewIntArr2 : not a list nor PyArray");
+          PyErr_Print();
+          return 0;
+        }
+#endif
     }
 }
 
-static int *convertPyToNewIntArr2(PyObject *pyLi)
+static void convertPyToNewIntArr3(PyObject *pyLi, std::vector<int>& arr)
 {
   if(PyList_Check(pyLi))
     {
       int size=PyList_Size(pyLi);
-      int *tmp=new int[size];
+      arr.resize(size);
       for(int i=0;i<size;i++)
         {
           PyObject *o=PyList_GetItem(pyLi,i);
           if(PyInt_Check(o))
             {
               int val=(int)PyInt_AS_LONG(o);
-              tmp[i]=val;
+              arr[i]=val;
             }
           else
             {
               PyErr_SetString(PyExc_TypeError,"list must contain integers only");
-              return NULL;
+              PyErr_Print();
             }
         }
-      return tmp;
     }
   else
     {
-      PyErr_SetString(PyExc_TypeError,"convertPyToNewIntArr : not a list");
-      return 0;
+#ifndef WITH_NUMPY2
+      PyErr_SetString(PyExc_TypeError,"convertPyToNewIntArr3 : not a list");
+      PyErr_Print();
+      return ;
+#else
+      if(PyArray_Check(pyLi))
+        {
+          npy_intp mySize = PyArray_SIZE(pyLi);
+          int *ret=(int *)PyArray_BYTES(pyLi);
+          arr.resize(mySize);
+          std::copy(ret,ret+mySize,arr.begin());
+          return ;
+        }
+      else
+        {
+          PyErr_SetString(PyExc_TypeError,"convertPyToNewIntArr3 : not a list nor PyArray");
+          PyErr_Print();
+          return ;
+        }
+#endif
     }
 }
 
@@ -98,13 +184,35 @@ static PyObject *convertDblArrToPyList(const double *ptr, int size)
   return ret;
 }
 
-static double *convertPyToNewDblArr2(PyObject *pyLi)
+static PyObject *convertDblArrToPyList2(const std::vector<double>& v)
+{
+  int size=v.size();
+  PyObject *ret=PyList_New(size);
+  for(int i=0;i<size;i++)
+    PyList_SetItem(ret,i,PyFloat_FromDouble(v[i]));
+  return ret;
+}
+
+static PyObject *convertDblArrToPyListOfTuple(const double *vals, int nbOfComp, int nbOfTuples)
+{
+  PyObject *ret=PyList_New(nbOfTuples);
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      PyObject *t=PyTuple_New(nbOfComp);
+      for(int j=0;j<nbOfComp;j++)
+        PyTuple_SetItem(t,j,PyFloat_FromDouble(vals[i*nbOfComp+j]));
+      PyList_SetItem(ret,i,t);
+    }
+  return ret;
+}
+
+static double *convertPyToNewDblArr2(PyObject *pyLi, int *size)
 {
   if(PyList_Check(pyLi))
     {
-      int size=PyList_Size(pyLi);
-      double *tmp=new double[size];
-      for(int i=0;i<size;i++)
+      *size=PyList_Size(pyLi);
+      double *tmp=new double[*size];
+      for(int i=0;i<*size;i++)
         {
           PyObject *o=PyList_GetItem(pyLi,i);
           if(PyFloat_Check(o))
@@ -114,7 +222,8 @@ static double *convertPyToNewDblArr2(PyObject *pyLi)
             }
           else
             {
-              PyErr_SetString(PyExc_TypeError,"list must contain floats only");
+              PyErr_SetString(PyExc_TypeError,"convertPyToNewDblArr2 : list must contain floats only");
+              PyErr_Print();
               return NULL;
             }
         }
@@ -123,6 +232,63 @@ static double *convertPyToNewDblArr2(PyObject *pyLi)
   else
     {
       PyErr_SetString(PyExc_TypeError,"convertPyToNewIntArr : not a list");
+      PyErr_Print();
       return 0;
     }
 }
+
+void convertPyObjToVecUMeshes(PyObject *ms, std::vector<ParaMEDMEM::MEDCouplingUMesh *>& v)
+{
+  if(PyList_Check(ms))
+    {
+      int size=PyList_Size(ms);
+      v.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *obj=PyList_GetItem(ms,i);
+          void *argp;
+          int status=SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,0|0);
+          if(!SWIG_IsOK(status))
+            {
+              PyErr_SetString(PyExc_TypeError,"list must contain only DataArrayInt");
+              PyErr_Print();
+              return;
+            }
+          ParaMEDMEM::MEDCouplingUMesh *arg=reinterpret_cast< ParaMEDMEM::MEDCouplingUMesh * >(argp);
+          v[i]=arg;
+        }
+    }
+  else
+    {
+      PyErr_SetString(PyExc_TypeError,"convertPyObjToVecUMeshes : not a list");
+      PyErr_Print();
+    }
+}
+
+void convertPyObjToVecDataArrayInt(PyObject *ms, std::vector<ParaMEDMEM::DataArrayInt *>& v)
+{
+  if(PyList_Check(ms))
+    {
+      int size=PyList_Size(ms);
+      v.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *obj=PyList_GetItem(ms,i);
+          void *argp;
+          int status=SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0);
+          if(!SWIG_IsOK(status))
+            {
+              PyErr_SetString(PyExc_TypeError,"list must contain only DataArrayInt");
+              PyErr_Print();
+              return;
+            }
+          ParaMEDMEM::DataArrayInt *arg=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp);
+          v[i]=arg;
+        }
+    }
+  else
+    {
+      PyErr_SetString(PyExc_TypeError,"convertPyObjToVecDataArrayInt : not a list");
+      PyErr_Print();
+    }
+}
index 483a7e8e1b5d49ef49a12bd04aed4135738ea59b..fd14551f1c4025d69dcc1a88d7f9bc1168fb5d98 100644 (file)
@@ -58,4 +58,8 @@ _libMEDCouplingRemapper_Swig_la_LDFLAGS  = -module $(PYTHON_LIBS) \
 
 CLEANFILES = libMEDCoupling_SwigWRAP.cxx libMEDCoupling_Swig.py libMEDCouplingRemapper_SwigWRAP.cxx libMEDCouplingRemapper_Swig.py
 
-dist_salomescript_DATA= MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py libMEDCoupling_Swig.py libMEDCouplingRemapper_Swig.py
+dist_salomescript_DATA= MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py libMEDCoupling_Swig.py libMEDCouplingRemapper_Swig.py MEDCouplingDataForTest.py
+
+UNIT_TEST_PROG = MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py
+
+#check : tests
index ec02326ac897617a120b499043f345312df71046..d6b35f44750b7f27179c2b58fcab0f300337dc12 100644 (file)
 
 #define MEDCOUPLING_EXPORT
 
+%include std_vector.i
+%include std_string.i
+
 %{
 #include "MEDCouplingMemArray.hxx"
 #include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingExtrudedMesh.hxx"
+#include "MEDCouplingCMesh.hxx"
 #include "MEDCouplingField.hxx"
 #include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingGaussLocalization.hxx"
 #include "MEDCouplingTypemaps.i"
 
 using namespace ParaMEDMEM;
 using namespace INTERP_KERNEL;
 %}
 
+%template(ivec) std::vector<int>;
+%template(dvec) std::vector<double>;
+%template(svec) std::vector<std::string>;
+
 %typemap(out) ParaMEDMEM::MEDCouplingMesh*
 {
   $result=convertMesh($1,$owner);
 }
 
+%typemap(out) ParaMEDMEM::MEDCouplingPointSet*
+{
+  $result=convertMesh($1,$owner);
+}
+
+#ifdef WITH_NUMPY2
+%init %{ import_array(); %}
+#endif
+
+%feature("autodoc", "1");
+%feature("docstring");
+
 %newobject ParaMEDMEM::DataArrayDouble::New;
 %newobject ParaMEDMEM::DataArrayInt::New;
+%newobject ParaMEDMEM::DataArrayDouble::convertToIntArr;
+%newobject ParaMEDMEM::DataArrayInt::convertToDblArr;
 %newobject ParaMEDMEM::MEDCouplingUMesh::New;
+%newobject ParaMEDMEM::MEDCouplingField::buildMeasureField;
 %newobject ParaMEDMEM::MEDCouplingFieldDouble::New;
 %newobject ParaMEDMEM::MEDCouplingFieldDouble::mergeFields;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::doublyContractedProduct;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::determinant;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenValues;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenVectors;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::inverse;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::trace;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::deviator;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::magnitude;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::maxPerTuple;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::keepSelectedComponents;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::dotFields;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::dot;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::crossProductFields;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::crossProduct;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::maxFields;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::max;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::minFields;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::min;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::getIdsInRange;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator+;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator-;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator*;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator/;
 %newobject ParaMEDMEM::MEDCouplingUMesh::clone;
 %newobject ParaMEDMEM::DataArrayDouble::deepCopy;
 %newobject ParaMEDMEM::DataArrayDouble::performCpy;
 %newobject ParaMEDMEM::DataArrayInt::deepCopy;
 %newobject ParaMEDMEM::DataArrayInt::performCpy;
+%newobject ParaMEDMEM::DataArrayInt::substr;
+%newobject ParaMEDMEM::DataArrayInt::changeNbOfComponents;
+%newobject ParaMEDMEM::DataArrayInt::keepSelectedComponents;
+%newobject ParaMEDMEM::DataArrayInt::selectByTupleId;
+%newobject ParaMEDMEM::DataArrayInt::renumber;
+%newobject ParaMEDMEM::DataArrayInt::renumberR;
+%newobject ParaMEDMEM::DataArrayInt::renumberAndReduce;
+%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2O;
+%newobject ParaMEDMEM::DataArrayInt::invertArrayN2O2O2N;
+%newobject ParaMEDMEM::DataArrayDouble::aggregate;
+%newobject ParaMEDMEM::DataArrayDouble::dot;
+%newobject ParaMEDMEM::DataArrayDouble::crossProduct;
+%newobject ParaMEDMEM::DataArrayDouble::add;
+%newobject ParaMEDMEM::DataArrayDouble::substract;
+%newobject ParaMEDMEM::DataArrayDouble::multiply;
+%newobject ParaMEDMEM::DataArrayDouble::divide;
+%newobject ParaMEDMEM::DataArrayDouble::substr;
+%newobject ParaMEDMEM::DataArrayDouble::changeNbOfComponents;
+%newobject ParaMEDMEM::DataArrayDouble::keepSelectedComponents;
+%newobject ParaMEDMEM::DataArrayDouble::getIdsInRange;
+%newobject ParaMEDMEM::DataArrayDouble::selectByTupleId;
+%newobject ParaMEDMEM::DataArrayDouble::applyFunc;
+%newobject ParaMEDMEM::DataArrayDouble::doublyContractedProduct;
+%newobject ParaMEDMEM::DataArrayDouble::determinant;
+%newobject ParaMEDMEM::DataArrayDouble::eigenValues;
+%newobject ParaMEDMEM::DataArrayDouble::eigenVectors;
+%newobject ParaMEDMEM::DataArrayDouble::inverse;
+%newobject ParaMEDMEM::DataArrayDouble::trace;
+%newobject ParaMEDMEM::DataArrayDouble::deviator;
+%newobject ParaMEDMEM::DataArrayDouble::magnitude;
+%newobject ParaMEDMEM::DataArrayDouble::maxPerTuple;
+%newobject ParaMEDMEM::DataArrayDouble::renumber;
+%newobject ParaMEDMEM::DataArrayDouble::renumberR;
+%newobject ParaMEDMEM::DataArrayDouble::renumberAndReduce;
 %newobject ParaMEDMEM::MEDCouplingFieldDouble::clone;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh;
+%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis;
+%newobject ParaMEDMEM::MEDCouplingMesh::getCoordinatesAndOwner;
+%newobject ParaMEDMEM::MEDCouplingMesh::getBarycenterAndOwner;
+%newobject ParaMEDMEM::MEDCouplingMesh::buildOrthogonalField;
+%newobject ParaMEDMEM::MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds;
+%newobject ParaMEDMEM::MEDCouplingMesh::buildPart;
 %newobject ParaMEDMEM::MEDCouplingMesh::mergeMyselfWith;
 %newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic;
-%newobject ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelf;
 %newobject ParaMEDMEM::MEDCouplingPointSet::zipCoordsTraducer;
-%newobject ParaMEDMEM::MEDCouplingUMesh::getMeasureField;
+%newobject ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer;
+%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity;
+%newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh;
+%newobject ParaMEDMEM::MEDCouplingMesh::getMeasureField;
+%newobject ParaMEDMEM::MEDCouplingUMesh::buildExtrudedMeshFromThis;
 %newobject ParaMEDMEM::MEDCouplingUMesh::mergeUMeshes;
+%newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt;
+%newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes;
+%newobject ParaMEDMEM::MEDCouplingUMesh::convertCellArrayPerGeoType;
+%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec;
+%newobject ParaMEDMEM::MEDCouplingUMesh::buildDirectionVectorField;
+%newobject ParaMEDMEM::MEDCouplingUMesh::getEdgeRatioField;
+%newobject ParaMEDMEM::MEDCouplingUMesh::getAspectRatioField;
+%newobject ParaMEDMEM::MEDCouplingUMesh::getWarpField;
+%newobject ParaMEDMEM::MEDCouplingUMesh::getSkewField;
+%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New;
+%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh;
+%newobject ParaMEDMEM::MEDCouplingCMesh::New;
+%newobject ParaMEDMEM::MEDCouplingCMesh::buildUnstructured;
 %feature("unref") DataArrayDouble "$this->decrRef();"
+%feature("unref") MEDCouplingPointSet "$this->decrRef();"
+%feature("unref") MEDCouplingMesh "$this->decrRef();"
 %feature("unref") MEDCouplingUMesh "$this->decrRef();"
+%feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();"
+%feature("unref") MEDCouplingCMesh "$this->decrRef();"
 %feature("unref") DataArrayInt "$this->decrRef();"
+%feature("unref") MEDCouplingField "$this->decrRef();"
 %feature("unref") MEDCouplingFieldDouble "$this->decrRef();"
 
-%ignore ParaMEDMEM::TimeLabel::operator=;
+%rename(assign) *::operator=;
 %ignore ParaMEDMEM::MemArray::operator=;
 %ignore ParaMEDMEM::MemArray::operator[];
+%ignore ParaMEDMEM::MEDCouplingPointSet::getCoords();
+%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo;
+%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo;
+%ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues;
+%ignore ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo;
 
+%rename (Exception) InterpKernelException;
 %nodefaultctor;
+
+namespace INTERP_KERNEL
+{
+  class Exception
+  {
+  public:
+    Exception(const char* what);
+    ~Exception() throw ();
+    const char *what() const throw ();
+  };
+}
+
 %include "MEDCouplingTimeLabel.hxx"
 %include "MEDCouplingRefCountObject.hxx"
-%include "MEDCouplingMesh.hxx"
-%include "MEDCouplingPointSet.hxx"
+
+namespace ParaMEDMEM
+{
+  typedef enum
+    {
+      UNSTRUCTURED = 5,
+      UNSTRUCTURED_DESC = 6,
+      CARTESIAN = 7,
+      EXTRUDED = 8
+    } MEDCouplingMeshType;
+
+  class DataArrayInt;
+  class DataArrayDouble;
+  class MEDCouplingFieldDouble;
+
+  class MEDCouplingMesh : public RefCountObject, public TimeLabel
+  {
+  public:
+    void setName(const char *name) { _name=name; }
+    const char *getName() const { return _name.c_str(); }
+    virtual MEDCouplingMeshType getType() const = 0;
+    bool isStructured() const;
+    virtual bool isEqual(const MEDCouplingMesh *other, double prec) const;
+    virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0;
+    virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
+    virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0;
+    virtual int getNumberOfCells() const throw(INTERP_KERNEL::Exception) = 0;
+    virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception) = 0;
+    virtual int getSpaceDimension() const throw(INTERP_KERNEL::Exception) = 0;
+    virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception) = 0;
+    virtual DataArrayDouble *getCoordinatesAndOwner() const = 0;
+    virtual DataArrayDouble *getBarycenterAndOwner() const = 0;
+    virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0;
+    virtual std::string simpleRepr() const = 0;
+    virtual std::string advancedRepr() const = 0;
+    // tools
+    virtual void getBoundingBox(double *bbox) const = 0;
+    virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0;
+    virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const = 0;
+    virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception);
+    virtual MEDCouplingFieldDouble *buildOrthogonalField() const = 0;
+    virtual void rotate(const double *center, const double *vector, double angle) = 0;
+    virtual void translate(const double *vector) = 0;
+    virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0;
+    virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const;
+    static MEDCouplingMesh *mergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2);
+    %extend
+       {
+         std::string __str__() const
+         {
+           return self->simpleRepr();
+         }
+
+         int getCellContainingPoint(PyObject *p, double eps) const
+         {
+           int sz;
+           double *pos=convertPyToNewDblArr2(p,&sz);
+           int ret=self->getCellContainingPoint(pos,eps);
+           delete [] pos;
+           return ret;
+         }
+         
+         void renumberCells(PyObject *li, bool check) throw(INTERP_KERNEL::Exception)
+         {
+           int size;
+           int *tmp=convertPyToNewIntArr2(li,&size);
+           self->renumberCells(tmp,check);
+           delete [] tmp;
+         }
+
+         PyObject *checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec) const throw(INTERP_KERNEL::Exception)
+         {
+           DataArrayInt *cellCor, *nodeCor;
+           self->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor);
+           PyObject *res = PyList_New(2);
+           PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 ));
+           PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 ));
+           return res;
+         }
+         DataArrayInt *getCellIdsFullyIncludedInNodeIds(PyObject *li) const
+         {
+           int size;
+           int *tmp=convertPyToNewIntArr2(li,&size);
+           DataArrayInt *ret=self->getCellIdsFullyIncludedInNodeIds(tmp,tmp+size);
+           delete [] tmp;
+           return ret;
+         }
+         PyObject *getNodeIdsOfCell(int cellId) const
+         {
+           std::vector<int> conn;
+           self->getNodeIdsOfCell(cellId,conn);
+           return convertIntArrToPyList2(conn);
+         }
+
+         PyObject *getCoordinatesOfNode(int nodeId) const
+         {
+           std::vector<double> coo;
+           self->getCoordinatesOfNode(nodeId,coo);
+           return convertDblArrToPyList2(coo);
+         }
+
+         void scale(PyObject *point, double factor)
+         {
+           int sz;
+           double *p=convertPyToNewDblArr2(point,&sz);
+           self->scale(p,factor);
+           delete [] p;
+         }
+       }
+  };
+}
+
 %include "MEDCouplingMemArray.hxx"
-%include "MEDCouplingMesh.hxx"
 %include "NormalizedUnstructuredMesh.hxx"
-%include "MEDCouplingField.hxx"
 %include "MEDCouplingNatureOfField.hxx"
+%include "MEDCouplingTimeDiscretization.hxx"
+%include "MEDCouplingGaussLocalization.hxx"
 
 namespace ParaMEDMEM
 {
+  class MEDCouplingPointSet : public ParaMEDMEM::MEDCouplingMesh
+    {
+    public:
+      void updateTime();
+      void setCoords(DataArrayDouble *coords);
+      DataArrayDouble *getCoordinatesAndOwner() const;
+      bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const;
+      void getBoundingBox(double *bbox) const;
+      void zipCoords();
+      double getCaracteristicDimension() const;
+      void translate(const double *vector);
+      void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception);
+      void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
+      virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0;
+      static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2);
+      static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type);
+      virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const = 0;
+      virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
+      virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
+      virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0;
+      virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
+      virtual bool isEmptyMesh(const std::vector<int>& tinyInfo) const = 0;
+      //! size of returned tinyInfo must be always the same.
+      void getTinySerializationInformation(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<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
+                           const std::vector<std::string>& littleStrings);
+      virtual void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) = 0;
+      virtual void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems) = 0;
+      virtual DataArrayInt *zipCoordsTraducer() = 0;
+      %extend 
+         {
+           std::string __str__() const
+           {
+             return self->simpleRepr();
+           }
+           
+           PyObject *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex) const
+           {
+             int newNbOfNodes;
+             DataArrayInt *ret0=self->buildNewNumberingFromCommonNodesFormat(comm,commIndex,newNbOfNodes);
+             PyObject *res = PyList_New(2);
+             PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+             PyList_SetItem(res,1,SWIG_From_int(newNbOfNodes));
+             return res;
+           }
+           
+           PyObject *findCommonNodes(int limitNodeId, double prec) const
+           {
+             DataArrayInt *comm, *commIndex;
+             self->findCommonNodes(limitNodeId,prec,comm,commIndex);
+             PyObject *res = PyList_New(2);
+             PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+             PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+             return res;
+           }
+           
+           PyObject *getCoords() const
+           {
+             DataArrayDouble *ret1=self->getCoords();
+             ret1->incrRef();
+             return SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0);
+           }
+           PyObject *buildPartOfMySelf(PyObject *li, bool keepCoords) const
+           {
+             int size;
+             int *tmp=convertPyToNewIntArr2(li,&size);
+             MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,tmp+size,keepCoords);
+             delete [] tmp;
+             return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+           }
+           PyObject *buildPartOfMySelfNode(PyObject *li, bool fullyIn) const
+           {
+             int size;
+             int *tmp=convertPyToNewIntArr2(li,&size);
+             MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,tmp+size,fullyIn);
+             delete [] tmp;
+             return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+           }
+           PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const
+           {
+             int size;
+             int *tmp=convertPyToNewIntArr2(li,&size);
+             MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,tmp+size,fullyIn);
+             delete [] tmp;
+             return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+           }
+           PyObject *findBoundaryNodes() const
+           {
+             std::vector<int> nodes;
+             self->findBoundaryNodes(nodes);
+             return convertIntArrToPyList2(nodes);
+           }
+           void rotate(PyObject *center, PyObject *vector, double alpha)
+           {
+             int sz;
+             double *c=convertPyToNewDblArr2(center,&sz);
+             if(!c)
+               return ;
+             double *v=convertPyToNewDblArr2(vector,&sz);
+             if(!v)
+               { delete [] c; return ; }
+             self->rotate(c,v,alpha);
+             delete [] c;
+             delete [] v;
+           }
+           void translate(PyObject *vector)
+           {
+             int sz;
+             double *v=convertPyToNewDblArr2(vector,&sz);
+             self->translate(v);
+             delete [] v;
+           }
+           void renumberNodes(PyObject *li, int newNbOfNodes)
+           {
+             int size;
+             int *tmp=convertPyToNewIntArr2(li,&size);
+             self->renumberNodes(tmp,newNbOfNodes);
+             delete [] tmp;
+           }
+           PyObject *findNodesOnPlane(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception)
+             {
+               std::vector<int> nodes;
+               int sz;
+               double *p=convertPyToNewDblArr2(pt,&sz);
+               double *v=convertPyToNewDblArr2(vec,&sz);
+               self->findNodesOnPlane(p,v,eps,nodes);
+               delete [] v;
+               delete [] p;
+               return convertIntArrToPyList2(nodes);
+             }
+           static void rotate2DAlg(PyObject *center, double angle, int nbNodes, PyObject *coords)
+           {
+             int sz;
+             double *c=convertPyToNewDblArr2(center,&sz);
+             double *coo=convertPyToNewDblArr2(coords,&sz);
+             ParaMEDMEM::MEDCouplingPointSet::rotate2DAlg(c,angle,nbNodes,coo);
+             for(int i=0;i<sz;i++)
+               PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i]));
+             delete [] coo;
+             delete [] c;
+           }
+           static void rotate3DAlg(PyObject *center, PyObject *vect, double angle, int nbNodes, PyObject *coords)
+           {
+             int sz,sz2;
+             double *c=convertPyToNewDblArr2(center,&sz);
+             double *coo=convertPyToNewDblArr2(coords,&sz);
+             double *v=convertPyToNewDblArr2(vect,&sz2);
+             ParaMEDMEM::MEDCouplingPointSet::rotate3DAlg(c,v,angle,nbNodes,coo);
+             for(int i=0;i<sz;i++)
+               PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i]));
+             delete [] coo;
+             delete [] c;
+           }
+         }
+    };
+  
   class MEDCouplingUMesh : public ParaMEDMEM::MEDCouplingPointSet
   {
   public:
@@ -84,31 +482,41 @@ namespace ParaMEDMEM
     MEDCouplingUMesh *clone(bool recDeepCpy) const;
     void updateTime();
     void checkCoherency() const throw(INTERP_KERNEL::Exception);
-    void setMeshDimension(int meshDim);
+    void setMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception);
     void allocateCells(int nbOfCells);
-    void setCoords(DataArrayDouble *coords);
-    DataArrayDouble *getCoords() const;
     void finishInsertingCells();
     void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true);
     DataArrayInt *getNodalConnectivity() const;
     DataArrayInt *getNodalConnectivityIndex() const;
     INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const;
     int getNumberOfNodesInCell(int cellId) const;
-    bool isStructured() const;
-    int getNumberOfCells() const;
-    int getNumberOfNodes() const;
-    int getSpaceDimension() const;
-    int getMeshDimension() const;
     int getMeshLength() const;
+    void computeTypes();
+    std::string reprConnectivityOfThis() const;
     //tools
-    void zipCoords();
-    DataArrayInt *zipCoordsTraducer();
+    bool checkConsecutiveCellTypes() const;
+    DataArrayInt *rearrange2ConsecutiveCellTypes();
+    DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception);
+    DataArrayInt *zipConnectivityTraducer(int compType);
     void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
-    MEDCouplingUMesh *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
+    MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
+    void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception);
+    bool isPresenceOfQuadratic() const;
+    MEDCouplingFieldDouble *buildDirectionVectorField() const;
+    void convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *getEdgeRatioField() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *getAspectRatioField() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception);
     %extend {
+      std::string __str__() const
+      {
+        return self->simpleRepr();
+      }
       void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, PyObject *li)
       {
-        int *tmp=convertPyToNewIntArr(li,size);
+        int sz;
+        int *tmp=convertPyToNewIntArr2(li,&sz);
         self->insertNextCell(type,size,tmp);
         delete [] tmp;
       }
@@ -124,23 +532,256 @@ namespace ParaMEDMEM
       PyObject *mergeNodes(double precision)
       {
         bool ret1;
-        DataArrayInt *ret0=self->mergeNodes(precision,ret1);
-        PyObject *res = PyList_New(2);
+        int ret2;
+        DataArrayInt *ret0=self->mergeNodes(precision,ret1,ret2);
+        PyObject *res = PyList_New(3);
         PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
         PyList_SetItem(res,1,SWIG_From_bool(ret1));
+        PyList_SetItem(res,2,SWIG_From_int(ret2));
         return res;
       }
+      PyObject *checkButterflyCells()
+      {
+        std::vector<int> cells;
+        self->checkButterflyCells(cells);
+        return convertIntArrToPyList2(cells);
+      }
+
+      PyObject *splitByType() const
+      {
+        std::vector<MEDCouplingUMesh *> ms=self->splitByType();
+        int sz=ms.size();
+        PyObject *ret = PyList_New(sz);
+        for(int i=0;i<sz;i++)
+          PyList_SetItem(ret,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ));
+        return ret;
+      }
+
+      PyObject *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, PyObject *ids) const
+      {
+        std::vector<int> idsPerGeoType;
+        convertPyToNewIntArr3(ids,idsPerGeoType);
+        MEDCouplingUMesh *ret=self->keepSpecifiedCells(type,idsPerGeoType);
+        return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 );
+      }
+
+      bool checkConsecutiveCellTypesAndOrder(PyObject *li) const
+      {
+        int sz;
+        INTERP_KERNEL::NormalizedCellType *order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz);
+        bool ret=self->checkConsecutiveCellTypesAndOrder(order,order+sz);
+        delete [] order;
+        return ret;
+      }
+
+      DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(PyObject *li) const
+      {
+        int sz;
+        INTERP_KERNEL::NormalizedCellType *order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz);
+        DataArrayInt *ret=self->getRenumArrForConsecutiveCellTypesSpec(order,order+sz);
+        delete [] order;
+        return ret;
+      }
+
+      PyObject *getCellsContainingPoints(PyObject *p, int nbOfPoints, double eps) const
+      {
+        int sz;
+        double *pos=convertPyToNewDblArr2(p,&sz);
+        std::vector<int> elts,eltsIndex;
+        self->getCellsContainingPoints(pos,nbOfPoints,eps,elts,eltsIndex);
+        delete [] pos;
+        PyObject *ret=PyList_New(2);
+        PyList_SetItem(ret,0,convertIntArrToPyList2(elts));
+        PyList_SetItem(ret,1,convertIntArrToPyList2(eltsIndex));
+        return ret;
+      }
+
+      PyObject *getCellsContainingPoint(PyObject *p, double eps) const
+      {
+        int sz;
+        double *pos=convertPyToNewDblArr2(p,&sz);
+        std::vector<int> elts;
+        self->getCellsContainingPoint(pos,eps,elts);
+        delete [] pos;
+        return convertIntArrToPyList2(elts);
+      }
+
+      static PyObject *mergeUMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<ParaMEDMEM::MEDCouplingUMesh *> meshes;
+        if(PyList_Check(ms))
+          {
+            int sz=PyList_Size(ms);
+            meshes.resize(sz);
+            for(int i=0;i<sz;i++)
+              {
+                PyObject *o=PyList_GetItem(ms,i);
+                void *arg;
+                SWIG_ConvertPtr(o,&arg,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, 0 |  0 );
+                meshes[i]=reinterpret_cast<ParaMEDMEM::MEDCouplingUMesh *>(arg);
+              }
+          }
+        else
+          {
+            PyErr_SetString(PyExc_TypeError,"mergeUMeshesOnSameCoords : not a list as first parameter");
+            PyErr_Print();
+            return 0;
+          }
+        MEDCouplingUMesh *ret=MEDCouplingUMesh::mergeUMeshesOnSameCoords(meshes);
+        return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+      }
+
+      static PyObject *fuseUMeshesOnSameCoords(PyObject *ms, int compType)
+      {
+        int sz;
+        std::vector<MEDCouplingUMesh *> meshes;
+        convertPyObjToVecUMeshes(ms,meshes);
+        std::vector<DataArrayInt *> corr;
+        MEDCouplingUMesh *um=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,compType,corr);
+        sz=corr.size();
+        PyObject *ret1=PyList_New(sz);
+        for(int i=0;i<sz;i++)
+          PyList_SetItem(ret1,i,SWIG_NewPointerObj(SWIG_as_voidptr(corr[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyObject *ret=PyList_New(2);
+        PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(um),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ));
+        PyList_SetItem(ret,1,ret1);
+        return ret;
+      }
+
+      PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<int> cells;
+        int sz;
+        double *v=convertPyToNewDblArr2(vec,&sz);
+        try
+          {
+            self->are2DCellsNotCorrectlyOriented(v,polyOnly,cells);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] v;
+            throw e;
+          }
+        delete [] v;
+        return convertIntArrToPyList2(cells);
+      }
+
+      void orientCorrectly2DCells(PyObject *vec, bool polyOnly) throw(INTERP_KERNEL::Exception)
+      {
+        int sz;
+        double *v=convertPyToNewDblArr2(vec,&sz);
+        try
+          {
+            self->orientCorrectly2DCells(v,polyOnly);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] v;
+            throw e;
+          }
+        delete [] v;
+      }
+      
+      PyObject *arePolyhedronsNotCorrectlyOriented() const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<int> cells;
+        self->arePolyhedronsNotCorrectlyOriented(cells);
+        return convertIntArrToPyList2(cells);
+      }
+
+      PyObject *getFastAveragePlaneOfThis() const throw(INTERP_KERNEL::Exception)
+      {
+        double vec[3];
+        double pos[3];
+        self->getFastAveragePlaneOfThis(vec,pos);
+        double vals[6];
+        std::copy(vec,vec+3,vals);
+        std::copy(pos,pos+3,vals+3);
+        return convertDblArrToPyListOfTuple(vals,3,2);
+      }
+    }
+    void convertToPolyTypes(const std::vector<int>& cellIdsToConvert);
+    MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy);
+    static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
+  };
+
+  class MEDCouplingExtrudedMesh : public ParaMEDMEM::MEDCouplingMesh
+  {
+  public:
+    static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception);
+    MEDCouplingUMesh *build3DUnstructuredMesh() const;
+    %extend {
+      std::string __str__() const
+      {
+        return self->simpleRepr();
+      }
+      PyObject *getMesh2D() const
+      {
+        MEDCouplingUMesh *ret=self->getMesh2D();
+        ret->incrRef();
+        return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+      }
+      PyObject *getMesh1D() const
+      {
+        MEDCouplingUMesh *ret=self->getMesh1D();
+        ret->incrRef();
+        return convertMesh(ret, SWIG_POINTER_OWN | 0 );
+      }
+      PyObject *getMesh3DIds() const
+      {
+        DataArrayInt *ret=self->getMesh3DIds();
+        ret->incrRef();
+        return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
+      } 
+    }
+  };
+
+  class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingMesh
+  {
+  public:
+    static MEDCouplingCMesh *New();
+    void setCoords(DataArrayDouble *coordsX,
+                   DataArrayDouble *coordsY=0,
+                   DataArrayDouble *coordsZ=0);
+    void setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception);
+    MEDCouplingUMesh *buildUnstructured() const;
+    %extend {
+      std::string __str__() const
+      {
+        return self->simpleRepr();
+      }
     }
-    MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
-    static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2);
   };
 }
 
+%extend ParaMEDMEM::DataArray
+{
+  void copyPartOfStringInfoFrom(const DataArray& other, PyObject *li) throw(INTERP_KERNEL::Exception)
+  {
+    std::vector<int> tmp;
+    convertPyToNewIntArr3(li,tmp);
+    self->copyPartOfStringInfoFrom(other,tmp);
+  }
+
+  void copyPartOfStringInfoFrom2(PyObject *li, const DataArray& other) throw(INTERP_KERNEL::Exception)
+  {
+    std::vector<int> tmp;
+    convertPyToNewIntArr3(li,tmp);
+    self->copyPartOfStringInfoFrom2(tmp,other);
+  }
+}
+
 %extend ParaMEDMEM::DataArrayDouble
  {
+   std::string __str__() const
+   {
+     return self->repr();
+   }
+
    void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple)
    {
-     double *tmp=convertPyToNewDblArr2(li);
+     int sz;
+     double *tmp=convertPyToNewDblArr2(li,&sz);
      self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple);
    }
 
@@ -149,13 +790,158 @@ namespace ParaMEDMEM
      const double *vals=self->getPointer();
      return convertDblArrToPyList(vals,self->getNbOfElems());
    }
+
+   PyObject *getValuesAsTuple()
+   {
+     const double *vals=self->getPointer();
+     int nbOfComp=self->getNumberOfComponents();
+     int nbOfTuples=self->getNumberOfTuples();
+     return convertDblArrToPyListOfTuple(vals,nbOfComp,nbOfTuples);
+   }
+
+   DataArrayDouble *renumber(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+            delete [] tmp;
+       }
+     DataArrayDouble *ret=self->renumber(tmp);
+     delete [] tmp;
+     return ret;
+   }
+
+   DataArrayDouble *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+            delete [] tmp;
+       }
+     DataArrayDouble *ret=self->renumberR(tmp);
+     delete [] tmp;
+     return ret;
+   }
+
+   DataArrayDouble *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+            delete [] tmp;
+       }
+     DataArrayDouble *ret=self->renumberAndReduce(tmp,newNbOfTuple);
+     delete [] tmp;
+     return ret;
+   }
+
+   void renumberInPlace(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+            delete [] tmp;
+       }
+     self->renumberInPlace(tmp);
+     delete [] tmp;
+   }
+
+   void renumberInPlaceR(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+            delete [] tmp;
+       }
+     self->renumberInPlaceR(tmp);
+     delete [] tmp;
+   }
+
+   DataArrayDouble *selectByTupleId(PyObject *li) const
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     DataArrayDouble *ret=self->selectByTupleId(tmp,tmp+size);
+     delete [] tmp;
+     return ret;
+   }
+
+   PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception)
+   {
+     int tmp;
+     double r1=self->getMaxValue(tmp);
+     PyObject *ret=PyTuple_New(2);
+     PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1));
+     PyTuple_SetItem(ret,1,PyInt_FromLong(tmp));
+     return ret;
+   }
+
+   PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception)
+   {
+     DataArrayInt *tmp;
+     double r1=self->getMaxValue2(tmp);
+     PyObject *ret=PyTuple_New(2);
+     PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1));
+     PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+     return ret;
+   }
+
+   PyObject *getMinValue() const throw(INTERP_KERNEL::Exception)
+   {
+     int tmp;
+     double r1=self->getMinValue(tmp);
+     PyObject *ret=PyTuple_New(2);
+     PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1));
+     PyTuple_SetItem(ret,1,PyInt_FromLong(tmp));
+     return ret;
+   }
+
+   PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception)
+   {
+     DataArrayInt *tmp;
+     double r1=self->getMinValue2(tmp);
+     PyObject *ret=PyTuple_New(2);
+     PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1));
+     PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+     return ret;
+   }
+   
+   DataArrayDouble *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception)
+   {
+     std::vector<int> tmp;
+     convertPyToNewIntArr3(li,tmp);
+     return self->keepSelectedComponents(tmp);
+   }
+
+   void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     std::vector<int> tmp;
+     convertPyToNewIntArr3(li,tmp);
+     self->setSelectedComponents(a,tmp);
+   }
  };
 
 %extend ParaMEDMEM::DataArrayInt
  {
+   std::string __str__() const
+   {
+     return self->repr();
+   }
+
    void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple)
    {
-     int *tmp=convertPyToNewIntArr2(li);
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
      self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple);
    }
 
@@ -164,40 +950,323 @@ namespace ParaMEDMEM
      const int *vals=self->getPointer();
      return convertIntArrToPyList(vals,self->getNbOfElems());
    }
- };
 
-%include "MEDCouplingField.hxx"
+   PyObject *getValuesAsTuple()
+   {
+     const int *vals=self->getPointer();
+     int nbOfComp=self->getNumberOfComponents();
+     int nbOfTuples=self->getNumberOfTuples();
+     return convertIntArrToPyListOfTuple(vals,nbOfComp,nbOfTuples);
+   }
+
+   static PyObject *makePartition(PyObject *gps, int newNb)
+   {
+     std::vector<DataArrayInt *> groups;
+     std::vector< std::vector<int> > fidsOfGroups;
+     convertPyObjToVecDataArrayInt(gps,groups);
+     ParaMEDMEM::DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::makePartition(groups,newNb,fidsOfGroups);
+     PyObject *ret = PyList_New(2);
+     PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+     int sz=fidsOfGroups.size();
+     PyObject *ret1 = PyList_New(sz);
+     for(int i=0;i<sz;i++)
+       PyList_SetItem(ret1,i,convertIntArrToPyList2(fidsOfGroups[i]));
+     PyList_SetItem(ret,1,ret1);
+     return ret;
+   }
+
+   void renumberInPlace(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+         delete [] tmp;
+       }
+     self->renumberInPlace(tmp);
+     delete [] tmp;
+   }
+
+   void renumberInPlaceR(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+            delete [] tmp;
+       }
+     self->renumberInPlaceR(tmp);
+     delete [] tmp;
+   }
+
+   DataArrayInt *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+            delete [] tmp;
+       }
+     DataArrayInt *ret=self->renumberAndReduce(tmp,newNbOfTuple);
+     delete [] tmp;
+     return ret;
+   }
+
+   DataArrayInt *renumber(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+         delete [] tmp;
+       }
+     DataArrayInt *ret=self->renumber(tmp);
+     delete [] tmp;
+     return ret;
+   }
+
+   DataArrayInt *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     if(size!=self->getNumberOfTuples())
+       {
+         throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !");
+         delete [] tmp;
+       }
+     DataArrayInt *ret=self->renumberR(tmp);
+     delete [] tmp;
+     return ret;
+   }
+
+   DataArrayInt *selectByTupleId(PyObject *li) const
+   {
+     int size;
+     int *tmp=convertPyToNewIntArr2(li,&size);
+     DataArrayInt *ret=self->selectByTupleId(tmp,tmp+size);
+     delete [] tmp;
+     return ret;
+   }
+
+   DataArrayInt *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception)
+   {
+     std::vector<int> tmp;
+     convertPyToNewIntArr3(li,tmp);
+     return self->keepSelectedComponents(tmp);
+   }
+
+   void setSelectedComponents(const DataArrayInt *a, PyObject *li) throw(INTERP_KERNEL::Exception)
+   {
+     std::vector<int> tmp;
+     convertPyToNewIntArr3(li,tmp);
+     self->setSelectedComponents(a,tmp);
+   }
+ };
 
 namespace ParaMEDMEM
 {
+  class MEDCouplingField : public ParaMEDMEM::RefCountObject, public ParaMEDMEM::TimeLabel
+  {
+  public:
+    virtual void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    virtual bool areCompatibleForMerge(const MEDCouplingField *other) const;
+    virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
+    virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
+    void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh);
+    void setName(const char *name);
+    const char *getDescription() const;
+    void setDescription(const char *desc);
+    const char *getName() const;
+    TypeOfField getTypeOfField() const;
+    MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDiscretization *getDiscretization() const;
+    void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
+                                    const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
+    void clearGaussLocalizations();
+    MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception);
+    int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
+    int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
+    const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
+    %extend {
+      PyObject *getMesh() const
+      {
+        MEDCouplingMesh *ret1=(MEDCouplingMesh *)self->getMesh();
+        ret1->incrRef();
+        return convertMesh(ret1, SWIG_POINTER_OWN | 0 );
+      }
+
+      PyObject *buildSubMeshData(PyObject *li) const
+      {
+        int size;
+        int *tmp=convertPyToNewIntArr2(li,&size);
+        DataArrayInt *ret1;
+        MEDCouplingMesh *ret0=self->buildSubMeshData(tmp,tmp+size,ret1);
+        delete [] tmp;
+        PyObject *res = PyList_New(2);
+        PyList_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 ));
+        PyList_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0));
+        return res;
+      }
+      void setGaussLocalizationOnCells(PyObject *li, const std::vector<double>& refCoo,
+                                       const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception)
+      {
+        int size;
+        int *tmp=convertPyToNewIntArr2(li,&size);
+        try
+          {
+            self->setGaussLocalizationOnCells(tmp,tmp+size,refCoo,gsCoo,wg);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] tmp;
+            throw e;
+          }
+        delete [] tmp;
+      }
+      PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<int> tmp;
+        self->getCellIdsHavingGaussLocalization(locId,tmp);
+        return convertIntArrToPyList2(tmp);
+      }
+    }
+  };
+
   class MEDCouplingFieldDouble : public ParaMEDMEM::MEDCouplingField
   {
   public:
     static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME);
+    void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
+    std::string simpleRepr() const;
+    std::string advancedRepr() const;
     MEDCouplingFieldDouble *clone(bool recDeepCpy) const;
+    MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const;
+    MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const;
+    TypeOfTimeDiscretization getTimeDiscretization() const;
     void checkCoherency() const throw(INTERP_KERNEL::Exception);
     double getIJ(int tupleId, int compoId) const;
-    void setArray(DataArrayDouble *array);
-    void setTime(double val, int dt, int it);
-    void setStartTime(double val, int dt, int it);
-    void setEndTime(double val, int dt, int it);
-    DataArrayDouble *getArray() const { return _array; }
-    void applyLin(double a, double b, int compoId);
-    int getNumberOfComponents() const;
+    double getIJK(int cellId, int nodeIdInCell, int compoId) const;
+    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);
+    void setStartTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception);
+    void setEndTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception);
+    DataArrayDouble *getArray() const throw(INTERP_KERNEL::Exception);
+    DataArrayDouble *getEndArray() const throw(INTERP_KERNEL::Exception);
+    void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception);
+    int getNumberOfComponents() const throw(INTERP_KERNEL::Exception);
     int getNumberOfTuples() const throw(INTERP_KERNEL::Exception);
+    int getNumberOfValues() const throw(INTERP_KERNEL::Exception);
     NatureOfField getNature() const { return _nature; }
     void setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception);
     void updateTime();
-    bool mergeNodes(double eps);
-    void applyFunc(int nbOfComp, const char *func);
-    void applyFunc(const char *func);
-    static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception);
+    void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception);
+    bool mergeNodes(double eps) throw(INTERP_KERNEL::Exception);
+    bool zipCoords() throw(INTERP_KERNEL::Exception);
+    bool zipConnectivity(int compType) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *determinant() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *eigenValues() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *eigenVectors() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *inverse() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *trace() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *deviator() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *magnitude() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception);
+    void changeNbOfComponents(int newNbOfComp, double dftValue=0.) throw(INTERP_KERNEL::Exception);
+    void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception);
+    void fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception);
+    void applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception);
+    void applyFunc(int nbOfComp, double val) throw(INTERP_KERNEL::Exception);
+    void applyFunc(const char *func) throw(INTERP_KERNEL::Exception);
+    void applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception);
+    void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception);
+    double accumulate(int compId) const throw(INTERP_KERNEL::Exception);
+    double getMaxValue() const throw(INTERP_KERNEL::Exception);
+    double getMinValue() const throw(INTERP_KERNEL::Exception);
+    double getAverageValue() const throw(INTERP_KERNEL::Exception);
+    double getWeightedAverageValue() const throw(INTERP_KERNEL::Exception);
+    double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception);
+    double normL1(int compId) const throw(INTERP_KERNEL::Exception);
+    double normL2(int compId) const throw(INTERP_KERNEL::Exception);
+    DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const;
+    static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const;
+    static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const;
+    static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const;
+    MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception);
+    const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception);
+    const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception);
+    const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception);
+    const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
     %extend {
+      std::string __str__() const
+      {
+        return self->simpleRepr();
+      }
+      PyObject *getValueOn(PyObject *sl) const throw(INTERP_KERNEL::Exception)
+      {
+        int sz;
+        double *spaceLoc=convertPyToNewDblArr2(sl,&sz);
+        sz=self->getNumberOfComponents();
+        double *res=new double[sz];
+        try
+          {
+            self->getValueOn(spaceLoc,res);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] spaceLoc;
+            delete [] res;
+            throw e;
+          }
+        delete [] spaceLoc;
+        PyObject *ret=convertDblArrToPyList(res,sz);
+        delete [] res;
+        return ret;
+      }
+      PyObject *getValueOn(PyObject *sl, double time) const throw(INTERP_KERNEL::Exception)
+      {
+        int sz;
+        double *spaceLoc=convertPyToNewDblArr2(sl,&sz);
+        sz=self->getNumberOfComponents();
+        double *res=new double[sz];
+        try
+          {
+            self->getValueOn(spaceLoc,time,res);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] spaceLoc;
+            delete [] res;
+            throw e;
+          }
+        delete [] spaceLoc;
+        PyObject *ret=convertDblArrToPyList(res,sz);
+        delete [] res;
+        return ret;
+      }
       void setValues(PyObject *li)
       {
         if(self->getArray()!=0)
           {
-            double *tmp=convertPyToNewDblArr2(li);
+            int sz;
+            double *tmp=convertPyToNewDblArr2(li,&sz);
             int nbTuples=self->getArray()->getNumberOfTuples();
             int nbOfCompo=self->getArray()->getNumberOfComponents();
             self->getArray()->useArray(tmp,true,CPP_DEALLOC,nbTuples,nbOfCompo);
@@ -237,6 +1306,125 @@ namespace ParaMEDMEM
         PyList_SetItem(res,2,SWIG_From_int(tmp2));
         return res;
       }
+      PyObject *accumulate() const
+      {
+        int sz=self->getNumberOfComponents();
+        double *tmp=new double[sz];
+        self->accumulate(tmp);
+        PyObject *ret=convertDblArrToPyList(tmp,sz);
+        delete [] tmp;
+        return ret;
+      }
+      PyObject *integral(bool isWAbs) const
+      {
+        int sz=self->getNumberOfComponents();
+        double *tmp=new double[sz];
+        self->integral(isWAbs,tmp);
+        PyObject *ret=convertDblArrToPyList(tmp,sz);
+        delete [] tmp;
+        return ret;
+      }
+      PyObject *normL1() const throw(INTERP_KERNEL::Exception)
+      {
+        int sz=self->getNumberOfComponents();
+        double *tmp=new double[sz];
+        self->normL1(tmp);
+        PyObject *ret=convertDblArrToPyList(tmp,sz);
+        delete [] tmp;
+        return ret;
+      }
+      PyObject *normL2() const throw(INTERP_KERNEL::Exception)
+      {
+        int sz=self->getNumberOfComponents();
+        double *tmp=new double[sz];
+        self->normL2(tmp);
+        PyObject *ret=convertDblArrToPyList(tmp,sz);
+        delete [] tmp;
+        return ret;
+      }
+
+      void renumberCells(PyObject *li, bool check) throw(INTERP_KERNEL::Exception)
+      {
+        int size;
+        int *tmp=convertPyToNewIntArr2(li,&size);
+        try
+          {
+            self->renumberCells(tmp,check);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] tmp;
+            throw e;
+          }
+        delete [] tmp;
+      }
+      void renumberNodes(PyObject *li) throw(INTERP_KERNEL::Exception)
+      {
+        int size;
+        int *tmp=convertPyToNewIntArr2(li,&size);
+        try
+          {
+            self->renumberNodes(tmp);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] tmp;
+            throw e;
+          }
+        delete [] tmp;
+      }
+
+      MEDCouplingFieldDouble *buildSubPart(PyObject *li) const throw(INTERP_KERNEL::Exception)
+      {
+        int size;
+        int *tmp=convertPyToNewIntArr2(li,&size);
+        MEDCouplingFieldDouble *ret=0;
+        try
+          {
+            ret=self->buildSubPart(tmp,tmp+size);
+          }
+        catch(INTERP_KERNEL::Exception& e)
+          {
+            delete [] tmp;
+            throw e;
+          }
+        delete [] tmp;
+        return ret;
+      }
+
+      PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception)
+      {
+        DataArrayInt *tmp;
+        double r1=self->getMaxValue2(tmp);
+        PyObject *ret=PyTuple_New(2);
+        PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1));
+        PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        return ret;
+      }
+      
+      PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception)
+      {
+        DataArrayInt *tmp;
+        double r1=self->getMinValue2(tmp);
+        PyObject *ret=PyTuple_New(2);
+        PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1));
+        PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        return ret;
+      }
+      
+      MEDCouplingFieldDouble *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<int> tmp;
+        convertPyToNewIntArr3(li,tmp);
+        return self->keepSelectedComponents(tmp);
+      }
+
+      void setSelectedComponents(const MEDCouplingFieldDouble *f, PyObject *li) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<int> tmp;
+        convertPyToNewIntArr3(li,tmp);
+        self->setSelectedComponents(f,tmp);
+      }
     }
   };
 }
index f68192850314674617cdf9165cc29cf5ec7b4f26..cde077cee2c0cf085b15299049b3aafc47f18f26 100644 (file)
@@ -23,6 +23,7 @@
 #include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingMemArray.hxx"
 #include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingGaussLocalization.hxx"
 
 extern "C"
 {
@@ -57,7 +58,7 @@ med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2] = { MED_POINT1,
 
 med_geometrie_element typmainoeud[1] = { MED_NONE };
 
-INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2] = { INTERP_KERNEL::NORM_ERROR,
+INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2] = { INTERP_KERNEL::NORM_POINT0,
                                                                           INTERP_KERNEL::NORM_SEG2,
                                                                           INTERP_KERNEL::NORM_SEG3,
                                                                           INTERP_KERNEL::NORM_TRI3,
@@ -109,6 +110,12 @@ med_geometrie_element typmai3[32] = { MED_POINT1,//0
                                       MED_POLYEDRE//31
 };
 
+double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12;
+
+int MEDLoader::_COMP_FOR_CELL=0;
+
+int MEDLoader::_TOO_LONG_STR=0;
+
 using namespace ParaMEDMEM;
 
 namespace MEDLoaderNS
@@ -132,37 +139,77 @@ namespace MEDLoaderNS
     int _val;
   };
   
-  std::string buildStringFromFortran(const char *expr, int lgth);
   std::vector<std::string> getMeshNamesFid(med_idt fid);
-  void readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, std::list<MEDLoader::MEDFieldDoublePerCellType>& field,
-                                    int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, double& time);
+  void readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName,
+                                    int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField,
+                                    std::list<MEDLoader::MEDFieldDoublePerCellType>& field,
+                                    double& time, std::vector<std::string>& infos);
   std::vector<int> getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector<std::string>& fams);
   std::vector<int> getIdsFromGroups(const char *fileName, const char *meshName, const std::vector<std::string>& grps);
   med_int getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception);
   void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entite_maillage& whichEntity);
-  void readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list<MEDLoader::MEDConnOfOneElemType>& conn);
-  int buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile,
-                                       std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile);
+  int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector<int>& possibilities);
+  void readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list<MEDLoader::MEDConnOfOneElemType>& conn);
+  int buildMEDSubConnectivityOfOneType(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families, INTERP_KERNEL::NormalizedCellType type,
+                                       std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile,
+                                       std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
   MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<int>& ids,
-                                          const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract) throw(INTERP_KERNEL::Exception);
+                                          const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception);
   void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt,
+                                            const std::vector<int>& familiesToKeep,
                                             DataArrayInt* &conn,
                                             DataArrayInt* &connIndex,
-                                            const std::vector<int>& familiesToKeep);
-  ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType);
-  int buildMEDSubConnectivityOfOneTypesPolyg(DataArrayInt *conn, DataArrayInt *connIndex, std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile);
-  int buildMEDSubConnectivityOfOneTypesPolyh(DataArrayInt *conn, DataArrayInt *connIndex, std::vector<int>& conn4MEDFile,
-                                             std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile);
-  int buildMEDSubConnectivityOfOneTypeStaticTypes(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile);
+                                            int *&cellRenum);
+  ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType,
+                                                     const std::vector<std::string>& infos);
+  int buildMEDSubConnectivityOfOneTypesPolyg(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
+                                             std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
+  int buildMEDSubConnectivityOfOneTypesPolyh(const std::vector<const DataArrayInt *>&conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
+                                             std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile,
+                                             std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
+  int buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
+                                                  INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
   ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order,
                                                           ParaMEDMEM::TypeOfField typeOfOutField);
-  void appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f);
-  void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, std::list<MEDLoader::MEDFieldDoublePerCellType>& split);
-  void writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool forceFromScratch);
-  void writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch);
+  ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *renumCell, const ParaMEDMEM::MEDCouplingUMesh *mesh,
+                                                          const std::vector<std::string>& infos, const char *fieldName, int iteration, int order, double time,
+                                                          std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerCellType);
+  med_idt appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt);
+  void appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f);
+  void appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds);
+  void appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIds);
+  void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIds, std::list<MEDLoader::MEDFieldDoublePerCellType>& split);
+  void fillGaussDataOnField(const char *fileName, const std::list<MEDLoader::MEDFieldDoublePerCellType>& data, MEDCouplingFieldDouble *f);
+  void writeUMeshesDirectly(const char *fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& mesh, const std::vector<const DataArrayInt *>& families, bool forceFromScratch, bool &isRenumbering);
+  void writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector<ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool forceFromScratch);
+  void writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch);
+  void writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f);
+}
+
+/*!
+ * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh.
+ */
+void MEDLoader::setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception)
+{
+  _EPS_FOR_NODE_COMP=val;
 }
 
-const char WHITE_SPACES[]=" \n";
+/*!
+ * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer.
+ */
+void MEDLoader::setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception)
+{
+  _COMP_FOR_CELL=val;
+}
+
+/*!
+ * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file.
+ * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown.
+ */
+void MEDLoader::setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception)
+{
+  _TOO_LONG_STR=val;
+}
 
 /*!
  * @param lgth is the size of fam tab. For classical types conn is size of 'lgth'*number_of_nodes_in_type.
@@ -171,8 +218,8 @@ const char WHITE_SPACES[]=" \n";
  */
 MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int *index, int *fam, int lgth, int connLgth):_lgth(lgth),_fam(fam),
                                                                                                                                                        _conn(conn),_index(index),
-                                                                                                                                                       _global(0),_type(type),
-                                                                                                                                                       _conn_lgth(connLgth)
+                                                                                                                                                       _global(0),_conn_lgth(connLgth),
+                                                                                                                                                       _type(type)
 {
 }
 
@@ -194,8 +241,13 @@ void MEDLoader::MEDConnOfOneElemType::releaseArray()
   delete [] _global;
 }
 
-MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple):_ntuple(ntuple),_ncomp(ncomp),_values(values),_type(type)
+MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple,
+                                                                const int *cellIdPerType, const char *locName):_ntuple(ntuple),_ncomp(ncomp),_values(values),_type(type)
 {
+  if(cellIdPerType)
+    _cell_id_per_type.insert(_cell_id_per_type.end(),cellIdPerType,cellIdPerType+ntuple);
+  if(locName)
+    _loc_name=locName;
 }
 
 void MEDLoader::MEDFieldDoublePerCellType::releaseArray()
@@ -203,21 +255,6 @@ void MEDLoader::MEDFieldDoublePerCellType::releaseArray()
   delete [] _values;
 }
 
-
-std::string MEDLoaderNS::buildStringFromFortran(const char *expr, int lgth)
-{
-  std::string ret(expr,lgth);
-  std::string whiteSpaces(WHITE_SPACES);
-  std::size_t lgthReal=strlen(ret.c_str());
-  std::string ret2=ret.substr(0,lgthReal);
-  std::size_t found=ret2.find_last_not_of(whiteSpaces);
-  if (found!=std::string::npos)
-    ret2.erase(found+1);
-  else
-    ret2.clear();//ret is all whitespace
-  return ret2;
-}
-
 std::vector<std::string> MEDLoaderNS::getMeshNamesFid(med_idt fid)
 {
   med_maillage type_maillage;
@@ -229,22 +266,150 @@ std::vector<std::string> MEDLoaderNS::getMeshNamesFid(med_idt fid)
   for(int i=0;i<n;i++)
     {
       MEDmaaInfo(fid,i+1,nommaa,&dim,&type_maillage,maillage_description);
-      std::string cur=buildStringFromFortran(nommaa,sizeof(nommaa));
+      std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa));
       ret[i]=cur;
     }
   return ret;
 }
 
-std::vector<std::string> MEDLoader::GetMeshNames(const char *fileName)
+void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list<MEDLoader::MEDFieldDoublePerCellType>& data, MEDCouplingFieldDouble *f)
+{
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  char locName[MED_TAILLE_NOM+1];
+  int nloc=MEDnGauss(fid);
+  med_geometrie_element typeGeo;
+  for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=data.begin();iter!=data.end();iter++)
+    {
+      const std::string& loc=(*iter).getLocName();
+      int idLoc=1;
+      int nbOfGaussPt=-1;
+      for(;idLoc<=nloc;idLoc++)
+        {
+          MEDgaussInfo(fid,idLoc,locName,&typeGeo,&nbOfGaussPt);
+          if(loc==locName)
+            break;
+        }
+      int dim=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension();
+      int nbPtPerCell=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getNumberOfNodes();
+      std::vector<double> refcoo(nbPtPerCell*dim),gscoo(nbOfGaussPt*dim),w(nbOfGaussPt);
+      MEDgaussLire(fid,(med_float *)&refcoo[0],(med_float *)&gscoo[0],(med_float *)&w[0],MED_FULL_INTERLACE,(char *)(*iter).getLocName().c_str());
+      f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w);
+    }
+  MEDfermer(fid);
+}
+
+void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception)
+{
+  int status=MEDLoaderBase::getStatusOfFile(fileName);
+  std::ostringstream oss;
+  oss << " File : \"" << fileName << "\"";
+  switch(status)
+    {
+    case MEDLoaderBase::DIR_LOCKED:
+      {
+        oss << " has been detected as unreadable : impossible to read anything !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    case MEDLoaderBase::NOT_EXIST:
+      {
+        oss << " has been detected as NOT EXISTING : impossible to read anything !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    case MEDLoaderBase::EXIST_WRONLY:
+      {
+        oss << " has been detected as WRITE ONLY : impossible to read anything !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    }
+  int fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  if(fid<0)
+    {
+      oss << " has been detected as unreadable by MED file : impossible to read anything !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  oss << " has been detected readable but ";
+  int major,minor,release;
+  MEDversionLire(fid,&major,&minor,&release);
+  if(major<2 || (major==2 && minor<2))
+    {
+      oss << "version of MED file is < 2.2 : impossible to read anything !";
+      MEDfermer(fid);
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDfermer(fid);
+}
+
+std::vector<std::string> MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   std::vector<std::string> ret=MEDLoaderNS::getMeshNamesFid(fid);
   MEDfermer(fid);
   return ret;
 }
 
-std::vector<std::string> MEDLoader::GetMeshFamilyNames(const char *fileName, const char *meshName)
+std::vector<std::string> MEDLoader::GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  std::vector<std::string> ret;
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  med_int nbFields=MEDnChamp(fid,0);
+  //
+  med_type_champ typcha;
+  //med_int nbpdtnor=0,pflsize,*pflval,lnsize;
+  med_int ngauss=0;
+  med_int numdt=0,numo=0,nbrefmaa;
+  med_float dt=0.0;
+  med_booleen local;
+  //char pflname[MED_TAILLE_NOM+1]="";
+  //char locname[MED_TAILLE_NOM+1]="";
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  //
+  for(int i=0;i<nbFields;i++)
+    {
+      med_int ncomp=MEDnChamp(fid,i+1);
+      char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+      char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+      MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      delete [] comp;
+      delete [] unit;
+      if(curFieldName==fieldName)
+        {
+          bool found=false;
+          for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
+            {
+              med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+              for(int k=0;k<nbPdt;k++)
+                {
+                  MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                  std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+                  if(std::find(ret.begin(),ret.end(),curMeshName)==ret.end())
+                    ret.push_back(curMeshName);
+                }
+            }
+          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+          for(int k=0;k<nbPdt;k++)
+            {
+              MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+              std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+              if(std::find(ret.begin(),ret.end(),curMeshName)==ret.end())
+                ret.push_back(curMeshName);
+            }
+        }
+    }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
+  MEDfermer(fid);
+  return ret;
+}
+
+std::vector<std::string> MEDLoader::GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   med_int nfam=MEDnFam(fid,(char *)meshName);
   std::vector<std::string> ret(nfam);
@@ -259,7 +424,7 @@ std::vector<std::string> MEDLoader::GetMeshFamilyNames(const char *fileName, con
       char *attdes=new char[MED_TAILLE_DESC*natt+1];
       char *gro=new char[MED_TAILLE_LNOM*ngro+1];
       MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
-      std::string cur=MEDLoaderNS::buildStringFromFortran(nomfam,sizeof(nomfam));
+      std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
       ret[i]=cur;
       delete [] attdes;
       delete [] gro;
@@ -270,8 +435,9 @@ std::vector<std::string> MEDLoader::GetMeshFamilyNames(const char *fileName, con
   return ret;
 }
   
-std::vector<std::string> MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName)
+std::vector<std::string> MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   med_int nfam=MEDnFam(fid,(char *)meshName);
   std::vector<std::string> ret;
@@ -288,7 +454,7 @@ std::vector<std::string> MEDLoader::GetMeshGroupsNames(const char *fileName, con
       MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
       for(int j=0;j<ngro;j++)
         {
-          std::string cur=MEDLoaderNS::buildStringFromFortran(gro+j*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
+          std::string cur=MEDLoaderBase::buildStringFromFortran(gro+j*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
           if(std::find(ret.begin(),ret.end(),cur)==ret.end())
             ret.push_back(cur);
         }
@@ -300,10 +466,10 @@ std::vector<std::string> MEDLoader::GetMeshGroupsNames(const char *fileName, con
   MEDfermer(fid);
   return ret;
 }
-
-std::vector<std::string> MEDLoader::GetCellFieldNamesOnMesh(const char *fileName, const char *meshName)
+std::vector<ParaMEDMEM::TypeOfField> MEDLoader::GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception)
 {
-  std::vector<std::string> ret;
+  CheckFileForRead(fileName);
+  std::vector<ParaMEDMEM::TypeOfField> ret;
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   med_int nbFields=MEDnChamp(fid,0);
   //
@@ -315,9 +481,9 @@ std::vector<std::string> MEDLoader::GetCellFieldNamesOnMesh(const char *fileName
   med_booleen local;
   //char pflname[MED_TAILLE_NOM+1]="";
   //char locname[MED_TAILLE_NOM+1]="";
-  char maa_ass[MED_TAILLE_NOM+1]="";
-  char dt_unit[MED_TAILLE_PNOM+1]="";
-  char nomcha[MED_TAILLE_NOM+1]="";
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
   //
   for(int i=0;i<nbFields;i++)
     {
@@ -325,43 +491,91 @@ std::vector<std::string> MEDLoader::GetCellFieldNamesOnMesh(const char *fileName
       char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
       char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
       MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
-      std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
       delete [] comp;
       delete [] unit;
-      bool found=false;
-      for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
+      if(curFieldName==fieldName)
         {
-          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
           if(nbPdt>0)
             {
-              MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
-              std::string curMeshName=MEDLoaderNS::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
-              if(curMeshName==meshName)
+              bool found=false;
+              for(int i=0;i<nbPdt && !found;i++)
                 {
-                  found=true;
-                  ret.push_back(curFieldName);
+                  MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                  std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+                  if(curMeshName==meshName)
+                    {
+                      ret.push_back(ON_NODES);
+                      found=true;
+                    }
+                }
+            }
+          bool found=false;
+          for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
+            {
+              med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+              if(nbPdt>0)
+                {
+                  MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                  std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+                  if(curMeshName==meshName)
+                    {
+                      found=true;
+                      ret.push_back(ON_CELLS);
+                    }
                 }
             }
         }
     }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
+  MEDfermer(fid);
+  return ret;
+}
+
+std::vector<std::string> MEDLoader::GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  std::vector<std::string> ret;
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  med_int nbFields=MEDnChamp(fid,0);
+  med_type_champ typcha;
+  for(int i=0;i<nbFields;i++)
+    {
+      med_int ncomp=MEDnChamp(fid,i+1);
+      char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+      char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+      char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+      MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+      ret.push_back(std::string(nomcha));
+      delete [] nomcha;
+      delete [] comp;
+      delete [] unit;
+    }
   MEDfermer(fid);
   return ret;
 }
 
-std::vector<std::string> MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName)
+std::vector<std::string> MEDLoader::GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   std::vector<std::string> ret;
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   med_int nbFields=MEDnChamp(fid,0);
   //
   med_type_champ typcha;
+  //med_int nbpdtnor=0,pflsize,*pflval,lnsize;
   med_int ngauss=0;
   med_int numdt=0,numo=0,nbrefmaa;
   med_float dt=0.0;
   med_booleen local;
-  char maa_ass[MED_TAILLE_NOM+1]="";
-  char dt_unit[MED_TAILLE_PNOM+1]="";
-  char nomcha[MED_TAILLE_NOM+1]="";
+  //char pflname[MED_TAILLE_NOM+1]="";
+  //char locname[MED_TAILLE_NOM+1]="";
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
   //
   for(int i=0;i<nbFields;i++)
     {
@@ -369,40 +583,80 @@ std::vector<std::string> MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName
       char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
       char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
       MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
-      std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
       delete [] comp;
       delete [] unit;
-      bool found=false;
+      //
       med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+      bool found=false;
       if(nbPdt>0)
+        {    
+          for(int i=0;i<nbPdt && !found;i++)
+            {
+              MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,i+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+              std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+              if(curMeshName==meshName)
+                {
+                  found=true;
+                  ret.push_back(curFieldName);
+                }
+            }
+        }
+      //
+      for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
         {
-          MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
-          std::string curMeshName=MEDLoaderNS::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
-          if(curMeshName==meshName)
+          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+          if(nbPdt>0)
             {
-              found=true;
-              ret.push_back(curFieldName);
+              MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+              std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+              if(curMeshName==meshName)
+                {
+                  found=true;
+                  ret.push_back(curFieldName);
+                }
             }
         }
     }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
   MEDfermer(fid);
   return ret;
 }
 
-std::vector< std::pair<int,int> > MEDLoader::GetCellFieldIterations(const char *fileName, const char *fieldName)
+std::vector<std::string> MEDLoader::GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
 {
-  std::vector< std::pair<int,int> > ret;
+  CheckFileForRead(fileName);
+  switch(type)
+    {
+    case ON_CELLS:
+      return GetCellFieldNamesOnMesh(fileName,meshName);
+    case ON_NODES:
+      return GetNodeFieldNamesOnMesh(fileName,meshName);
+    default:
+      throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !");
+    } 
+}
+
+std::vector<std::string> MEDLoader::GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  std::vector<std::string> ret;
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   med_int nbFields=MEDnChamp(fid,0);
   //
   med_type_champ typcha;
+  //med_int nbpdtnor=0,pflsize,*pflval,lnsize;
   med_int ngauss=0;
   med_int numdt=0,numo=0,nbrefmaa;
   med_float dt=0.0;
   med_booleen local;
-  char maa_ass[MED_TAILLE_NOM+1]="";
-  char dt_unit[MED_TAILLE_PNOM+1]="";
-  char nomcha[MED_TAILLE_NOM+1]="";
+  //char pflname[MED_TAILLE_NOM+1]="";
+  //char locname[MED_TAILLE_NOM+1]="";
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
   //
   for(int i=0;i<nbFields;i++)
     {
@@ -410,31 +664,36 @@ std::vector< std::pair<int,int> > MEDLoader::GetCellFieldIterations(const char *
       char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
       char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
       MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
-      std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
       delete [] comp;
       delete [] unit;
-      if(curFieldName==fieldName)
+      bool found=false;
+      for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
         {
-          bool found=false;
-          for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
+          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+          if(nbPdt>0)
             {
-              med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
-              for(int k=0;k<nbPdt;k++)
+              MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+              std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+              if(curMeshName==meshName)
                 {
-                  MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
                   found=true;
-                  ret.push_back(std::make_pair(numdt,numo));
+                  ret.push_back(curFieldName);
                 }
             }
         }
     }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
   MEDfermer(fid);
   return ret;
 }
 
-std::vector< std::pair<int,int> > MEDLoader::GetNodeFieldIterations(const char *fileName, const char *fieldName)
+std::vector<std::string> MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
 {
-  std::vector< std::pair<int,int> > ret;
+  CheckFileForRead(fileName);
+  std::vector<std::string> ret;
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   med_int nbFields=MEDnChamp(fid,0);
   //
@@ -443,9 +702,9 @@ std::vector< std::pair<int,int> > MEDLoader::GetNodeFieldIterations(const char *
   med_int numdt=0,numo=0,nbrefmaa;
   med_float dt=0.0;
   med_booleen local;
-  char maa_ass[MED_TAILLE_NOM+1]="";
-  char dt_unit[MED_TAILLE_PNOM+1]="";
-  char nomcha[MED_TAILLE_NOM+1]="";
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
   //
   for(int i=0;i<nbFields;i++)
     {
@@ -453,43 +712,45 @@ std::vector< std::pair<int,int> > MEDLoader::GetNodeFieldIterations(const char *
       char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
       char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
       MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
-      std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
       delete [] comp;
       delete [] unit;
-      if(curFieldName==fieldName)
+      bool found=false;
+      med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+      if(nbPdt>0)
         {
-          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
-          for(int k=0;k<nbPdt;k++)
+          MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+          std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+          if(curMeshName==meshName)
             {
-              MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
-              ret.push_back(std::make_pair(numdt,numo));
+              found=true;
+              ret.push_back(curFieldName);
             }
         }
     }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
   MEDfermer(fid);
   return ret;
 }
 
-void MEDLoaderNS::readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, std::list<MEDLoader::MEDFieldDoublePerCellType>& field,
-                                               int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, double& time)
+std::vector< std::pair< std::pair<int,int>, double> > MEDLoader::GetAllFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
 {
-  time=0.;
+  CheckFileForRead(fileName);
+  std::string meshNameCpp(meshName);
+  std::vector< std::pair< std::pair<int,int>, double> > ret;
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   med_int nbFields=MEDnChamp(fid,0);
   //
   med_type_champ typcha;
-  char nomcha[MED_TAILLE_NOM+1]="";
-  char pflname [MED_TAILLE_NOM+1]="";
-  char locname [MED_TAILLE_NOM+1]="";
-  std::map<ParaMEDMEM::TypeOfField, med_entite_maillage> tabEnt;
-  std::map<ParaMEDMEM::TypeOfField, med_geometrie_element *> tabType;
-  std::map<ParaMEDMEM::TypeOfField, int> tabTypeLgth;
-  tabEnt[ON_CELLS]=MED_MAILLE;
-  tabType[ON_CELLS]=typmai;
-  tabTypeLgth[ON_CELLS]=MED_NBR_GEOMETRIE_MAILLE+2;
-  tabEnt[ON_NODES]=MED_NOEUD;
-  tabType[ON_NODES]=typmainoeud;
-  tabTypeLgth[ON_NODES]=1;
+  med_int ngauss=0;
+  med_int numdt=0,numo=0,nbrefmaa;
+  med_float dt=0.0;
+  med_booleen local;
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
   //
   for(int i=0;i<nbFields;i++)
     {
@@ -497,63 +758,359 @@ void MEDLoaderNS::readFieldDoubleDataInMedFile(const char *fileName, const char
       char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
       char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
       MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
-      std::string curFieldName=buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
       delete [] comp;
       delete [] unit;
       if(curFieldName==fieldName)
         {
           bool found=false;
-          for(int j=0;j<tabTypeLgth[typeOfOutField] && !found;j++)
+          for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
             {
-              med_int nbPdt=MEDnPasdetemps(fid,nomcha,tabEnt[typeOfOutField],typmai[j]);
-              if(nbPdt>0)
+              med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+              for(int k=0;k<nbPdt;k++)
                 {
-                  int nval=MEDnVal(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order,(char *)meshName,MED_COMPACT);
-                  double *valr=new double[ncomp*nval];
-                  //
-                  med_int ngauss=0;
-                  med_int numdt=0,numo=0,nbrefmaa;
-                  char dt_unit[MED_TAILLE_PNOM+1]="";
-                  char maa_ass[MED_TAILLE_NOM+1]="";
-                  med_float dt=0.0;
-                  med_booleen local;
-                  med_int nbPdt=MEDnPasdetemps(fid,(char *)fieldName,MED_MAILLE,tabType[typeOfOutField][j]);
-                  bool found2=false;
-                  for(int k=0;k<nbPdt && !found2;k++)
+                  MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                  std::string maa_ass_cpp(maa_ass);
+                  if(meshNameCpp==maa_ass_cpp)
                     {
-                      MEDpasdetempsInfo(fid,(char *)fieldName,MED_MAILLE,tabType[typeOfOutField][j],k+1,&ngauss,
-                                        &numdt,&numo,dt_unit,&dt,maa_ass,&local,&nbrefmaa);
-                      found2=(numdt==iteration && numo==order);
-                      if(found2)
-                        time=dt;
+                      found=true;
+                      ret.push_back(std::make_pair(std::make_pair(numdt,numo),dt));
                     }
-                  MEDchampLire(fid,(char *)meshName,(char *)fieldName,(unsigned char*)valr,MED_FULL_INTERLACE,MED_ALL,locname,
-                               pflname,MED_COMPACT,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order);
-                  field.push_back(MEDLoader::MEDFieldDoublePerCellType(typmai2[j],valr,ncomp,nval));
                 }
             }
+          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+          for(int k=0;k<nbPdt;k++)
+            {
+              MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+              std::string maa_ass_cpp(maa_ass);
+              if(meshNameCpp==maa_ass_cpp)
+                ret.push_back(std::make_pair(std::make_pair(numdt,numo),dt));
+            }
         }
     }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
   MEDfermer(fid);
+  return ret;
 }
 
-std::vector<int> MEDLoaderNS::getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector<std::string>& fams)
+double MEDLoader::GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
 {
-  std::vector<int> ret;
+  CheckFileForRead(fileName);
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
-  med_int nfam=MEDnFam(fid,(char *)meshName);
-  char nomfam[MED_TAILLE_NOM+1];
-  med_int numfam;
-  for(int i=0;i<nfam;i++)
-    {
-      int ngro=MEDnGroupe(fid,(char *)meshName,i+1);
-      med_int natt=MEDnAttribut(fid,(char *)meshName,i+1);
+  med_int nbFields=MEDnChamp(fid,0);
+  //
+  med_type_champ typcha;
+  med_int ngauss=0;
+  med_int numdt=0,numo=0,nbrefmaa;
+  med_float dt=0.0;
+  med_booleen local;
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  //
+  bool found=false;
+  bool found2=false;
+  double ret;
+  for(int i=0;i<nbFields && !found;i++)
+    {
+      med_int ncomp=MEDnChamp(fid,i+1);
+      char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+      char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+      MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      delete [] comp;
+      delete [] unit;
+      if(curFieldName==fieldName)
+        {
+          found=true;
+          for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found2;j++)
+            {
+              med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+              for(int k=0;k<nbPdt;k++)
+                {
+                  MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                  if(numdt==iteration && numo==order)
+                    {
+                      found2=true;
+                      ret=dt;
+                    }
+                }
+            }
+          if(!found2)
+            {
+              med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+              for(int k=0;k<nbPdt && !found2;k++)
+                {
+                  MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                  if(numdt==iteration && numo==order)
+                    {
+                      found2=true;
+                      ret=dt;
+                    }
+                }
+            }
+        }
+    }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
+  MEDfermer(fid);
+  if(!found || !found2)
+    {
+      std::ostringstream oss;
+      oss << "No such field with name \"" << fieldName << "\" and iteration,order=(" << iteration << "," << order << ") exists in file \"" << fileName << "\" !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  return ret;
+}
+
+std::vector< std::pair<int,int> > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  switch(type)
+    {
+    case ON_CELLS:
+      return GetCellFieldIterations(fileName,meshName,fieldName);
+    case ON_NODES:
+      return GetNodeFieldIterations(fileName,meshName,fieldName);
+    default:
+      throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !");
+    }
+}
+
+std::vector< std::pair<int,int> > MEDLoader::GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  std::string meshNameCpp(meshName);
+  std::vector< std::pair<int,int> > ret;
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  med_int nbFields=MEDnChamp(fid,0);
+  //
+  med_type_champ typcha;
+  med_int ngauss=0;
+  med_int numdt=0,numo=0,nbrefmaa;
+  med_float dt=0.0;
+  med_booleen local;
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  //
+  for(int i=0;i<nbFields;i++)
+    {
+      med_int ncomp=MEDnChamp(fid,i+1);
+      char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+      char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+      MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      delete [] comp;
+      delete [] unit;
+      if(curFieldName==fieldName)
+        {
+          bool found=false;
+          for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
+            {
+              med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+              for(int k=0;k<nbPdt;k++)
+                {
+                  MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                  std::string maa_ass_cpp(maa_ass);
+                  if(meshNameCpp==maa_ass_cpp)
+                    {
+                      found=true;
+                      ret.push_back(std::make_pair(numdt,numo));
+                    }
+                }
+            }
+        }
+    }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
+  MEDfermer(fid);
+  return ret;
+}
+
+std::vector< std::pair<int,int> > MEDLoader::GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  std::string meshNameCpp(meshName);
+  std::vector< std::pair<int,int> > ret;
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  med_int nbFields=MEDnChamp(fid,0);
+  //
+  med_type_champ typcha;
+  med_int ngauss=0;
+  med_int numdt=0,numo=0,nbrefmaa;
+  med_float dt=0.0;
+  med_booleen local;
+  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+  char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  //
+  for(int i=0;i<nbFields;i++)
+    {
+      med_int ncomp=MEDnChamp(fid,i+1);
+      char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+      char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+      MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      delete [] comp;
+      delete [] unit;
+      if(curFieldName==fieldName)
+        {
+          med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+          for(int k=0;k<nbPdt;k++)
+            {
+              MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+               std::string maa_ass_cpp(maa_ass);
+               if(meshNameCpp==maa_ass_cpp)
+                 {
+                   ret.push_back(std::make_pair(numdt,numo));
+                 }
+            }
+        }
+    }
+  delete [] maa_ass;
+  delete [] dt_unit;
+  delete [] nomcha;
+  MEDfermer(fid);
+  return ret;
+}
+
+/*!
+ * This method reads all the content of a field 'fieldName' at a time specified by (iteration,order) lying on a mesh 'meshName' with a specified type 'TypeOfOutField'
+ * The returned values are strored in 'field' (sorted by type of cell), time corresponding to field, and 'infos' to load properly little strings.
+ * The principle of this method is to put into 'field' only data that fulfills \b perfectly request.
+ */
+void MEDLoaderNS::readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, 
+                                               int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField,
+                                               std::list<MEDLoader::MEDFieldDoublePerCellType>& field,
+                                               double& time, std::vector<std::string>& infos)
+{
+  time=0.;
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  med_int nbFields=MEDnChamp(fid,0);
+  //
+  med_type_champ typcha;
+  char nomcha[MED_TAILLE_NOM+1]="";
+  char pflname [MED_TAILLE_NOM+1]="";
+  char locname [MED_TAILLE_NOM+1]="";
+  std::map<ParaMEDMEM::TypeOfField, med_entite_maillage> tabEnt;
+  std::map<ParaMEDMEM::TypeOfField, med_geometrie_element *> tabType;
+  std::map<ParaMEDMEM::TypeOfField, int> tabTypeLgth;
+  tabEnt[ON_CELLS]=MED_MAILLE;
+  tabType[ON_CELLS]=typmai;
+  tabTypeLgth[ON_CELLS]=MED_NBR_GEOMETRIE_MAILLE+2;
+  tabEnt[ON_NODES]=MED_NOEUD;
+  tabType[ON_NODES]=typmainoeud;
+  tabTypeLgth[ON_NODES]=1;
+  tabEnt[ON_GAUSS_PT]=MED_MAILLE;
+  tabType[ON_GAUSS_PT]=typmai;
+  tabTypeLgth[ON_GAUSS_PT]=MED_NBR_GEOMETRIE_MAILLE+2;
+  tabEnt[ON_GAUSS_NE]=MED_MAILLE;
+  tabType[ON_GAUSS_NE]=typmai;
+  tabTypeLgth[ON_GAUSS_NE]=MED_NBR_GEOMETRIE_MAILLE+2;
+  //
+  for(int i=0;i<nbFields;i++)
+    {
+      med_int ncomp=MEDnChamp(fid,i+1);
+      char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+      char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+      MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+      std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+      if(curFieldName==fieldName)
+        {
+          infos.resize(ncomp);
+          for(int i=0;i<ncomp;i++)
+            infos[i]=MEDLoaderBase::buildUnionUnit(comp+i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,unit+i*MED_TAILLE_PNOM,MED_TAILLE_PNOM);
+          bool found=false;
+          for(int j=0;j<tabTypeLgth[typeOfOutField] && !found;j++)
+            {
+              med_int nbPdt=MEDnPasdetemps(fid,nomcha,tabEnt[typeOfOutField],typmai[j]);
+              if(nbPdt>0)
+                {
+                  int nval=MEDnVal(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order,(char *)meshName,MED_COMPACT);
+                  double *valr=new double[ncomp*nval];
+                  //
+                  med_int ngauss=0;
+                  med_int numdt=0,numo=0,nbrefmaa;
+                  char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM);
+                  char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+                  med_float dt=0.0;
+                  med_booleen local;
+                  med_int nbPdt=MEDnPasdetemps(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j]);
+                  bool found2=false;
+                  for(int k=0;k<nbPdt && !found2;k++)
+                    {
+                      MEDpasdetempsInfo(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j],k+1,&ngauss,
+                                        &numdt,&numo,dt_unit,&dt,maa_ass,&local,&nbrefmaa);
+                      found2=(numdt==iteration && numo==order);
+                      if(found2)
+                        time=dt;
+                    }
+                  if(!found2)
+                    {
+                      std::ostringstream oss; oss << "FieldDouble in file \""<< fileName<< "\" with name \"" << fieldName << "\" on mesh \"" <<  meshName;
+                      oss << "\" does not have such time step : iteration=" << iteration << " order=" << order << std::endl;
+                      delete [] valr;
+                      delete [] comp;
+                      delete [] unit;
+                      delete [] dt_unit;
+                      delete [] maa_ass;
+                      MEDfermer(fid);
+                      throw INTERP_KERNEL::Exception(oss.str().c_str());
+                    }
+                  MEDchampLire(fid,(char *)meshName,(char *)fieldName,(unsigned char*)valr,MED_FULL_INTERLACE,MED_ALL,locname,
+                               pflname,MED_COMPACT,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order);
+                  std::string tmp(locname);
+                  if((locname[0]!='\0' && (typeOfOutField!=ON_GAUSS_PT && typeOfOutField!=ON_GAUSS_NE))
+                     || (tmp!=MED_GAUSS_ELNO && typeOfOutField==ON_GAUSS_NE)
+                     || (locname[0]=='\0' && typeOfOutField==ON_GAUSS_PT)
+                     || (tmp==MED_GAUSS_ELNO && typeOfOutField==ON_GAUSS_PT))
+                    {
+                      delete [] dt_unit;
+                      delete [] maa_ass;
+                      delete [] valr;
+                      continue;
+                    }
+                  int *pfl=0;
+                  if(pflname[0]!='\0')
+                    {
+                      pfl=new int[nval];
+                      MEDprofilLire(fid,pfl,pflname);
+                    }
+                  field.push_back(MEDLoader::MEDFieldDoublePerCellType(typmai2[j],valr,ncomp,nval,pfl,locname));
+                  delete [] pfl;
+                  delete [] dt_unit;
+                  delete [] maa_ass;
+                }
+            }
+        }
+      delete [] comp;
+      delete [] unit;
+    }
+  MEDfermer(fid);
+}
+
+std::vector<int> MEDLoaderNS::getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector<std::string>& fams)
+{
+  std::vector<int> ret;
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  med_int nfam=MEDnFam(fid,(char *)meshName);
+  char nomfam[MED_TAILLE_NOM+1];
+  med_int numfam;
+  for(int i=0;i<nfam;i++)
+    {
+      int ngro=MEDnGroupe(fid,(char *)meshName,i+1);
+      med_int natt=MEDnAttribut(fid,(char *)meshName,i+1);
       med_int *attide=new int[natt];
       med_int *attval=new int[natt];
       char *attdes=new char[MED_TAILLE_DESC*natt+1];
       char *gro=new char[MED_TAILLE_LNOM*ngro+1];
       MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
-      std::string cur=buildStringFromFortran(nomfam,sizeof(nomfam));
+      std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
       if(std::find(fams.begin(),fams.end(),cur)!=fams.end())
         ret.push_back(numfam);
       delete [] attdes;
@@ -581,10 +1138,10 @@ std::vector<int> MEDLoaderNS::getIdsFromGroups(const char *fileName, const char
       char *attdes=new char[MED_TAILLE_DESC*natt+1];
       char *gro=new char[MED_TAILLE_LNOM*ngro+1];
       MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
-      std::string cur=buildStringFromFortran(nomfam,sizeof(nomfam));
+      std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
       for(int j=0;j<ngro;j++)
         {
-          std::string cur=buildStringFromFortran(gro+j*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
+          std::string cur=MEDLoaderBase::buildStringFromFortran(gro+j*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
           if(std::find(grps.begin(),grps.end(),cur)!=grps.end())
             {
               ret.push_back(numfam);
@@ -643,20 +1200,76 @@ void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfEle
     }
 }
 
-void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list<MEDLoader::MEDConnOfOneElemType>& conn)
+/*!
+ * This method returns a first quick overview of mesh with name 'meshName' into the file 'fileName'.
+ * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method.
+ * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned.
+ */
+int MEDLoaderNS::readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector<int>& possibilities)
+{
+  possibilities.clear();
+  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+  int ret;
+  std::set<int> poss;
+  char nommaa[MED_TAILLE_NOM+1];
+  char maillage_description[MED_TAILLE_DESC+1];
+  med_maillage type_maillage;
+  med_int Mdim;
+  std::string trueMeshName;
+  med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName);
+  MEDmaaInfo(fid,meshId,nommaa,&Mdim,&type_maillage,maillage_description);
+  for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
+    {
+      med_geometrie_element curMedType=typmai[i];
+      int curNbOfElemM=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,curMedType,MED_NOD);
+      int curNbOfElemF=MEDnEntMaa(fid,nommaa,MED_CONN,MED_FACE,curMedType,MED_NOD);
+      int curNbOfElem;
+      med_entite_maillage whichEntity;
+      MEDLoaderNS::dispatchElems(curNbOfElemM,curNbOfElemF,curNbOfElem,whichEntity);
+      if(curNbOfElem>0)
+        {
+          INTERP_KERNEL::NormalizedCellType type=typmai2[i];
+          int curDim=(int)INTERP_KERNEL::CellModel::getCellModel(type).getDimension();
+          poss.insert(curDim);
+        }
+    }
+  MEDfermer(fid);
+  if(!poss.empty())
+    {
+      ret=*poss.rbegin();
+      for(std::set<int>::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++)
+        possibilities.push_back(*it-ret);
+    }
+  else
+    ret=-2;
+  return ret;
+}
+
+void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list<MEDLoader::MEDConnOfOneElemType>& conn)
 {
   char nommaa[MED_TAILLE_NOM+1];
   char maillage_description[MED_TAILLE_DESC+1];
-  char comp[3*MED_TAILLE_PNOM+1];
-  char unit[3*MED_TAILLE_PNOM+1];
   med_maillage type_maillage;
   med_int Mdim;
   MEDmaaInfo(fid,meshId,nommaa,&Mdim,&type_maillage,maillage_description);
-  spaceDim=(int)Mdim;
-  nCoords=MEDnEntMaa(fid,nommaa,MED_COOR,MED_NOEUD,(med_geometrie_element)0,(med_connectivite)0);
-  coords=new double[nCoords*spaceDim];
+  med_int edim=MEDdimEspaceLire(fid,nommaa);
+  int spaceDim=std::max((int)Mdim,(int)edim);
+  int nCoords=MEDnEntMaa(fid,nommaa,MED_COOR,MED_NOEUD,(med_geometrie_element)0,(med_connectivite)0);
+  coords=DataArrayDouble::New();
+  coords->alloc(nCoords,spaceDim);
+  double *coordsPtr=coords->getPointer();
   med_repere repere;
-  MEDcoordLire(fid,nommaa,Mdim,coords,MED_FULL_INTERLACE,MED_ALL,NULL,0,&repere,comp,unit);
+  char *comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM);
+  char *unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM);
+  MEDcoordLire(fid,nommaa,spaceDim,coordsPtr,MED_FULL_INTERLACE,MED_ALL,NULL,0,&repere,comp,unit);
+  for(int i=0;i<spaceDim;i++)
+    {
+      std::string n,u;
+      std::string info=MEDLoaderBase::buildUnionUnit(comp+i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,unit+i*MED_TAILLE_PNOM,MED_TAILLE_PNOM);
+      coords->setInfoOnComponent(i,info.c_str());
+    }
+  delete [] comp;
+  delete [] unit;
   med_booleen inoele, inuele;
   for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
     {
@@ -678,7 +1291,7 @@ void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&c
           delete [] noms;
           //trying to read global numbering
           int *globArr=new int[curNbOfElem];
-          if(MEDglobalNumLire(fid,nommaa,globArr,curNbOfElem,whichEntity,curMedType)==0)
+          if(MEDnumLire(fid,nommaa,globArr,curNbOfElem,whichEntity,curMedType)==0)
             elem.setGlobal(globArr);
           else
             delete [] globArr;
@@ -697,9 +1310,14 @@ void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&c
       int *index=new int[curNbOfPolyElem+1];
       int *locConn=new int[arraySize];
       int *fam=new int[curNbOfPolyElem];
+      int *globArr=new int[curNbOfPolyElem];
       MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYGON,locConn,index,fam,curNbOfPolyElem,arraySize);
       MEDpolygoneConnLire(fid,nommaa,index,curNbOfPolyElem+1,locConn,whichPolyEntity,MED_NOD);
-      MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,MED_MAILLE,MED_POLYGONE);
+      MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,whichPolyEntity,MED_POLYGONE);
+      if(MEDnumLire(fid,nommaa,globArr,curNbOfPolyElem,whichPolyEntity,MED_POLYGONE)==0)
+        elem.setGlobal(globArr);
+      else
+        delete [] globArr;
       conn.push_back(elem);
     }
   curNbOfPolyElem=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,MED_POLYEDRE,MED_NOD);
@@ -711,6 +1329,7 @@ void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&c
       int *indexFace=new int[indexFaceLgth];
       int *locConn=new int[connFaceLgth];
       int *fam=new int[curNbOfPolyElem];
+      int *globArr=new int[curNbOfPolyElem];
       MEDpolyedreConnLire(fid,nommaa,index,curNbOfPolyElem+1,indexFace,indexFaceLgth,locConn,MED_NOD);
       MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,MED_MAILLE,MED_POLYEDRE);
       int arraySize=connFaceLgth;
@@ -734,6 +1353,10 @@ void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&c
       delete [] locConn;
       delete [] indexFace;
       MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYHED,finalConn,finalIndex,fam,curNbOfPolyElem,arraySize);
+      if(MEDnumLire(fid,nommaa,globArr,curNbOfPolyElem,MED_MAILLE,MED_POLYEDRE)==0)
+        elem.setGlobal(globArr);
+      else
+        delete [] globArr;
       conn.push_back(elem);
     }
 }
@@ -795,7 +1418,8 @@ public:
   int operator()(int res, const MEDLoader::MEDFieldDoublePerCellType& elt) { return res+elt.getNbOfTuple(); }
 };
 
-ParaMEDMEM::DataArrayDouble *MEDLoaderNS::buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType)
+ParaMEDMEM::DataArrayDouble *MEDLoaderNS::buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType,
+                                                                const std::vector<std::string>& infos)
 {
   ParaMEDMEM::DataArrayDouble *ret=ParaMEDMEM::DataArrayDouble::New();
   int totalNbOfTuple=std::accumulate(fieldPerType.begin(),fieldPerType.end(),0,FieldPerTypeAccumulator());
@@ -803,6 +1427,8 @@ ParaMEDMEM::DataArrayDouble *MEDLoaderNS::buildArrayFromRawData(const std::list<
   double *ptr=new double[nbOfComp*totalNbOfTuple];
   ret->useArray(ptr,true,ParaMEDMEM::CPP_DEALLOC,totalNbOfTuple,nbOfComp);
   std::for_each(fieldPerType.begin(),fieldPerType.end(),FieldPerTypeCopier(ptr));
+  for(int i=0;i<nbOfComp;i++)
+    ret->setInfoOnComponent(i,infos[i].c_str());
   return ret;
 }
 
@@ -819,23 +1445,33 @@ private:
   int _sigma;
 };
 
+/*!
+ * This method fills unstructured connectivity using basic MED file format 'medConnFrmt'.
+ * If in each elements of 'medConnFrmt' a renumbering cell array is found the aggregate array 'cellRenum' is returned.
+ */
 void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt,
+                                                       const std::vector<int>& familiesToKeep,
                                                        DataArrayInt* &conn,
                                                        DataArrayInt* &connIndex,
-                                                       const std::vector<int>& familiesToKeep)
+                                                       int *&cellRenum)
 {
   bool keepAll=familiesToKeep.empty();
   if(medConnFrmt.empty())
     {
       conn=0;
       connIndex=0;
+      cellRenum=0;
       return ;
     }
   std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=medConnFrmt.begin();
   int totalNbOfCells=0;
   int totalNbOfMedConn=0;
+  bool renumber=true;
+  cellRenum=0;
   for(;iter!=medConnFrmt.end();iter++)
     {
+      if((*iter).getGlobal()==0)
+        renumber=false;
       const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel((*iter).getType());
       if(keepAll)
         totalNbOfCells+=(*iter).getLength();
@@ -865,11 +1501,15 @@ void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader
   int connFillId=0;
   conn->alloc(totalNbOfMedConn+totalNbOfCells,1);
   int *connPtr=conn->getPointer();
+  if(renumber)
+    cellRenum=new int[totalNbOfCells];
+  int *renumW=cellRenum;
   for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
     {
       INTERP_KERNEL::NormalizedCellType type=(*iter).getType();
       const int *sourceConn=(*iter).getArray();
       const int *sourceIndex=(*iter).getIndex();
+      const int *globalNum=(*iter).getGlobal();
       const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type);
       int nbOfCellsInCurType;
       int nbOfNodesIn1Cell=cellMod.getNumberOfNodes();
@@ -879,9 +1519,11 @@ void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader
       for(int i=0;i<nbOfCellsInCurType;i++)
         {
           if(keepAll)
-            {
+            {//duplication of next 3 lines needed.
               *connIdxPtr=connFillId;
               *connPtr++=type;
+              if(renumber)
+                *renumW++=globalNum[i];
               if(!isDyn)
                 tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
               else
@@ -892,13 +1534,15 @@ void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader
               connPtr=tmpConnPtr;
             }
           else if(std::find(familiesToKeep.begin(),familiesToKeep.end(),(*iter).getFam()[i])!=familiesToKeep.end())
-            {
+            {//duplication of next 3 lines needed.
               *connIdxPtr=connFillId;
               *connPtr++=type;
+              if(renumber)
+                *renumW++=globalNum[i];
               if(!isDyn)
                 tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
-              else
-                tmpConnPtr=std::transform(sourceConn,sourceConn+sourceIndex[i+1]-sourceIndex[i],connPtr,std::bind2nd(std::minus<int>(),1));
+              else//The duplication of code is motivated by the line underneath.
+                tmpConnPtr=std::transform((*iter).getArray()+sourceIndex[i]-1,(*iter).getArray()+sourceIndex[i+1]-1,connPtr,std::bind2nd(std::minus<int>(),1));
               connIdxPtr++;
               nbOfNodesIn1Cell=tmpConnPtr-connPtr;
               connFillId+=nbOfNodesIn1Cell+1;
@@ -922,87 +1566,171 @@ namespace MEDLoaderNS
 }
 
 /*!
- * This method builds a sub set of connectivity for a given type 'type'.
- * @param conn input containing connectivity with MEDCoupling format.
- * @param connIndex input containing connectivity index in MEDCoupling format.
+ * This method builds a sub set of connectivity for a given type 'type'. \b WARNING connV,connVIndex and familiesV must have same size !
+ * @param connV input containing connectivity with MEDCoupling format.
+ * @param connVIndex input containing connectivity index in MEDCoupling format.
+ * @param familiesV input that may be equal to 0. This specifies an array specifying cell family foreach cell.
  * @param type input specifying which cell types will be extracted in conn4MEDFile. 
  * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
  * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
  * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
+ * @param fam4MEDFile output containing family number of cells whose type is 'type'. This output is updated only if 'families' is different than 0.
  * @return nb of elements extracted.
  */
-int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile)
+int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector<const DataArrayInt *>& connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
+                                                             INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
 {
   int ret=0;
-  int nbOfElem=connIndex->getNbOfElems()-1;
-  const int *connPtr=conn->getPointer();
-  const int *connIdxPtr=connIndex->getPointer();
-  for(int i=0;i<nbOfElem;i++)
+  int nbOfMeshes=connV.size();
+  int renumOffset=0;
+  for(int i=0;i<nbOfMeshes;i++)
     {
-      int delta=connIdxPtr[1]-connIdxPtr[0];
-      if(*connPtr==type)
+      const DataArrayInt *conn=connV[i];
+      const DataArrayInt *connIndex=connVIndex[i];
+      const DataArrayInt *families=familiesV[i];
+      int nbOfElem=connIndex->getNbOfElems()-1;
+      const int *connPtr=conn->getConstPointer();
+      const int *connIdxPtr=connIndex->getConstPointer();
+      const int *famPtr=0;
+      if(families)
+        famPtr=families->getConstPointer();
+      for(int i=0;i<nbOfElem;i++)
         {
-          conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
-          ret++;
+          int delta=connIdxPtr[1]-connIdxPtr[0];
+          if(*connPtr==type)
+            {
+              conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
+              if(families)
+                fam4MEDFile.push_back(famPtr[i]);
+              renumber.push_back(i+1+renumOffset);
+              ret++;
+            }
+          connIdxPtr++;
+          connPtr+=delta;
         }
-      connIdxPtr++;
-      connPtr+=delta;
+      renumOffset+=nbOfElem;
     }
   std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
   return ret;
 }
 
-int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(DataArrayInt *conn, DataArrayInt *connIndex, std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile)
+int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(const std::vector<const DataArrayInt *>&connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
+                                                        std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
 {
   int ret=0;
-  int nbOfElem=connIndex->getNbOfElems()-1;
-  const int *connPtr=conn->getPointer();
-  const int *connIdxPtr=connIndex->getPointer();
+  int nbOfMeshes=connV.size();
   connIndex4MEDFile.push_back(1);
-  for(int i=0;i<nbOfElem;i++)
+  int renumOffset=0;
+  for(int i=0;i<nbOfMeshes;i++)
     {
-      int delta=connIdxPtr[1]-connIdxPtr[0];
-      if(*connPtr==INTERP_KERNEL::NORM_POLYGON)
+      const DataArrayInt *conn=connV[i];
+      const DataArrayInt *connIndex=connVIndex[i];
+      const DataArrayInt *families=familiesV[i];
+      int nbOfElem=connIndex->getNbOfElems()-1;
+      const int *connPtr=conn->getConstPointer();
+      const int *connIdxPtr=connIndex->getConstPointer();
+      const int *famPtr=0;
+      if(families)
+        famPtr=families->getConstPointer();
+      for(int i=0;i<nbOfElem;i++)
         {
-          conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
-          connIndex4MEDFile.push_back(connIndex4MEDFile.back()+delta-1);
-          ret++;
+          int delta=connIdxPtr[1]-connIdxPtr[0];
+          if(*connPtr==INTERP_KERNEL::NORM_POLYGON)
+            {
+              conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
+              connIndex4MEDFile.push_back(connIndex4MEDFile.back()+delta-1);
+              if(families)
+                fam4MEDFile.push_back(famPtr[i]);
+              renumber.push_back(i+1+renumOffset);
+              ret++;
+            }
+          connIdxPtr++;
+          connPtr+=delta;
         }
-      connIdxPtr++;
-      connPtr+=delta;
+      renumOffset+=nbOfElem;
     }
   std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
   return ret;
 }
   
-int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(DataArrayInt *conn, DataArrayInt *connIndex, std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile)
+int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const std::vector<const DataArrayInt *>& connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
+                                                        std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile,
+                                                        std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
 {
-  return 0;
+  int ret=0;
+  int nbOfMeshes=connV.size();
+  connIndexRk24MEDFile.push_back(1);
+  connIndex4MEDFile.push_back(1);
+  int renumOffset=0;
+  for(int i=0;i<nbOfMeshes;i++)
+    {
+      const DataArrayInt *conn=connV[i];
+      const DataArrayInt *connIndex=connVIndex[i];
+      const DataArrayInt *families=familiesV[i];
+      int nbOfElem=connIndex->getNbOfElems()-1;
+      const int *connPtr=conn->getConstPointer();
+      const int *connIdxPtr=connIndex->getConstPointer();
+      const int *famPtr=0;
+      if(families)
+        famPtr=families->getConstPointer();
+      for(int i=0;i<nbOfElem;i++)
+        {
+          int delta=connIdxPtr[1]-connIdxPtr[0];
+          if(*connPtr==INTERP_KERNEL::NORM_POLYHED)
+            {
+              int nbOfFacesOfPolyh=std::count(connPtr+1,connPtr+delta,-1)+1;
+              const int *work=connPtr+1;
+              while(work!=connPtr+delta)
+                {
+                  const int *end=std::find(work,connPtr+delta,-1);
+                  conn4MEDFile.insert(conn4MEDFile.end(),work,end);
+                  connIndex4MEDFile.push_back(connIndex4MEDFile.back()+std::distance(work,end));
+                  if(end==connPtr+delta)
+                    work=connPtr+delta;
+                  else
+                    work=end+1;
+                }
+              connIndexRk24MEDFile.push_back(connIndexRk24MEDFile.back()+nbOfFacesOfPolyh);
+              if(families)
+                fam4MEDFile.push_back(famPtr[i]);
+              renumber.push_back(i+1+renumOffset);
+              ret++;
+            }
+          connIdxPtr++;
+          connPtr+=delta;
+        }
+      renumOffset+=nbOfElem;
+    }
+  std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
+  return ret;
 }
   
 /*!
  * This method builds a sub set of connectivity for a given type 'type'.
  * @param conn input containing connectivity with MEDCoupling format.
  * @param connIndex input containing connectivity index in MEDCoupling format.
+ * @param families input containing, if any, the family number of each cells
  * @param type input specifying which cell types will be extracted in conn4MEDFile. 
  * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
  * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
  * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
+ * @param fam4MEDFile output containing families id of cells whose type is 'type'.
  * @return nb of elements extracted.
  */
-int MEDLoaderNS::buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile,
-                                                  std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile)
+int MEDLoaderNS::buildMEDSubConnectivityOfOneType(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
+                                                  INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile,
+                                                  std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
 {
     
   const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type);
   if(!cellMod.isDynamic())
-    return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,type,conn4MEDFile);
+    return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,families,type,conn4MEDFile,fam4MEDFile,renumber);
   else
     {
       if(type==INTERP_KERNEL::NORM_POLYGON)
-        return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,conn4MEDFile,connIndex4MEDFile);
+        return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,fam4MEDFile,renumber);
       else
-        return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile);
+        return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile,fam4MEDFile,renumber);
     }
 }
   
@@ -1010,19 +1738,18 @@ int MEDLoaderNS::buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayI
  * @param ids is a in vector containing families ids whose cells have to be kept. If empty all cells are kept.
  * @param typesToKeep is a in vector that indicates which types to keep after dimension filtering.
  * @param meshDimExtract out parameter that gives the mesh dimension.
+ * @param cellRenum out parameter that specifies the renumbering (if !=0) of cells in file.
  */
 MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<int>& ids,
-                                                     const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract) throw(INTERP_KERNEL::Exception)
+                                                     const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception)
 {
   //Extraction data from MED file.
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
   std::string trueMeshName;
   med_int mid=getIdFromMeshName(fid,meshName,trueMeshName);
-  double *coords;
-  int nCoords;
-  int spaceDim;
+  DataArrayDouble *coords=0;
   std::list<MEDLoader::MEDConnOfOneElemType> conn;
-  readUMeshDataInMedFile(fid,mid,coords,nCoords,spaceDim,conn);
+  readUMeshDataInMedFile(fid,mid,coords,conn);
   meshDimExtract=MEDLoaderNS::calculateHighestMeshDim<MEDLoader::MEDConnOfOneElemType>(conn);
   meshDimExtract=meshDimExtract+meshDimRelToMax;
   MEDLoaderNS::keepSpecifiedMeshDim<MEDLoader::MEDConnOfOneElemType>(conn,meshDimExtract);
@@ -1033,13 +1760,11 @@ MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const
   ret->setName(trueMeshName.c_str());
   ret->setMeshDimension(meshDimExtract);
   //
-  DataArrayDouble *coordsArr=DataArrayDouble::New();
-  coordsArr->useArray(coords,true,ParaMEDMEM::CPP_DEALLOC,nCoords,spaceDim);
-  ret->setCoords(coordsArr);
-  coordsArr->decrRef();
+  ret->setCoords(coords);
+  coords->decrRef();
   //
   DataArrayInt *connArr,*connIndexArr;
-  tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,connArr,connIndexArr,ids);
+  tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,ids,connArr,connIndexArr,cellRenum);
   ret->setConnectivity(connArr,connIndexArr);
   //clean-up
   if(connArr)
@@ -1050,140 +1775,546 @@ MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const
   return ret;
 }
 
-ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order,
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *cellRenum, const ParaMEDMEM::MEDCouplingUMesh *mesh,
+                                                                     const std::vector<std::string>& infos, const char *fieldName, int iteration, int order, double time,
+                                                                     std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerCellType)
+{
+  if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE)
+    MEDLoaderNS::keepSpecifiedMeshDim<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType,meshDim);
+  //for profiles
+  ParaMEDMEM::MEDCouplingUMesh *newMesh=0;
+  std::string mName(mesh->getName());
+  for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
+    {
+      const std::vector<int>& cellIds=(*iter).getCellIdPerType();
+      if(!cellIds.empty())
+        {
+          std::vector<int> ci(cellIds.size());
+          std::transform(cellIds.begin(),cellIds.end(),ci.begin(),std::bind2nd(std::plus<int>(),-1));
+          ParaMEDMEM::MEDCouplingUMesh *mesh2;
+          if(typeOfOutField==ON_CELLS)
+            {
+              if(newMesh)
+                mesh2=newMesh->keepSpecifiedCells((*iter).getType(),ci);
+              else
+                mesh2=mesh->keepSpecifiedCells((*iter).getType(),ci);
+            }
+          else if(typeOfOutField==ON_NODES)
+            {
+              DataArrayInt *da=0,*da2=0;
+              if(newMesh)
+                {
+                  if((int)ci.size()!=newMesh->getNumberOfNodes())
+                    {
+                      da=newMesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]);
+                      mesh2=dynamic_cast<MEDCouplingUMesh *>(newMesh->buildPartAndReduceNodes(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems(),da2));
+                    }
+                }
+              else
+                {
+                  if((int)ci.size()!=mesh->getNumberOfNodes())
+                    {
+                      da=mesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]);
+                      mesh2=dynamic_cast<MEDCouplingUMesh *>(mesh->buildPartAndReduceNodes(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems(),da2));
+                      //
+                      int nnodes=mesh2->getNumberOfNodes();
+                      DataArrayInt *da3=DataArrayInt::New();
+                      const int *da2Ptr=da2->getConstPointer();
+                      da3->alloc(nnodes,1);
+                      int *da3Ptr=da3->getPointer();
+                      for(int i=0;i<(int)ci.size();i++)
+                        {
+                          int val=da2Ptr[ci[i]];
+                          if(val!=-1)
+                            da3Ptr[val]=i;
+                        }
+                      mesh2->renumberNodes(da3->getConstPointer(),nnodes);
+                      da3->decrRef();
+                    }
+                  else
+                    {
+                      mesh2=mesh->clone(true);
+                      da=DataArrayInt::New();
+                      da->alloc((int)ci.size(),1);
+                      std::copy(ci.begin(),ci.end(),da->getPointer());
+                      da2=da->invertArrayO2N2N2O(ci.size());
+                      mesh2->renumberNodes(da2->getConstPointer(),(int)ci.size());
+                    }
+                }
+              if(da)
+                da->decrRef();
+              if(da2)
+                da2->decrRef();
+            }
+          if(newMesh)
+            newMesh->decrRef();
+          newMesh=mesh2;
+        }
+    }
+  //
+  ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField,ONE_TIME);
+  ret->setName(fieldName);
+  ret->setTime(time,iteration,order);
+  if(newMesh)
+    {
+      newMesh->setName(mName.c_str());//retrieving mesh name to avoid renaming due to mesh restriction in case of profile.
+      ret->setMesh(newMesh);
+      newMesh->decrRef();
+    }
+  else
+    ret->setMesh(mesh);
+  ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType,infos);
+  ret->setArray(arr);
+  arr->decrRef();
+  //
+  if(typeOfOutField==ON_GAUSS_PT)
+    fillGaussDataOnField(fileName,fieldPerCellType,ret);
+  if(cellRenum)
+    ret->renumberCellsWithoutMesh(cellRenum,true);
+  return ret;
+}
+
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order,
                                                                      ParaMEDMEM::TypeOfField typeOfOutField)
 {
   std::list<MEDLoader::MEDFieldDoublePerCellType> fieldPerCellType;
   double time;
-  readFieldDoubleDataInMedFile(fileName,meshName,fieldName,fieldPerCellType,iteration,order,typeOfOutField,time);
+  std::vector<std::string> infos;
+  readFieldDoubleDataInMedFile(fileName,meshName,fieldName,iteration,order,typeOfOutField,fieldPerCellType,time,infos);
   std::vector<int> familiesToKeep;
   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
-  if(typeOfOutField==ON_CELLS)
+  if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE)
     for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
       typesToKeep.push_back((*iter).getType());
   unsigned meshDim;
-  ParaMEDMEM::MEDCouplingUMesh *mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
-  if(typeOfOutField==ON_CELLS)
-    MEDLoaderNS::keepSpecifiedMeshDim<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType,meshDim);
-  ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField,ONE_TIME);
-  ret->setName(fieldName);
-  ret->setTime(time,iteration,order);
-  ret->setMesh(mesh);
+  int *cellRenum;
+  ParaMEDMEM::MEDCouplingUMesh *mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
+  ParaMEDMEM::MEDCouplingFieldDouble *ret=readFieldDoubleLev2(fileName,typeOfOutField,meshDim,cellRenum,mesh,infos,fieldName,iteration,order,time,fieldPerCellType);
+  if(cellRenum)
+    mesh->renumberCells(cellRenum,true);
   mesh->decrRef();
-  ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType);
-  ret->setArray(arr);
-  arr->decrRef();
+  //clean-up
+  delete [] cellRenum;
   releaseMEDFileCoreFrmt<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType);
   return ret;
 }
 
 MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   std::vector<int> familiesToKeep;
   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
   unsigned meshDim;
-  return MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
+  int *cellRenum;
+  ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
+  if(cellRenum)
+    {
+      ret->renumberCells(cellRenum,true);
+      delete [] cellRenum;
+    }
+  return ret;
 }
 
 ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   std::vector<int> familiesToKeep;
   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
   unsigned meshDim;
-  return MEDLoaderNS::readUMeshFromFileLev1(fileName,0,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
+  int *cellRenum;
+  ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,0,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
+  if(cellRenum)
+    {
+      ret->renumberCells(cellRenum,true);
+      delete [] cellRenum;
+    }
+  return ret;
+}
+
+int MEDLoader::ReadUMeshDimFromFile(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  std::vector<int> poss;
+  return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss);
 }
 
-ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams)
+ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   std::vector<int> familiesToKeep=MEDLoaderNS::getIdsFromFamilies(fileName,meshName,fams);
   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
   unsigned meshDim;
-  return MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
+  int *cellRenum;
+  ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
+  if(fams.size()==1)
+    ret->setName(fams.back().c_str());
+  if(cellRenum)
+    {
+      ret->renumberCells(cellRenum,true);
+      delete [] cellRenum;
+    }
+  return ret;
 }
 
-ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps)
+ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception)
 {
+  CheckFileForRead(fileName);
   std::vector<int> familiesToKeep=MEDLoaderNS::getIdsFromGroups(fileName,meshName,grps);
   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
   unsigned meshDim;
-  return MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
+  int *cellRenum;
+  ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
+  if(grps.size()==1)
+    ret->setName(grps.back().c_str());
+  if(cellRenum)
+    {
+      ret->renumberCells(cellRenum,true);
+      delete [] cellRenum;
+    }
+  return ret;
+}
+
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
+{
+  CheckFileForRead(fileName);
+  switch(type)
+    {
+    case ON_CELLS:
+      return ReadFieldCell(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
+    case ON_NODES:
+      return ReadFieldNode(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
+    case ON_GAUSS_PT:
+      return ReadFieldGauss(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
+    case ON_GAUSS_NE:
+      return ReadFieldGaussNE(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
+    default:
+      throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES, ON_CELLS, ON_GAUSS_PT or ON_GAUSS_NE !");
+    } 
+}
+
+std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                  const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
+{
+  if(its.empty())
+    return std::vector<ParaMEDMEM::MEDCouplingFieldDouble *>();
+  CheckFileForRead(fileName);
+  std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ret(its.size());
+  if(its.empty())
+    return ret;
+  //Retrieving mesh of rank 0 and field on rank 0 too.
+  std::list<MEDLoader::MEDFieldDoublePerCellType> fieldPerCellType;
+  double time;
+  std::vector<std::string> infos;
+  MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[0].first,its[0].second,type,fieldPerCellType,time,infos);
+  std::vector<int> familiesToKeep;
+  std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
+  if(type==ON_CELLS || type==ON_GAUSS_PT || type==ON_GAUSS_NE)
+    for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
+      typesToKeep.push_back((*iter).getType());
+  unsigned meshDim;
+  int *cellRenum;
+  ParaMEDMEM::MEDCouplingUMesh *m1=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
+  ret[0]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infos,fieldName,its[0].first,its[0].second,time,fieldPerCellType);
+  if(cellRenum)
+    m1->renumberCells(cellRenum,true);
+  MEDLoaderNS::releaseMEDFileCoreFrmt<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType);
+  //
+  for(int itId=1;itId<(int)its.size();itId++)
+    {
+      std::list<MEDLoader::MEDFieldDoublePerCellType> fieldPerCellType;
+      double time;
+      std::vector<std::string> infos;
+      MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[itId].first,its[itId].second,type,fieldPerCellType,time,infos);
+      std::vector<int> familiesToKeep;
+      std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
+      if(type==ON_CELLS || type==ON_GAUSS_PT || type==ON_GAUSS_NE)
+        for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
+          typesToKeep.push_back((*iter).getType());
+      ret[itId]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infos,fieldName,its[itId].first,its[itId].second,time,fieldPerCellType);
+      //clean-up
+      MEDLoaderNS::releaseMEDFileCoreFrmt<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType);
+    }
+  m1->decrRef();
+  delete [] cellRenum;
+  return ret;
+}
+
+std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsCellOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                            const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
+{
+  return ReadFieldsOnSameMesh(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,its);
+}
+
+std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsNodeOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                      const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
+{
+  return ReadFieldsOnSameMesh(ON_NODES,fileName,meshName,meshDimRelToMax,fieldName,its);
+}
+
+std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsGaussOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                       const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
+{
+  return ReadFieldsOnSameMesh(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,its);
+}
+
+std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsGaussNEOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                         const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
+{
+  return ReadFieldsOnSameMesh(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,its);
 }
 
-ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order)
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
 {
   return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_CELLS);
 }
 
-ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order)
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
 {
   return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_NODES);
 }
 
-void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool forceFromScratch)
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
+{
+  return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_PT);
+}
+
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
+{
+  return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_NE);
+}
+
+/*!
+ * @param families input parameter that specifies the field on int on each cells of 'mesh'.
+ * @param isRenumbering output parameter that specifies if a renumbering of mesh has been needed.
+ */
+void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& mesh, const std::vector<const DataArrayInt *>& families, bool forceFromScratch, bool &isRenumbering)
 {
   med_idt fid=MEDouvrir((char *)fileName,forceFromScratch?MED_CREATION:MED_LECTURE_ECRITURE);
-  std::string meshName(mesh->getName());
+  std::string meshName(mesh[0]->getName());
   if(meshName=="")
     {
       MEDfermer(fid);
       throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !");
     }
-  char maa[MED_TAILLE_NOM+1];
-  strcpy(maa,meshName.c_str());
-  MEDmaaCr(fid,maa,mesh->getSpaceDimension(),MED_NON_STRUCTURE,maa);
-  std::set<INTERP_KERNEL::NormalizedCellType> allTypes(mesh->getAllTypes());
-  DataArrayInt *conn=mesh->getNodalConnectivity();
-  DataArrayInt *connIndex=mesh->getNodalConnectivityIndex();
-  char familyName[MED_TAILLE_NOM+1];
-  std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0');
-  const char DftFamilyName[]="DftFamily";
-  std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName);
-  for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE+2;i++)
+  isRenumbering=false;
+  bool isFamilies=true;
+  std::vector<const DataArrayInt *> conn;
+  std::vector<const DataArrayInt *> connIndex;
+  std::set<INTERP_KERNEL::NormalizedCellType> allTypes;
+  for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=mesh.begin();iter!=mesh.end();iter++)
     {
-      med_geometrie_element curMedType=typmai[i];
-      INTERP_KERNEL::NormalizedCellType curType=typmai2[i];
-      if(allTypes.find(curType)!=allTypes.end())
+      isRenumbering|=!(*iter)->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2);
+      isFamilies&=(families[std::distance(mesh.begin(),iter)]!=0);
+      conn.push_back((*iter)->getNodalConnectivity());
+      connIndex.push_back((*iter)->getNodalConnectivityIndex());
+      const std::set<INTERP_KERNEL::NormalizedCellType>& curTypes=(*iter)->getAllTypes();
+      allTypes.insert(curTypes.begin(),curTypes.end());
+    }
+  char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  char *desc=MEDLoaderBase::buildEmptyString(MED_TAILLE_DESC);
+  MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR);
+  MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_DESC,desc,MEDLoader::_TOO_LONG_STR);
+  const int spaceDim=mesh[0]->getSpaceDimension();
+  MEDmaaCr(fid,maa,spaceDim,MED_NON_STRUCTURE,desc);
+  MEDdimEspaceCr(fid,maa,spaceDim);
+  for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=mesh.begin();iter!=mesh.end();iter++)
+    {
+      for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE+2;i++)
         {
-          std::vector<int> medConn;
-          std::vector<int> medConnIndex;
-          std::vector<int> medConnIndex2;
-          int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn,medConnIndex,medConnIndex2);
-          if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE)
-            MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD);
-          else
+          med_geometrie_element curMedType=typmai[i];
+          INTERP_KERNEL::NormalizedCellType curType=typmai2[i];
+          if(allTypes.find(curType)!=allTypes.end())
             {
-              if(curMedType==MED_POLYGONE)
-                MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD);
+              std::vector<int> medConn;
+              std::vector<int> medConnIndex;
+              std::vector<int> medConnIndex2;
+              std::vector<int> fam;
+              std::vector<int> renumber;
+              int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam,renumber);
+              if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE)
+                MEDconnEcr(fid,maa,(*iter)->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD);
+              else
+                {
+                  if(curMedType==MED_POLYGONE)
+                    MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD);
+                  if(curMedType==MED_POLYEDRE)
+                    {
+                      MEDpolyedreConnEcr(fid,maa,&medConnIndex2[0],medConnIndex2.size(),&medConnIndex[0],medConnIndex.size(),
+                                         &medConn[0],MED_NOD);
+                    }
+                }
+              if(isFamilies)
+                MEDfamEcr(fid,maa,&fam[0],nbOfElt,MED_MAILLE,curMedType);
+              if(isRenumbering)
+                MEDnumEcr(fid,maa,&renumber[0],nbOfElt,MED_MAILLE,curMedType);
             }
         }
     }
+  char familyName[MED_TAILLE_NOM+1];
+  std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0');
+  const char DftFamilyName[]="DftFamily";
+  std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName);
   MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0);
-  DataArrayDouble *arr=mesh->getCoords();
-  char comp[2*MED_TAILLE_PNOM+1];
-  char unit[2*MED_TAILLE_PNOM+1];
-  std::fill(comp,comp+2*MED_TAILLE_PNOM,' ');
-  comp[2*MED_TAILLE_PNOM]='\0';
-  char *work=comp;
-  for(int i=0;i<mesh->getSpaceDimension();i++,work+=3)
-    *work='X'+i;
-  std::fill(unit,unit+2*MED_TAILLE_PNOM+1,'\0');
-  MEDcoordEcr(fid,maa,mesh->getSpaceDimension(),arr->getPointer(),MED_FULL_INTERLACE,mesh->getNumberOfNodes(),MED_CART,comp,unit);
+  DataArrayDouble *arr=mesh[0]->getCoords();
+  char *comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM);
+  char *unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM);
+  for(int i=0;i<spaceDim;i++)
+    {
+      std::string info=arr->getInfoOnComponent(i);
+      std::string c,u;
+      MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
+      MEDLoaderBase::safeStrCpy(c.c_str(),MED_TAILLE_PNOM-1,comp+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+      MEDLoaderBase::safeStrCpy(u.c_str(),MED_TAILLE_PNOM-1,unit+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+    }
+  MEDcoordEcr(fid,maa,spaceDim,arr->getPointer(),MED_FULL_INTERLACE,mesh[0]->getNumberOfNodes(),MED_CART,comp,unit);
+  delete [] comp;
+  delete [] unit;
+  delete [] maa;
+  delete [] desc;
   MEDfermer(fid);
 }
 
-void MEDLoaderNS::appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f)
+/*!
+ * In this method meshes are assumed to shared the same coords.
+ * This method makes the assumption that 'meshes' is not empty, no check on that is done (responsability of the caller)
+ */
+void MEDLoaderNS::writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector<ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool forceFromScratch)
+{
+  std::string meshNameCpp(meshName);
+  char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  MEDLoaderBase::safeStrCpy(meshName,MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR);
+  if(meshNameCpp=="")
+    throw INTERP_KERNEL::Exception("writeUMeshesPartitionDirectly : Invalid meshName : Must be different from \"\" !");
+  std::vector< DataArrayInt * > corr;
+  MEDCouplingUMesh *m=ParaMEDMEM::MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr);
+  m->setName(meshName);
+  std::vector< std::vector<int> > fidsOfGroups;
+  DataArrayInt *arr2=DataArrayInt::makePartition(corr,m->getNumberOfCells(),fidsOfGroups);
+  for(std::vector< DataArrayInt * >::iterator it=corr.begin();it!=corr.end();it++)
+    (*it)->decrRef();
+  bool isRenumbering;
+  std::vector<const MEDCouplingUMesh *> mv(1); mv[0]=m;
+  std::vector<const DataArrayInt *> famv(1); famv[0]=arr2;
+  writeUMeshesDirectly(fileName,mv,famv,forceFromScratch,isRenumbering);
+  // families creation
+  std::set<int> familyIds;
+  for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++)
+    for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
+      familyIds.insert(*it2);
+  std::vector< std::vector<int> > gidsOfFamilies(familyIds.size());
+  int fid=0;
+  for(std::set<int>::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++)
+    {
+      int gid=0;
+      for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++,gid++)
+        for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
+          if(*it2==*it)
+            gidsOfFamilies[fid].push_back(gid);
+    }
+  fid=0;
+  med_idt fid2=MEDouvrir((char *)fileName,MED_LECTURE_ECRITURE);
+  for(std::set<int>::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++)
+    {
+      int ngro=gidsOfFamilies[fid].size();
+      char *groName=MEDLoaderBase::buildEmptyString(MED_TAILLE_LNOM*ngro);
+      for(int i=0;i<ngro;i++)
+        MEDLoaderBase::safeStrCpy(meshes[gidsOfFamilies[fid][i]]->getName(),MED_TAILLE_LNOM-1,groName+i*MED_TAILLE_LNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_LNOM-1 to avoid to write '\0' on next compo
+      std::ostringstream oss; oss << "Family_" << *it;
+      char *famName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+      MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,famName,MEDLoader::_TOO_LONG_STR);
+      MEDfamCr(fid2,maa,famName,*it,0,0,0,0,groName,ngro);
+      delete [] famName;
+      delete [] groName;
+    }
+  MEDfermer(fid2);
+  // end families creation
+  delete [] maa;
+  arr2->decrRef();
+  m->decrRef();
+}
+
+/*!
+ * This method makes the assumption that f->getMesh() nodes are fully included in already written mesh in 'fileName'.
+ * @param thisMeshNodeIds points to a tab of size f->getMesh()->getNumberOfNodes() that says for a node i in f->getMesh() that its id is thisMeshNodeIds[i] is already written mesh.
+ */
+void MEDLoaderNS::appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds)
+{
+  med_int numdt,numo;
+  med_float dt;
+  char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR);
+  med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt);
+  int nbOfNodes=f->getMesh()->getNumberOfNodes();
+  const double *pt=f->getArray()->getConstPointer();
+  int *profile=new int[nbOfNodes];
+  std::ostringstream oss; oss << "Pfln" << f->getName();
+  char *profileName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,profileName,MEDLoader::_TOO_LONG_STR);
+  std::transform(thisMeshNodeIds,thisMeshNodeIds+nbOfNodes,profile,std::bind2nd(std::plus<int>(),1));
+  MEDprofilEcr(fid,profile,nbOfNodes,profileName);
+  delete [] profile;
+  MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfNodes,
+              (char *)MED_NOGAUSS,MED_ALL,profileName,MED_COMPACT,MED_NOEUD,
+              MED_NONE,numdt,(char *)"",dt,numo);
+  delete [] profileName;
+  delete [] nommaa;
+  MEDfermer(fid);
+}
+
+/*!
+ * This method makes the assumption that f->getMesh() cells are fully included in already written mesh in 'fileName'.
+ * @param thisMeshCellIdsPerType points to a tab of size f->getMesh()->getNumberOfCells() that says for a cell i in f->getMesh() that its id is thisMeshCellIds[i] of corresponding type is already written mesh.
+ */
+void MEDLoaderNS::appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIdsPerType)
+{
+  med_int numdt,numo;
+  med_float dt;
+  int nbComp=f->getNumberOfComponents();
+  med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt);
+  std::list<MEDLoader::MEDFieldDoublePerCellType> split;
+  prepareCellFieldDoubleForWriting(f,thisMeshCellIdsPerType,split);
+  const double *pt=f->getArray()->getConstPointer();
+  int number=0;
+  for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
+    {
+      char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+      MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR);
+      char *profileName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+      std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++;
+      MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,profileName,MEDLoader::_TOO_LONG_STR);
+      const std::vector<int>& ids=(*iter).getCellIdPerType();
+      int *profile=new int [ids.size()];
+      std::transform(ids.begin(),ids.end(),profile,std::bind2nd(std::plus<int>(),1));
+      MEDprofilEcr(fid,profile,ids.size(),profileName);
+      delete [] profile;
+      MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(),
+                  (char *)MED_NOGAUSS,MED_ALL,profileName,MED_COMPACT,MED_MAILLE,
+                  typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo);
+      delete [] profileName;
+      delete [] nommaa;
+      pt+=(*iter).getNbOfTuple()*nbComp;
+    }
+  MEDfermer(fid);
+}
+
+/*!
+ * This method performs the classical job for fields before any values setting.
+ */
+med_idt MEDLoaderNS::appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt)
 {
   med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE_ECRITURE);
   int nbComp=f->getNumberOfComponents();
-  char *comp=new char[nbComp*MED_TAILLE_PNOM+1];
-  std::fill(comp,comp+nbComp*MED_TAILLE_PNOM,' ');
-  comp[nbComp*MED_TAILLE_PNOM]='\0';
-  char *unit=new char[nbComp*MED_TAILLE_PNOM+1];
-  std::fill(unit,unit+nbComp*MED_TAILLE_PNOM,' ');
-  unit[nbComp*MED_TAILLE_PNOM]='\0';
+  char *comp=MEDLoaderBase::buildEmptyString(nbComp*MED_TAILLE_PNOM);
+  char *unit=MEDLoaderBase::buildEmptyString(nbComp*MED_TAILLE_PNOM);
+  for(int i=0;i<nbComp;i++)
+    {
+      std::string info=f->getArray()->getInfoOnComponent(i);
+      std::string c,u;
+      MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
+      MEDLoaderBase::safeStrCpy(c.c_str(),MED_TAILLE_PNOM-1,comp+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);
+      MEDLoaderBase::safeStrCpy(u.c_str(),MED_TAILLE_PNOM-1,unit+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);
+    }
   MEDchampCr(fid,(char *)f->getName(),MED_FLOAT64,comp,unit,nbComp);
-  med_int numdt,numo;
-  med_float dt;
   ParaMEDMEM::TypeOfTimeDiscretization td=f->getTimeDiscretization();
   if(td==ParaMEDMEM::NO_TIME)
     {
@@ -1196,19 +2327,45 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCoupl
       numdt=(med_int)tmp1; numo=(med_int)tmp2;
       dt=(med_float)tmp0;
     }
+  delete [] comp;
+  delete [] unit;
+  return fid;
+}
+
+void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f2)
+{
+  med_int numdt,numo;
+  med_float dt;
+  //renumbering
+  const ParaMEDMEM::MEDCouplingFieldDouble *f=f2;
+  const MEDCouplingMesh *mesh=f->getMesh();
+  const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(mesh);
+  if(!meshC)
+    throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !");
+  bool renum=!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2);
+  if(renum)
+    {
+      ParaMEDMEM::MEDCouplingFieldDouble *f3=f2->clone(true);
+      DataArrayInt *da=meshC->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2);
+      f3->renumberCells(da->getConstPointer(),false);
+      da->decrRef();
+      f=f3;
+    }
+  //end renumbering
+  int nbComp=f->getNumberOfComponents();
+  med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt);
   const double *pt=f->getArray()->getConstPointer();
+  char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+  MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR);
   switch(f->getTypeOfField())
     {
     case ParaMEDMEM::ON_CELLS:
       {
         std::list<MEDLoader::MEDFieldDoublePerCellType> split;
-        prepareCellFieldDoubleForWriting(f,split);
+        prepareCellFieldDoubleForWriting(f,0,split);
         for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
           {
-            char nommaa[MED_TAILLE_NOM+1];
-            std::fill(nommaa,nommaa+MED_TAILLE_NOM,' '); nommaa[MED_TAILLE_NOM]='\0';
-            strcpy(nommaa,f->getMesh()->getName());
-            MEDchampEcr(fid,(char *)nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(),
+            MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(),
                         (char *)MED_NOGAUSS,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE,
                         typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo);
             pt+=(*iter).getNbOfTuple()*nbComp;
@@ -1218,42 +2375,94 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCoupl
     case ParaMEDMEM::ON_NODES:
       {
         int nbOfTuples=f->getArray()->getNumberOfTuples();
-        MEDchampEcr(fid,(char *)f->getMesh()->getName(),(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfTuples,(char *)MED_NOGAUSS,
+        MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfTuples,(char *)MED_NOGAUSS,
                     MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_NOEUD,MED_NONE,numdt,(char *)"",dt,numo);
         break;
       }
+    case ParaMEDMEM::ON_GAUSS_PT:
+      {
+        std::list<MEDLoader::MEDFieldDoublePerCellType> split;
+        prepareCellFieldDoubleForWriting(f,0,split);
+        int idGp=0;
+        for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
+          {
+            char *nomGauss=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM);
+            std::ostringstream oss; oss << "GP_" << f->getName() << idGp++;
+            MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,nomGauss,MEDLoader::_TOO_LONG_STR);
+            int id=f->getGaussLocalizationIdOfOneType((*iter).getType());
+            const MEDCouplingGaussLocalization& gl=f->getGaussLocalization(id);
+            MEDgaussEcr(fid,typmai3[(int)(*iter).getType()],(med_float*)&gl.getRefCoords()[0],MED_FULL_INTERLACE,gl.getNumberOfGaussPt(),
+                        (med_float*)&gl.getGaussCoords()[0],
+                        (med_float*)&gl.getWeights()[0],nomGauss);
+            int nbOfValues=gl.getNumberOfGaussPt()*f->getMesh()->getNumberOfCellsWithType((*iter).getType());
+            MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfValues,
+                        nomGauss,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE,
+                        typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo);
+            pt+=nbOfValues*nbComp;
+            delete [] nomGauss;
+          }
+        break;
+      }
+    case ParaMEDMEM::ON_GAUSS_NE:
+      {
+        std::list<MEDLoader::MEDFieldDoublePerCellType> split;
+        prepareCellFieldDoubleForWriting(f,0,split);
+        for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
+          {
+            int nbPtPerCell=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getNumberOfNodes();
+            int nbOfValues=nbPtPerCell*f->getMesh()->getNumberOfCellsWithType((*iter).getType());
+            MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfValues,
+                        (char *)MED_GAUSS_ELNO,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE,
+                        typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo);
+            pt+=nbOfValues*nbComp;
+          }
+        break;
+      }
     default:
       throw INTERP_KERNEL::Exception("Not managed this type of FIELD !");
     }
-  delete [] comp;
-  delete [] unit;
+  delete [] nommaa;
   MEDfermer(fid);
+  if(renum)
+    ((ParaMEDMEM::MEDCouplingFieldDouble *)f)->decrRef();
 }
 
-void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, std::list<MEDLoader::MEDFieldDoublePerCellType>& split)
+/*!
+ * This method splits field 'f' into types to be ready for writing.
+ * @param cellIdsPerType this parameter can be 0 if not in profile mode. If it is != 0 this array is of size f->getMesh()->getNumberOfCells().
+ */
+void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIdsPerType, std::list<MEDLoader::MEDFieldDoublePerCellType>& split)
 {
   int nbComp=f->getNumberOfComponents();
   const MEDCouplingMesh *mesh=f->getMesh();
   const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(mesh);
   if(!meshC)
     throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !");
-  if(!meshC->checkConsecutiveCellTypes())
+  if(!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2))
     throw INTERP_KERNEL::Exception("Unstructuded mesh has not consecutive cell types !");
   const int *connI=meshC->getNodalConnectivityIndex()->getConstPointer();
   const int *conn=meshC->getNodalConnectivity()->getConstPointer();
   int nbOfCells=meshC->getNumberOfCells();
   INTERP_KERNEL::NormalizedCellType curType;
+  const int *wCellIdsPT=cellIdsPerType;
   for(const int *pt=connI;pt!=connI+nbOfCells;)
     {
       curType=(INTERP_KERNEL::NormalizedCellType)conn[*pt];
       const int *pt2=std::find_if(pt+1,connI+nbOfCells,ConnReaderML(conn,(int)curType));
-      split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt));
+      if(!cellIdsPerType)
+        split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,0,0));
+      else
+        {
+          split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,wCellIdsPT,0));
+          wCellIdsPT+=std::distance(pt,pt2);
+        }
       pt=pt2;
     }
 }
 
-void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch)
+void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch)
 {
+  f->checkCoherency();
   std::string meshName(f->getMesh()->getName());
   if(meshName.empty())
     throw INTERP_KERNEL::Exception("Trying to write a mesh (f->getMesh()) with no name ! MED file format needs a not empty mesh name !");
@@ -1261,47 +2470,304 @@ void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::ME
   if(fieldName.empty())
     throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !");
   MEDCouplingUMesh *mesh=dynamic_cast<MEDCouplingUMesh *>((MEDCouplingMesh *)f->getMesh());
-  writeUMeshDirectly(fileName,mesh,forceFromScratch);
-  appendFieldDirectly(fileName,f);
+  if(mesh)
+    {
+      bool isRenumbering;
+      std::vector<const MEDCouplingUMesh *> meshV(1); meshV[0]=mesh;
+      std::vector<const DataArrayInt *> famV(1); famV[0]=0;
+      writeUMeshesDirectly(fileName,meshV,famV,forceFromScratch,isRenumbering);
+      if(isRenumbering)
+        {
+          ParaMEDMEM::MEDCouplingFieldDouble *f2=f->clone(true);
+          DataArrayInt *da=mesh->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2);
+          f2->renumberCells(da->getConstPointer(),false);
+          da->decrRef();
+          appendFieldDirectly(fileName,f2);
+          f2->decrRef();
+        }
+      else
+        appendFieldDirectly(fileName,f);
+      return ;
+    }
+  throw INTERP_KERNEL::Exception("The mesh underlying field is not unstructured ! Only unstructured mesh supported for writting now !");
 }
 
-void MEDLoader::WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch)
+/*!
+ * When called this method expectes that file 'fileName' is already existing and has a mesh with name equal to
+ * f->getMesh()->getName(). If not the behaviour of this method is not warranted.
+ * This method reads the corresponding mesh into the file and try to fit it with f->getMesh().
+ * If it appears that f->getMesh() equals exactly mesh into the file 
+ */
+void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f)
+{
+  std::vector<int> poss;
+  int mDimInFile=MEDLoaderNS::readUMeshDimFromFile(fileName,f->getMesh()->getName(),poss);
+  int mdim=f->getMesh()->getMeshDimension();
+  int f2=mdim-mDimInFile;
+  if(std::find(poss.begin(),poss.end(),f2)==poss.end())
+    {
+      std::ostringstream oss; oss << "Trying to fit with the existing \"" << f->getMesh()->getName() << "mesh in file \"" << fileName;
+      oss << "\" but meshdimension does not match !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDCouplingUMesh *m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2);
+  MEDCouplingUMesh *m2=MEDCouplingUMesh::mergeUMeshes(m,(MEDCouplingUMesh *)f->getMesh());
+  bool areNodesMerged;
+  int newNbOfNodes;
+  DataArrayInt *da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes);
+  if(!areNodesMerged || newNbOfNodes!=m->getNumberOfNodes())
+    {
+      da->decrRef();
+      m2->decrRef();
+      m->decrRef();
+      std::ostringstream oss; oss << "Nodes in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit coordinates of unstructured grid f->getMesh() !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  switch(f->getTypeOfField())
+    {
+    case ParaMEDMEM::ON_CELLS:
+      {
+        da->decrRef();
+        DataArrayInt *da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL);
+        if(m2->getNumberOfCells()!=m->getNumberOfCells())
+          {
+            da2->decrRef();
+            m2->decrRef();
+            m->decrRef();
+            std::ostringstream oss1; oss1 << "Cells in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit connectivity of unstructured grid f->getMesh() !";
+            throw INTERP_KERNEL::Exception(oss1.str().c_str());
+          }
+        da=m2->convertCellArrayPerGeoType(da2);
+        DataArrayInt *da3=da->substr(m2->getNumberOfCells());
+        da2->decrRef();
+        da2=m2->convertCellArrayPerGeoType(da3);
+        da3->decrRef();
+        appendCellProfileField(fileName,f,da2->getConstPointer());
+        da2->decrRef();
+        break;
+      }
+    case ParaMEDMEM::ON_NODES:
+      {
+        appendNodeProfileField(fileName,f,da->getConstPointer()+m->getNumberOfNodes());
+        break;
+      }
+    default:
+      {
+        da->decrRef();
+        m2->decrRef();
+        m->decrRef();
+        throw INTERP_KERNEL::Exception("Not implemented other profile fitting from already written mesh for fields than on NODES and on CELLS.");
+      }
+    }
+  da->decrRef();
+  m2->decrRef();
+  m->decrRef();
+}
+
+void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
 {
   std::string meshName(mesh->getName());
   if(meshName.empty())
     throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name !");
   int status=MEDLoaderBase::getStatusOfFile(fileName);
+  bool isRenumbering;
   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
     {
       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
+  std::vector<const ParaMEDMEM::MEDCouplingUMesh *> meshV(1); meshV[0]=mesh;
+  std::vector<const ParaMEDMEM::DataArrayInt *> famV(1); famV[0]=0;
   if(writeFromScratch)
     {
-      MEDLoaderNS::writeUMeshDirectly(fileName,mesh,true);
+      MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
       return ;
     }
   if(status==MEDLoaderBase::NOT_EXIST)
     {
-      MEDLoaderNS::writeUMeshDirectly(fileName,mesh,true);
+      MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
       return;
     }
   else
     {
       std::vector<std::string> meshNames=GetMeshNames(fileName);
-      std::string fileNameCpp(mesh->getName());
-      if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end())
-        MEDLoaderNS::writeUMeshDirectly(fileName,mesh,false);
+      if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end())
+        MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering);
+      else
+        {
+          std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \"";
+          oss << meshName << "\" !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+}
+
+void MEDLoader::WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+{
+  std::string meshName(mesh->getName());
+  if(meshName.empty())
+    throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name !");
+  int status=MEDLoaderBase::getStatusOfFile(fileName);
+  bool isRenumbering;
+  if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
+    {
+      std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  std::vector<const ParaMEDMEM::MEDCouplingUMesh *> meshV(1); meshV[0]=mesh;
+  std::vector<const ParaMEDMEM::DataArrayInt *> famV(1); famV[0]=0;
+  if(writeFromScratch)
+    {
+      MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
+      return ;
+    }
+  if(status==MEDLoaderBase::NOT_EXIST)
+    {
+      MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
+      return;
+    }
+  else
+    MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering);
+}
+
+void MEDLoader::WriteUMeshesPartition(const char *fileName, const char *meshNameC, const std::vector<ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+{
+  std::string meshName(meshNameC);
+  if(meshName.empty())
+    throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !");
+  int status=MEDLoaderBase::getStatusOfFile(fileName);
+  if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
+    {
+      std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("List of meshes must be not empty !");
+  DataArrayDouble *coords=meshes.front()->getCoords();
+  for(std::vector<ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
+    if(coords!=(*iter)->getCoords())
+      throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !");
+  std::set<std::string> tmp;
+  for(std::vector<ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
+    {
+      if(tmp.find((*iter)->getName())==tmp.end())
+        tmp.insert((*iter)->getName());
+      else
+        throw INTERP_KERNEL::Exception("The names of meshes must be different each other !");
+    }
+  tmp.clear();
+  if(writeFromScratch)
+    {
+      MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
+      return ;
+    }
+  if(status==MEDLoaderBase::NOT_EXIST)
+    {
+      MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
+      return;
+    }
+  else
+    {
+      std::vector<std::string> meshNames=GetMeshNames(fileName);
+      if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end())
+        MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false);
       else
         {
           std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \"";
-          oss << fileNameCpp << "\" !";
+          oss << meshName << "\" !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
 }
 
-void MEDLoader::WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch)
+void MEDLoader::WriteUMeshesPartitionDep(const char *fileName, const char *meshNameC, const std::vector<ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+{
+  std::string meshName(meshNameC);
+  if(meshName.empty())
+    throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !");
+  int status=MEDLoaderBase::getStatusOfFile(fileName);
+  if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
+    {
+      std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("List of meshes must be not empty !");
+  DataArrayDouble *coords=meshes.front()->getCoords();
+  for(std::vector<ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
+    if(coords!=(*iter)->getCoords())
+      throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !");
+  std::set<std::string> tmp;
+  for(std::vector<ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
+    {
+      if(tmp.find((*iter)->getName())==tmp.end())
+        tmp.insert((*iter)->getName());
+      else
+        throw INTERP_KERNEL::Exception("The names of meshes must be different each other !");
+    }
+  tmp.clear();
+  if(writeFromScratch)
+    {
+      MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
+      return ;
+    }
+  if(status==MEDLoaderBase::NOT_EXIST)
+    {
+      MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
+      return;
+    }
+  else
+    {
+      MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false);
+    }
+}
+
+void MEDLoader::WriteUMeshes(const char *fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+{
+  int status=MEDLoaderBase::getStatusOfFile(fileName);
+  if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
+    {
+      std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("List of meshes must be not empty !");
+  std::string meshName(meshes[0]->getName());
+  if(meshName.empty())
+    throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change name of first element of 2nd parameter !");
+  DataArrayDouble *coords=meshes.front()->getCoords();
+  for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
+    if(coords!=(*iter)->getCoords())
+      throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !");
+  std::set<int> tmp;
+  for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
+    {
+      if(tmp.find((*iter)->getMeshDimension())==tmp.end())
+        tmp.insert((*iter)->getMeshDimension());
+      else
+        throw INTERP_KERNEL::Exception("The mesh dimension of meshes must be different each other !");
+    }
+  tmp.clear();
+  bool isRenumbering;
+  std::vector<const DataArrayInt *> families(meshes.size());
+  if(writeFromScratch)
+    {
+      MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering);
+      return ;
+    }
+  if(status==MEDLoaderBase::NOT_EXIST)
+    {
+      MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering);
+      return;
+    }
+  else
+    {
+      MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,false,isRenumbering);
+      return;
+    }
+}
+
+void MEDLoader::WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
 {
   int status=MEDLoaderBase::getStatusOfFile(fileName);
   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
@@ -1326,15 +2792,33 @@ void MEDLoader::WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDou
       if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end())
         MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false);
       else
-        {
-          std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \"";
-          oss << fileNameCpp << "\" !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str()); 
-        }
+        MEDLoaderNS::writeFieldTryingToFitExistingMesh(fileName,f);
+    }
+}
+
+void MEDLoader::WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+{
+  int status=MEDLoaderBase::getStatusOfFile(fileName);
+  if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
+    {
+      std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(writeFromScratch)
+    {
+      MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true);
+     return ;
     }
+  if(status==MEDLoaderBase::NOT_EXIST)
+    {
+     MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true);
+     return ;
+    }
+  else
+    MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false);
 }
 
-void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f)
+void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception)
 {
   f->checkCoherency();
   int status=MEDLoaderBase::getStatusOfFile(fileName);
@@ -1343,5 +2827,8 @@ void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDM
       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
+  std::string fieldName(f->getName());
+  if(fieldName.empty())
+    throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !");
   MEDLoaderNS::appendFieldDirectly(fileName,f);
 }
index cb2f74381c3502e44538d29b801f3826d1eac897..b90cad0f778f4114ed85c22b9cbd7b5bda3ad8df 100644 (file)
@@ -20,7 +20,9 @@
 #ifndef __MEDLOADER_HXX__
 #define __MEDLOADER_HXX__
 
+#include "MEDLoaderDefines.hxx"
 #include "InterpKernelException.hxx"
+#include "MEDCouplingRefCountObject.hxx"
 #include "NormalizedUnstructuredMesh.hxx"
 
 #include <list>
@@ -33,9 +35,9 @@ namespace ParaMEDMEM
   class MEDCouplingFieldDouble;
 }
 
-class MEDLoader
+class MEDLOADER_EXPORT MEDLoader
 {
-public:
+ public:
   class MEDConnOfOneElemType
   {
   public:
@@ -47,6 +49,7 @@ public:
     int *getIndex() const { return _index; }
     int *getFam() const { return _fam; }
     void setGlobal(int *global);
+    const int *getGlobal() const { return _global; }
     void releaseArray();
   private:
     int _lgth;
@@ -61,38 +64,77 @@ public:
   class MEDFieldDoublePerCellType
   {
   public:
-    MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple);
+    MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple, const int *cellIdPerType, const char *locName);
     INTERP_KERNEL::NormalizedCellType getType() const { return _type; }
     int getNbComp() const { return _ncomp; }
     int getNbOfTuple() const { return _ntuple; }
     int getNbOfValues() const { return _ncomp*_ntuple; }
     double *getArray() const { return _values; }
+    const std::string& getLocName() const { return _loc_name; }
+    const std::vector<int>& getCellIdPerType() const { return _cell_id_per_type; }
     void releaseArray();
   private:
     int _ntuple;
     int _ncomp;
     double *_values;
+    std::string _loc_name;
+    std::vector<int> _cell_id_per_type;
     INTERP_KERNEL::NormalizedCellType _type;
   };
   //
-  static std::vector<std::string> GetMeshNames(const char *fileName);
-  static std::vector<std::string> GetMeshGroupsNames(const char *fileName, const char *meshName);
-  static std::vector<std::string> GetMeshFamilyNames(const char *fileName, const char *meshName);
-  static std::vector<std::string> GetCellFieldNamesOnMesh(const char *fileName, const char *meshName);
-  static std::vector<std::string> GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName);
-  static std::vector< std::pair<int,int> > GetCellFieldIterations(const char *fileName, const char *fieldName);
-  static std::vector< std::pair<int,int> > GetNodeFieldIterations(const char *fileName, const char *fieldName);
-  static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams);
-  static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps);
+  static void setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception);
+  static void setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception);
+  static void setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception);
+  static void CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<ParaMEDMEM::TypeOfField> GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector< std::pair<int,int> > GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception);
+  static std::vector< std::pair<int,int> > GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception);
+  static std::vector< std::pair<int,int> > GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception);
+  static std::vector< std::pair< std::pair<int,int>, double> > GetAllFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception);
+  static double GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception);
   static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception);
   static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception);
-  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order);
-  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order);
-  static void WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch);
-  static void WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch);
-  static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f);
-private:
+  static int ReadUMeshDimFromFile(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                      const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception);
+  static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsCellOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                          const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception);
+  static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsNodeOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                          const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception);
+  static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsGaussOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                           const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception);
+  static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsGaussNEOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
+                                                                                           const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static void WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteUMeshesPartition(const char *fileName, const char *meshName, const std::vector<ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteUMeshesPartitionDep(const char *fileName, const char *meshName, const std::vector<ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteUMeshes(const char *fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception);
+ private:
   MEDLoader();
+ public:
+  static double _EPS_FOR_NODE_COMP;
+  static int _COMP_FOR_CELL;
+  static int _TOO_LONG_STR;
 };
 
 #endif
index ec50466fd6897859dd968e15b6129ad596d9a9fc..14c33ac1ed3ef57ac07ec50844f84d2f860065bc 100644 (file)
 #include "MEDLoaderBase.hxx"
 #include "InterpKernelException.hxx"
 
+#include <sstream>
 #include <fstream>
+#include <cstring>
+#include <iostream>
+
+const char MEDLoaderBase::WHITE_SPACES[]=" \n";
 
 int MEDLoaderBase::getStatusOfFile(const char *fileName)
 {
   std::ifstream ifs;
   ifs.open(fileName);
-  unsigned int res=0;
   if((ifs.rdstate() & std::ifstream::failbit)!=0)
     {
-      res+=1;
       ifs.close();
+      return NOT_EXIST;
     }
   std::ofstream ofs(fileName,std::ios_base::app);
   if((ofs.rdstate() & std::ofstream::failbit)!=0)
     {
-      ofs.close();
-      res+=2;
+      return EXIST_RDONLY;
     }
-  switch(res)
+  return EXIST_RW;
+}
+
+char *MEDLoaderBase::buildEmptyString(int lgth)
+{
+  char *ret=new char[lgth+1];
+  std::fill(ret,ret+lgth,' ');
+  ret[lgth]='\0';
+  return ret;
+}
+
+std::string MEDLoaderBase::buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth)
+{
+  std::string ret(buildStringFromFortran(name,nameLgth));
+  std::string unitCpp(buildStringFromFortran(unit,unitLgth));
+  if(unitCpp[0]=='\0')
+    return ret;
+  ret+=" (";
+  ret+=unitCpp;
+  ret+=")";
+  return ret;
+}
+
+void MEDLoaderBase::splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit)
+{
+  std::string::size_type f1=s.find_first_of('(');
+  std::string::size_type f2=s.find_last_of(')');
+  if(f1!=std::string::npos && f2!=std::string::npos)
     {
-    case 0:
-      return EXIST_RW;
-    case 1:
-      {
-        std::ifstream ifs2;
-        ifs2.open(fileName);
-        if((ifs2.rdstate() & std::ifstream::failbit)!=0)
-          return EXIST_WRONLY;
-        else
-          return NOT_EXIST;
-      }
-    case 2:
-      return EXIST_RDONLY;
-    case 3:
-      return DIR_LOCKED;
-    default:
-      throw INTERP_KERNEL::Exception("Internal error !");
+      if(f1<f2)
+        {
+          name=s.substr(0,f1);
+          unit=s.substr(f1+1,f2-f1-1);
+          strip(name);
+          strip(unit);
+          return;
+        }
+    }
+  name=s;
+  unit="";
+}
+
+void MEDLoaderBase::strip(std::string& s)
+{
+  std::string::size_type f1=s.find_first_not_of(' ');
+  std::string::size_type f2=s.find_last_not_of(' ');
+  s=s.substr(f1,f2-f1+1);
+}
+
+/*!
+ * This method operates a safe copy from 'src' to 'dest' by checking the size of 'src' before trying to copy.
+ * If size of 'src' string is higher than 'maxLgth' the behaviour is dependant from 'behaviour' parameter.
+ * If 'behaviour' equals 0 an exception is thrown. If 'behaviour' equals 1 an attempt of zipping of string will be done
+ * ( see zipString to have more details).
+ */
+void MEDLoaderBase::safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour) throw(INTERP_KERNEL::Exception)
+{
+  if((int)strlen(src)>maxLgth)
+    {
+      if(behaviour==0 || behaviour>1)
+        {
+          std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      else if(behaviour==1)
+        {
+          std::string s=zipString(src,maxLgth);
+          std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : ";
+          std::cerr << "zipping to : " << s << "\n";
+          strcpy(dest,s.c_str());
+          return ;
+        }
+    }
+  strcpy(dest,src);
+}
+
+std::string MEDLoaderBase::buildStringFromFortran(const char *expr, int lgth)
+{
+  std::string ret(expr,lgth);
+  std::string whiteSpaces(WHITE_SPACES);
+  std::size_t lgthReal=strlen(ret.c_str());
+  std::string ret2=ret.substr(0,lgthReal);
+  std::size_t found=ret2.find_last_not_of(whiteSpaces);
+  if (found!=std::string::npos)
+    ret2.erase(found+1);
+  else
+    ret2.clear();//ret is all whitespace
+  return ret2;
+}
+
+/*!
+ * This method given the target size to respect 'sizeToRespect' tries to reduce size of 'src' string.
+ * This method uses several soft methods to do its job. But if it fails a simple cut of string will be performed.
+ */
+std::string MEDLoaderBase::zipString(const char *src, int sizeToRespect)
+{
+  std::string s(src);
+  strip(s);
+  if((int)s.length()<=sizeToRespect)
+    return s;
+  s=src;
+  zipEqualConsChar(s,3);
+  if((int)s.length()<=sizeToRespect)
+    return s;
+  s=src;
+  zipEqualConsChar(s,2);
+  if((int)s.length()<=sizeToRespect)
+    return s;
+  s=src;
+  return s.substr(0,sizeToRespect);
+}
+
+/*!
+ * This method see if there is in 's' more than 'minConsSmChar' consecutive same character.
+ * If yes, the group will be zipped using only one character for this group.
+ * If no such group is found, s remains unchanged.
+ */
+void MEDLoaderBase::zipEqualConsChar(std::string& s, int minConsSmChar)
+{
+  for(std::string::iterator it=s.begin();it!=s.end();it++)
+    {
+      char tmp=*it;
+      int sz=1;
+      for(std::string::iterator it2=it+1;it2!=s.end() && *it2==tmp;it2++)
+        sz++;
+      if(sz>=minConsSmChar)
+        s.erase(it+1,it+sz);
     }
 }
+
index 06df9422bf961f246816c62aff4f9e8784aca564..09e0c5850e621a456b8c8ae75acf8f74728b1a28 100644 (file)
 #ifndef __MEDLOADERBASE_HXX__
 #define __MEDLOADERBASE_HXX__
 
-class MEDLoaderBase
+#include "MEDLoaderDefines.hxx"
+#include "InterpKernelException.hxx"
+
+#include <string>
+
+class MEDLOADER_EXPORT MEDLoaderBase
 {
 public:
   static int getStatusOfFile(const char *fileName);
+  static char *buildEmptyString(int lgth);
+  static std::string buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth);
+  static void splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit);
+  static void strip(std::string& s);
+  static void safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour) throw(INTERP_KERNEL::Exception);
+  static std::string buildStringFromFortran(const char *expr, int lgth);
+  static void zipEqualConsChar(std::string& s, int minConsSmChar);
+  static std::string zipString(const char *src, int sizeToRespect);
 public:
   static const int EXIST_RW=0;
   static const int NOT_EXIST=1;
   static const int EXIST_RDONLY=2;
   static const int EXIST_WRONLY=3;
   static const int DIR_LOCKED=4;
+  static const char WHITE_SPACES[];
 };
 
 #endif
diff --git a/src/MEDLoader/MEDLoaderDefines.hxx b/src/MEDLoader/MEDLoaderDefines.hxx
new file mode 100644 (file)
index 0000000..656caa4
--- /dev/null
@@ -0,0 +1,33 @@
+//  Copyright (C) 2007-2010  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 __MEDLOADERDEFINES_HXX__
+#define __MEDLOADERDEFINES_HXX__
+
+#ifdef WIN32
+# if defined medloader_EXPORTS
+#  define MEDLOADER_EXPORT __declspec(dllexport)
+# else
+#  define MEDLOADER_EXPORT __declspec(dllimport)
+# endif
+#else
+# define MEDLOADER_EXPORT
+#endif 
+
+#endif
index bc5acc7e0097a316c0ff76049b42b2511b0b7bc1..3a2fbb7608bd22f46993b7e5411eafd93bd28908 100755 (executable)
 
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
+MEDLOADER_SUBDIRS =
+
 if !MED_ENABLE_MICROMED
-  SUBDIRS = . Swig
+   MEDLOADER_SUBDIRS += . Swig
+if CPPUNIT_IS_OK
+   MEDLOADER_SUBDIRS += Test
+endif
 endif
 
+SUBDIRS = $(MEDLOADER_SUBDIRS)
+
 #DIST_SUBDIRS = Swig
 
 lib_LTLIBRARIES = libmedloader.la
 
 salomeinclude_HEADERS= \
+MEDLoaderDefines.hxx \
 MEDLoader.hxx MEDLoaderBase.hxx
 
 dist_libmedloader_la_SOURCES= \
 MEDLoader.cxx MEDLoaderBase.cxx
 
-libmedloader_la_CPPFLAGS= $(MPI_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \
+libmedloader_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \
        -I$(srcdir)/../INTERP_KERNEL \
        -I$(srcdir)/../INTERP_KERNEL/Geometric2D \
        -I$(srcdir)/../INTERP_KERNEL/Bases \
        -I$(srcdir)/../MEDCoupling
 
-# change motivated by the bug KERNEL4778.
 libmedloader_la_LDFLAGS= ../MEDCoupling/libmedcoupling.la \
-../INTERP_KERNEL/libinterpkernel.la $(MPI_LIBS) $(MED2_LIBS) $(HDF5_LIBS)
+../INTERP_KERNEL/libinterpkernel.la $(MED2_LIBS) $(HDF5_LIBS)
diff --git a/src/MEDLoader/Swig/MEDLoaderDataForTest.py b/src/MEDLoader/Swig/MEDLoaderDataForTest.py
new file mode 100644 (file)
index 0000000..2ec4ac8
--- /dev/null
@@ -0,0 +1,304 @@
+#  -*- coding: iso-8859-1 -*-
+#  Copyright (C) 2007-2010  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
+#
+
+from libMEDLoader_Swig import *
+from math import pi,e,sqrt
+
+class MEDLoaderDataForTest:
+    def build1DMesh_1(cls):
+        coords=[ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 ]
+        conn=[ 0,1, 1,2, 2,3 , 3,4,5]
+        mesh=MEDCouplingUMesh.New();
+        mesh.setName("1DMesh_1");
+        mesh.setMeshDimension(1);
+        mesh.allocateCells(4);
+        mesh.insertNextCell(NORM_SEG2,2,conn[0:2])
+        mesh.insertNextCell(NORM_SEG2,2,conn[2:4])
+        mesh.insertNextCell(NORM_SEG2,2,conn[4:6])
+        mesh.insertNextCell(NORM_SEG3,3,conn[6:9])
+        mesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,6,1);
+        myCoords.setInfoOnComponent(0,"tototototototot (m*m*m*m*m*m*m*m)");
+        mesh.setCoords(myCoords);
+        return mesh;
+
+    def build2DCurveMesh_1(cls):
+        coords=[ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 ]
+        conn=[ 0,1, 1,2, 2,3 , 3,4,5]
+        mesh=MEDCouplingUMesh.New();
+        mesh.setName("2DCurveMesh_1");
+        mesh.setMeshDimension(1);
+        mesh.allocateCells(4);
+        mesh.insertNextCell(NORM_SEG2,2,conn[0:2])
+        mesh.insertNextCell(NORM_SEG2,2,conn[2:4])
+        mesh.insertNextCell(NORM_SEG2,2,conn[4:6])
+        mesh.insertNextCell(NORM_SEG3,3,conn[6:9])
+        mesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,6,2);
+        mesh.setCoords(myCoords);
+        return mesh;
+
+    def build2DMesh_1(cls):
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7,
+                      -0.05,0.95, 0.2,1.2, 0.45,0.95]
+        targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(6);
+        targetMesh.setName("2DMesh_1");
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6])
+        targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20])
+        targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,12,2);
+        myCoords.setInfoOnComponent(0,"tototototototot (m)");
+        myCoords.setInfoOnComponent(1,"energie (kW)");
+        targetMesh.setCoords(myCoords)
+        return targetMesh;
+
+    def build2DMesh_2(cls):
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7,
+                      -0.05,0.95, 0.2,1.2, 0.45,0.95]
+        targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(5);
+        targetMesh.setName("2DMesh_2");
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6])
+        targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,12,2);
+        myCoords.setInfoOnComponent(0,"toto (m)");
+        myCoords.setInfoOnComponent(1,"energie (kW)");
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
+    def build3DMesh_1(cls):
+        coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0.,
+                3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0.,
+                0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1.,
+                3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1.,
+                0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2.,
+        3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2.,
+                0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3.,
+                3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.]
+        conn=[
+            # 0
+            0,11,1,3,15,26,16,18,   1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17,
+            1,6,5,3,16,21,20,18,   13,10,9,6,28,25,24,21,
+            11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23,
+            7,12,14,13,22,27,29,28,
+            # 1
+            15,26,16,18,30,41,31,33,   16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32,
+            16,21,20,18,31,36,35,33,   28,25,24,21,43,40,39,36,
+            26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38,
+            22,27,29,28,37,42,44,43,
+            # 2
+            30,41,31,33,45,56,46,48,  31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47,
+            31,36,35,33,46,51,50,48,  43,40,39,36,58,55,54,51,
+            41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53,
+            37,42,44,43,52,57,59,58]
+        #
+        ret=MEDCouplingUMesh.New();
+        ret.setName("3DMesh_1");
+        ret.setMeshDimension(3);
+        ret.allocateCells(18);
+        #
+        ret.insertNextCell(NORM_HEXA8,8,conn[0:8])
+        ret.insertNextCell(NORM_HEXA8,8,conn[51:59])
+        ret.insertNextCell(NORM_HEXA8,8,conn[59:67])
+        ret.insertNextCell(NORM_HEXA8,8,conn[110:118])
+        #
+        ret.insertNextCell(NORM_HEXA8,8,conn[118:126])
+        ret.insertNextCell(NORM_HEXA8,8,conn[169:177])
+        ret.insertNextCell(NORM_HEXA8,8,conn[177:185])
+        ret.insertNextCell(NORM_HEXA8,8,conn[228:236])
+        #
+        ret.insertNextCell(NORM_HEXA8,8,conn[236:244])
+        ret.insertNextCell(NORM_HEXA8,8,conn[287:295])
+        ret.insertNextCell(NORM_HEXA8,8,conn[295:303])
+        ret.insertNextCell(NORM_HEXA8,8,conn[346:354])
+        #
+        ret.insertNextCell(NORM_POLYHED,43,conn[8:51])
+        ret.insertNextCell(NORM_POLYHED,43,conn[67:110])
+        ret.insertNextCell(NORM_POLYHED,43,conn[126:169])
+        ret.insertNextCell(NORM_POLYHED,43,conn[185:228])
+        ret.insertNextCell(NORM_POLYHED,43,conn[244:287])
+        ret.insertNextCell(NORM_POLYHED,43,conn[303:346])
+        #
+        ret.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(coords,60,3);
+        myCoords.setInfoOnComponent(0,"titi (m)");
+        myCoords.setInfoOnComponent(1,"density power (MW/m^3)");
+        myCoords.setInfoOnComponent(2,"t (kW)");
+        ret.setCoords(myCoords);
+        return ret;
+    
+    def build3DSurfMesh_1(cls):
+        targetCoords=[-0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3
+                      ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3]
+        targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(6);
+        targetMesh.setName("3DSurfMesh_1");
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6])
+        targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20])
+        targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,12,3);
+        myCoords.setInfoOnComponent(0,"toto (m)");
+        myCoords.setInfoOnComponent(2,"ff (km)");#component 1 is not set for test
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+    
+    def build3DMesh_2(cls):
+        m3dsurfBase=MEDLoaderDataForTest.build3DSurfMesh_1();
+        numbers=[0,1,3,4,5]
+        m3dsurf=m3dsurfBase.buildPartOfMySelf(numbers,False);
+        m1dBase=MEDLoaderDataForTest.build1DMesh_1();
+        numbers2=[0,1,2,3]
+        m1d=m1dBase.buildPartOfMySelf(numbers2,False);
+        m1d.changeSpaceDimension(3);
+        vec=[0.,1.,0.]
+        pt=[0.,0.,0.]
+        m1d.rotate(pt,vec,-pi/2.);
+        ret=m3dsurf.buildExtrudedMeshFromThis(m1d,0);
+        return ret;
+
+    def buildVecFieldOnCells_1(cls):
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        nbOfCells=mesh.getNumberOfCells();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setName("VectorFieldOnCells");
+        f1.setMesh(mesh);
+        array=DataArrayDouble.New();
+        arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.]
+        array.setValues(arr1,nbOfCells,3);
+        array.setInfoOnComponent(0,"power (MW/m^3)");
+        array.setInfoOnComponent(1,"density (g/cm^3)");
+        array.setInfoOnComponent(2,"temperature (K)");
+        f1.setArray(array);
+        tmp=array.getPointer();
+        f1.setTime(2.,0,1);
+        f1.checkCoherency();
+        return f1;
+
+    def buildVecFieldOnNodes_1(cls):
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        nbOfNodes=mesh.getNumberOfNodes();
+        f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME);
+        f1.setName("VectorFieldOnNodes");
+        f1.setMesh(mesh);
+        array=DataArrayDouble.New();
+        f1.setArray(array);
+        arr1=[70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95.,
+        1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025.]
+        array.setValues(arr1,nbOfNodes,3);
+        array.setInfoOnComponent(0,"power (MW/m^3)");
+        array.setInfoOnComponent(1,"density (g/cm^3)");
+        array.setInfoOnComponent(2,"temperature (K)");
+        f1.setTime(2.12,2,3);
+        f1.checkCoherency();
+        return f1;
+
+    def buildVecFieldOnGauss_1(cls):
+        _a=0.446948490915965;
+        _b=0.091576213509771;
+        _p1=0.11169079483905;
+        _p2=0.0549758718227661;
+        refCoo1=[ 0.,0., 1.,0., 0.,1. ]
+        gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b,
+                 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ];
+        wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ]
+        _refCoo1=refCoo1;
+        _gsCoo1=gsCoo1;
+        _wg1=wg1;
+        m=MEDLoaderDataForTest.build2DMesh_2();
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME);
+        f.setTime(3.14,1,5);
+        f.setMesh(m);
+        f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+        refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ]
+        _refCoo2=refCoo2;
+        _gsCoo1=_gsCoo1[0:6];
+        _wg1=_wg1[0:3];
+        f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo1,_wg1);
+        refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ]
+        _refCoo3=refCoo3;
+        _gsCoo1=_gsCoo1[0:4];
+        _wg1=_wg1[0:2];
+        f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo3,_gsCoo1,_wg1);
+        array=DataArrayDouble.New();
+        array.alloc(19,2);
+        ptr=array.getPointer();
+        for i in xrange(19*2):
+            array.setIJ(0,i,float(i+7));
+            pass
+        f.setArray(array);
+        f.setName("MyFirstFieldOnGaussPoint");
+        array.setInfoOnComponent(0,"power (MW/m^3)");
+        array.setInfoOnComponent(1,"density");
+        f.checkCoherency();
+        return f;
+
+    def buildVecFieldOnGaussNE_1(cls):
+        m=MEDLoaderDataForTest.build2DMesh_2();
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME);
+        f.setTime(3.14,1,5);
+        f.setMesh(m);
+        array=DataArrayDouble.New();
+        array.alloc(20,2);
+        for i in xrange(2*20):
+            array.setIJ(0,i,float(i+8));
+        f.setArray(array);
+        array.setInfoOnComponent(0,"power (W)");
+        array.setInfoOnComponent(1,"temperature");
+        f.setName("MyFieldOnGaussNE");
+        f.checkCoherency();
+        return f;
+    
+    build1DMesh_1=classmethod(build1DMesh_1)
+    build2DCurveMesh_1=classmethod(build2DCurveMesh_1)
+    build2DMesh_1=classmethod(build2DMesh_1)
+    build2DMesh_2=classmethod(build2DMesh_2)
+    build3DMesh_1=classmethod(build3DMesh_1)
+    build3DSurfMesh_1=classmethod(build3DSurfMesh_1)
+    build3DMesh_2=classmethod(build3DMesh_2)
+    buildVecFieldOnCells_1=classmethod(buildVecFieldOnCells_1)
+    buildVecFieldOnNodes_1=classmethod(buildVecFieldOnNodes_1)
+    buildVecFieldOnGauss_1=classmethod(buildVecFieldOnGauss_1)
+    buildVecFieldOnGaussNE_1=classmethod(buildVecFieldOnGaussNE_1)
+    pass
diff --git a/src/MEDLoader/Swig/MEDLoaderTest.py b/src/MEDLoader/Swig/MEDLoaderTest.py
new file mode 100644 (file)
index 0000000..e0c9a08
--- /dev/null
@@ -0,0 +1,542 @@
+#  -*- coding: iso-8859-1 -*-
+#  Copyright (C) 2007-2010  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
+#
+
+from libMEDLoader_Swig import *
+import unittest
+from math import pi,e,sqrt
+from MEDLoaderDataForTest import MEDLoaderDataForTest
+
+class MEDLoaderTest(unittest.TestCase):
+    def testMesh1DRW(self):
+        mesh=MEDLoaderDataForTest.build1DMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMesh("Pyfile1.med",mesh,True);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh2DCurveRW(self):
+        mesh=MEDLoaderDataForTest.build2DCurveMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMesh("Pyfile2.med",mesh,True);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh2DRW(self):
+        mesh=MEDLoaderDataForTest.build2DMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMesh("Pyfile3.med",mesh,True);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh3DSurfRW(self):
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMesh("Pyfile4.med",mesh,True);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh3DRW(self):
+        mesh=MEDLoaderDataForTest.build3DMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMesh("Pyfile5.med",mesh,True);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testFieldRW1(self):
+        f1=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        MEDLoader.WriteField("Pyfile6.med",f1,True);
+        f2=MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        #
+        f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        MEDLoader.WriteField("Pyfile7.med",f1,True);
+        f2=MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        pass
+
+    def testFieldRW2(self):
+        fileName="Pyfile8.med";
+        VAL1=12345.67890314;
+        VAL2=-1111111111111.;
+        f1=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        MEDLoader.WriteField(fileName,f1,True);
+        f1.setTime(10.,8,9);
+        f1.getArray().setIJ(0,0,VAL1);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(10.14,18,19);
+        f1.getArray().setIJ(0,0,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        #retrieving time steps...
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9);
+        f1.setTime(10.,8,9);
+        f1.getArray().setIJ(0,0,VAL1);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1);
+        f3=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        self.assertTrue(f3.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19);
+        f1.setTime(10.14,18,19);
+        f1.getArray().setIJ(0,0,VAL2);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        #test of throw on invalid (dt,it)
+        self.assertRaises(Exception,MEDLoader.ReadFieldCell,fileName,f1.getMesh().getName(),0,f1.getName(),28,19);
+        #ON NODES
+        f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        fileName2="Pyfile9.med";
+        MEDLoader.WriteField(fileName2,f1,True);
+        f1.setTime(110.,108,109);
+        tmp=f1.getArray().getPointer();
+        f1.getArray().setIJ(0,3,VAL1);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1);
+        f1.setTime(210.,208,209);
+        f1.getArray().setIJ(0,3,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1);
+        f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109);
+        f1.setTime(110.,108,109);
+        f1.getArray().setIJ(0,3,VAL1);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3);
+        f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        self.assertTrue(f3.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209);
+        f1.setTime(210.,208,209);
+        f1.getArray().setIJ(0,3,VAL2);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        pass
+
+    #
+    # Multi field in a same file, but this field has several
+    #
+    def testFieldRW3(self):
+        fileName="Pyfile11.med";
+        VAL1=12345.67890314;
+        VAL2=-1111111111111.;
+        name1="AField";
+        name3="AMesh1";
+        name2="AMesh2";
+        f1=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        f1.getMesh().setName(name3);
+        f1.setName(name1);
+        f1.setTime(10.,8,9);
+        tmp=f1.getArray().getPointer();
+        f1.getArray().setIJ(0,0,VAL1);
+        MEDLoader.WriteField(fileName,f1,True);
+        f1.setTime(10.14,18,19);
+        f1.getArray().setIJ(0,0,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.getMesh().setName(name2);
+        f1.setTime(10.55,28,29);
+        f1.getArray().setIJ(0,0,3*VAL1);
+        MEDLoader.WriteField(fileName,f1,False);
+        vec=MEDLoader.GetMeshNamesOnField(fileName,name1);
+        self.assertEqual(2,len(vec));
+        self.assertTrue(vec[0]==name3);
+        self.assertTrue(vec[1]==name2);
+        f1.setTime(10.66,38,39);
+        f1.getArray().setIJ(0,0,3*VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(10.77,48,49);
+        f1.getArray().setIJ(0,0,4*VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        #ON NODES
+        f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        f1.setName(name1);
+        f1.getMesh().setName(name2);
+        f1.setTime(110.,8,9);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(110.,108,109);
+        tmp=f1.getArray().getPointer();
+        f1.getArray().setIJ(0,3,VAL1);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(210.,208,209);
+        f1.getArray().setIJ(0,3,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        #
+        it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1);
+        self.assertEqual(2,len(it1));
+        self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]);
+        self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]);
+        it2=MEDLoader.GetCellFieldIterations(fileName,name2,name1);
+        self.assertEqual(3,len(it2));
+        self.assertEqual(28,it2[0][0]); self.assertEqual(29,it2[0][1]);
+        self.assertEqual(38,it2[1][0]); self.assertEqual(39,it2[1][1]);
+        self.assertEqual(48,it2[2][0]); self.assertEqual(49,it2[2][1]);
+        it3=MEDLoader.GetNodeFieldIterations(fileName,name2,name1);
+        self.assertEqual(3,len(it3));
+        self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]);
+        self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]);
+        self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]);
+        it4=MEDLoader.GetNodeFieldIterations(fileName,name3,name1);
+        self.assertTrue(len(it4)==0);
+        #
+        #
+        f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9);
+        self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19);
+        self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,28,29);
+        self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,38,39);
+        self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,48,49);
+        self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13);
+        #
+        f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,8,9);
+        self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13);
+        f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,108,109);
+        self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13);
+        f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,208,209);
+        self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13);
+        pass
+
+    def testMultiMeshRW1(self):
+        fileName="Pyfile10.med";
+        mesh1=MEDLoaderDataForTest.build3DMesh_1();
+        part1=[1,2,4,13,15]
+        mesh2=mesh1.buildPartOfMySelf(part1,True);
+        mesh2.setName("mesh2");
+        part2=[3,4,13,14]
+        mesh3=mesh1.buildPartOfMySelf(part2,True);
+        mesh3.setName("mesh3");
+        mesh4=MEDCouplingUMesh.New();
+        mesh4.setName("mesh4");
+        mesh4.setMeshDimension(3);
+        mesh4.allocateCells(1);
+        conn=[0,11,1,3]
+        mesh4.insertNextCell(NORM_TETRA4,4,conn[0:4])
+        mesh4.finishInsertingCells();
+        mesh4.setCoords(mesh1.getCoords());
+        meshes=[mesh1,mesh2,mesh3,mesh4]
+        mnane="3DToto";
+        MEDLoader.WriteUMeshesPartition(fileName,mnane,meshes,True);
+        #
+        mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane);
+        mesh1.setName(mnane);
+        part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
+        mesh6=mesh5.buildPartOfMySelf(part3,True);
+        mesh6.setName(mnane);
+        self.assertTrue(mesh6.isEqual(mesh1,1e-12));
+        grps=MEDLoader.GetMeshGroupsNames(fileName,mnane);
+        self.assertEqual(4,len(grps));
+        grps.index("mesh2");
+        grps.index("mesh3");
+        grps.index("mesh4");
+        grps.index("3DMesh_1");
+        #
+        vec=["mesh2"];
+        mesh2_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        self.assertTrue(mesh2_2.isEqual(mesh2,1e-12));
+        vec=["mesh3"];
+        mesh3_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        self.assertTrue(mesh3_2.isEqual(mesh3,1e-12));
+        vec=["mesh4"];
+        mesh4_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        self.assertTrue(mesh4_2.isEqual(mesh4,1e-12));
+        vec=["3DMesh_1"];
+        mesh1_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        mesh1.setName("3DMesh_1");
+        self.assertTrue(mesh1_2.isEqual(mesh1,1e-12));
+        #
+        vec=["Family_4","Family_2"];
+        mesh2_2=MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec);
+        mesh2_2.setName("mesh2");
+        self.assertTrue(mesh2_2.isEqual(mesh2,1e-12));
+        pass
+
+    def testFieldProfilRW1(self):
+        fileName="Pyfile12.med";
+        mesh1=MEDLoaderDataForTest.build3DMesh_1();
+        da,b,newNbOfNodes=mesh1.mergeNodes(1e-12);
+        MEDLoader.WriteUMesh(fileName,mesh1,True);
+        part1=[1,2,4,13,15]
+        mesh2=mesh1.buildPartOfMySelf(part1,True);
+        mesh2.setName(mesh1.getName());#<- important for the test
+        #
+        nbOfCells=mesh2.getNumberOfCells();
+        self.assertEqual(5,nbOfCells);
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setName("VectorFieldOnCells");
+        f1.setMesh(mesh2);
+        array=DataArrayDouble.New();
+        array.alloc(nbOfCells,2);
+        f1.setArray(array);
+        arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.]
+        array.setValues(arr1,nbOfCells,2);
+        f1.setTime(3.14,2,7);
+        f1.checkCoherency();
+        #
+        MEDLoader.WriteField(fileName,f1,False);#<- False important for the test
+        #
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7);
+        f2.checkCoherency();
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        #
+        pass
+
+    def testFieldGaussRW1(self):
+        fileName="Pyfile13.med";
+        f1=MEDLoaderDataForTest.buildVecFieldOnGauss_1();
+        MEDLoader.WriteField(fileName,f1,True);
+        f2=MEDLoader.ReadField(ON_GAUSS_PT,fileName,f1.getMesh().getName(),0,f1.getName(),1,5);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        pass
+
+    def testFieldGaussNERW1(self):
+        fileName="Pyfile14.med";
+        f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1();
+        MEDLoader.WriteField(fileName,f1,True);
+        f2=MEDLoader.ReadField(ON_GAUSS_NE,fileName,f1.getMesh().getName(),0,f1.getName(),1,5);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        pass
+
+    def testMesh3DSurfShuffleRW(self):
+        fileName="Pyfile15.med";
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        renumber1=[2,5,1,0,3,4]
+        mesh.renumberCells(renumber1,False);
+        mesh.checkCoherency();
+        MEDLoader.WriteUMesh(fileName,mesh,True);
+        mesh_rw=MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMultiFieldShuffleRW1(self):
+        fileName="Pyfile17.med";
+        m=MEDLoaderDataForTest.build3DMesh_2();
+        self.assertEqual(20,m.getNumberOfCells());
+        self.assertEqual(45,m.getNumberOfNodes());
+        polys=[1,4,6]
+        m.convertToPolyTypes(polys);
+        renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11]
+        m.renumberCells(renum,False);
+        m.orientCorrectlyPolyhedrons();
+        # Writing
+        MEDLoader.WriteUMesh(fileName,m,True);
+        f1Tmp=m.getMeasureField(False);
+        f1=f1Tmp.buildNewTimeReprFromThis(ONE_TIME,False);
+        f1.setTime(0.,1,2);
+        f_1=f1.cloneWithMesh(True);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.applyFunc("2*x");
+        f1.setTime(0.01,3,4);
+        f_2=f1.cloneWithMesh(True);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.applyFunc("2*x/3");
+        f1.setTime(0.02,5,6);
+        f_3=f1.cloneWithMesh(True);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        # Reading
+        its=[(1,2),(3,4),(5,6)];
+        fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its);
+        self.assertEqual(3,len(fs));
+        self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12));
+        self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12));
+        self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12));
+        pass
+
+    def testWriteUMeshesRW1(self):
+        fileName="Pyfile18.med";
+        m3d=MEDLoaderDataForTest.build3DMesh_2();
+        pt=[0.,0.,-0.3]
+        vec=[0.,0.,1.]
+        nodes=m3d.findNodesOnPlane(pt,vec,1e-12);
+        m2d=m3d.buildFacePartOfMySelfNode(nodes,True);
+        renumber=[1,2,0,4,3]
+        m2d.renumberCells(renumber,False);
+        m2d.setName("ExampleOfMultiDimW");
+        meshes=[m2d,m3d]
+        MEDLoader.WriteUMeshes(fileName,meshes,True);
+        m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0);
+        self.assertTrue(not m3d_bis.isEqual(m3d,1e-12));
+        m3d_bis.setName(m3d.getName());
+        self.assertTrue(m3d_bis.isEqual(m3d,1e-12));
+        m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces
+        self.assertTrue(m2d_bis.isEqual(m2d,1e-12));
+        # Creation of a field on faces.
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setName("FieldOnFacesShuffle");
+        f1.setMesh(m2d);
+        array=DataArrayDouble.New();
+        arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.]
+        array.setValues(arr1,m2d.getNumberOfCells(),2);
+        array.setInfoOnComponent(0,"plkj (mm)");
+        array.setInfoOnComponent(1,"pqqqss (mm)");
+        f1.setArray(array);
+        tmp=array.setValues(arr1,m2d.getNumberOfCells(),2);
+        f1.setTime(3.14,2,7);
+        f1.checkCoherency();
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7);
+        self.assertTrue(f2.isEqual(f1,1e-12,1e-12));
+        pass
+
+    def testFieldNodeProfilRW1(self):
+        fileName="Pyfile19.med";
+        fileName2="Pyfile20.med";
+        m=MEDLoaderDataForTest.build2DMesh_1();
+        nbOfNodes=m.getNumberOfNodes();
+        MEDLoader.WriteUMesh(fileName,m,True);
+        f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME);
+        f1.setName("VFieldOnNodes");
+        f1.setMesh(m);
+        array=DataArrayDouble.New();
+        arr1=[1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.]
+        array.setValues(arr1,nbOfNodes,2);
+        f1.setArray(array);
+        array.setInfoOnComponent(0,"tyty (mm)");
+        array.setInfoOnComponent(1,"uiop (MW)");
+        f1.setTime(3.14,2,7);
+        f1.checkCoherency();
+        arr2=[2,4,5,3,6,7]
+        f2=f1.buildSubPart(arr2);
+        f2.getMesh().setName(f1.getMesh().getName());
+        MEDLoader.WriteField(fileName,f2,False);#<- False important for the test
+        #
+        f3=MEDLoader.ReadFieldNode(fileName,f2.getMesh().getName(),0,f2.getName(),2,7);
+        f3.checkCoherency();
+        self.assertTrue(f3.isEqual(f2,1e-12,1e-12));
+        #
+        arr3=[1,3,0,5,2,4]
+        f2.renumberNodes(arr3);
+        MEDLoader.WriteUMesh(fileName2,m,True);
+        MEDLoader.WriteField(fileName2,f2,False);#<- False important for the test
+        f3=MEDLoader.ReadFieldNode(fileName2,f2.getMesh().getName(),0,f2.getName(),2,7);
+        f3.checkCoherency();
+        self.assertTrue(f3.isEqual(f2,1e-12,1e-12));
+        #
+        pass
+
+    def testFieldNodeProfilRW2(self):
+        fileName="Pyfile23.med";
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        MEDLoader.WriteUMesh(fileName,mesh,True);
+        #
+        f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME);
+        f1.setName("FieldMix");
+        f1.setMesh(mesh);
+        arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150.,
+              1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.];
+        array=DataArrayDouble.New();
+        array.setValues(arr2,12,2);
+        f1.setArray(array);
+        array.setInfoOnComponent(0,"plkj (mm)");
+        array.setInfoOnComponent(1,"pqqqss (mm)");
+        tmp=array.getPointer();
+        f1.setTime(3.17,2,7);
+        #
+        renumArr=[3,7,2,1,5,11,10,0,9,6,8,4]
+        f1.renumberNodes(renumArr);
+        f1.checkCoherency();
+        MEDLoader.WriteField(fileName,f1,False);#<- False important for the test
+        f2=MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7);
+        self.assertTrue(f2.isEqual(f1,1e-12,1e-12));
+        #
+        pass
+
+    def testMixCellAndNodesFieldRW1(self):
+        fileName="Pyfile21.med";
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setName("FieldMix");
+        f1.setMesh(mesh);
+        array=DataArrayDouble.New();
+        f1.setArray(array);
+        arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.]
+        array.setValues(arr1,6,2);
+        array.setInfoOnComponent(0,"plkj (mm)");
+        array.setInfoOnComponent(1,"pqqqss (mm)");
+        f1.setTime(3.14,2,7);
+        f1.checkCoherency();
+        #
+        f2=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME);
+        f2.setName("FieldMix");
+        f2.setMesh(mesh);
+        array=DataArrayDouble.New();
+        f2.setArray(array);
+        arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150.,
+              1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.]
+        array.setValues(arr2,12,2)
+        array.setInfoOnComponent(0,"plkj (mm)");
+        array.setInfoOnComponent(1,"pqqqss (mm)");
+        f2.setTime(3.17,2,7);
+        f2.checkCoherency();
+        #
+        MEDLoader.WriteField(fileName,f1,True);
+        ts=MEDLoader.GetTypesOfField(fileName,f1.getName(),f1.getMesh().getName());
+        self.assertEqual(1,len(ts));
+        self.assertEqual(ON_CELLS,ts[0]);
+        fs=MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName());
+        self.assertEqual(1,len(fs));
+        self.assertTrue(fs[0]=="FieldMix");
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f2);
+        fs=MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName());
+        self.assertEqual(1,len(fs));
+        self.assertTrue(fs[0]=="FieldMix");
+        #
+        ts=MEDLoader.GetTypesOfField(fileName,f1.getName(),f1.getMesh().getName());
+        self.assertEqual(2,len(ts));
+        self.assertEqual(ON_NODES,ts[0]);
+        self.assertEqual(ON_CELLS,ts[1]);
+        #
+        f3=MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7);
+        self.assertTrue(f3.isEqual(f2,1e-12,1e-12));
+        f3=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7);
+        self.assertTrue(f3.isEqual(f1,1e-12,1e-12));
+        #
+        pass
+
+    def testGetAllFieldNamesRW1(self):
+        fileName="Pyfile22.med";
+        mesh=MEDLoaderDataForTest.build2DMesh_2();
+        f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME);
+        f1.setName("Field1");
+        f1.setTime(3.44,5,6);
+        f1.setMesh(mesh);
+        f1.fillFromAnalytic(2,"x+y");
+        MEDLoader.WriteField(fileName,f1,True);
+        f1.setTime(1002.3,7,8);
+        f1.fillFromAnalytic(2,"x+77.*y");
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setName("Field2");
+        MEDLoader.WriteField(fileName,f1,False);
+        f1.setName("Field3");
+        mesh.setName("2DMesh_2Bis");
+        MEDLoader.WriteField(fileName,f1,False);
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setName("Field8");
+        f1.setTime(8.99,7,9);
+        f1.setMesh(mesh);
+        f1.fillFromAnalytic(3,"3*x+y");
+        MEDLoader.WriteField(fileName,f1,False);
+        fs=MEDLoader.GetAllFieldNames(fileName);
+        self.assertEqual(4,len(fs));
+        self.assertTrue(fs[0]=="Field1");
+        self.assertTrue(fs[1]=="Field2");
+        self.assertTrue(fs[2]=="Field3");
+        self.assertTrue(fs[3]=="Field8");
+        pass
+    pass
+
+unittest.main()
diff --git a/src/MEDLoader/Swig/MEDLoaderTest2.py b/src/MEDLoader/Swig/MEDLoaderTest2.py
new file mode 100644 (file)
index 0000000..bc39c1b
--- /dev/null
@@ -0,0 +1,344 @@
+#  -*- coding: iso-8859-1 -*-
+#  Copyright (C) 2007-2010  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
+#
+
+from libMEDLoader_Swig import *
+import unittest
+from math import pi,e,sqrt
+from MEDLoaderDataForTest import MEDLoaderDataForTest
+
+class MEDLoaderTest(unittest.TestCase):
+    def testMesh1DRW(self):
+        mesh=MEDLoaderDataForTest.build1DMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMeshDep("Pyfile1.med",mesh,False);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh2DCurveRW(self):
+        mesh=MEDLoaderDataForTest.build2DCurveMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMeshDep("Pyfile2.med",mesh,False);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh2DRW(self):
+        mesh=MEDLoaderDataForTest.build2DMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMeshDep("Pyfile3.med",mesh,False);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh3DSurfRW(self):
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMeshDep("Pyfile4.med",mesh,False);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMesh3DRW(self):
+        mesh=MEDLoaderDataForTest.build3DMesh_1();
+        mesh.checkCoherency();
+        MEDLoader.WriteUMeshDep("Pyfile5.med",mesh,False);
+        mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testFieldRW1(self):
+        f1=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        MEDLoader.WriteFieldDep("Pyfile6.med",f1,False);
+        f2=MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        #
+        f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        MEDLoader.WriteFieldDep("Pyfile7.med",f1,False);
+        f2=MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        pass
+
+    def testFieldRW2(self):
+        fileName="Pyfile8.med";
+        VAL1=12345.67890314;
+        VAL2=-1111111111111.;
+        f1=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        MEDLoader.WriteFieldDep(fileName,f1,False);
+        f1.setTime(10.,8,9);
+        f1.getArray().setIJ(0,0,VAL1);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(10.14,18,19);
+        f1.getArray().setIJ(0,0,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        #retrieving time steps...
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9);
+        f1.setTime(10.,8,9);
+        f1.getArray().setIJ(0,0,VAL1);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1);
+        f3=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        self.assertTrue(f3.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19);
+        f1.setTime(10.14,18,19);
+        f1.getArray().setIJ(0,0,VAL2);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        #ON NODES
+        f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        fileName2="Pyfile9.med";
+        MEDLoader.WriteFieldDep(fileName2,f1,False);
+        f1.setTime(110.,108,109);
+        tmp=f1.getArray().getPointer();
+        f1.getArray().setIJ(0,3,VAL1);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1);
+        f1.setTime(210.,208,209);
+        f1.getArray().setIJ(0,3,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1);
+        f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109);
+        f1.setTime(110.,108,109);
+        f1.getArray().setIJ(0,3,VAL1);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3);
+        f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        self.assertTrue(f3.isEqual(f2,1e-12,1e-12));
+        f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209);
+        f1.setTime(210.,208,209);
+        f1.getArray().setIJ(0,3,VAL2);
+        self.assertTrue(f1.isEqual(f2,1e-12,1e-12));
+        pass
+
+    #
+    # Multi field in a same file, but this field has several
+    #
+    def testFieldRW3(self):
+        fileName="Pyfile11.med";
+        VAL1=12345.67890314;
+        VAL2=-1111111111111.;
+        name1="AField";
+        name3="AMesh1";
+        name2="AMesh2";
+        f1=MEDLoaderDataForTest.buildVecFieldOnCells_1();
+        f1.getMesh().setName(name3);
+        f1.setName(name1);
+        f1.setTime(10.,8,9);
+        tmp=f1.getArray().getPointer();
+        f1.getArray().setIJ(0,0,VAL1);
+        MEDLoader.WriteFieldDep(fileName,f1,False);
+        f1.setTime(10.14,18,19);
+        f1.getArray().setIJ(0,0,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.getMesh().setName(name2);
+        f1.setTime(10.55,28,29);
+        f1.getArray().setIJ(0,0,3*VAL1);
+        MEDLoader.WriteFieldDep(fileName,f1,False);
+        f1.setTime(10.66,38,39);
+        f1.getArray().setIJ(0,0,3*VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(10.77,48,49);
+        f1.getArray().setIJ(0,0,4*VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        #ON NODES
+        f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1();
+        f1.setName(name1);
+        f1.getMesh().setName(name2);
+        f1.setTime(110.,8,9);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(110.,108,109);
+        tmp=f1.getArray().getPointer();
+        f1.getArray().setIJ(0,3,VAL1);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.setTime(210.,208,209);
+        f1.getArray().setIJ(0,3,VAL2);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        #
+        it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1);
+        self.assertEqual(2,len(it1));
+        self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]);
+        self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]);
+        it2=MEDLoader.GetCellFieldIterations(fileName,name2,name1);
+        self.assertEqual(3,len(it2));
+        self.assertEqual(28,it2[0][0]); self.assertEqual(29,it2[0][1]);
+        self.assertEqual(38,it2[1][0]); self.assertEqual(39,it2[1][1]);
+        self.assertEqual(48,it2[2][0]); self.assertEqual(49,it2[2][1]);
+        it3=MEDLoader.GetNodeFieldIterations(fileName,name2,name1);
+        self.assertEqual(3,len(it3));
+        self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]);
+        self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]);
+        self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]);
+        it4=MEDLoader.GetNodeFieldIterations(fileName,name3,name1);
+        self.assertTrue(len(it4)==0);
+        #
+        #
+        f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9);
+        self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19);
+        self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,28,29);
+        self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,38,39);
+        self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13);
+        f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,48,49);
+        self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13);
+        #
+        f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,8,9);
+        self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13);
+        f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,108,109);
+        self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13);
+        f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,208,209);
+        self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13);
+        pass
+
+    def testMultiMeshRW1(self):
+        fileName="Pyfile10.med";
+        mesh1=MEDLoaderDataForTest.build3DMesh_1();
+        part1=[1,2,4,13,15]
+        mesh2=mesh1.buildPartOfMySelf(part1,True);
+        mesh2.setName("mesh2");
+        part2=[3,4,13,14]
+        mesh3=mesh1.buildPartOfMySelf(part2,True);
+        mesh3.setName("mesh3");
+        mesh4=MEDCouplingUMesh.New();
+        mesh4.setName("mesh4");
+        mesh4.setMeshDimension(3);
+        mesh4.allocateCells(1);
+        conn=[0,11,1,3]
+        mesh4.insertNextCell(NORM_TETRA4,4,conn[0:4])
+        mesh4.finishInsertingCells();
+        mesh4.setCoords(mesh1.getCoords());
+        meshes=[mesh1,mesh2,mesh3,mesh4]
+        mnane="3DToto";
+        MEDLoader.WriteUMeshesPartitionDep(fileName,mnane,meshes,False);
+        #
+        mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane);
+        mesh1.setName(mnane);
+        part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
+        mesh6=mesh5.buildPartOfMySelf(part3,True);
+        mesh6.setName(mnane);
+        self.assertTrue(mesh6.isEqual(mesh1,1e-12));
+        grps=MEDLoader.GetMeshGroupsNames(fileName,mnane);
+        self.assertEqual(4,len(grps));
+        grps.index("mesh2");
+        grps.index("mesh3");
+        grps.index("mesh4");
+        grps.index("3DMesh_1");
+        #
+        vec=["mesh2"];
+        mesh2_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        self.assertTrue(mesh2_2.isEqual(mesh2,1e-12));
+        vec=["mesh3"];
+        mesh3_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        self.assertTrue(mesh3_2.isEqual(mesh3,1e-12));
+        vec=["mesh4"];
+        mesh4_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        self.assertTrue(mesh4_2.isEqual(mesh4,1e-12));
+        vec=["3DMesh_1"];
+        mesh1_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec);
+        mesh1.setName("3DMesh_1");
+        self.assertTrue(mesh1_2.isEqual(mesh1,1e-12));
+        #
+        vec=["Family_4","Family_2"];
+        mesh2_2=MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec);
+        mesh2_2.setName("mesh2");
+        self.assertTrue(mesh2_2.isEqual(mesh2,1e-12));
+        pass
+
+    def testMesh3DSurfShuffleRW(self):
+        fileName="Pyfile15.med";
+        mesh=MEDLoaderDataForTest.build3DSurfMesh_1();
+        renumber1=[2,5,1,0,3,4]
+        mesh.renumberCells(renumber1,False);
+        mesh.checkCoherency();
+        MEDLoader.WriteUMeshDep(fileName,mesh,False);
+        mesh_rw=MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0);
+        self.assertTrue(mesh.isEqual(mesh_rw,1e-12));
+        pass
+
+    def testMultiFieldShuffleRW1(self):
+        fileName="Pyfile17.med";
+        m=MEDLoaderDataForTest.build3DMesh_2();
+        self.assertEqual(20,m.getNumberOfCells());
+        self.assertEqual(45,m.getNumberOfNodes());
+        polys=[1,4,6]
+        m.convertToPolyTypes(polys);
+        renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11]
+        m.renumberCells(renum,False);
+        m.orientCorrectlyPolyhedrons();
+        # Writing
+        MEDLoader.WriteUMeshDep(fileName,m,False);
+        f1Tmp=m.getMeasureField(False);
+        f1=f1Tmp.buildNewTimeReprFromThis(ONE_TIME,False);
+        f1.setTime(0.,1,2);
+        f_1=f1.cloneWithMesh(True);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.applyFunc("2*x");
+        f1.setTime(0.01,3,4);
+        f_2=f1.cloneWithMesh(True);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f1.applyFunc("2*x/3");
+        f1.setTime(0.02,5,6);
+        f_3=f1.cloneWithMesh(True);
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        # Reading
+        its=[(1,2),(3,4),(5,6)];
+        fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its);
+        self.assertEqual(3,len(fs));
+        self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12));
+        self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12));
+        self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12));
+        pass
+
+    def testWriteUMeshesRW1(self):
+        fileName="Pyfile18.med";
+        m3d=MEDLoaderDataForTest.build3DMesh_2();
+        pt=[0.,0.,-0.3]
+        vec=[0.,0.,1.]
+        nodes=m3d.findNodesOnPlane(pt,vec,1e-12);
+        m2d=m3d.buildFacePartOfMySelfNode(nodes,True);
+        renumber=[1,2,0,4,3]
+        m2d.renumberCells(renumber,False);
+        m2d.setName("ExampleOfMultiDimW");
+        meshes=[m2d,m3d]
+        MEDLoader.WriteUMeshes(fileName,meshes,False);
+        m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0);
+        self.assertTrue(not m3d_bis.isEqual(m3d,1e-12));
+        m3d_bis.setName(m3d.getName());
+        self.assertTrue(m3d_bis.isEqual(m3d,1e-12));
+        m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces
+        self.assertTrue(m2d_bis.isEqual(m2d,1e-12));
+        # Creation of a field on faces.
+        f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME);
+        f1.setName("FieldOnFacesShuffle");
+        f1.setMesh(m2d);
+        array=DataArrayDouble.New();
+        arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.]
+        array.setValues(arr1,m2d.getNumberOfCells(),2);
+        array.setInfoOnComponent(0,"plkj (mm)");
+        array.setInfoOnComponent(1,"pqqqss (mm)");
+        f1.setArray(array);
+        tmp=array.setValues(arr1,m2d.getNumberOfCells(),2);
+        f1.setTime(3.14,2,7);
+        f1.checkCoherency();
+        MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+        f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7);
+        self.assertTrue(f2.isEqual(f1,1e-12,1e-12));
+        pass
+    pass
+
+unittest.main()
diff --git a/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/src/MEDLoader/Swig/MEDLoaderTypemaps.i
new file mode 100644 (file)
index 0000000..94811c3
--- /dev/null
@@ -0,0 +1,134 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <vector>
+
+static std::vector<std::pair<int,int> > convertTimePairIdsFromPy(PyObject *pyLi)
+{
+  std::vector<std::pair<int,int> > ret;
+  if(PyList_Check(pyLi))
+    {
+      int size=PyList_Size(pyLi);
+      ret.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          if(PyTuple_Check(o))
+            {
+              std::pair<int,int> p;
+              int size2=PyTuple_Size(o);
+              if(size2!=2)
+                {
+                  const char msg[]="tuples in list must be of size 2 (dt,it) !";
+                  ret.clear();
+                  PyErr_SetString(PyExc_TypeError,msg);
+                  PyErr_Print();
+                  throw INTERP_KERNEL::Exception(msg);
+                }
+              PyObject *o0=PyTuple_GetItem(o,0);
+              if(PyInt_Check(o0))
+                p.first=(int)PyInt_AS_LONG(o0);
+              else
+                {
+                  const char msg[]="First elem of tuples in list must be integer : dt !";
+                  ret.clear();
+                  PyErr_SetString(PyExc_TypeError,msg);
+                  PyErr_Print();
+                  throw INTERP_KERNEL::Exception(msg);
+                }
+              PyObject *o1=PyTuple_GetItem(o,1);
+              if(PyInt_Check(o1))
+                p.second=(int)PyInt_AS_LONG(o1);
+              else
+                {
+                  const char msg[]="Second elem of tuples in list must be integer : dt !";
+                  ret.clear();
+                  PyErr_SetString(PyExc_TypeError,msg);
+                  PyErr_Print();
+                  throw INTERP_KERNEL::Exception(msg);
+                }
+              ret[i]=p;
+            }
+          else
+            {
+              const char msg[]="list must contain tuples only";
+              ret.clear();
+              PyErr_SetString(PyExc_TypeError,msg);
+              PyErr_Print();
+              throw INTERP_KERNEL::Exception(msg);
+              return ret;
+            }
+        }
+    }
+  else
+    {
+      ret.clear();
+      const char msg[]="convertTimePairIdsFromPy : not a list";
+      PyErr_SetString(PyExc_TypeError,msg);
+      PyErr_Print();
+      throw INTERP_KERNEL::Exception(msg);
+    }
+  return ret;
+}
+
+static PyObject *convertFieldDoubleVecToPy(const std::vector<ParaMEDMEM::MEDCouplingFieldDouble *>& li)
+{
+  int sz=li.size();
+  PyObject *ret=PyList_New(sz);
+  for(int i=0;i<sz;i++)
+    {
+      PyObject *o=SWIG_NewPointerObj((void*)li[i],SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,SWIG_POINTER_OWN | 0);
+      PyList_SetItem(ret,i,o);
+    }
+  return ret;
+}
+
+static std::vector<ParaMEDMEM::MEDCouplingUMesh *> convertFieldDoubleVecFromPy(PyObject *pyLi)
+{
+  std::vector<ParaMEDMEM::MEDCouplingUMesh *> ret;
+  if(PyList_Check(pyLi))
+    {
+      int size=PyList_Size(pyLi);
+      ret.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *obj=PyList_GetItem(pyLi,i);
+          void *argp;
+          int status=SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,0|0);
+          if(!SWIG_IsOK(status))
+            {
+              const char msg[]="list must contain only MEDCouplingUMesh";
+              PyErr_SetString(PyExc_TypeError,msg);
+              PyErr_Print();
+              throw INTERP_KERNEL::Exception(msg);
+            }
+          ParaMEDMEM::MEDCouplingUMesh *arg=reinterpret_cast< ParaMEDMEM::MEDCouplingUMesh * >(argp);
+          ret[i]=arg;
+        }
+    }
+  else
+    {
+      ret.clear();
+      const char msg[]="convertFieldDoubleVecFromPy : not a list";
+      PyErr_SetString(PyExc_TypeError,msg);
+      PyErr_Print();
+      throw INTERP_KERNEL::Exception(msg);
+    }
+  return ret;
+}
index eda6669e2567144e72bcf03902851281f3a805c9..ab110a19dbe1f0b0a0aa097d49e3c2e1868c80cb 100644 (file)
@@ -24,9 +24,9 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 lib_LTLIBRARIES = _libMEDLoader_Swig.la
 
 salomeinclude_HEADERS =  \
-       libMEDLoader_Swig.i
+       libMEDLoader_Swig.i MEDLoaderTypemaps.i
 
-SWIG_DEF = libMEDLoader_Swig.i
+SWIG_DEF = libMEDLoader_Swig.i MEDLoaderTypemaps.i
 
 SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../MEDCoupling -I$(srcdir)/../../MEDCoupling_Swig \
        -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../INTERP_KERNEL/Bases
@@ -50,5 +50,6 @@ _libMEDLoader_Swig_la_LDFLAGS  = -module $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS
 
 CLEANFILES = libMEDLoader_Swig_wrap.cxx libMEDLoader_Swig.py
 
-dist_salomescript_DATA= libMEDLoader_Swig.py
+dist_salomescript_DATA= libMEDLoader_Swig.py MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py
 
+UNIT_TEST_PROG = MEDLoaderTest.py MEDLoaderTest2.py
\ No newline at end of file
index 5a5b6087a12ed0ba6baff824212233c30fe116d4..5feded4d5f6275a77b1376b6d20f77c0f8fa32fa 100644 (file)
 
 %module libMEDLoader_Swig
 
-%include std_vector.i
-%include std_string.i
+#define MEDCOUPLING_EXPORT
+#define MEDLOADER_EXPORT
 
-%include "MEDCouplingTypemaps.i"
 %include "libMEDCoupling_Swig.i"
 
 %{
 #include "MEDLoader.hxx"
+#include "MEDLoaderTypemaps.i"
 %}
 
 #if SWIG_VERSION >= 0x010329
 %template()  std::vector<std::string>;
 #endif
 
+%newobject MEDLoader::ReadUMeshFromFamilies;
+%newobject MEDLoader::ReadUMeshFromGroups;
 %newobject MEDLoader::ReadUMeshFromFile;
-%newobject MEDLoader::ReadFieldDoubleCell;
+%newobject MEDLoader::ReadField;
+%newobject MEDLoader::ReadFieldCell;
+%newobject MEDLoader::ReadFieldNode;
+%newobject MEDLoader::ReadFieldGauss;
+%newobject MEDLoader::ReadFieldGaussNE;
 
 class MEDLoader
 {
 public:
-  static std::vector<std::string> GetMeshNames(const char *fileName);
-  static std::vector<std::string> GetMeshGroupsNames(const char *fileName, const char *meshName);
-  static std::vector<std::string> GetMeshFamilyNames(const char *fileName, const char *meshName);
-  static std::vector<std::string> GetCellFieldNamesOnMesh(const char *fileName, const char *meshName);
-  static std::vector<std::string> GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName);
+  static void setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception);
+  static void setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception);
+  static void setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception);
+  static void CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static std::vector<std::string> GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception);
+  static double GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
   %extend
      {
-       static PyObject *GetCellFieldIterations(const char *fileName, const char *fieldName)
+       static PyObject *GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
        {
-         std::vector< std::pair<int,int> > res=MEDLoader::GetCellFieldIterations(fileName,fieldName);
+         std::vector< std::pair<int,int> > res=MEDLoader::GetFieldIterations(type,fileName,meshName,fieldName);
          PyObject *ret=PyList_New(res.size());
          int rk=0;
          for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++)
@@ -60,12 +75,96 @@ public:
            }
          return ret;
        }
+
+       static PyObject *GetAllFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector< std::pair< std::pair<int,int>, double> > res=MEDLoader::GetAllFieldIterations(fileName,meshName,fieldName);
+         PyObject *ret=PyList_New(res.size());
+         int rk=0;
+         for(std::vector< std::pair< std::pair<int,int>, double> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++)
+           {
+             PyObject *elt=PyTuple_New(3);
+             PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first.first));
+             PyTuple_SetItem(elt,1,SWIG_From_int((*iter).first.second));
+             PyTuple_SetItem(elt,2,SWIG_From_double((*iter).second));
+             PyList_SetItem(ret,rk,elt);
+           }
+         return ret;
+       }
+
+       static PyObject *GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector< std::pair<int,int> > res=MEDLoader::GetCellFieldIterations(fileName,meshName,fieldName);
+         PyObject *ret=PyList_New(res.size());
+         int rk=0;
+         for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++)
+           {
+             PyObject *elt=PyTuple_New(2);
+             PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first));
+             PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second));
+             PyList_SetItem(ret,rk,elt);
+           }
+         return ret;
+       }
+       static PyObject *GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector< std::pair<int,int> > res=MEDLoader::GetNodeFieldIterations(fileName,meshName,fieldName);
+         PyObject *ret=PyList_New(res.size());
+         int rk=0;
+         for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++)
+           {
+             PyObject *elt=PyTuple_New(2);
+             PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first));
+             PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second));
+             PyList_SetItem(ret,rk,elt);
+           }
+         return ret;
+       }
+       static PyObject *ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax,
+                                             const char *fieldName, PyObject *liIts) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector<std::pair<int,int> > its=convertTimePairIdsFromPy(liIts);
+         std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> res=MEDLoader::ReadFieldsOnSameMesh(type,fileName,meshName,meshDimRelToMax,fieldName,its);
+         return convertFieldDoubleVecToPy(res);
+       }
+       static void WriteUMeshesPartition(const char *fileName, const char *meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector<ParaMEDMEM::MEDCouplingUMesh *> v=convertFieldDoubleVecFromPy(li);
+         MEDLoader::WriteUMeshesPartition(fileName,meshName,v,writeFromScratch);
+       }
+       static void WriteUMeshesPartitionDep(const char *fileName, const char *meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector<ParaMEDMEM::MEDCouplingUMesh *> v=convertFieldDoubleVecFromPy(li);
+         MEDLoader::WriteUMeshesPartitionDep(fileName,meshName,v,writeFromScratch);
+       }
+       static void WriteUMeshes(const char *fileName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector<ParaMEDMEM::MEDCouplingUMesh *> v=convertFieldDoubleVecFromPy(li);
+         std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v2(v.begin(),v.end());
+         MEDLoader::WriteUMeshes(fileName,v2,writeFromScratch);
+       }
+       static PyObject *GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception)
+       {
+         std::vector< ParaMEDMEM::TypeOfField > v=MEDLoader::GetTypesOfField(fileName,fieldName,meshName);
+         int size=v.size();
+         PyObject *ret=PyList_New(size);
+         for(int i=0;i<size;i++)
+           PyList_SetItem(ret,i,PyInt_FromLong((int)v[i]));
+         return ret;
+       }
      }
-  //std::vector< std::pair<int,int> > GetNodeFieldIterations(const char *fileName, const char *fieldName);
+  static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception);
   static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception);
   static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception);
-  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order);
-  static void WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch);
-  static void WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch);
-  static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception);
+  static void WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception);
+  static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception);
 };
diff --git a/src/MEDLoader/Test/MEDLoaderTest.cxx b/src/MEDLoader/Test/MEDLoaderTest.cxx
new file mode 100644 (file)
index 0000000..6dadebf
--- /dev/null
@@ -0,0 +1,1053 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MEDLoaderTest.hxx"
+#include "MEDLoader.hxx"
+#include "MEDLoaderBase.hxx"
+#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingMemArray.hxx"
+
+#include <cmath>
+
+using namespace ParaMEDMEM;
+
+void MEDLoaderTest::testMesh1DRW()
+{
+  MEDCouplingUMesh *mesh=build1DMesh_1();
+  mesh->checkCoherency();
+  MEDLoader::WriteUMesh("file1.med",mesh,true);
+  MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file1.med",mesh->getName(),0);
+  CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
+  mesh_rw->decrRef();
+  mesh->decrRef();
+}
+
+void MEDLoaderTest::testMesh2DCurveRW()
+{
+  MEDCouplingUMesh *mesh=build2DCurveMesh_1();
+  mesh->checkCoherency();
+  MEDLoader::WriteUMesh("file2.med",mesh,true);
+  MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file2.med",mesh->getName(),0);
+  CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
+  mesh_rw->decrRef();
+  mesh->decrRef();
+}
+
+void MEDLoaderTest::testMesh2DRW()
+{
+  MEDCouplingUMesh *mesh=build2DMesh_1();
+  mesh->checkCoherency();
+  MEDLoader::WriteUMesh("file3.med",mesh,true);
+  MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file3.med",mesh->getName(),0);
+  CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
+  mesh_rw->decrRef();
+  mesh->decrRef();
+}
+
+void MEDLoaderTest::testMesh3DSurfRW()
+{
+  MEDCouplingUMesh *mesh=build3DSurfMesh_1();
+  mesh->checkCoherency();
+  MEDLoader::WriteUMesh("file4.med",mesh,true);
+  MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file4.med",mesh->getName(),0);
+  CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
+  mesh_rw->decrRef();
+  mesh->decrRef();
+}
+
+void MEDLoaderTest::testMesh3DRW()
+{
+  MEDCouplingUMesh *mesh=build3DMesh_1();
+  mesh->checkCoherency();
+  MEDLoader::WriteUMesh("file5.med",mesh,true);
+  MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file5.med",mesh->getName(),0);
+  CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
+  mesh_rw->decrRef();
+  mesh->decrRef();
+}
+
+/*!
+ * Most basic test : one and only one MEDCoupling field in a new file.
+ */
+void MEDLoaderTest::testFieldRW1()
+{
+  MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1();
+  MEDLoader::WriteField("file6.med",f1,true);
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell("file6.med",f1->getMesh()->getName(),0,f1->getName(),0,1);
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  f1->decrRef();
+  f2->decrRef();
+  //
+  f1=buildVecFieldOnNodes_1();
+  MEDLoader::WriteField("file7.med",f1,true);
+  f2=MEDLoader::ReadFieldNode("file7.med",f1->getMesh()->getName(),0,f1->getName(),2,3);
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  f1->decrRef();
+  f2->decrRef();
+}
+
+/*!
+ * Multi field writing in a same file.
+ */
+void MEDLoaderTest::testFieldRW2()
+{
+  const char fileName[]="file8.med";
+  static const double VAL1=12345.67890314;
+  static const double VAL2=-1111111111111.;
+  MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1();
+  MEDLoader::WriteField(fileName,f1,true);
+  f1->setTime(10.,8,9);
+  double *tmp=f1->getArray()->getPointer();
+  tmp[0]=VAL1;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->setTime(10.14,18,19);
+  tmp[0]=VAL2;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  //retrieving time steps...
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),8,9);
+  f1->setTime(10.,8,9);
+  tmp[0]=VAL1;
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  f2->decrRef();
+  f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),0,1);
+  MEDCouplingFieldDouble *f3=buildVecFieldOnCells_1();
+  CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12));
+  f3->decrRef();
+  f2->decrRef();
+  f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),18,19);
+  f1->setTime(10.14,18,19);
+  tmp[0]=VAL2;
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  //test of throw on invalid (dt,it)
+  CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),28,19),INTERP_KERNEL::Exception);
+  f2->decrRef();
+  f1->decrRef();
+  //ON NODES
+  f1=buildVecFieldOnNodes_1();
+  const char fileName2[]="file9.med";
+  MEDLoader::WriteField(fileName2,f1,true);
+  f1->setTime(110.,108,109);
+  tmp=f1->getArray()->getPointer();
+  tmp[3]=VAL1;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1);
+  f1->setTime(210.,208,209);
+  tmp[3]=VAL2;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1);
+  f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),108,109);
+  f1->setTime(110.,108,109);
+  tmp[3]=VAL1;
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  f2->decrRef();
+  f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),2,3);
+  f3=buildVecFieldOnNodes_1();
+  CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12));
+  f3->decrRef();
+  f2->decrRef();
+  f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),208,209);
+  f1->setTime(210.,208,209);
+  tmp[3]=VAL2;
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  f2->decrRef();
+  f1->decrRef();
+}
+
+/*!
+ * Multi field in a same file, but this field has several
+ */
+void MEDLoaderTest::testFieldRW3()
+{
+  const char fileName[]="file11.med";
+  static const double VAL1=12345.67890314;
+  static const double VAL2=-1111111111111.;
+  const char name1[]="AField";
+  const char name3[]="AMesh1";
+  const char name2[]="AMesh2";
+  MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1();
+  ((MEDCouplingMesh *)f1->getMesh())->setName(name3);
+  f1->setName(name1);
+  f1->setTime(10.,8,9);
+  double *tmp=f1->getArray()->getPointer();
+  tmp[0]=VAL1;
+  MEDLoader::WriteField(fileName,f1,true);
+  f1->setTime(10.14,18,19);
+  tmp[0]=VAL2;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  ((MEDCouplingMesh *)f1->getMesh())->setName(name2);
+  f1->setTime(10.55,28,29);
+  tmp[0]=3*VAL1;
+  MEDLoader::WriteField(fileName,f1,false);
+  std::vector<std::string> vec=MEDLoader::GetMeshNamesOnField(fileName,name1);
+  CPPUNIT_ASSERT_EQUAL(2,(int)vec.size());
+  CPPUNIT_ASSERT(vec[0]==name3);
+  CPPUNIT_ASSERT(vec[1]==name2);
+  f1->setTime(10.66,38,39);
+  tmp[0]=3*VAL2;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->setTime(10.77,48,49);
+  tmp[0]=4*VAL2;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  //ON NODES
+  f1->decrRef();
+  f1=buildVecFieldOnNodes_1();
+  f1->setName(name1);
+  ((MEDCouplingMesh *)f1->getMesh())->setName(name2);
+  f1->setTime(110.,8,9);
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->setTime(110.,108,109);
+  tmp=f1->getArray()->getPointer();
+  tmp[3]=VAL1;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->setTime(210.,208,209);
+  tmp[3]=VAL2;
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  //
+  std::vector< std::pair<int,int> > it1=MEDLoader::GetCellFieldIterations(fileName,name3,name1);
+  CPPUNIT_ASSERT_EQUAL(2,(int)it1.size());
+  CPPUNIT_ASSERT_EQUAL(8,it1[0].first); CPPUNIT_ASSERT_EQUAL(9,it1[0].second);
+  CPPUNIT_ASSERT_EQUAL(18,it1[1].first); CPPUNIT_ASSERT_EQUAL(19,it1[1].second);
+  std::vector< std::pair<int,int> > it2=MEDLoader::GetCellFieldIterations(fileName,name2,name1);
+  CPPUNIT_ASSERT_EQUAL(3,(int)it2.size());
+  CPPUNIT_ASSERT_EQUAL(28,it2[0].first); CPPUNIT_ASSERT_EQUAL(29,it2[0].second);
+  CPPUNIT_ASSERT_EQUAL(38,it2[1].first); CPPUNIT_ASSERT_EQUAL(39,it2[1].second);
+  CPPUNIT_ASSERT_EQUAL(48,it2[2].first); CPPUNIT_ASSERT_EQUAL(49,it2[2].second);
+  std::vector< std::pair<int,int> > it3=MEDLoader::GetNodeFieldIterations(fileName,name2,name1);
+  CPPUNIT_ASSERT_EQUAL(3,(int)it3.size());
+  CPPUNIT_ASSERT_EQUAL(8,it3[0].first); CPPUNIT_ASSERT_EQUAL(9,it3[0].second);
+  CPPUNIT_ASSERT_EQUAL(108,it3[1].first); CPPUNIT_ASSERT_EQUAL(109,it3[1].second);
+  CPPUNIT_ASSERT_EQUAL(208,it3[2].first); CPPUNIT_ASSERT_EQUAL(209,it3[2].second);
+  std::vector< std::pair<int,int> > it4=MEDLoader::GetNodeFieldIterations(fileName,name3,name1);
+  CPPUNIT_ASSERT(it4.empty());
+  //
+  f1->decrRef();
+  //
+  f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,8,9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[0],1e-13);
+  f1->decrRef();
+  f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,18,19);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[0],1e-13);
+  f1->decrRef();
+  f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,28,29);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13);
+  f1->decrRef();
+  f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,38,39);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13);
+  f1->decrRef();
+  f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,48,49);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13);
+  f1->decrRef();
+  //
+  f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,8,9);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13);
+  f1->decrRef();
+  f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,108,109);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13);
+  f1->decrRef();
+  f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,208,209);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[3],1e-13);
+  f1->decrRef();
+}
+
+void MEDLoaderTest::testMultiMeshRW1()
+{
+  const char fileName[]="file10.med";
+  MEDCouplingUMesh *mesh1=build3DMesh_1();
+  const int part1[5]={1,2,4,13,15};
+  MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true);
+  mesh2->setName("mesh2");
+  const int part2[4]={3,4,13,14};
+  MEDCouplingUMesh *mesh3=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part2,part2+4,true);
+  mesh3->setName("mesh3");
+  MEDCouplingUMesh *mesh4=MEDCouplingUMesh::New();
+  mesh4->setName("mesh4");
+  mesh4->setMeshDimension(3);
+  mesh4->allocateCells(1);
+  int conn[4]={0,11,1,3};
+  mesh4->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn);
+  mesh4->finishInsertingCells();
+  mesh4->setCoords(mesh1->getCoords());
+  std::vector<MEDCouplingUMesh *> meshes;
+  meshes.push_back(mesh1);
+  meshes.push_back(mesh2);
+  meshes.push_back(mesh3);
+  meshes.push_back(mesh4);
+  const char mnane[]="3DToto";
+  MEDLoader::WriteUMeshesPartition(fileName,mnane,meshes,true);
+  //
+  MEDCouplingUMesh *mesh5=MEDLoader::ReadUMeshFromFile(fileName,mnane);
+  mesh1->setName(mnane);
+  const int part3[18]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
+  MEDCouplingUMesh *mesh6=(MEDCouplingUMesh *)mesh5->buildPartOfMySelf(part3,part3+18,true);
+  mesh6->setName(mnane);
+  mesh5->decrRef();
+  CPPUNIT_ASSERT(mesh6->isEqual(mesh1,1e-12));
+  mesh6->decrRef();
+  std::vector<std::string> grps=MEDLoader::GetMeshGroupsNames(fileName,mnane);
+  CPPUNIT_ASSERT_EQUAL(4,(int)grps.size());
+  CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh2"))!=grps.end());
+  CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh3"))!=grps.end());
+  CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh4"))!=grps.end());
+  CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("3DMesh_1"))!=grps.end());
+  //
+  std::vector<std::string> vec;
+  vec.push_back(std::string("mesh2"));
+  MEDCouplingUMesh *mesh2_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec);
+  CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12));
+  mesh2_2->decrRef();
+  vec.clear(); vec.push_back(std::string("mesh3"));
+  MEDCouplingUMesh *mesh3_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec);
+  CPPUNIT_ASSERT(mesh3_2->isEqual(mesh3,1e-12));
+  mesh3_2->decrRef();
+  vec.clear(); vec.push_back(std::string("mesh4"));
+  MEDCouplingUMesh *mesh4_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec);
+  CPPUNIT_ASSERT(mesh4_2->isEqual(mesh4,1e-12));
+  mesh4_2->decrRef();
+  vec.clear(); vec.push_back(std::string("3DMesh_1"));
+  MEDCouplingUMesh *mesh1_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec);
+  mesh1->setName("3DMesh_1");
+  CPPUNIT_ASSERT(mesh1_2->isEqual(mesh1,1e-12));
+  mesh1_2->decrRef();
+  //
+  vec.clear(); vec.push_back(std::string("Family_4")); vec.push_back(std::string("Family_2"));
+  mesh2_2=MEDLoader::ReadUMeshFromFamilies(fileName,mnane,0,vec);
+  mesh2_2->setName("mesh2");
+  CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12));
+  mesh2_2->decrRef();
+  //
+  mesh4->decrRef();
+  mesh3->decrRef();
+  mesh2->decrRef();
+  mesh1->decrRef();
+}
+
+void MEDLoaderTest::testFieldProfilRW1()
+{
+  const char fileName[]="file12.med";
+  MEDCouplingUMesh *mesh1=build3DMesh_1();
+  bool b;
+  int newNbOfNodes;
+  DataArrayInt *da=mesh1->mergeNodes(1e-12,b,newNbOfNodes);
+  da->decrRef();
+  MEDLoader::WriteUMesh(fileName,mesh1,true);
+  const int part1[5]={1,2,4,13,15};
+  MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true);
+  mesh2->setName(mesh1->getName());//<- important for the test
+  //
+  int nbOfCells=mesh2->getNumberOfCells();
+  CPPUNIT_ASSERT_EQUAL(5,nbOfCells);
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setName("VectorFieldOnCells");
+  f1->setMesh(mesh2);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(nbOfCells,2);
+  f1->setArray(array);
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.};
+  std::copy(arr1,arr1+10,tmp);
+  f1->setTime(3.14,2,7);
+  f1->checkCoherency();
+  //
+  MEDLoader::WriteField(fileName,f1,false);//<- false important for the test
+  //
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7);
+  f2->checkCoherency();
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  //
+  f2->decrRef();
+  f1->decrRef();
+  mesh1->decrRef();
+  mesh2->decrRef();
+}
+
+void MEDLoaderTest::testFieldNodeProfilRW1()
+{
+  const char fileName[]="file19.med";
+  const char fileName2[]="file20.med";
+  MEDCouplingUMesh *m=build2DMesh_1();
+  int nbOfNodes=m->getNumberOfNodes();
+  MEDLoader::WriteUMesh(fileName,m,true);
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
+  f1->setName("VFieldOnNodes");
+  f1->setMesh(m);
+  DataArrayDouble *array=DataArrayDouble::New();
+  const double arr1[24]={1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.};
+  array->alloc(nbOfNodes,2);
+  std::copy(arr1,arr1+24,array->getPointer());
+  f1->setArray(array);
+  array->setInfoOnComponent(0,"tyty (mm)");
+  array->setInfoOnComponent(1,"uiop (MW)");
+  array->decrRef();
+  f1->setTime(3.14,2,7);
+  f1->checkCoherency();
+  const int arr2[6]={2,4,5,3,6,7};
+  MEDCouplingFieldDouble *f2=f1->buildSubPart(arr2,arr2+6);
+  ((MEDCouplingMesh *)f2->getMesh())->setName(f1->getMesh()->getName());
+  MEDLoader::WriteField(fileName,f2,false);//<- false important for the test
+  //
+  MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f2->getMesh()->getName(),0,f2->getName(),2,7);
+  f3->checkCoherency();
+  CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12));
+  f3->decrRef();
+  //
+  const int arr3[6]={1,3,0,5,2,4};
+  f2->renumberNodes(arr3);
+  MEDLoader::WriteUMesh(fileName2,m,true);
+  MEDLoader::WriteField(fileName2,f2,false);//<- false important for the test
+  f3=MEDLoader::ReadFieldNode(fileName2,f2->getMesh()->getName(),0,f2->getName(),2,7);
+  f3->checkCoherency();
+  CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12));
+  f3->decrRef();
+  f2->decrRef();
+  //
+  f1->decrRef();
+  m->decrRef();
+}
+
+void MEDLoaderTest::testFieldNodeProfilRW2()
+{
+  const char fileName[]="file23.med";
+  MEDCouplingUMesh *mesh=build3DSurfMesh_1();
+  MEDLoader::WriteUMesh(fileName,mesh,true);
+  //
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
+  f1->setName("FieldMix");
+  f1->setMesh(mesh);
+  const double arr2[24]={
+    1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150.,
+    1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.
+  };
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(12,2);
+  f1->setArray(array);
+  array->setInfoOnComponent(0,"plkj (mm)");
+  array->setInfoOnComponent(1,"pqqqss (mm)");
+  array->decrRef();
+  double *tmp=array->getPointer();
+  std::copy(arr2,arr2+24,tmp);
+  f1->setTime(3.17,2,7);
+  //
+  const int renumArr[12]={3,7,2,1,5,11,10,0,9,6,8,4};
+  f1->renumberNodes(renumArr);
+  f1->checkCoherency();
+  MEDLoader::WriteField(fileName,f1,false);//<- false important for the test
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7);
+  CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12));
+  //
+  f2->decrRef();
+  mesh->decrRef();
+  f1->decrRef();
+}
+
+void MEDLoaderTest::testFieldGaussRW1()
+{
+  const char fileName[]="file13.med";
+  MEDCouplingFieldDouble *f1=buildVecFieldOnGauss_1();
+  MEDLoader::WriteField(fileName,f1,true);
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_PT,fileName,f1->getMesh()->getName(),0,f1->getName(),1,5);
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  f2->decrRef();
+  f1->decrRef();
+}
+
+void MEDLoaderTest::testFieldGaussNERW1()
+{
+  const char fileName[]="file14.med";
+  MEDCouplingFieldDouble *f1=buildVecFieldOnGaussNE_1();
+  MEDLoader::WriteField(fileName,f1,true);
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_NE,fileName,f1->getMesh()->getName(),0,f1->getName(),1,5);
+  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
+  f2->decrRef();
+  f1->decrRef();
+}
+
+void MEDLoaderTest::testLittleStrings1()
+{
+  std::string s("azeeeerrrtty");
+  MEDLoaderBase::zipEqualConsChar(s,3);
+  CPPUNIT_ASSERT(s=="azertty");
+}
+
+void MEDLoaderTest::testMesh3DSurfShuffleRW()
+{
+  const char fileName[]="file15.med";
+  MEDCouplingUMesh *mesh=build3DSurfMesh_1();
+  const int renumber1[6]={2,5,1,0,3,4};
+  mesh->renumberCells(renumber1,false);
+  mesh->checkCoherency();
+  MEDLoader::WriteUMesh(fileName,mesh,true);
+  MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(fileName,mesh->getName(),0);
+  CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
+  mesh_rw->decrRef();
+  mesh->decrRef();
+}
+
+void MEDLoaderTest::testFieldShuffleRW1()
+{
+  const char fileName[]="file16.med";
+  MEDCouplingUMesh *mesh=build3DSurfMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setName("FieldOnCellsShuffle");
+  f1->setMesh(mesh);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(6,2);
+  f1->setArray(array);
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.};
+  std::copy(arr1,arr1+12,tmp);
+  f1->setTime(3.14,2,7);
+  f1->checkCoherency();
+  //
+  const int renumber1[6]={2,1,5,0,3,4};
+  f1->renumberCells(renumber1,false);
+  MEDLoader::WriteField(fileName,f1,true);
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,mesh->getName(),0,f1->getName(),2,7);
+  CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12));
+  f2->decrRef();
+  //
+  mesh->decrRef();
+  f1->decrRef();
+}
+
+void MEDLoaderTest::testMultiFieldShuffleRW1()
+{
+  const char fileName[]="file17.med";
+  MEDCouplingUMesh *m=build3DMesh_2();
+  CPPUNIT_ASSERT_EQUAL(20,m->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(45,m->getNumberOfNodes());
+  const int polys[3]={1,4,6};
+  std::vector<int> poly2(polys,polys+3);
+  m->convertToPolyTypes(poly2);
+  const int renum[20]={1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11};
+  m->renumberCells(renum,false);
+  m->orientCorrectlyPolyhedrons();
+  // Writing
+  MEDLoader::WriteUMesh(fileName,m,true);
+  MEDCouplingFieldDouble *f1Tmp=m->getMeasureField(false);
+  MEDCouplingFieldDouble *f1=f1Tmp->buildNewTimeReprFromThis(ONE_TIME,false);
+  f1Tmp->decrRef();
+  f1->setTime(0.,1,2);
+  MEDCouplingFieldDouble *f_1=f1->cloneWithMesh(true);
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->applyFunc("2*x");
+  f1->setTime(0.01,3,4);
+  MEDCouplingFieldDouble *f_2=f1->cloneWithMesh(true);
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->applyFunc("2*x/3");
+  f1->setTime(0.02,5,6);
+  MEDCouplingFieldDouble *f_3=f1->cloneWithMesh(true);
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->decrRef();
+  // Reading
+  std::vector<std::pair<int,int> > its;
+  its.push_back(std::pair<int,int>(1,2));
+  its.push_back(std::pair<int,int>(3,4));
+  its.push_back(std::pair<int,int>(5,6));
+  std::vector<MEDCouplingFieldDouble *> fs=MEDLoader::ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1->getMesh()->getName(),0,f_1->getName(),its);
+  CPPUNIT_ASSERT_EQUAL(3,(int)fs.size());
+  const MEDCouplingMesh *mm=fs[0]->getMesh();
+  CPPUNIT_ASSERT(fs[0]->isEqual(f_1,1e-12,1e-12));
+  CPPUNIT_ASSERT(fs[1]->isEqual(f_2,1e-12,1e-12));
+  CPPUNIT_ASSERT(fs[2]->isEqual(f_3,1e-12,1e-12));
+  CPPUNIT_ASSERT(mm==fs[1]->getMesh());// <- important for the test
+  CPPUNIT_ASSERT(mm==fs[2]->getMesh());// <- important for the test
+  for(std::vector<MEDCouplingFieldDouble *>::iterator iter=fs.begin();iter!=fs.end();iter++)
+    (*iter)->decrRef();
+  //
+  f_1->decrRef();
+  f_2->decrRef();
+  f_3->decrRef();
+  //
+  m->decrRef();
+}
+
+void MEDLoaderTest::testWriteUMeshesRW1()
+{
+  const char fileName[]="file18.med";
+  MEDCouplingUMesh *m3d=build3DMesh_2();
+  const double pt[3]={0.,0.,-0.3};
+  const double vec[3]={0.,0.,1.};
+  std::vector<int> nodes;
+  m3d->findNodesOnPlane(pt,vec,1e-12,nodes);
+  MEDCouplingUMesh *m2d=(MEDCouplingUMesh *)m3d->buildFacePartOfMySelfNode(&nodes[0],&nodes[0]+nodes.size(),true);
+  const int renumber[5]={1,2,0,4,3};
+  m2d->renumberCells(renumber,false);
+  m2d->setName("ExampleOfMultiDimW");
+  std::vector<const MEDCouplingUMesh *> meshes;
+  meshes.push_back(m2d);
+  meshes.push_back(m3d);
+  MEDLoader::WriteUMeshes(fileName,meshes,true);
+  MEDCouplingUMesh *m3d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName(),0);
+  CPPUNIT_ASSERT(!m3d_bis->isEqual(m3d,1e-12));
+  m3d_bis->setName(m3d->getName());
+  CPPUNIT_ASSERT(m3d_bis->isEqual(m3d,1e-12));
+  MEDCouplingUMesh *m2d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName(),-1);//-1 for faces
+  CPPUNIT_ASSERT(m2d_bis->isEqual(m2d,1e-12));
+  // Creation of a field on faces.
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setName("FieldOnFacesShuffle");
+  f1->setMesh(m2d);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(m2d->getNumberOfCells(),2);
+  array->setInfoOnComponent(0,"plkj (mm)");
+  array->setInfoOnComponent(1,"pqqqss (mm)");
+  f1->setArray(array);
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.};
+  std::copy(arr1,arr1+10,tmp);
+  f1->setTime(3.14,2,7);
+  f1->checkCoherency();
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),-1,f1->getName(),2,7);
+  CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12));
+  f1->decrRef();
+  f2->decrRef();
+  //
+  m2d_bis->decrRef();
+  m3d_bis->decrRef();
+  m2d->decrRef();
+  m3d->decrRef();
+}
+
+void MEDLoaderTest::testMixCellAndNodesFieldRW1()
+{
+  const char fileName[]="file21.med";
+  MEDCouplingUMesh *mesh=build3DSurfMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setName("FieldMix");
+  f1->setMesh(mesh);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(6,2);
+  f1->setArray(array);
+  array->setInfoOnComponent(0,"plkj (mm)");
+  array->setInfoOnComponent(1,"pqqqss (mm)");
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.};
+  std::copy(arr1,arr1+12,tmp);
+  f1->setTime(3.14,2,7);
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
+  f2->setName("FieldMix");
+  f2->setMesh(mesh);
+  array=DataArrayDouble::New();
+  array->alloc(12,2);
+  f2->setArray(array);
+  array->setInfoOnComponent(0,"plkj (mm)");
+  array->setInfoOnComponent(1,"pqqqss (mm)");
+  array->decrRef();
+  tmp=array->getPointer();
+  const double arr2[24]={
+    1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150.,
+    1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.
+  };
+  std::copy(arr2,arr2+24,tmp);
+  f2->setTime(3.17,2,7);
+  f2->checkCoherency();
+  //
+  MEDLoader::WriteField(fileName,f1,true);
+  std::vector<ParaMEDMEM::TypeOfField> ts=MEDLoader::GetTypesOfField(fileName,f1->getName(),f1->getMesh()->getName());
+  CPPUNIT_ASSERT_EQUAL(1,(int)ts.size());
+  CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[0]);
+  std::vector<std::string> fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName());
+  CPPUNIT_ASSERT_EQUAL(1,(int)fs.size());
+  CPPUNIT_ASSERT(fs[0]=="FieldMix");
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f2);
+  fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName());
+  CPPUNIT_ASSERT_EQUAL(1,(int)fs.size());
+  CPPUNIT_ASSERT(fs[0]=="FieldMix");
+  //
+  ts=MEDLoader::GetTypesOfField(fileName,f1->getName(),f1->getMesh()->getName());
+  CPPUNIT_ASSERT_EQUAL(2,(int)ts.size());
+  CPPUNIT_ASSERT_EQUAL(ON_NODES,ts[0]);
+  CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[1]);
+  //
+  MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7);
+  CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12));
+  f3->decrRef();
+  f3=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7);
+  CPPUNIT_ASSERT(f3->isEqual(f1,1e-12,1e-12));
+  f3->decrRef();
+  //
+  f1->decrRef();
+  f2->decrRef();
+  mesh->decrRef();
+}
+
+void MEDLoaderTest::testGetAllFieldNamesRW1()
+{
+  const char fileName[]="file22.med";
+  MEDCouplingUMesh *mesh=build2DMesh_2();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
+  f1->setName("Field1");
+  f1->setTime(3.44,5,6);
+  f1->setMesh(mesh);
+  f1->fillFromAnalytic(2,"x+y");
+  MEDLoader::WriteField(fileName,f1,true);
+  f1->setTime(1002.3,7,8);
+  f1->fillFromAnalytic(2,"x+77.*y");
+  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
+  f1->setName("Field2");
+  MEDLoader::WriteField(fileName,f1,false);
+  f1->setName("Field3");
+  mesh->setName("2DMesh_2Bis");
+  MEDLoader::WriteField(fileName,f1,false);
+  f1->decrRef();
+  f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setName("Field8");
+  f1->setTime(8.99,7,9);
+  f1->setMesh(mesh);
+  f1->fillFromAnalytic(3,"3*x+y");
+  MEDLoader::WriteField(fileName,f1,false);
+  f1->decrRef();
+  std::vector<std::string> fs=MEDLoader::GetAllFieldNames(fileName);
+  CPPUNIT_ASSERT_EQUAL(4,(int)fs.size());
+  CPPUNIT_ASSERT(fs[0]=="Field1");
+  CPPUNIT_ASSERT(fs[1]=="Field2");
+  CPPUNIT_ASSERT(fs[2]=="Field3");
+  CPPUNIT_ASSERT(fs[3]=="Field8");
+  mesh->decrRef();
+}
+
+MEDCouplingUMesh *MEDLoaderTest::build1DMesh_1()
+{
+  double coords[6]={ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 };
+  int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5};
+  MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
+  mesh->setName("1DMesh_1");
+  mesh->setMeshDimension(1);
+  mesh->allocateCells(4);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6);
+  mesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(6,1);
+  myCoords->setInfoOnComponent(0,"tototototototot (m*m*m*m*m*m*m*m)");
+  std::copy(coords,coords+6,myCoords->getPointer());
+  mesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return mesh;
+}
+
+MEDCouplingUMesh *MEDLoaderTest::build2DCurveMesh_1()
+{
+  double coords[12]={ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 };
+  int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5};
+  MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
+  mesh->setName("2DCurveMesh_1");
+  mesh->setMeshDimension(1);
+  mesh->allocateCells(4);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6);
+  mesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(6,2);
+  std::copy(coords,coords+12,myCoords->getPointer());
+  mesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return mesh;
+}
+
+MEDCouplingUMesh *MEDLoaderTest::build2DMesh_1()
+{
+  double targetCoords[24]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, -0.05,0.95, 0.2,1.2, 0.45,0.95 };
+  int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4};
+  MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
+  targetMesh->setMeshDimension(2);
+  targetMesh->allocateCells(6);
+  targetMesh->setName("2DMesh_1");
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20);
+  targetMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(12,2);
+  myCoords->setInfoOnComponent(0,"tototototototot (m)");
+  myCoords->setInfoOnComponent(1,"energie (kW)");
+  std::copy(targetCoords,targetCoords+24,myCoords->getPointer());
+  targetMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return targetMesh;
+}
+
+MEDCouplingUMesh *MEDLoaderTest::build2DMesh_2()
+{
+  double targetCoords[24]={
+    -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7,
+    -0.05,0.95, 0.2,1.2, 0.45,0.95
+  };
+  int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4};
+  MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
+  targetMesh->setMeshDimension(2);
+  targetMesh->allocateCells(5);
+  targetMesh->setName("2DMesh_2");
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16);
+  targetMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(12,2);
+  myCoords->setInfoOnComponent(0,"toto (m)");
+  myCoords->setInfoOnComponent(1,"energie (kW)");
+  std::copy(targetCoords,targetCoords+24,myCoords->getPointer());
+  targetMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return targetMesh;
+}
+
+MEDCouplingUMesh *MEDLoaderTest::build3DSurfMesh_1()
+{
+  double targetCoords[36]={
+    -0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3
+    ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3
+  };
+  int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4};
+  MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
+  targetMesh->setMeshDimension(2);
+  targetMesh->allocateCells(6);
+  targetMesh->setName("3DSurfMesh_1");
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20);
+  targetMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(12,3);
+  myCoords->setInfoOnComponent(0,"toto (m)");
+  myCoords->setInfoOnComponent(2,"ff (km)");//component 1 is not set for test
+  std::copy(targetCoords,targetCoords+36,myCoords->getPointer());
+  targetMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return targetMesh;
+}
+
+MEDCouplingUMesh *MEDLoaderTest::build3DMesh_1()
+{
+  double coords[180]={
+    0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0.,
+    3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0.,
+    0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1.,
+    3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1.,
+    0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2.,
+    3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2.,
+    0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3.,
+    3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.};
+
+  int conn[354]={
+    // 0
+    0,11,1,3,15,26,16,18,   1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17,
+    1,6,5,3,16,21,20,18,   13,10,9,6,28,25,24,21,
+    11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23,
+    7,12,14,13,22,27,29,28,
+    // 1
+    15,26,16,18,30,41,31,33,   16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32,
+    16,21,20,18,31,36,35,33,   28,25,24,21,43,40,39,36,
+    26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38,
+    22,27,29,28,37,42,44,43,
+    // 2
+    30,41,31,33,45,56,46,48,  31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47,
+    31,36,35,33,46,51,50,48,  43,40,39,36,58,55,54,51,
+    41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53,
+    37,42,44,43,52,57,59,58
+  };
+  //
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
+  ret->setName("3DMesh_1");
+  ret->setMeshDimension(3);
+  ret->allocateCells(18);
+  //
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110);
+  //
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228);
+  //
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295);
+  ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346);
+  //
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8);
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67);
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126);
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185);
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244);
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303);
+  //
+  ret->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(60,3);
+  myCoords->setInfoOnComponent(0,"titi (m)");
+  myCoords->setInfoOnComponent(1,"density power (MW/m^3)");
+  myCoords->setInfoOnComponent(2,"t (kW)");
+  std::copy(coords,coords+180,myCoords->getPointer());
+  ret->setCoords(myCoords);
+  myCoords->decrRef();
+  return ret;
+}
+
+MEDCouplingUMesh *MEDLoaderTest::build3DMesh_2()
+{
+  MEDCouplingUMesh *m3dsurfBase=build3DSurfMesh_1();
+  int numbers[5]={0,1,3,4,5};
+  MEDCouplingUMesh *m3dsurf=(MEDCouplingUMesh *)m3dsurfBase->buildPartOfMySelf(numbers,numbers+5,false);
+  m3dsurfBase->decrRef();
+  MEDCouplingUMesh *m1dBase=build1DMesh_1();
+  int numbers2[4]={0,1,2,3};
+  MEDCouplingUMesh *m1d=(MEDCouplingUMesh *)m1dBase->buildPartOfMySelf(numbers2,numbers2+4,false);
+  m1dBase->decrRef();
+  m1d->changeSpaceDimension(3);
+  const double vec[3]={0.,1.,0.};
+  const double pt[3]={0.,0.,0.};
+  m1d->rotate(pt,vec,-M_PI/2.);
+  MEDCouplingUMesh *ret=m3dsurf->buildExtrudedMeshFromThis(m1d,0);
+  m1d->decrRef();
+  m3dsurf->decrRef();
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnCells_1()
+{
+  MEDCouplingUMesh *mesh=build3DSurfMesh_1();
+  int nbOfCells=mesh->getNumberOfCells();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setName("VectorFieldOnCells");
+  f1->setMesh(mesh);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(nbOfCells,3);
+  array->setInfoOnComponent(0,"power (MW/m^3)");
+  array->setInfoOnComponent(1,"density (g/cm^3)");
+  array->setInfoOnComponent(2,"temperature (K)");
+  f1->setArray(array);
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[18]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.};
+  std::copy(arr1,arr1+18,tmp);
+  f1->setTime(2.,0,1);
+  f1->checkCoherency();
+  mesh->decrRef();
+  return f1;
+}
+
+MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnNodes_1()
+{
+  MEDCouplingUMesh *mesh=build3DSurfMesh_1();
+  int nbOfNodes=mesh->getNumberOfNodes();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
+  f1->setName("VectorFieldOnNodes");
+  f1->setMesh(mesh);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(nbOfNodes,3);
+  f1->setArray(array);
+  array->setInfoOnComponent(0,"power (MW/m^3)");
+  array->setInfoOnComponent(1,"density (g/cm^3)");
+  array->setInfoOnComponent(2,"temperature (K)");
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[36]={
+    70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95.,
+    1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025.,
+  };
+  std::copy(arr1,arr1+36,tmp);
+  f1->setTime(2.12,2,3);
+  f1->checkCoherency();
+  mesh->decrRef();
+  return f1;
+}
+
+MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGauss_1()
+{
+  const double _a=0.446948490915965;
+  const double _b=0.091576213509771;
+  const double _p1=0.11169079483905;
+  const double _p2=0.0549758718227661;
+  const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. };
+  const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b,
+                            2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 };
+  const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 };
+  std::vector<double> _refCoo1(refCoo1,refCoo1+6);
+  std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12);
+  std::vector<double> _wg1(wg1,wg1+6);
+  MEDCouplingUMesh *m=build2DMesh_2();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME);
+  f->setTime(3.14,1,5);
+  f->setMesh(m);
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+  const double refCoo2[12]={-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 };
+  std::vector<double> _refCoo2(refCoo2,refCoo2+12);
+  _gsCoo1.resize(6); _wg1.resize(3);
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,_refCoo2,_gsCoo1,_wg1);
+  const double refCoo3[8]={ 0.,0., 1.,0., 1.,1., 0.,1. };
+  std::vector<double> _refCoo3(refCoo3,refCoo3+8);
+  _gsCoo1.resize(4); _wg1.resize(2);
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo3,_gsCoo1,_wg1);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(19,2);
+  double *ptr=array->getPointer();
+  for(int i=0;i<19*2;i++)
+    ptr[i]=(double)(i+7);
+  f->setArray(array);
+  f->setName("MyFirstFieldOnGaussPoint");
+  array->setInfoOnComponent(0,"power (MW/m^3)");
+  array->setInfoOnComponent(1,"density");
+  array->decrRef();
+  f->checkCoherency();
+  m->decrRef();
+  return f;
+}
+
+MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGaussNE_1()
+{
+  MEDCouplingUMesh *m=build2DMesh_2();
+  MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME);
+  f->setTime(3.14,1,5);
+  f->setMesh(m);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(20,2);
+  double *ptr=array->getPointer();
+  for(int i=0;i<20*2;i++)
+    ptr[i]=(double)(i+8);
+  f->setArray(array);
+  array->setInfoOnComponent(0,"power (W)");
+  array->setInfoOnComponent(1,"temperature");
+  f->setName("MyFieldOnGaussNE");
+  array->decrRef();
+  f->checkCoherency();
+  m->decrRef();
+  return f;
+}
+
diff --git a/src/MEDLoader/Test/MEDLoaderTest.hxx b/src/MEDLoader/Test/MEDLoaderTest.hxx
new file mode 100644 (file)
index 0000000..aa17ea3
--- /dev/null
@@ -0,0 +1,92 @@
+//  Copyright (C) 2007-2010  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 __MEDLOADERTEST_HXX__
+#define __MEDLOADERTEST_HXX__
+
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace ParaMEDMEM
+{
+  class MEDCouplingUMesh;
+  class MEDCouplingFieldDouble;
+
+  class MEDLoaderTest : public CppUnit::TestFixture
+  {
+    CPPUNIT_TEST_SUITE(MEDLoaderTest);
+    CPPUNIT_TEST( testMesh1DRW );
+    CPPUNIT_TEST( testMesh2DCurveRW );
+    CPPUNIT_TEST( testMesh2DRW );
+    CPPUNIT_TEST( testMesh3DSurfRW );
+    CPPUNIT_TEST( testMesh3DRW );
+    CPPUNIT_TEST( testFieldRW1 );
+    CPPUNIT_TEST( testFieldRW2 );
+    CPPUNIT_TEST( testFieldRW3 );
+    CPPUNIT_TEST( testMultiMeshRW1 );
+    CPPUNIT_TEST( testFieldProfilRW1 );
+    CPPUNIT_TEST( testFieldNodeProfilRW1 );
+    CPPUNIT_TEST( testFieldNodeProfilRW2 );
+    CPPUNIT_TEST( testFieldGaussRW1 );
+    CPPUNIT_TEST( testFieldGaussNERW1 );
+    CPPUNIT_TEST( testLittleStrings1 );
+    CPPUNIT_TEST( testMesh3DSurfShuffleRW );
+    CPPUNIT_TEST( testFieldShuffleRW1 );
+    CPPUNIT_TEST( testMultiFieldShuffleRW1 );
+    CPPUNIT_TEST( testWriteUMeshesRW1 );
+    CPPUNIT_TEST( testMixCellAndNodesFieldRW1 );
+    CPPUNIT_TEST( testGetAllFieldNamesRW1 );
+    CPPUNIT_TEST_SUITE_END();
+  public:
+    void testMesh1DRW();
+    void testMesh2DCurveRW();
+    void testMesh2DRW();
+    void testMesh3DSurfRW();
+    void testMesh3DRW();
+    void testFieldRW1();
+    void testFieldRW2();
+    void testFieldRW3();
+    void testMultiMeshRW1();
+    void testFieldProfilRW1();
+    void testFieldNodeProfilRW1();
+    void testFieldNodeProfilRW2();
+    void testFieldGaussRW1();
+    void testFieldGaussNERW1();
+    void testLittleStrings1();
+    void testMesh3DSurfShuffleRW();
+    void testFieldShuffleRW1();
+    void testMultiFieldShuffleRW1();
+    void testWriteUMeshesRW1();
+    void testMixCellAndNodesFieldRW1();
+    void testGetAllFieldNamesRW1();
+  private:
+    MEDCouplingUMesh *build1DMesh_1();
+    MEDCouplingUMesh *build2DCurveMesh_1();
+    MEDCouplingUMesh *build2DMesh_1();
+    MEDCouplingUMesh *build2DMesh_2();
+    MEDCouplingUMesh *build3DSurfMesh_1();
+    MEDCouplingUMesh *build3DMesh_1();
+    MEDCouplingUMesh *build3DMesh_2();
+    MEDCouplingFieldDouble *buildVecFieldOnCells_1();
+    MEDCouplingFieldDouble *buildVecFieldOnNodes_1();
+    MEDCouplingFieldDouble *buildVecFieldOnGauss_1();
+    MEDCouplingFieldDouble *buildVecFieldOnGaussNE_1();
+  };
+}
+
+#endif
diff --git a/src/MEDLoader/Test/Makefile.am b/src/MEDLoader/Test/Makefile.am
new file mode 100755 (executable)
index 0000000..46e1c40
--- /dev/null
@@ -0,0 +1,39 @@
+#  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+bin_PROGRAMS= TestMEDLoader
+
+TestMEDLoader_CPPFLAGS=@CPPUNIT_INCLUDES@ @PTHREAD_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../../INTERP_KERNEL/Bases -I$(srcdir)/../../INTERP_KERNELTest -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../INTERP_KERNEL/Geometric2D -I$(srcdir)/../../MEDCoupling
+
+TestMEDLoader_LDFLAGS = @CPPUNIT_LIBS@ ../libmedloader.la ../../MEDCoupling/libmedcoupling.la ../../INTERP_KERNEL/libinterpkernel.la
+
+dist_TestMEDLoader_SOURCES = TestMEDLoader.cxx MEDLoaderTest.cxx MEDLoaderTest.hxx
+
+UNIT_TEST_PROG = TestMEDLoader
+
+check : tests
+
+CLEANFILES = \
+        UnitTestsResult
+       
+clean-local:
+       rm -rf *.med
+       
\ No newline at end of file
diff --git a/src/MEDLoader/Test/TestMEDLoader.cxx b/src/MEDLoader/Test/TestMEDLoader.cxx
new file mode 100644 (file)
index 0000000..a48da92
--- /dev/null
@@ -0,0 +1,25 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "CppUnitTest.hxx"
+#include "MEDLoaderTest.hxx"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDLoaderTest );
+
+#include "BasicMainTest.hxx"
index 32bcc69ea1e71725e41520f90cfc3143a76df86a..4003b65fce0040b5d7205434d48b10882d2df07e 100644 (file)
@@ -84,42 +84,60 @@ namespace ParaMEDMEM
   {
     _union_group = source_group.fuse(target_group);  
   }
-
-  DEC::DEC(const int *src_ids_bg, const int *src_ids_end,
-           const int *trg_ids_bg, const int *trg_ids_end,
-           const MPI_Comm& world_comm):_local_field(0), 
-                                       _owns_field(false),
-                                       _owns_groups(true),
-                                       _icoco_field(0)
+  DEC::DEC(const std::set<int>& source_ids, const std::set<int>& target_ids, const MPI_Comm& world_comm):_local_field(0), 
+                                                                                                         _owns_field(false),
+                                                                                                         _owns_groups(true),
+                                                                                                         _icoco_field(0)
   {
     ParaMEDMEM::CommInterface comm;
     // Create the list of procs including source and target
-    int nbOfProcsInComm=std::distance(src_ids_bg,src_ids_end)+std::distance(trg_ids_bg,trg_ids_end);
-    int *allRanks=new int[nbOfProcsInComm];
-    std::copy(src_ids_bg,src_ids_end,allRanks);
-    std::copy(trg_ids_bg,trg_ids_end,allRanks+std::distance(src_ids_bg,src_ids_end));
+    std::set<int> union_ids; // source and target ids in world_comm
+    union_ids.insert(source_ids.begin(),source_ids.end());
+    union_ids.insert(target_ids.begin(),target_ids.end());
+    int* union_ranks_world=new int[union_ids.size()]; // ranks of sources and targets in world_comm
+    std::copy<std::set<int>::const_iterator,int*> (union_ids.begin(), union_ids.end(), union_ranks_world);
+
     // Create a communicator on these procs
-    MPI_Group src_trg_group, world_group;
+    MPI_Group union_group,world_group;
     comm.commGroup(world_comm,&world_group);
-    comm.groupIncl(world_group,nbOfProcsInComm,allRanks,&src_trg_group);
-    MPI_Comm src_trg_comm;
-    comm.commCreate(world_comm,src_trg_group,&src_trg_comm);
-    delete [] allRanks;
-    //
-    if(src_trg_comm==MPI_COMM_NULL)
-      {//Current procid is not part of src_trg_comm
+    comm.groupIncl(world_group,union_ids.size(),union_ranks_world,&union_group);
+    MPI_Comm union_comm;
+    comm.commCreate(world_comm,union_group,&union_comm);
+    delete[] union_ranks_world;
+
+    if (union_comm==MPI_COMM_NULL)
+      { // This process is not in union
         _source_group=0;
         _target_group=0;
         _union_group=0;
         return;
       }
-    std::set<int> source_ids(src_ids_bg,src_ids_end);
-    _source_group=new MPIProcessorGroup(comm,source_ids,src_trg_comm);
-    std::set<int> target_ids(trg_ids_bg,trg_ids_end);
-    _target_group=new MPIProcessorGroup(comm,target_ids,src_trg_comm);
-    std::set<int> src_trg_ids(src_ids_bg,src_ids_end);
-    src_trg_ids.insert(trg_ids_bg,trg_ids_end);
-    _union_group=new MPIProcessorGroup(comm,src_trg_ids,src_trg_comm);
+
+    // Translate source_ids and target_ids from world_comm to union_comm
+    int* source_ranks_world=new int[source_ids.size()]; // ranks of sources in world_comm
+    std::copy<std::set<int>::const_iterator,int*> (source_ids.begin(), source_ids.end(),source_ranks_world);
+    int* source_ranks_union=new int[source_ids.size()]; // ranks of sources in union_comm
+    int* target_ranks_world=new int[target_ids.size()]; // ranks of targets in world_comm
+    std::copy<std::set<int>::const_iterator,int*> (target_ids.begin(), target_ids.end(),target_ranks_world);
+    int* target_ranks_union=new int[target_ids.size()]; // ranks of targets in union_comm
+    MPI_Group_translate_ranks(world_group,source_ids.size(),source_ranks_world,union_group,source_ranks_union);
+    MPI_Group_translate_ranks(world_group,target_ids.size(),target_ranks_world,union_group,target_ranks_union);
+    std::set<int> source_ids_union;
+    for (int i=0;i<(int)source_ids.size();i++)
+      source_ids_union.insert(source_ranks_union[i]);
+    std::set<int> target_ids_union;
+    for (int i=0;i<(int)target_ids.size();i++)
+      target_ids_union.insert(target_ranks_union[i]);
+    delete [] source_ranks_world;
+    delete [] source_ranks_union;
+    delete [] target_ranks_world;
+    delete [] target_ranks_union;
+
+    // Create the MPIProcessorGroups
+    _source_group= new MPIProcessorGroup(comm,source_ids_union,union_comm);
+    _target_group = new MPIProcessorGroup(comm,target_ids_union,union_comm);
+    _union_group = _source_group->fuse(*_target_group);
+
   }
 
   DEC::~DEC()
index e6082516825fda38a8f3f3c23a2993197ca1b7e0..3c5ddf8fb72acdfb001f848234a521257303b2d3 100644 (file)
@@ -24,6 +24,8 @@
 #include "NormalizedUnstructuredMesh.hxx"
 #include "DECOptions.hxx"
 
+#include <set>
+
 namespace ICoCo
 {
   class Field;
@@ -39,8 +41,7 @@ namespace ParaMEDMEM
   public:
     DEC():_local_field(0) { }
     DEC(ProcessorGroup& source_group, ProcessorGroup& target_group);
-    DEC(const int *src_ids_bg, const int *src_ids_end,
-        const int *trg_ids_bg, const int *trg_ids_end,
+    DEC(const std::set<int>& src_ids, const std::set<int>& trg_ids,
         const MPI_Comm& world_comm=MPI_COMM_WORLD);
     void setNature(NatureOfField nature);
     void attachLocalField( MEDCouplingFieldDouble* field);
index e694c4e1dde10a72f455e5c44f57f3f3bdf90a72..3252279cdd67bc138703da2f271ff70a27aaa180 100644 (file)
@@ -35,7 +35,7 @@
 
 using namespace std;
 
-#define USE_DIRECTED_BB
+//#define USE_DIRECTED_BB
 
 namespace ParaMEDMEM 
 { 
@@ -299,14 +299,11 @@ namespace ParaMEDMEM
                             ptDist2, nbDistElem, MPI_DOUBLE,
                             iprocdistant_in_union, 1112, 
                             *comm, &status);
-    if(!distant_mesh_tmp->isEmptyMesh(tinyInfoDistant))
-      {
-        distant_mesh=distant_mesh_tmp;
-        //finish unserialization
-        distant_mesh->unserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts);
-      }
-    else
-      distant_mesh_tmp->decrRef();
+    //
+    distant_mesh=distant_mesh_tmp;
+    //finish unserialization
+    distant_mesh->unserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts);
+    //
     distant_ids_recv=new int[tinyInfoDistant.back()];
     comm_interface.sendRecv((void *)distant_ids_send->getConstPointer(),tinyInfoLocal.back(), MPI_INT,
                             iprocdistant_in_union, 1113,
index 7794ef15025a1eb6fb2c601756a16be55dd16df2..0d805af4f7f29439f658e14ca44a1d6c62e56706 100644 (file)
@@ -288,7 +288,7 @@ namespace ParaMEDMEM
           }
         int* recvcounts=new int[world_size];
         int* recvdispls=new int[world_size];
-        int *dummyrecv;
+        int *dummyrecv=0;
         for (int i=0; i <world_size; i++)
           {
             recvcounts[i]=0;
@@ -328,7 +328,7 @@ namespace ParaMEDMEM
               recvdispls[i]=recvdispls[i-1]+recvcounts[i-1];
           }
 
-        int *dummysend;
+        int *dummysend=0;
         for (int i=0; i <world_size; i++)
           {
             sendcounts[i]=0;
index 9733769211f9361fefcb5005a75d34d7445f3724..1251ee1d690bfe1fd928d6b1111f67241ef2d61a 100644 (file)
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-
-//////////////////////////////////////////////////////////////////////////////
-// File:        ICoCoField.cpp
-// Directory:   $TRIO_U_ROOT/Kernel/ICoCo
-// Version:     /main/1
-//////////////////////////////////////////////////////////////////////////////
+// ICoCo file common to several codes
+// ICoCoField.cpp
+// version 1.2 10/05/2010
 
 #include <ICoCoField.hxx>
 #include <string>
-#include <stdlib.h>
 
 using namespace ICoCo;
 using std::string;
index c9d2813f685b3885fab20f2dc14c77a03dccbacb..b38eb003437a56b4be1a04307ddb394d104683fa 100644 (file)
@@ -1,31 +1,15 @@
-//  Copyright (C) 2007-2010  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 __ICOCOFIELD_HXX__
-#define __ICOCOFIELD_HXX__
+// ICoCo file common to several codes
+// ICoCoField.h
+// version 1.2 10/05/2010
 
+#ifndef _ICoCoField_included_
+#define _ICoCoField_included_
 #include <string>
 
-namespace ICoCo
-{
-  class Field
-  {
+
+namespace ICoCo {
+
+  class Field {
   public:
     Field();
     virtual ~Field();
@@ -37,5 +21,4 @@ namespace ICoCo
     std::string* _name;
   };
 }
-
 #endif
index 1e5a14d227d05846812f874290fe0f44e60a16f8..0b18196c21b537f732a0b9494daf0658f3a28cf5 100644 (file)
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-
-//////////////////////////////////////////////////////////////////////////////
-// File:        ICoCoTrioField.cpp
-// Directory:   $TRIO_U_ROOT/Kernel/Framework
-// Version:     
-//////////////////////////////////////////////////////////////////////////////
+// ICoCo file common to several codes
+// ICoCoTrioField.cpp
+// version 1.2 10/05/2010
 
 #include <ICoCoTrioField.hxx>
 #include <string.h>
 #include <iostream>
-#include <stdlib.h>
+#include <iomanip>
 
 using namespace ICoCo;
 using namespace std;
 
+// Default constructor
 TrioField::TrioField() :
   _type(0),
+  _mesh_dim(0),
+  _space_dim(0),
+  _nbnodes(0),
+  _nodes_per_elem(0),
+  _nb_elems(0),
+  _itnumber(0),
   _connectivity(0),
   _coords(0),
+  _time1(0.),
+  _time2(0.),
+  _nb_field_components(0),
   _field(0),
   _has_field_ownership(false) { }
 
+// Copy constructor
+TrioField::TrioField(const TrioField& OtherField) {
+  (*this)=OtherField;
+}
+
+// Destructor
 TrioField::~TrioField() {
   clear();
 }
@@ -57,134 +70,124 @@ void TrioField::clear() {
   _has_field_ownership=false;
 }
 
-int TrioField::nb_values() const
-{
+// Returns the number of value locations
+// The size of field is nb_values()*_nb_field_components
+int TrioField::nb_values() const {
   if (_type==0)
     return _nb_elems;
-  else   
-    if (_type==1)
-      return _nbnodes;
-  exit(-1);
+  else if (_type==1)
+    return _nbnodes;
+  throw 0;
+  //exit(-1);
   return -1;
-  
 }
+
+// Save field to a .field file (loadable by visit!)
 void TrioField::save(ostream& os) const{
-  os <<getName()<<endl;
-  os<<_type<<endl;
-  os<<_mesh_dim<<endl;
-  os<< _space_dim<<endl;
-  os<< _nbnodes<<endl;
-  os<< _nodes_per_elem<<endl;
-  os<< _nb_elems<<endl;
+
+  os << setprecision(12);
+  os << getName() << endl;
+  os << _type << endl;
+  os << _mesh_dim << endl;
+  os << _space_dim << endl;
+  os << _nbnodes << endl;
+  os << _nodes_per_elem << endl;
+  os << _nb_elems << endl;
     
   os<< _itnumber<<endl;
-  for (int i=0;i<_nb_elems;i++) 
-    {
-      for (int j=0;j<_nodes_per_elem;j++)
-        os << " "<<_connectivity[i*_nodes_per_elem+j];
-      os<<endl;
-    }
-  
+  for (int i=0;i<_nb_elems;i++) {
+    for (int j=0;j<_nodes_per_elem;j++)
+      os << " " << _connectivity[i*_nodes_per_elem+j];
+    os<<endl;
+  }
   
-  for (int i=0;i<_nbnodes;i++) 
-    {
-      for (int j=0;j<_space_dim;j++)
-        os <<" "<< _coords[i*_space_dim+j] ;
-      os  << endl;
-    }
+  for (int i=0;i<_nbnodes;i++) {
+    for (int j=0;j<_space_dim;j++)
+      os << " " << _coords[i*_space_dim+j] ;
+    os << endl;
+  }
   
-  os<< _time1<<endl;
-  os<<_time2<<endl;
-  os<< _nb_field_components<<endl;
-  if (_field)
-    {
-      os <<1<<endl;
-      for (int i=0;i<nb_values();i++) 
-        {
-          for (int j=0;j<_nb_field_components;j++)
-            os <<" "<< _field[i*_nb_field_components+j];
-          os << endl;
-        }
+  os << _time1 << endl;
+  os << _time2 << endl;
+  os << _nb_field_components << endl;
+
+  if (_field) {
+    os << 1 << endl;
+    for (int i=0;i<nb_values();i++) {
+      for (int j=0;j<_nb_field_components;j++)
+        os << " " << _field[i*_nb_field_components+j];
+      os << endl;
     }
+  }
   else
-    {
-      os<<0<<endl;
-    }
-  os<< _has_field_ownership<<endl;
-}
+    os << 0 << endl;
 
+  os << _has_field_ownership << endl;
 
+}
 
+// Restore field from a .field file
 void TrioField::restore(istream& in) {
+
   string name;
   in >> name; 
   setName(name);
-  in>>_type;
-  in>>_mesh_dim;
-  in>> _space_dim;
-  in>> _nbnodes;
-  in>> _nodes_per_elem;
-  in>> _nb_elems;
+  in >> _type;
+  in >> _mesh_dim;
+  in >> _space_dim;
+  in >> _nbnodes;
+  in >> _nodes_per_elem;
+  in >> _nb_elems;
     
-  in>> _itnumber;
+  in >> _itnumber;
   if (_connectivity)
     delete [] _connectivity;
   _connectivity=new int[_nodes_per_elem*_nb_elems];
-  for (int i=0;i<_nb_elems;i++) 
-    {
-      for (int j=0;j<_nodes_per_elem;j++)
-        in>>_connectivity[i*_nodes_per_elem+j];
-      
-    }
+  for (int i=0;i<_nb_elems;i++) {
+    for (int j=0;j<_nodes_per_elem;j++)
+      in >> _connectivity[i*_nodes_per_elem+j];
+  }
   if (_coords)
     delete [] _coords;
   _coords=new double[_nbnodes*_space_dim];
-  for (int i=0;i<_nbnodes;i++) 
-    {
-      for (int j=0;j<_space_dim;j++)
-        in>> _coords[i*_space_dim+j] ;
-     
-    }
+  for (int i=0;i<_nbnodes;i++) {
+    for (int j=0;j<_space_dim;j++)
+      in >> _coords[i*_space_dim+j];
+  }
   
-  in>> _time1;
-  in>>_time2;
-  in>> _nb_field_components;
+  in >> _time1;
+  in >> _time2;
+  in >> _nb_field_components;
   int test;
-  in>> test;
-  if (test)
-    {
-      if (_field)
-        delete [] _field;
-      _field=new double[_nb_field_components*nb_values()];
-      for (int i=0;i<nb_values();i++) 
-        {
-          for (int j=0;j<_nb_field_components;j++)
-            in>> _field[i*_nb_field_components+j];
-         
-        }
+  in >> test;
+  if (test) {
+    if (_field)
+      delete [] _field;
+    _field=new double[_nb_field_components*nb_values()];
+    for (int i=0;i<nb_values();i++) {
+      for (int j=0;j<_nb_field_components;j++)
+        in>> _field[i*_nb_field_components+j];
     }
+  }
   else
-    {
-      _field=0;
-    }
-  in>> _has_field_ownership;
+    _field=0;
+
+  in >> _has_field_ownership;
 }
-   void TrioField::print() {
 
-  }
 
 // After the call to set_standalone(), field ownership is true and field is allocated
-// to the size _nb_field_components*_nb_elems.
+// to the size _nb_field_components*nb_values().
 // The values of the field have been copied if necessary.
 void TrioField::set_standalone() {
   if (!_field) {
-    _field=new double[_nb_field_components*_nb_elems];
+    _field=new double[_nb_field_components*nb_values()];
     _has_field_ownership=true;
     
   }
   else if (!_has_field_ownership) {
-    double *tmp_field=new double[_nb_field_components*_nb_elems];
-    memcpy(tmp_field,_field,_nb_field_components*_nb_elems*sizeof(double));
+    double *tmp_field=new double[_nb_field_components*nb_values()];
+    memcpy(tmp_field,_field,_nb_field_components*nb_values()*sizeof(double));
     _field=tmp_field;
     _has_field_ownership=true;
   }
@@ -192,6 +195,7 @@ void TrioField::set_standalone() {
 
 // Used to simulate a 0D geometry (Cathare/Trio for example).
 void TrioField::dummy_geom() {
+  _type=0;
   _mesh_dim=2;
   _space_dim=2;
   _nbnodes=3;
@@ -201,9 +205,9 @@ void TrioField::dummy_geom() {
   if (_connectivity)
     delete[] _connectivity;
   _connectivity=new int[3];
-  _connectivity[0]=1;
-  _connectivity[1]=2;
-  _connectivity[2]=3;
+  _connectivity[0]=0;
+  _connectivity[1]=1;
+  _connectivity[2]=2;
   if (_coords)
     delete[] _coords;
   _coords=new double[6];
@@ -213,53 +217,60 @@ void TrioField::dummy_geom() {
   _coords[3]=0;
   _coords[4]=0;
   _coords[5]=1;
+  _time1=0;
+  _time2=1;
+  _nb_field_components=1;
   if (_field && _has_field_ownership)
     delete[] _field;
   _has_field_ownership=false;
   _field=0;
 }
 
-// Surcharge de l'operateur = pour la classe TrioField
-// remplace les valeurs trouvee dans le TrioField donnee en parametre
+// Overloading operator = for TrioField
+// This becomes an exact copy of NewField.
+// If NewField._has_field_ownership is false, they point to the same values.
+// Otherwise the values are copied.
 TrioField& TrioField::operator=(const TrioField& NewField){
 
-    clear();
-    _type=NewField._type;
-    _mesh_dim=NewField._mesh_dim;
-    _space_dim=NewField._space_dim;
-    _nbnodes=NewField._nbnodes;
-    _nodes_per_elem=NewField._nodes_per_elem;
-    _nb_elems=NewField._nb_elems;
-    _itnumber=NewField._itnumber;
-      // std::string _name; // ?? Hérité de la classe mère
-    _time1=NewField._time1;
-    _time2=NewField._time2;
-    _nb_field_components=NewField._nb_field_components;
+  clear();
 
-    if (!NewField._connectivity)
-        _connectivity=0;
-    else {
-      _connectivity=new int[_nodes_per_elem*_nb_elems];
-      memcpy( _connectivity,NewField._connectivity,_nodes_per_elem*_nb_elems*sizeof(int));
-    }
+  _type=NewField._type;
+  _mesh_dim=NewField._mesh_dim;
+  _space_dim=NewField._space_dim;
+  _nbnodes=NewField._nbnodes;
+  _nodes_per_elem=NewField._nodes_per_elem;
+  _nb_elems=NewField._nb_elems;
+  _itnumber=NewField._itnumber;
+  _time1=NewField._time1;
+  _time2=NewField._time2;
+  _nb_field_components=NewField._nb_field_components;
 
-    if (!NewField._coords)
-        _coords=0;
-    else {
-       _coords=new double[_nbnodes*_space_dim];
-       memcpy( _coords,NewField._coords,_nbnodes*_space_dim*sizeof(double));
-    }
+  if (!NewField._connectivity)
+    _connectivity=0;
+  else {
+    _connectivity=new int[_nodes_per_elem*_nb_elems];
+    memcpy( _connectivity,NewField._connectivity,_nodes_per_elem*_nb_elems*sizeof(int));
+  }
 
-    //Copie des valeurs du champ
-    _has_field_ownership=NewField._has_field_ownership;
-    if (_has_field_ownership) {
-      _field=new double[_nb_elems*_nb_field_components];
-      memcpy(_field,NewField._field,_nb_elems*_nb_field_components*sizeof(double));
-    }
-    else
-      _field=NewField._field;
+  if (!NewField._coords)
+    _coords=0;
+  else {
+    _coords=new double[_nbnodes*_space_dim];
+    memcpy( _coords,NewField._coords,_nbnodes*_space_dim*sizeof(double));
+  }
 
-    return(*this);
+  //Copie des valeurs du champ
+  _has_field_ownership=NewField._has_field_ownership;
+  if (_has_field_ownership) {
+    _field=new double[nb_values()*_nb_field_components];
+    memcpy(_field,NewField._field,nb_values()*_nb_field_components*sizeof(double));
+  }
+  else
+    _field=NewField._field;
+
+  return(*this);
 
 }
 
+
+
index cb238ff5c79c625c7be49c516f617ba608a8b268..738e312ea333c82155564704b0c07500038ba8c2 100644 (file)
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+// ICoCo file common to several codes
+// ICoCoTrioField.h
+// version 1.2 10/05/2010
 
-//////////////////////////////////////////////////////////////////////////////
-// File:        ICoCoTrioField.h
-// Directory:   $TRIO_U_ROOT/Kernel/Framework
-// Version:     
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef _ICOCOTRIOFIELD_HXX_
-#define _ICOCOTRIOFIELD_HXX_
+#ifndef _ICoCoTrioField_included_
+#define _ICoCoTrioField_included_
 
 #include <ICoCoField.hxx>
-namespace ICoCo
-{
-        /*!
-                \brief structure for coupling Trio codes via the ICoCo interface
-
-                This structure contains all the necessary information 
-                for constructing a ParaMEDMEM::ParaFIELD (with the addition of the MPI
-                communicator). The ICoCo API specifies two kinds of calls for
-                the ICoCo::Field : either with the mesh only or with the entire information (mesh and field).
-                This structure can therefore be left without _time, _nb_field_components, _field
-                information, which are related to the field values.
+namespace ICoCo {
 
-                _coords and _connectivity tables are always owned by the TrioField.
-
-         */
-  class TrioField:public Field
-  {
+  //////////////////////////////////////////////////////////////////////////////
+  //
+  // .DESCRIPTION 
+  //     class TrioField, used for coupling Trio codes via the ICoCo interface
+  //     This structure contains all the necessary information 
+  //     for constructing a ParaMEDMEM::ParaFIELD (with the addition of the MPI
+  //     communicator).
+  //     This structure can either own or not _field values (_has_field_ownership)
+  //     For _coords, _connectivity and _field, a null pointer means no data allocated.
+  //     _coords and _connectivity tables, when allocated, are always owned by the TrioField.
+  //
+  //////////////////////////////////////////////////////////////////////////////
+  class TrioField:public Field {
   public:
     
     TrioField();
+    TrioField(const TrioField& OtherField);
     ~TrioField();
     void clear();
-    void print();
     void set_standalone();
     void dummy_geom();
     TrioField& operator=(const TrioField& NewField);
     void save(std::ostream& os) const;
     void restore(std::istream& in);
     int nb_values() const ;
+
   public:
     int _type ; // 0 elem 1 nodes
     int _mesh_dim;
index 1eb5a243edb00121fa7c53e8b8ffa1687d75e74c..6c4674f84131a47b74610fd43cab19a6158dc5a7 100644 (file)
@@ -123,9 +123,8 @@ namespace ParaMEDMEM
 
   }
 
-  InterpKernelDEC::InterpKernelDEC(const int *src_ids_bg, const int *src_ids_end,
-                                   const int *trg_ids_bg, const int *trg_ids_end,
-                                   const MPI_Comm& world_comm):DEC(src_ids_bg,src_ids_end,trg_ids_bg,trg_ids_end,world_comm),
+  InterpKernelDEC::InterpKernelDEC(const std::set<int>& src_ids, const std::set<int>& trg_ids,
+                                   const MPI_Comm& world_comm):DEC(src_ids,trg_ids,world_comm),
                                                                _interpolation_matrix(0)
   {
   }
@@ -160,10 +159,8 @@ namespace ParaMEDMEM
       {
         //locate the distant meshes
         ElementLocator locator(*_local_field, *_target_group, *_source_group);
-
-        //transfering option from InterpKernelDEC to ElementLocator                 
-        locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment());
-
+        //transfering option from InterpKernelDEC to ElementLocator   
+        locator.copyOptions(*this);
         MEDCouplingPointSet* distant_mesh=0; 
         int* distant_ids=0;
         std::string distantMeth;
@@ -194,8 +191,7 @@ namespace ParaMEDMEM
       {
         ElementLocator locator(*_local_field, *_source_group, *_target_group);
         //transfering option from InterpKernelDEC to ElementLocator
-        locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment());
-
+        locator.copyOptions(*this);
         MEDCouplingPointSet* distant_mesh=0;
         int* distant_ids=0;
         for (int i=0; i<_source_group->size(); i++)
index 908f21700772f5802c6a91f404d6e97ceffec163..7930a044d8022d2ed5357c217c106f88d43b5cc1 100644 (file)
@@ -33,8 +33,7 @@ namespace ParaMEDMEM
   public:  
     InterpKernelDEC();
     InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group);
-    InterpKernelDEC(const int *src_ids_bg, const int *src_ids_end,
-                    const int *trg_ids_bg, const int *trg_ids_end,
+    InterpKernelDEC(const std::set<int>& src_ids, const std::set<int>& trg_ids,
                     const MPI_Comm& world_comm=MPI_COMM_WORLD);
     virtual ~InterpKernelDEC();
     void synchronize();
index 5f3a424eae198838869bf1bf3a313805955ea2e7..c7db0371c929bb165b44819ad96cfc82990751a3 100644 (file)
@@ -24,6 +24,8 @@
 #include "InterpolationMatrix.hxx"
 #include "TranslationRotationMatrix.hxx"
 #include "Interpolation.hxx"
+#include "Interpolation1D.txx"
+#include "Interpolation2DCurve.txx"
 #include "Interpolation2D.txx"
 #include "Interpolation3DSurf.txx"
 #include "Interpolation3D.txx"
@@ -160,6 +162,28 @@ namespace ParaMEDMEM
       {
         throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions");
       }
+    else if( distant_support.getMeshDimension() == 1
+             && distant_support.getSpaceDimension() == 1 )
+      {
+        MEDCouplingNormalizedUnstructuredMesh<1,1> target_wrapper(distant_supportC);
+        MEDCouplingNormalizedUnstructuredMesh<1,1> source_wrapper(source_supportC);
+
+        INTERP_KERNEL::Interpolation1D interpolation(*this);
+        colSize=interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str());
+        target_wrapper.releaseTempArrays();
+        source_wrapper.releaseTempArrays();
+      }
+    else if( distant_support.getMeshDimension() == 1
+             && distant_support.getSpaceDimension() == 2 )
+      {
+        MEDCouplingNormalizedUnstructuredMesh<2,1> target_wrapper(distant_supportC);
+        MEDCouplingNormalizedUnstructuredMesh<2,1> source_wrapper(source_supportC);
+
+        INTERP_KERNEL::Interpolation2DCurve interpolation(*this);
+        colSize=interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str());
+        target_wrapper.releaseTempArrays();
+        source_wrapper.releaseTempArrays();
+      }
     else if ( distant_support.getMeshDimension() == 2
               && distant_support.getSpaceDimension() == 3 )
       {
index 6822a19fbb87403986755ccd3f17167d857db24a..e0f0ba0854c0f359772f2c2fa62fcd2a125569fd 100644 (file)
@@ -213,7 +213,7 @@ namespace ParaMEDMEM
   double ParaFIELD::getVolumeIntegral(int icomp, bool isWAbs) const
   {
     CommInterface comm_interface = _topology->getProcGroup()->getCommInterface();
-    double integral=_field->measureAccumulate(icomp,isWAbs);
+    double integral=_field->integral(icomp,isWAbs);
     double total=0.;
     const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*>(_topology->getProcGroup()))->getComm();
     comm_interface.allReduce(&integral, &total, 1, MPI_DOUBLE, MPI_SUM, *comm);
diff --git a/src/ParaMEDMEMTest/MPI2Connector.cxx b/src/ParaMEDMEMTest/MPI2Connector.cxx
new file mode 100644 (file)
index 0000000..8daa235
--- /dev/null
@@ -0,0 +1,143 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MPI2Connector.hxx"
+
+#include <iostream>
+
+MPI2Connector::MPI2Connector()
+{
+  MPI_Comm_size( MPI_COMM_WORLD, &_nb_proc );
+  MPI_Comm_rank( MPI_COMM_WORLD, &_num_proc );
+}
+
+MPI2Connector::~MPI2Connector()
+{
+}
+
+MPI_Comm MPI2Connector::remoteMPI2Connect(const std::string& service)
+{
+  int i;
+  char port_name[MPI_MAX_PORT_NAME];
+  char port_name_clt[MPI_MAX_PORT_NAME];
+  std::ostringstream msg;
+  MPI_Comm icom;
+
+  if( service.size() == 0 )
+    {
+      msg << "[" << _num_proc << "] You have to give a service name !";
+      std::cerr << msg.str().c_str() << std::endl;
+      throw std::exception();
+    }
+
+  _srv = false;
+
+  MPI_Barrier(MPI_COMM_WORLD);
+
+  MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+  if( _num_proc == 0 )
+    { 
+      /* rank 0 try to be a server. If service is already published, try to be a cient */
+      MPI_Open_port(MPI_INFO_NULL, port_name); 
+      if ( MPI_Publish_name((char*)service.c_str(), MPI_INFO_NULL, port_name) == MPI_SUCCESS )
+        {
+          _srv = true;
+          _port_name = port_name;
+          std::cerr << "[" << _num_proc << "] service " << service << " available at " << port_name << std::endl;
+        }      
+      else if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )
+        {
+          std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl;
+          MPI_Close_port( port_name );
+        }
+      else
+        {
+          msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt;
+          std::cerr << msg.str().c_str() << std::endl;
+          throw std::exception();
+        }
+    }
+  else
+    {
+      i=0;
+      /* Waiting rank 0 publish name and try to be a client */
+      while ( i != TIMEOUT  ) 
+        {
+          sleep(1);
+          if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )
+            {
+              std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl;
+              break;
+            }
+          i++;
+        }
+      if(i==TIMEOUT)
+        {
+          msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt;
+          std::cerr << msg.str().c_str() << std::endl;
+          throw std::exception();
+        }
+    }
+  MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
+  
+  /* If rank 0 is server, all processes call MPI_Comm_accept */
+  /* If rank 0 is not server, all processes call MPI_Comm_connect */
+  int srv = (int)_srv;
+  MPI_Bcast(&srv,1,MPI_INT,0,MPI_COMM_WORLD);
+  _srv = (bool)srv;
+  if ( _srv )
+    MPI_Comm_accept( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
+  else
+    MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
+
+  /* create global communicator: servers have low index in global communicator*/
+  MPI_Intercomm_merge(icom,!_srv,&_gcom);
+
+  /* only rank 0 can be server for unpublish name */
+  if(_num_proc != 0) _srv = false;
+
+  return _gcom;
+
+}
+
+void MPI2Connector::remoteMPI2Disconnect(const std::string& service)
+{
+  std::ostringstream msg;
+
+  if( service.size() == 0 )
+    {
+      msg << "[" << _num_proc << "] You have to give a service name !";
+      std::cerr << msg.str().c_str() << std::endl;
+      throw std::exception();
+    }
+
+  MPI_Comm_disconnect( &_gcom ); 
+  if ( _srv )
+    {
+
+      char port_name[MPI_MAX_PORT_NAME];
+      strcpy(port_name,_port_name.c_str());
+
+      MPI_Unpublish_name((char*)service.c_str(), MPI_INFO_NULL, port_name); 
+      std::cerr << "[" << _num_proc << "] " << service << ": close port " << _port_name << std::endl;
+      MPI_Close_port( port_name ); 
+    }
+  
+}
+
diff --git a/src/ParaMEDMEMTest/MPI2Connector.hxx b/src/ParaMEDMEMTest/MPI2Connector.hxx
new file mode 100644 (file)
index 0000000..905de10
--- /dev/null
@@ -0,0 +1,48 @@
+//  Copyright (C) 2007-2010  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 __MPI2CONNECTOR_HXX__
+#define __MPI2CONNECTOR_HXX__
+
+#include <mpi.h>
+#include <string>
+#include <sstream>
+
+class MPI2Connector
+{
+public:
+  MPI2Connector();
+  ~MPI2Connector();
+  // MPI2 connection
+  MPI_Comm remoteMPI2Connect(const std::string& service);
+  // MPI2 disconnection
+  void remoteMPI2Disconnect(const std::string& service);
+private:
+  // Processus id
+  int _num_proc;
+  // Processus size
+  int _nb_proc;
+  MPI_Comm _gcom;
+  bool _srv;
+  std::string _port_name;
+private:
+  static const int TIMEOUT=5;
+};
+
+#endif
index 200a4bf44e09517ab82e4ca2fb2f608534f4f261..f172ee9fc2de4843c4a5f0a1a09f496556a329f1 100644 (file)
@@ -25,9 +25,8 @@ salomeinclude_HEADERS = \
        MPIMainTest.hxx \
        MPIAccessDECTest.hxx \
        MPIAccessTest.hxx \
-       ParaMEDMEMTest.hxx
-
-EXTRA_DIST += MPIMainTest.hxx ParaMEDMEMTest_NonCoincidentDEC.cxx
+       ParaMEDMEMTest.hxx \
+       MPI2Connector.hxx       
 
 dist_libParaMEDMEMTest_la_SOURCES = \
        ParaMEDMEMTest.cxx \
@@ -39,6 +38,7 @@ dist_libParaMEDMEMTest_la_SOURCES = \
        ParaMEDMEMTest_ICocoTrio.cxx \
        ParaMEDMEMTest_Gauthier1.cxx \
        ParaMEDMEMTest_FabienAPI.cxx \
+       ParaMEDMEMTest_NonCoincidentDEC.cxx \
        MPIAccessDECTest.cxx \
        test_AllToAllDEC.cxx \
        test_AllToAllvDEC.cxx \
@@ -62,7 +62,6 @@ dist_libParaMEDMEMTest_la_SOURCES = \
        test_MPI_Access_Time_0.cxx \
        test_MPI_Access_ISend_IRecv_BottleNeck.cxx
 
-
 libParaMEDMEMTest_la_CPPFLAGS = \
        @CPPUNIT_INCLUDES@ \
        $(MPI_INCLUDES) \
@@ -91,6 +90,21 @@ dist_TestMPIAccessDEC_SOURCES = TestMPIAccessDEC.cxx
 dist_TestMPIAccess_SOURCES = TestMPIAccess.cxx
 dist_test_perf_SOURCES = test_perf.cxx
 
+if MPI2_IS_OK
+bin_PROGRAMS += \
+       ParaMEDMEMTestMPI2_1 \
+       ParaMEDMEMTestMPI2_2
+
+dist_ParaMEDMEMTestMPI2_1_SOURCES = \
+       MPI2Connector.cxx \
+       ParaMEDMEMTestMPI2_1.cxx
+
+dist_ParaMEDMEMTestMPI2_2_SOURCES = \
+       MPI2Connector.cxx \
+       ParaMEDMEMTestMPI2_2.cxx
+
+endif
+
 LDADD = $(MED2_LIBS) $(libMEDMEMTest_la_LDFLAGS) -lm $(MPI_LIBS) \
        libParaMEDMEMTest.la \
        ../INTERP_KERNEL/libinterpkernel.la $(CPPUNIT_LIBS) \
@@ -101,7 +115,6 @@ LDADD = $(MED2_LIBS) $(libMEDMEMTest_la_LDFLAGS) -lm $(MPI_LIBS) \
 
 if MED_ENABLE_FVM
        LDADD += $(FVM_LIBS)
-       dist_libParaMEDMEMTest_la_SOURCES += ParaMEDMEMTest_NonCoincidentDEC.cxx
        libParaMEDMEMTest_la_CPPFLAGS += -DMED_ENABLE_FVM $(FVM_INCLUDES)
        libParaMEDMEMTest_la_LDFLAGS += $(FVM_LIBS)
 endif
index da4e4873cbdf385c0c8758c96cea152ad555adc8..be30599ae5c9481a3a7d114a6831f20fa290ff7f 100644 (file)
@@ -36,6 +36,8 @@ class ParaMEDMEMTest : public CppUnit::TestFixture
   CPPUNIT_TEST(testMPIProcessorGroup_rank);
   CPPUNIT_TEST(testBlockTopology_constructor);
   CPPUNIT_TEST(testBlockTopology_serialize);
+  CPPUNIT_TEST(testInterpKernelDEC_1D);
+  CPPUNIT_TEST(testInterpKernelDEC_2DCurve);
   CPPUNIT_TEST(testInterpKernelDEC_2D);
   CPPUNIT_TEST(testInterpKernelDEC2_2D);
   CPPUNIT_TEST(testInterpKernelDEC_2DP0P1);
@@ -44,6 +46,7 @@ class ParaMEDMEMTest : public CppUnit::TestFixture
   CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P1P1P0);
   CPPUNIT_TEST(testInterpKernelDEC2DM1D_P0P0);
   CPPUNIT_TEST(testInterpKernelDECPartialProcs);
+  CPPUNIT_TEST(testInterpKernelDEC3DSurfEmptyBBox);
 
   CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D);
   CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D);
@@ -68,6 +71,7 @@ class ParaMEDMEMTest : public CppUnit::TestFixture
   CPPUNIT_TEST(testGauthier1);
   CPPUNIT_TEST(testGauthier2);
   CPPUNIT_TEST(testFabienAPI1);
+  CPPUNIT_TEST(testFabienAPI2);
   CPPUNIT_TEST(testMEDLoaderRead1);
   CPPUNIT_TEST(testMEDLoaderPolygonRead);
   CPPUNIT_TEST(testMEDLoaderPolyhedronRead);
@@ -87,6 +91,8 @@ public:
   void testMPIProcessorGroup_rank();
   void testBlockTopology_constructor();
   void testBlockTopology_serialize();
+  void testInterpKernelDEC_1D();
+  void testInterpKernelDEC_2DCurve();
   void testInterpKernelDEC_2D();
   void testInterpKernelDEC2_2D();
   void testInterpKernelDEC_2DP0P1();
@@ -95,6 +101,7 @@ public:
   void testInterpKernelDECNonOverlapp_2D_P0P1P1P0();
   void testInterpKernelDEC2DM1D_P0P0();
   void testInterpKernelDECPartialProcs();
+  void testInterpKernelDEC3DSurfEmptyBBox();
 #ifdef MED_ENABLE_FVM
   void testNonCoincidentDEC_2D();
   void testNonCoincidentDEC_3D();
@@ -118,6 +125,7 @@ public:
   void testGauthier1();
   void testGauthier2();
   void testFabienAPI1();
+  void testFabienAPI2();
   //
   void testMEDLoaderRead1();
   void testMEDLoaderPolygonRead();
@@ -130,11 +138,13 @@ public:
   std::string makeTmpFile( const std::string&, const std::string& = "" );
 
 private:
+#ifdef MED_ENABLE_FVM
   void testNonCoincidentDEC(const std::string& filename1, 
                             const std::string& meshname1, 
                             const std::string& filename2, 
                             const std::string& meshname2,
                             int nbprocsource, double epsilon);
+#endif
   void testAsynchronousInterpKernelDEC_2D(double dtA, double tmaxA, 
                                           double dtB, double tmaxB,
                                           bool WithPointToPoint, bool Asynchronous, bool WithInterp, const char *srcMeth, const char *targetMeth);
diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx
new file mode 100644 (file)
index 0000000..599d3fb
--- /dev/null
@@ -0,0 +1,125 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "MPI2Connector.hxx"
+#include "ParaMESH.hxx"
+#include "ParaFIELD.hxx"
+#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "InterpKernelDEC.hxx"
+#include "MPIProcessorGroup.hxx"
+#include "CommInterface.hxx"
+
+#include <mpi.h>
+#include <iostream>
+#include <stdlib.h>
+
+class MPI2ParaMEDMEMTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( MPI2ParaMEDMEMTest );
+  CPPUNIT_TEST( testBasicMPI2_1 );
+  CPPUNIT_TEST_SUITE_END();
+public:
+  void testBasicMPI2_1();
+};
+
+using namespace ParaMEDMEM;
+
+void MPI2ParaMEDMEMTest::testBasicMPI2_1()
+{
+  int lsize, lrank, gsize, grank;
+  MPI_Comm gcom;
+  std::string service = "SERVICE";
+  std::ostringstream meshfilename, meshname;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::MEDCouplingUMesh *mesh;
+  ParaMEDMEM::ParaFIELD *parafield=0;
+  ParaMEDMEM::CommInterface *interface;
+  ParaMEDMEM::MPIProcessorGroup *source, *target;
+
+  MPI_Comm_size( MPI_COMM_WORLD, &lsize );
+  MPI_Comm_rank( MPI_COMM_WORLD, &lrank );
+  if(lsize!=2)
+    {
+      CPPUNIT_ASSERT(false);
+      return;
+    }
+
+  /* Connection to remote programm */
+  MPI2Connector *mpio = new MPI2Connector;
+  gcom = mpio->remoteMPI2Connect(service);
+  MPI_Comm_size( gcom, &gsize );
+  MPI_Comm_rank( gcom, &grank );
+  if(gsize!=5)
+    {
+      CPPUNIT_ASSERT(false);
+      return;
+    }
+  interface = new ParaMEDMEM::CommInterface;
+  source = new ParaMEDMEM::MPIProcessorGroup(*interface,0,lsize-1,gcom);
+  target = new ParaMEDMEM::MPIProcessorGroup(*interface,lsize,gsize-1,gcom);
+
+  const double sourceCoordsAll[2][8]={{0.4,0.5,0.4,1.5,1.6,1.5,1.6,0.5},
+                                      {0.3,-0.5,1.6,-0.5,1.6,-1.5,0.3,-1.5}};
+  
+  int conn4All[8]={0,1,2,3,4,5,6,7};
+  
+  std::ostringstream stream; stream << "sourcemesh2D proc " << grank;
+  mesh=MEDCouplingUMesh::New(stream.str().c_str(),2);
+  mesh->allocateCells(2);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All);
+  mesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(4,2);
+  const double *sourceCoords=sourceCoordsAll[grank];
+  std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer());
+  mesh->setCoords(myCoords);
+  myCoords->decrRef();
+  paramesh=new ParaMESH(mesh,*source,"source mesh");
+  ParaMEDMEM::ComponentTopology comptopo;
+  parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+  double *value=parafield->getField()->getArray()->getPointer();
+  value[0]=34+13*((double)grank);
+
+  ParaMEDMEM::InterpKernelDEC dec(*source,*target);
+  parafield->getField()->setNature(ConservativeVolumic);
+
+
+  dec.setMethod("P0");
+  dec.attachLocalField(parafield);
+  dec.synchronize();
+  dec.setForcedRenormalization(false);
+  dec.sendData();
+  /* Deconnection of remote programm */
+  mpio->remoteMPI2Disconnect(service);
+  /* clean-up */
+  delete mpio;
+  delete parafield;
+  mesh->decrRef();
+  delete paramesh;
+  delete source;
+  delete target;
+  delete interface;
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION( MPI2ParaMEDMEMTest );
+
+#include "MPIMainTest.hxx"
diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx
new file mode 100644 (file)
index 0000000..9ed8819
--- /dev/null
@@ -0,0 +1,130 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "MPI2Connector.hxx"
+#include "ParaMESH.hxx"
+#include "ParaFIELD.hxx"
+#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "InterpKernelDEC.hxx"
+#include "MPIProcessorGroup.hxx"
+#include "CommInterface.hxx"
+
+#include <mpi.h>
+#include <iostream>
+#include <stdlib.h>
+
+class MPI2ParaMEDMEMTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( MPI2ParaMEDMEMTest );
+  CPPUNIT_TEST( testBasicMPI2_1 );
+  CPPUNIT_TEST_SUITE_END();
+public:
+  void testBasicMPI2_1();
+};
+
+using namespace ParaMEDMEM;
+
+void MPI2ParaMEDMEMTest::testBasicMPI2_1()
+{
+  int lsize, lrank, gsize, grank;
+  MPI_Comm gcom;
+  std::string service = "SERVICE";
+  std::ostringstream meshfilename, meshname;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::MEDCouplingUMesh* mesh;
+  ParaMEDMEM::ParaFIELD *parafield=0;
+  ParaMEDMEM::CommInterface* interface;
+  ParaMEDMEM::MPIProcessorGroup* source, *target;
+  
+  MPI_Comm_size( MPI_COMM_WORLD, &lsize );
+  MPI_Comm_rank( MPI_COMM_WORLD, &lrank );
+  if(lsize!=3)
+    {
+      CPPUNIT_ASSERT(false);
+      return;
+    }
+
+  /* Connection to remote programm */
+  MPI2Connector *mpio = new MPI2Connector;
+  gcom = mpio->remoteMPI2Connect(service);
+  
+  MPI_Comm_size( gcom, &gsize );
+  MPI_Comm_rank( gcom, &grank );
+  if(gsize!=5)
+    {
+      CPPUNIT_ASSERT(false);
+      return;
+    }
+
+  interface = new ParaMEDMEM::CommInterface;
+  source = new ParaMEDMEM::MPIProcessorGroup(*interface,0,gsize-lsize-1,gcom);
+  target = new ParaMEDMEM::MPIProcessorGroup(*interface,gsize-lsize,gsize-1,gcom);
+
+  const double targetCoordsAll[3][16]={{0.7,1.45,0.7,1.65,0.9,1.65,0.9,1.45,  1.1,1.4,1.1,1.6,1.3,1.6,1.3,1.4},
+                                       {0.7,-0.6,0.7,0.7,0.9,0.7,0.9,-0.6,  1.1,-0.7,1.1,0.6,1.3,0.6,1.3,-0.7},
+                                       {0.7,-1.55,0.7,-1.35,0.9,-1.35,0.9,-1.55,  1.1,-1.65,1.1,-1.45,1.3,-1.45,1.3,-1.65}};
+  int conn4All[8]={0,1,2,3,4,5,6,7};
+  double targetResults[3][2]={{34.,34.},{38.333333333333336,42.666666666666664},{47.,47.}};
+
+  std::ostringstream stream; stream << "targetmesh2D proc " << grank-(gsize-lsize);
+  mesh=MEDCouplingUMesh::New(stream.str().c_str(),2);
+  mesh->allocateCells(2);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All);
+  mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All+4);
+  mesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(8,2);
+  const double *targetCoords=targetCoordsAll[grank-(gsize-lsize)];
+  std::copy(targetCoords,targetCoords+16,myCoords->getPointer());
+  mesh->setCoords(myCoords);
+  myCoords->decrRef();
+  paramesh=new ParaMESH (mesh,*target,"target mesh");
+  ParaMEDMEM::ComponentTopology comptopo;
+  parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+
+  ParaMEDMEM::InterpKernelDEC dec(*source,*target);
+  parafield->getField()->setNature(ConservativeVolumic);
+
+  dec.setMethod("P0");
+  dec.attachLocalField(parafield);
+  dec.synchronize();
+  dec.setForcedRenormalization(false);
+  dec.recvData();
+  const double *res=parafield->getField()->getArray()->getConstPointer();
+  const double *expected=targetResults[grank-(gsize-lsize)];
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13);
+  /* Deconnection of remote programm */
+  mpio->remoteMPI2Disconnect(service);
+  /* clean-up */
+  delete mpio;
+  delete parafield;
+  mesh->decrRef();
+  delete paramesh;
+  delete source;
+  delete target;
+  delete interface;
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION( MPI2ParaMEDMEMTest );
+
+#include "MPIMainTest.hxx"
index 92c33f5b3f522514dbe54484f32d20e673c63485..a08eb999521ac9213c94eeccab71a262a834ffdb 100644 (file)
@@ -40,8 +40,10 @@ void ParaMEDMEMTest::testFabienAPI1()
   //
   if(size!=3)
     return ;
-  int procs_source[1]={0};
-  int procs_target[1]={1};
+  int procs_source_c[1]={0};
+  std::set<int> procs_source(procs_source_c,procs_source_c+1);
+  int procs_target_c[1]={1};
+  std::set<int> procs_target(procs_target_c,procs_target_c+1);
   //
   ParaMEDMEM::MEDCouplingUMesh *mesh=0;
   ParaMEDMEM::ParaMESH *paramesh=0;
@@ -53,7 +55,92 @@ void ParaMEDMEMTest::testFabienAPI1()
   double targetCoords[8]={ 0.,0., 1., 0., 0., 1., 1., 1. };
   CommInterface comm;
   //
-  ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_source+1,procs_target,procs_target+1);
+  ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_target);
+  if(dec->isInSourceSide())
+    {    
+      mesh=MEDCouplingUMesh::New();
+      mesh->setMeshDimension(2);
+      DataArrayDouble *myCoords=DataArrayDouble::New();
+      myCoords->alloc(4,2);
+      std::copy(targetCoords,targetCoords+8,myCoords->getPointer());
+      mesh->setCoords(myCoords);
+      myCoords->decrRef();
+      int targetConn[4]={0,2,3,1};
+      mesh->allocateCells(1);
+      mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn);
+      mesh->finishInsertingCells();
+      ParaMEDMEM::ComponentTopology comptopo;
+      paramesh=new ParaMESH(mesh,*dec->getSourceGrp(),"source mesh");
+      parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      parafield->getField()->setNature(ConservativeVolumic);
+      double *vals=parafield->getField()->getArray()->getPointer();
+      vals[0]=7.;
+    }
+  if(dec->isInTargetSide())
+    {
+      mesh=MEDCouplingUMesh::New();
+      mesh->setMeshDimension(2);
+      DataArrayDouble *myCoords=DataArrayDouble::New();
+      myCoords->alloc(4,2);
+      std::copy(targetCoords,targetCoords+8,myCoords->getPointer());
+      mesh->setCoords(myCoords);
+      myCoords->decrRef();
+      int targetConn[6]={0,2,1,2,3,1};
+      mesh->allocateCells(2);
+      mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn);
+      mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3);
+      mesh->finishInsertingCells();
+      ParaMEDMEM::ComponentTopology comptopo;
+      paramesh=new ParaMESH(mesh,*dec->getTargetGrp(),"target mesh");
+      parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      parafield->getField()->setNature(ConservativeVolumic);
+    }
+  dec->attachLocalField(parafield);
+  dec->synchronize();
+  dec->sendRecvData();
+  if(dec->isInTargetSide())
+    {
+      const double *valsToTest=parafield->getField()->getArray()->getConstPointer();
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[0],7.,1e-14);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[1],7.,1e-14);
+    }
+  //
+  delete parafield;
+  delete paramesh;
+  if(mesh)
+    mesh->decrRef();
+  delete dec;
+  MPI_Barrier(MPI_COMM_WORLD);
+}
+
+/*!
+ * Idem testFabienAPI1 except that procs are shuffled. Test of the good management of group translation in newly created communicator.
+ */
+void ParaMEDMEMTest::testFabienAPI2()
+{
+  int size;
+  int rank;
+  MPI_Comm_size(MPI_COMM_WORLD,&size);
+  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+  //
+  if(size!=3)
+    return ;
+  int procs_source_c[1]={2};//difference with testFabienAPI1
+  std::set<int> procs_source(procs_source_c,procs_source_c+1);
+  int procs_target_c[1]={1};
+  std::set<int> procs_target(procs_target_c,procs_target_c+1);
+  //
+  ParaMEDMEM::MEDCouplingUMesh *mesh=0;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::ParaFIELD *parafield=0;
+  //
+  ParaMEDMEM::CommInterface interface;
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+  double targetCoords[8]={ 0.,0., 1., 0., 0., 1., 1., 1. };
+  CommInterface comm;
+  //
+  ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_target);
   if(dec->isInSourceSide())
     {    
       mesh=MEDCouplingUMesh::New();
index 11c5828438631bb81333efa7bbd1d1cf1fc2a3c7..17cadfe05c3d7d9b7dd6fa47719d7903dccf2368 100644 (file)
@@ -252,7 +252,7 @@ void ParaMEDMEMTest::testGauthier1()
   
         MPI_Barrier(MPI_COMM_WORLD);
 
-        clock_t clock0= clock ();
+        //clock_t clock0= clock ();
         int compti=0;
 
         bool init=true; // first time step ??
@@ -261,7 +261,7 @@ void ParaMEDMEMTest::testGauthier1()
         while (!stop) {
   
           compti++;
-          clock_t clocki= clock ();
+          //clock_t clocki= clock ();
           //cout << compti << " CLOCK " << (clocki-clock0)*1.e-6 << endl; 
           for (int non_unif=0;non_unif<2;non_unif++)
             {
@@ -278,7 +278,7 @@ void ParaMEDMEMTest::testGauthier1()
                     if(rank!=3)
                       champ_emetteur._field[0]=40;
                 }
-              bool ok=false; // Is the time interval successfully solved ?
+              //bool ok=false; // Is the time interval successfully solved ?
     
               // Loop on the time interval tries
               if(1) {
index 38649136266863be35976786d32cdd76d5bd2bec..b3a573c3e699e56548d6524d40d1146358566d0c 100644 (file)
@@ -236,7 +236,7 @@ void ParaMEDMEMTest::testICocoTrio1()
         if (cas=="emetteur") 
           if (non_unif)
             champ_emetteur._field[0]=40;
-        bool ok=false; // Is the time interval successfully solved ?
+        //bool ok=false; // Is the time interval successfully solved ?
     
         // Loop on the time interval tries
         if(1)
index c4198160829b6561d21665797c8ce538323e8ae2..f4e941ee096acaaf6937091f048d36848643d543 100644 (file)
@@ -47,7 +47,7 @@
 
 using namespace std;
 using namespace ParaMEDMEM;
+
 void ParaMEDMEMTest::testInterpKernelDEC_2D()
 {
   testInterpKernelDEC_2D_("P0","P0");
@@ -68,6 +68,385 @@ void ParaMEDMEMTest::testInterpKernelDEC_2DP0P1()
   //testInterpKernelDEC_2D_("P0","P1");
 }
 
+void ParaMEDMEMTest::testInterpKernelDEC_1D()
+{
+  int size;
+  int rank;
+  MPI_Comm_size(MPI_COMM_WORLD,&size);
+  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+  //
+  if(size!=5)
+    return ;
+  int nproc_source = 3;
+  set<int> self_procs;
+  set<int> procs_source;
+  set<int> procs_target;
+  
+  for (int i=0; i<nproc_source; i++)
+    procs_source.insert(i);
+  for (int i=nproc_source; i<size; i++)
+    procs_target.insert(i);
+  self_procs.insert(rank);
+  //
+  ParaMEDMEM::MEDCouplingUMesh *mesh=0;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::ParaFIELD *parafieldP0=0;
+  //
+  ParaMEDMEM::CommInterface interface;
+  //
+  ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs);
+  ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target);
+  ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source);
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+  if(source_group->containsMyRank())
+    {
+      if(rank==0)
+        {
+          double coords[4]={0.3,0.7, 0.9,1.0};
+          int conn[4]={0,1,2,3};
+          mesh=MEDCouplingUMesh::New("Source mesh Proc0",1);
+          mesh->allocateCells(2);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(4,1);
+          std::copy(coords,coords+4,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+        }
+      if(rank==1)
+        {
+          double coords[2]={0.7,0.9};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Source mesh Proc1",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,1);
+          std::copy(coords,coords+2,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+        }
+      if(rank==2)
+        {
+          double coords[2]={1.,1.12};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Source mesh Proc2",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,1);
+          std::copy(coords,coords+2,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+        }
+      paramesh=new ParaMESH(mesh,*source_group,"source mesh");
+      ParaMEDMEM::ComponentTopology comptopo;
+      parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      double *valueP0=parafieldP0->getField()->getArray()->getPointer();
+      parafieldP0->getField()->setNature(ConservativeVolumic);
+      if(rank==0)
+        {
+          valueP0[0]=7.; valueP0[1]=8.;
+        }
+      if(rank==1)
+        {
+          valueP0[0]=9.;
+        }
+      if(rank==2)
+        {
+          valueP0[0]=10.;
+        }
+    }
+  else
+    {
+      const char targetMeshName[]="target mesh";
+      if(rank==3)
+        {
+          double coords[2]={0.5,0.75};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Target mesh Proc3",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,1);
+          std::copy(coords,coords+2,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+          paramesh=new ParaMESH(mesh,*target_group,targetMeshName);
+        }
+      if(rank==4)
+        {
+          double coords[2]={0.75,1.2};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Target mesh Proc4",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,1);
+          std::copy(coords,coords+2,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+          paramesh=new ParaMESH(mesh,*target_group,targetMeshName);
+        }
+      ParaMEDMEM::ComponentTopology comptopo;
+      parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      parafieldP0->getField()->setNature(ConservativeVolumic);
+    }
+  // test 1
+  ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group);
+  if (source_group->containsMyRank())
+    { 
+      dec.setMethod("P0");
+      dec.attachLocalField(parafieldP0);
+      dec.synchronize();
+      dec.setForcedRenormalization(false);
+      dec.sendData();
+      dec.recvData();
+      const double *valueP0=parafieldP0->getField()->getArray()->getPointer();
+      if(rank==0)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7);
+        }
+      if(rank==1)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7);
+        }
+      if(rank==2)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7);
+        }
+    }
+  else
+    {
+      dec.setMethod("P0");
+      dec.attachLocalField(parafieldP0);
+      dec.synchronize();
+      dec.setForcedRenormalization(false);
+      dec.recvData();
+      const double *res=parafieldP0->getField()->getArray()->getConstPointer();
+      if(rank==3)
+        {
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples());
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents());
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12);
+        }
+      if(rank==4)
+        {
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples());
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents());
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12);
+        }
+      dec.sendData();
+    }
+  //
+  delete parafieldP0;
+  mesh->decrRef();
+  delete paramesh;
+  delete self_group;
+  delete target_group;
+  delete source_group;
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+}
+
+void ParaMEDMEMTest::testInterpKernelDEC_2DCurve()
+{
+  int size;
+  int rank;
+  MPI_Comm_size(MPI_COMM_WORLD,&size);
+  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+  //
+  if(size!=5)
+    return ;
+  int nproc_source = 3;
+  set<int> self_procs;
+  set<int> procs_source;
+  set<int> procs_target;
+  
+  for (int i=0; i<nproc_source; i++)
+    procs_source.insert(i);
+  for (int i=nproc_source; i<size; i++)
+    procs_target.insert(i);
+  self_procs.insert(rank);
+  //
+  ParaMEDMEM::MEDCouplingUMesh *mesh=0;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::ParaFIELD *parafieldP0=0;
+  //
+  ParaMEDMEM::CommInterface interface;
+  //
+  ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs);
+  ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target);
+  ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source);
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+  if(source_group->containsMyRank())
+    {
+      if(rank==0)
+        {
+          double coords[8]={0.3,0.3,0.7,0.7, 0.9,0.9,1.0,1.0};
+          int conn[4]={0,1,2,3};
+          mesh=MEDCouplingUMesh::New("Source mesh Proc0",1);
+          mesh->allocateCells(2);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(4,2);
+          std::copy(coords,coords+8,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+        }
+      if(rank==1)
+        {
+          double coords[4]={0.7,0.7,0.9,0.9};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Source mesh Proc1",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,2);
+          std::copy(coords,coords+4,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+        }
+      if(rank==2)
+        {
+          double coords[4]={1.,1.,1.12,1.12};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Source mesh Proc2",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,2);
+          std::copy(coords,coords+4,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+        }
+      paramesh=new ParaMESH(mesh,*source_group,"source mesh");
+      ParaMEDMEM::ComponentTopology comptopo;
+      parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      double *valueP0=parafieldP0->getField()->getArray()->getPointer();
+      parafieldP0->getField()->setNature(ConservativeVolumic);
+      if(rank==0)
+        {
+          valueP0[0]=7.; valueP0[1]=8.;
+        }
+      if(rank==1)
+        {
+          valueP0[0]=9.;
+        }
+      if(rank==2)
+        {
+          valueP0[0]=10.;
+        }
+    }
+  else
+    {
+      const char targetMeshName[]="target mesh";
+      if(rank==3)
+        {
+          double coords[4]={0.5,0.5,0.75,0.75};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Target mesh Proc3",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,2);
+          std::copy(coords,coords+4,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+          paramesh=new ParaMESH(mesh,*target_group,targetMeshName);
+        }
+      if(rank==4)
+        {
+          double coords[4]={0.75,0.75,1.2,1.2};
+          int conn[2]={0,1};
+          mesh=MEDCouplingUMesh::New("Target mesh Proc4",1);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(2,2);
+          std::copy(coords,coords+4,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+          paramesh=new ParaMESH(mesh,*target_group,targetMeshName);
+        }
+      ParaMEDMEM::ComponentTopology comptopo;
+      parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      parafieldP0->getField()->setNature(ConservativeVolumic);
+    }
+  // test 1
+  ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group);
+  if (source_group->containsMyRank())
+    { 
+      dec.setMethod("P0");
+      dec.attachLocalField(parafieldP0);
+      dec.synchronize();
+      dec.setForcedRenormalization(false);
+      dec.sendData();
+      dec.recvData();
+      const double *valueP0=parafieldP0->getField()->getArray()->getPointer();
+      if(rank==0)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7);
+        }
+      if(rank==1)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7);
+        }
+      if(rank==2)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7);
+        }
+    }
+  else
+    {
+      dec.setMethod("P0");
+      dec.attachLocalField(parafieldP0);
+      dec.synchronize();
+      dec.setForcedRenormalization(false);
+      dec.recvData();
+      const double *res=parafieldP0->getField()->getArray()->getConstPointer();
+      if(rank==3)
+        {
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples());
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents());
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12);
+        }
+      if(rank==4)
+        {
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples());
+          CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents());
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12);
+        }
+      dec.sendData();
+    }
+  //
+  delete parafieldP0;
+  mesh->decrRef();
+  delete paramesh;
+  delete self_group;
+  delete target_group;
+  delete source_group;
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+}
+
+
 /*
  * Check methods defined in InterpKernelDEC.hxx
  *
@@ -1531,6 +1910,158 @@ void ParaMEDMEMTest::testInterpKernelDECPartialProcs()
   MPI_Barrier(MPI_COMM_WORLD);
 }
 
+/*!
+ * This test reproduces bug of Gauthier on 13/9/2010 concerning 3DSurf meshes.
+ * It is possible to lead to dead lock in InterpKernelDEC when 3DSurfMeshes global bounding boxes intersects whereas cell bounding box intersecting only on one side.
+ */
+void ParaMEDMEMTest::testInterpKernelDEC3DSurfEmptyBBox()
+{
+  int size;
+  int rank;
+  MPI_Comm_size(MPI_COMM_WORLD,&size);
+  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+  //
+  if(size!=3)
+    return ;
+  int nproc_source = 1;
+  set<int> self_procs;
+  set<int> procs_source;
+  set<int> procs_target;
+  
+  for (int i=0; i<nproc_source; i++)
+    procs_source.insert(i);
+  for (int i=nproc_source; i<size; i++)
+    procs_target.insert(i);
+  self_procs.insert(rank);
+  //
+  ParaMEDMEM::MEDCouplingUMesh *mesh=0;
+  ParaMEDMEM::ParaMESH *paramesh=0;
+  ParaMEDMEM::ParaFIELD *parafieldP0=0;
+  //
+  ParaMEDMEM::CommInterface interface;
+  //
+  ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs);
+  ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target);
+  ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source);
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+  if(source_group->containsMyRank())
+    {
+      double coords[15]={1.,0.,0., 2.,0.,0., 2.,2.,0., 0.,2.,0., 0.5,0.5,1.};
+      int conn[7]={0,1,2,3,0,3,4};
+      mesh=MEDCouplingUMesh::New("Source mesh Proc0",2);
+      mesh->allocateCells(2);
+      mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn);
+      mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+4);
+      mesh->finishInsertingCells();
+      DataArrayDouble *myCoords=DataArrayDouble::New();
+      myCoords->alloc(5,3);
+      std::copy(coords,coords+15,myCoords->getPointer());
+      mesh->setCoords(myCoords);
+      myCoords->decrRef();
+      //
+      paramesh=new ParaMESH(mesh,*source_group,"source mesh");
+      ParaMEDMEM::ComponentTopology comptopo;
+      parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      double *valueP0=parafieldP0->getField()->getArray()->getPointer();
+      parafieldP0->getField()->setNature(ConservativeVolumic);
+      valueP0[0]=7.; valueP0[1]=8.;
+    }
+  else
+    {
+      const char targetMeshName[]="target mesh";
+      if(rank==1)
+        {
+          double coords[12]={0.25,0.25,0.5, 0.,0.25,0.5, 0.,0.,0.5, 0.25,0.,0.5};
+          int conn[4]={0,1,2,3};
+          mesh=MEDCouplingUMesh::New("Target mesh Proc1",2);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(4,3);
+          std::copy(coords,coords+12,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+          paramesh=new ParaMESH(mesh,*target_group,targetMeshName);
+        }
+      if(rank==2)
+        {
+          double coords[12]={0.,0.25,0.5, 0.,0.,0.5, -1.,0.,0.5, -1.,0.25,0.5};
+          int conn[4]={0,1,2,3};
+          mesh=MEDCouplingUMesh::New("Target mesh Proc2",2);
+          mesh->allocateCells(1);
+          mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn);
+          mesh->finishInsertingCells();
+          DataArrayDouble *myCoords=DataArrayDouble::New();
+          myCoords->alloc(4,3);
+          std::copy(coords,coords+12,myCoords->getPointer());
+          mesh->setCoords(myCoords);
+          myCoords->decrRef();
+          paramesh=new ParaMESH(mesh,*target_group,targetMeshName);
+        }
+      ParaMEDMEM::ComponentTopology comptopo;
+      parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo);
+      parafieldP0->getField()->setNature(ConservativeVolumic);
+    }
+  // test 1
+  ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group);
+  if (source_group->containsMyRank())
+    { 
+      dec.setMethod("P0");
+      dec.attachLocalField(parafieldP0);
+      dec.synchronize();
+      // dec.setForcedRenormalization(false);
+      // dec.sendData();
+      // dec.recvData();
+      // const double *valueP0=parafieldP0->getField()->getArray()->getPointer();
+      // if(rank==0)
+      //   {
+      //     CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7);
+      //     CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7);
+      //   }
+      // if(rank==1)
+      //   {
+      //     CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7);
+      //   }
+      // if(rank==2)
+      //   {
+      //     CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7);
+      //   }
+    }
+  else
+    {
+      dec.setMethod("P0");
+      dec.attachLocalField(parafieldP0);
+      dec.synchronize();
+      // dec.setForcedRenormalization(false);
+      // dec.recvData();
+      // const double *res=parafieldP0->getField()->getArray()->getConstPointer();
+      // if(rank==3)
+      //   {
+      //     CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples());
+      //     CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents());
+      //     CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12);
+      //   }
+      // if(rank==4)
+      //   {
+      //     CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples());
+      //     CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents());
+      //     CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12);
+      //   }
+      // dec.sendData();
+    }
+  //
+  delete parafieldP0;
+  mesh->decrRef();
+  delete paramesh;
+  delete self_group;
+  delete target_group;
+  delete source_group;
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+}
+
 /*!
  * Tests an asynchronous exchange between two codes
  * one sends data with dtA as an interval, the max time being tmaxA
index 325b46f0310809158db8d834862ca9b6b29edb24..b0b21613780e996157444a3c0666cdd1f5c29fbd 100644 (file)
@@ -45,17 +45,17 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllTypes().size());
   for(int i=0;i<12;i++)
     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(i));
-  for(int i=12;i<14;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(i));
-  for(int i=14;i<16;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(i));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(12));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(13));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(14));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(15));
   CPPUNIT_ASSERT_EQUAL(90,mesh->getNodalConnectivity()->getNbOfElems());
   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+90,0));
-  CPPUNIT_ASSERT_EQUAL(711,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+17,0));
+  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+17,0));
   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
   mesh->decrRef();
   //
-  vector<string> families=MEDLoader::GetMeshFamilyNames(fileName.c_str(),meshNames[0].c_str());
+  vector<string> families=MEDLoader::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str());
   CPPUNIT_ASSERT_EQUAL(8,(int)families.size());
   CPPUNIT_ASSERT(families[2]=="FAMILLE_ELEMENT_3");
   //
@@ -103,21 +103,21 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(2,(int)fieldsName.size());
   CPPUNIT_ASSERT(fieldsName[0]=="fieldcelldoublescalar");
   CPPUNIT_ASSERT(fieldsName[1]=="fieldcelldoublevector");
-  std::vector<std::pair<int,int> > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),fieldsName[0].c_str());
+  std::vector<std::pair<int,int> > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[0].c_str());
   CPPUNIT_ASSERT_EQUAL(1,(int)its0.size());
   CPPUNIT_ASSERT_EQUAL(-1,its0[0].first);
   CPPUNIT_ASSERT_EQUAL(-1,its0[0].second);
-  std::vector<std::pair<int,int> > its1=MEDLoader::GetCellFieldIterations(fileName.c_str(),fieldsName[1].c_str());
+  std::vector<std::pair<int,int> > its1=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[1].c_str());
   CPPUNIT_ASSERT_EQUAL(1,(int)its1.size());
   CPPUNIT_ASSERT_EQUAL(-1,its1[0].first);
   CPPUNIT_ASSERT_EQUAL(-1,its1[0].second);
   //
-  MEDCouplingFieldDouble *field0=MEDLoader::ReadFieldDoubleCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second);
+  MEDCouplingFieldDouble *field0=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second);
   field0->checkCoherency();
   CPPUNIT_ASSERT(field0->getName()==fieldsName[0]);
   CPPUNIT_ASSERT_EQUAL(1,field0->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(16,field0->getNumberOfTuples());
-  const double expectedValues[16]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,3.,3.,2.,2.};
+  const double expectedValues[16]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,2.,3.,3.,2.};
   double diffValue[16];
   std::transform(field0->getArray()->getPointer(),field0->getArray()->getPointer()+16,expectedValues,diffValue,std::minus<double>());
   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue,diffValue+16),1e-12);
@@ -131,22 +131,22 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size());
   for(int i=0;i<12;i++)
     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i));
-  for(int i=12;i<14;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i));
-  for(int i=14;i<16;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15));
   CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems());
   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0));
-  CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
+  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12);
   field0->decrRef();
   //
-  MEDCouplingFieldDouble *field1=MEDLoader::ReadFieldDoubleCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[1].c_str(),its1[0].first,its1[0].second);
+  MEDCouplingFieldDouble *field1=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[1].c_str(),its1[0].first,its1[0].second);
   field1->checkCoherency();
   CPPUNIT_ASSERT(field1->getName()==fieldsName[1]);
   CPPUNIT_ASSERT_EQUAL(3,field1->getNumberOfComponents());
   CPPUNIT_ASSERT_EQUAL(16,field1->getNumberOfTuples());
-  const double expectedValues2[48]={1.,0.,1.,1.,0.,1.,1.,0.,1.,2.,1.,0.,2.,1.,0.,2.,1.,0.,3.,0.,1.,3.,0.,1.,3.,0.,1.,4.,1.,0.,4.,1.,0.,4.,1.,0.,6.,1.,1.,6.,0.,0.,5.,0.,0.,5.,1.,1.};
+  const double expectedValues2[48]={1.,0.,1.,1.,0.,1.,1.,0.,1.,2.,1.,0.,2.,1.,0.,2.,1.,0.,3.,0.,1.,3.,0.,1.,3.,0.,1.,4.,1.,0.,4.,1.,0.,4.,1.,0.,5.,0.,0.,6.,1.,1.,6.,0.,0.,5.,1.,1.};
   double diffValue2[48];
   std::transform(field1->getArray()->getPointer(),field1->getArray()->getPointer()+48,expectedValues2,diffValue2,std::minus<double>());
   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue2,diffValue2+48),1e-12);
@@ -160,13 +160,13 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size());
   for(int i=0;i<12;i++)
     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i));
-  for(int i=12;i<14;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i));
-  for(int i=14;i<16;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15));
   CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems());
   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0));
-  CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
+  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12);
   field1->decrRef();
   //fields on nodes
@@ -174,7 +174,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(2,(int)fieldsNameNode.size());
   CPPUNIT_ASSERT(fieldsNameNode[0]=="fieldnodedouble");
   CPPUNIT_ASSERT(fieldsNameNode[1]=="fieldnodeint");
-  std::vector<std::pair<int,int> > its0Node=MEDLoader::GetNodeFieldIterations(fileName.c_str(),fieldsNameNode[0].c_str());
+  std::vector<std::pair<int,int> > its0Node=MEDLoader::GetNodeFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsNameNode[0].c_str());
   CPPUNIT_ASSERT_EQUAL(3,(int)its0Node.size());
   CPPUNIT_ASSERT_EQUAL(1,its0Node[0].first);
   CPPUNIT_ASSERT_EQUAL(-1,its0Node[0].second);
@@ -182,7 +182,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(-1,its0Node[1].second);
   CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].first);//strange but like that
   CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].second);
-  MEDCouplingFieldDouble *field0Nodes=MEDLoader::ReadFieldDoubleNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second);
+  MEDCouplingFieldDouble *field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second);
   field0Nodes->checkCoherency();
   CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]);
   CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents());
@@ -196,7 +196,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT(constMesh);
   field0Nodes->decrRef();
   //
-  field0Nodes=MEDLoader::ReadFieldDoubleNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[1].first,its0Node[1].second);
+  field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[1].first,its0Node[1].second);
   field0Nodes->checkCoherency();
   CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]);
   CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents());
@@ -214,17 +214,17 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size());
   for(int i=0;i<12;i++)
     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i));
-  for(int i=12;i<14;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i));
-  for(int i=14;i<16;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15));
   CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems());
   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0));
-  CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
+  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12);
   field0Nodes->decrRef();
   //
-  field0Nodes=MEDLoader::ReadFieldDoubleNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[2].first,its0Node[2].second);
+  field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[2].first,its0Node[2].second);
   field0Nodes->checkCoherency();
   CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]);
   CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents());
@@ -242,13 +242,13 @@ void ParaMEDMEMTest::testMEDLoaderRead1()
   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size());
   for(int i=0;i<12;i++)
     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i));
-  for(int i=12;i<14;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i));
-  for(int i=14;i<16;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13));
+  CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14));
+  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15));
   CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems());
   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0));
-  CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
+  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0));
   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12);
   field0Nodes->decrRef();
 }
@@ -286,9 +286,9 @@ void ParaMEDMEMTest::testMEDLoaderPolygonRead()
   CPPUNIT_ASSERT(fieldsName[0]=="bord_:_distorsion");
   CPPUNIT_ASSERT(fieldsName[1]=="bord_:_familles");
   CPPUNIT_ASSERT(fieldsName[2]=="bord_:_non-ortho");
-  std::vector<std::pair<int,int> > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),fieldsName[0].c_str());
+  std::vector<std::pair<int,int> > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[0].c_str());
   CPPUNIT_ASSERT_EQUAL(1,(int)its0.size());
-  MEDCouplingFieldDouble *field=MEDLoader::ReadFieldDoubleCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second);
+  MEDCouplingFieldDouble *field=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second);
   field->checkCoherency();
   CPPUNIT_ASSERT(field->getName()==fieldsName[0]);
   CPPUNIT_ASSERT_EQUAL(1,field->getNumberOfComponents());
@@ -345,18 +345,29 @@ void ParaMEDMEMTest::testMEDLoaderPolyhedronRead()
   CPPUNIT_ASSERT_EQUAL(17,mesh->getNumberOfCells());
   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
   CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllTypes().size());
-  for(int i=0;i<6;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(i));
-  for(int i=6;i<14;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(i));
-  for(int i=14;i<17;i++)
-    CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i));
+  CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(0));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(1));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(2));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(3));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(4));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(5));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(6));
+  CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(7));
+  CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(8));
+  CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(9));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(10));
+  CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(11));
+  CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(12));
+  CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(13));
+  CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(14));
+  CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(15));
+  CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(16));
   CPPUNIT_ASSERT_DOUBLES_EQUAL(110.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
   CPPUNIT_ASSERT_EQUAL(83,mesh->getNodalConnectivity()->getNbOfElems());
   CPPUNIT_ASSERT_EQUAL(619,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+83,0));
   mesh->decrRef();
   //
-  vector<string> families=MEDLoader::GetMeshFamilyNames(fileName.c_str(),meshNames[0].c_str());
+  vector<string> families=MEDLoader::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str());
   CPPUNIT_ASSERT_EQUAL(4,(int)families.size());
   CPPUNIT_ASSERT(families[0]=="FAMILLE_FACE_POLYGONS3");
   CPPUNIT_ASSERT(families[1]=="FAMILLE_FACE_QUAD41");
index ee55782a8d2bdcdb534369b18cecc7db308d32d1..8911fba39324697ae7b19f513aac8b8f9d35dd51 100644 (file)
@@ -17,6 +17,8 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
+#ifdef MED_ENABLE_FVM
+
 #include "ParaMEDMEMTest.hxx"
 #include <cppunit/TestAssert.h>
 
@@ -251,3 +253,4 @@ void ParaMEDMEMTest::testNonCoincidentDEC(const string& filename1,
   MPI_Barrier(MPI_COMM_WORLD);
   
 }
+#endif
index 8df876e608d799c2d4e9284ebd63e51e489f222d..c65f7eaced7a4e7c142d822936a7a9154118fd1d 100644 (file)
@@ -43,7 +43,7 @@ _libParaMEDMEM_Swig_la_CPPFLAGS = $(PYTHON_INCLUDES) \
        $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \
        -I$(srcdir)/../INTERP_KERNEL \
        $(MPI_INCLUDES) -I$(srcdir)/../ParaMEDMEM -I$(srcdir)/../MEDCoupling_Swig -I$(srcdir)/../INTERP_KERNEL/Bases \
-       -I$(srcdir)/../MEDCoupling -I$(srcdir)/../ParaMEDLoader -I$(srcdir)/../MEDLoader
+       -I$(srcdir)/../MEDCoupling -I$(srcdir)/../ParaMEDLoader -I$(srcdir)/../MEDLoader -I$(srcdir)/../MEDLoader/Swig
 
 _libParaMEDMEM_Swig_la_LDFLAGS  = -module $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS) $(MPI_LIBS) \
        ../MEDCoupling/libmedcoupling.la ../INTERP_KERNEL/libinterpkernel.la \