Salome HOME
fix conflict
authorCédric Aguerre <cedric.aguerre@edf.fr>
Mon, 30 Nov 2015 15:55:49 +0000 (16:55 +0100)
committerCédric Aguerre <cedric.aguerre@edf.fr>
Mon, 30 Nov 2015 15:55:49 +0000 (16:55 +0100)
71 files changed:
1  2 
medtool/doc/user/doxygen/Doxyfile_med_user.in
medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesmeshes.doxy
medtool/doc/user/doxygen/doxfiles/reference/distrib/parallel.dox
medtool/doc/user/doxygen/doxfiles/reference/fields/discretization.dox
medtool/doc/user/doxygen/doxfiles/reference/interpolation/Geometric2D.dox
medtool/doc/user/doxygen/doxfiles/reference/interpolation/interpolation.dox
medtool/doc/user/doxygen/doxfiles/reference/interpolation/intersectors.dox
medtool/doc/user/doxygen/doxy2swig/doxy2swig.cmake
medtool/doc/user/doxygen/fakesources/MEDCouplingFieldDouble.C
medtool/doc/user/doxygen/fakesources/MEDCouplingMemArray.C
medtool/doc/user/doxygen/fakesources/MEDCouplingMesh.C
medtool/doc/user/doxygen/fakesources/MEDCouplingUMesh.C
medtool/doc/user/doxygen/fakesources/MEDFileField.C
medtool/doc/user/doxygen/fakesources/MEDFileMesh.C
medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx
medtool/src/INTERP_KERNEL/InterpolationOptions.hxx
medtool/src/INTERP_KERNEL/InterpolationUtils.hxx
medtool/src/INTERP_KERNEL/PolygonAlgorithms.hxx
medtool/src/MEDCoupling/MEDCouplingAMRAttribute.cxx
medtool/src/MEDCoupling/MEDCouplingFieldTemplate.hxx
medtool/src/MEDCoupling/MEDCouplingMesh.cxx
medtool/src/MEDCoupling/MEDCouplingRefCountObject.hxx
medtool/src/MEDCoupling/MEDCouplingUMesh.cxx
medtool/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py
medtool/src/MEDLoader/MEDFileMeshLL.cxx
medtool/src/MEDLoader/SauvMedConvertor.cxx
medtool/src/MEDLoader/Test/MEDLoaderTest.cxx
medtool/src/MEDLoader/Test/MEDLoaderTest.hxx
medtool/src/ParaMEDMEM/BlockTopology.cxx
medtool/src/ParaMEDMEM/BlockTopology.hxx
medtool/src/ParaMEDMEM/CMakeLists.txt
medtool/src/ParaMEDMEM/CommInterface.cxx
medtool/src/ParaMEDMEM/ComponentTopology.hxx
medtool/src/ParaMEDMEM/DEC.hxx
medtool/src/ParaMEDMEM/DECOptions.hxx
medtool/src/ParaMEDMEM/DisjointDEC.cxx
medtool/src/ParaMEDMEM/DisjointDEC.hxx
medtool/src/ParaMEDMEM/ElementLocator.cxx
medtool/src/ParaMEDMEM/ElementLocator.hxx
medtool/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx
medtool/src/ParaMEDMEM/ExplicitMapping.hxx
medtool/src/ParaMEDMEM/ExplicitTopology.cxx
medtool/src/ParaMEDMEM/ExplicitTopology.hxx
medtool/src/ParaMEDMEM/InterpKernelDEC.cxx
medtool/src/ParaMEDMEM/InterpolationMatrix.hxx
medtool/src/ParaMEDMEM/LinearTimeInterpolator.hxx
medtool/src/ParaMEDMEM/MPIAccessDEC.cxx
medtool/src/ParaMEDMEM/MPIAccessDEC.hxx
medtool/src/ParaMEDMEM/MPIProcessorGroup.cxx
medtool/src/ParaMEDMEM/MxN_Mapping.cxx
medtool/src/ParaMEDMEM/MxN_Mapping.hxx
medtool/src/ParaMEDMEM/NonCoincidentDEC.cxx
medtool/src/ParaMEDMEM/OverlapDEC.cxx
medtool/src/ParaMEDMEM/OverlapDEC.hxx
medtool/src/ParaMEDMEM/OverlapElementLocator.hxx
medtool/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx
medtool/src/ParaMEDMEM/OverlapMapping.hxx
medtool/src/ParaMEDMEM/ParaFIELD.cxx
medtool/src/ParaMEDMEM/ParaFIELD.hxx
medtool/src/ParaMEDMEM/ParaGRID.cxx
medtool/src/ParaMEDMEM/ParaGRID.hxx
medtool/src/ParaMEDMEM/ParaMESH.cxx
medtool/src/ParaMEDMEM/ParaMESH.hxx
medtool/src/ParaMEDMEM/ProcessorGroup.hxx
medtool/src/ParaMEDMEM/StructuredCoincidentDEC.cxx
medtool/src/ParaMEDMEM/StructuredCoincidentDEC.hxx
medtool/src/ParaMEDMEM/TimeInterpolator.hxx
medtool/src/ParaMEDMEM/Topology.hxx
medtool/src/ParaMEDMEMTest/CMakeLists.txt
medtool/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx
medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx

index 6c4cc970df7713332fb133920dbe51a29146d4fc,0000000000000000000000000000000000000000..dbb6c559689e16c1c50ed87173bae124bb01e3a5
mode 100644,000000..100644
--- /dev/null
@@@ -1,282 -1,0 +1,286 @@@
 +# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 +#
 +# 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, or (at your option) any later version.
 +#
 +# 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
 +#
 +
 +# Doxyfile 0.1
 +#---------------------------------------------------------------------------
 +# General configuration options
 +#---------------------------------------------------------------------------
 +#
 +PROJECT_NAME           = "SALOME MED Users' Guide"
 +PROJECT_NUMBER         =
 +OUTPUT_DIRECTORY       = doc_ref_user
 +OUTPUT_LANGUAGE        = English
 +EXTRACT_ALL            = YES
 +EXTRACT_PRIVATE        = NO
 +EXTRACT_STATIC         = NO
 +HIDE_UNDOC_MEMBERS     = YES
 +HIDE_UNDOC_CLASSES     = YES
 +BRIEF_MEMBER_DESC      = NO
 +REPEAT_BRIEF           = YES
 +ALWAYS_DETAILED_SEC    = NO
 +FULL_PATH_NAMES        = NO
 +STRIP_FROM_PATH        =
 +INTERNAL_DOCS          = NO
 +STRIP_CODE_COMMENTS    = YES
 +CASE_SENSE_NAMES       = YES
 +SHORT_NAMES            = NO
 +HIDE_SCOPE_NAMES       = NO
 +VERBATIM_HEADERS       = NO
 +SHOW_INCLUDE_FILES     = NO
 +JAVADOC_AUTOBRIEF      = NO
 +INHERIT_DOCS           = YES
 +MARKDOWN_SUPPORT       = YES
 +INLINE_INFO            = NO
 +SORT_MEMBER_DOCS       = NO
 +DISTRIBUTE_GROUP_DOC   = NO
 +TAB_SIZE               = 8
 +GENERATE_TODOLIST      = YES
 +GENERATE_TESTLIST      = YES
 +GENERATE_BUGLIST       = YES
 +ALIASES                =
 +ENABLED_SECTIONS       = user MEDCOUPLING_ug
 +MAX_INITIALIZER_LINES  = 30
 +OPTIMIZE_OUTPUT_FOR_C  = NO
 +SHOW_USED_FILES        = NO
 +SORT_BRIEF_DOCS        = YES
 +#---------------------------------------------------------------------------
 +# configuration options related to warning and progress messages
 +#---------------------------------------------------------------------------
 +QUIET                  = NO
 +WARNINGS               = YES
 +WARN_IF_UNDOCUMENTED   = YES
 +WARN_FORMAT            = "$file:$line: $text"
 +WARN_LOGFILE           = log_user
 +#---------------------------------------------------------------------------
 +# configuration options related to the input files
 +#---------------------------------------------------------------------------
 +
 +INPUT                  = @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/index.dox \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/faq.dox \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/start \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/tutorial.dox \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/gui.dox \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/arrays \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/meshes \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/fields \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/medloader \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/interpolation \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/cpp \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/distrib \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/misc \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/examples/examples.dox \                         
 +                         @CMAKE_CURRENT_BINARY_DIR@/medcouplingexamplesPY.dox \
 +                         @CMAKE_CURRENT_BINARY_DIR@/medcouplingexamplesCPP.dox \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/appendix \
 +                         @CMAKE_CURRENT_SOURCE_DIR@/fakesources \
 +                         @PROJECT_SOURCE_DIR@/src/ParaMEDMEM \
 +                         @PROJECT_SOURCE_DIR@/src/INTERP_KERNEL \
 +                         @PROJECT_SOURCE_DIR@/src/INTERP_KERNEL/Bases \
 +                         @PROJECT_SOURCE_DIR@/src/INTERP_KERNEL/Geometric2D \
 +                         @PROJECT_SOURCE_DIR@/src/MEDCoupling \
 +                         @PROJECT_SOURCE_DIR@/src/MEDLoader \
 +                         @PROJECT_SOURCE_DIR@/src/MEDCouplingCorba 
 +
 +FILE_PATTERNS          = InterpKernelDEC.* \
 +                         OverlapDEC.* \
 +                         DEC.* \
++                         DECOptions.* \
 +                         DisjointDEC.* \
++                         *Topology.* \
 +                         MPIProcessorGroup.* \
++                         ProcessorGroup.* \
 +                         MPIAccess.* \
 +                         StructuredCoincidentDEC.* \
 +                         ExplicitCoincidentDEC.* \
 +                         NonCoincidentDEC.* \
 +                         CommInterface.* \
 +                         ICoCo*.* \
 +                         NormalizedGeometricTypes \
 +                         NormalizedUnstructuredMesh.* \
 +                         Interpolation2D.* \
 +                         Interpolation3D.* \
 +                         Interpolation3DSurf.* \
 +                         InterpolationMatrix.* \
 +                         PlanarIntersector.* \
 +                         TargetIntersector.* \
 +                         Interpolation.* \
 +                         InterpolationOptions.* \
 +                         InterpKernelGeo2DAbstractEdge.* \
 +                         InterpKernelGeo2DEdge.* \
 +                         InterpKernelGeo2DEdgeArcCircle.* \
 +                         InterpKernelGeo2DEdgeLin.* \
 +                         InterpKernelGeo2DComposedEdge.* \
 +                         InterpKernelGeo2DElementaryEdge.* \
 +                         InterpKernelGeo2DNode.* \
 +                         InterpKernelGeo2DQuadraticPolygon.* \
 +                         ParaFIELD.* \
++                         ParaMESH.* \
 +                         MEDCouplingMesh.* \
 +                         MEDCouplingUMesh.* \
 +                         MEDCoupling1GTUMesh.* \
 +                         MEDCouplingPointSet.* \
 +                         MEDCouplingCMesh.* \
 +                         MEDCouplingIMesh.* \
 +                         MEDCouplingStructuredMesh.* \
 +                         MEDCouplingCurveLinearMesh.* \
 +                         MEDCouplingExtrudedMesh.* \
 +                         MEDCouplingFieldDouble.* \
 +                         MEDCouplingField.* \
 +                         MEDCouplingNatureOfFieldEnum \
 +                         MEDCouplingNatureOfField.hxx \
 +                         MEDCouplingFieldTemplate.* \
 +                         MEDCouplingFieldDiscretization.* \
 +                         MEDCouplingTimeDiscretization.* \
 +                         MEDCouplingAMRAttribute.* \
 +                         MEDCouplingCartesianAMRMesh.* \
 +                         MEDCouplingTimeLabel.* \
 +                         MEDCouplingRefCountObject.* \
 +                         MEDCouplingAutoRefCountObjectPtr.* \
 +                         MEDCouplingMemArray.* \
 +                         MEDCouplingGaussLocalization.* \
 +                         MEDCouplingRemapper.* \
 +                         MEDLoader.* \
 +                         MEDFileData.* \
 +                         MEDFileParameter.* \
 +                         MEDFileMesh.* \
 +                         MEDFileField.* \
 +                         *Servant.* \
 +                         *.dox
 +RECURSIVE              = YES
 +EXCLUDE                = CVS
 +EXCLUDE_PATTERNS       = *~
 +EXAMPLE_PATH           = @PROJECT_SOURCE_DIR@/src/ParaMEDMEM \
 +                         @PROJECT_SOURCE_DIR@/src/MEDCoupling/Test \
 +                         @PROJECT_SOURCE_DIR@/src/MEDCoupling_Swig \
 +                         @PROJECT_SOURCE_DIR@/src/MEDLoader/Swig
 +EXAMPLE_PATTERNS       = *.cxx *.py
 +EXAMPLE_RECURSIVE      = NO
 +IMAGE_PATH             = @CMAKE_CURRENT_SOURCE_DIR@/figures
 +INPUT_FILTER           =
 +FILTER_SOURCE_FILES    = NO
 +#---------------------------------------------------------------------------
 +# configuration options related to source browsing
 +#---------------------------------------------------------------------------
 +SOURCE_BROWSER         = NO
 +INLINE_SOURCES         = NO
 +REFERENCED_BY_RELATION = YES
 +REFERENCES_RELATION    = YES
 +#---------------------------------------------------------------------------
 +# configuration options related to the alphabetical class index
 +#---------------------------------------------------------------------------
 +ALPHABETICAL_INDEX     = YES
 +COLS_IN_ALPHA_INDEX    = 5
 +IGNORE_PREFIX          =
 +#---------------------------------------------------------------------------
 +# configuration options related to the HTML output
 +#---------------------------------------------------------------------------
 +GENERATE_HTML          = YES
 +HTML_OUTPUT            = html
 +HTML_HEADER            = @CMAKE_CURRENT_BINARY_DIR@/static/header.html
 +HTML_FOOTER            = @CMAKE_CURRENT_SOURCE_DIR@/static/footer.html
 +HTML_EXTRA_STYLESHEET  = @CMAKE_CURRENT_SOURCE_DIR@/static/salome_extra.css
 +GENERATE_HTMLHELP      = NO
 +GENERATE_CHI           = YES
 +BINARY_TOC             = NO
 +TOC_EXPAND             = YES
 +DISABLE_INDEX          = NO
 +ENUM_VALUES_PER_LINE   = 4
 +GENERATE_TREEVIEW      = YES
 +TREEVIEW_WIDTH         = 250
 +
 +#---------------------------------------------------------------------------
 +#SORT related options
 +#---------------------------------------------------------------------------
 +SORT_GROUP_NAMES = NO
 +
 +#---------------------------------------------------------------------------
 +# configuration options related to the LaTeX output
 +#---------------------------------------------------------------------------
 +GENERATE_LATEX         = YES
 +LATEX_OUTPUT           = latex
 +COMPACT_LATEX          = YES
 +PAPER_TYPE             = a4wide
 +EXTRA_PACKAGES         =
 +LATEX_HEADER           =
 +PDF_HYPERLINKS         = NO
 +USE_PDFLATEX           = NO
 +LATEX_BATCHMODE        = NO
 +#---------------------------------------------------------------------------
 +# configuration options related to the RTF output
 +#---------------------------------------------------------------------------
 +GENERATE_RTF           = NO
 +RTF_OUTPUT             = rtf
 +COMPACT_RTF            = NO
 +RTF_HYPERLINKS         = NO
 +RTF_STYLESHEET_FILE    =
 +RTF_EXTENSIONS_FILE    =
 +#---------------------------------------------------------------------------
 +# configuration options related to the man page output
 +#---------------------------------------------------------------------------
 +GENERATE_MAN           = NO
 +MAN_OUTPUT             = man
 +MAN_EXTENSION          = .3
 +MAN_LINKS              = NO
 +#---------------------------------------------------------------------------
 +# configuration options related to the XML output
 +#---------------------------------------------------------------------------
 +GENERATE_XML           = YES
 +XML_OUTPUT             = xml
 +XML_PROGRAMLISTING     = NO
 +#---------------------------------------------------------------------------
 +# Configuration options related to the preprocessor
 +#---------------------------------------------------------------------------
 +ENABLE_PREPROCESSING   = YES
 +MACRO_EXPANSION        = YES
 +EXPAND_ONLY_PREDEF     = YES
 +SEARCH_INCLUDES        = YES
 +INCLUDE_PATH           =
 +INCLUDE_FILE_PATTERNS  =
 +PREDEFINED             =
 +EXPAND_AS_DEFINED      = MEDCOUPLING_EXPORT MEDCOUPLINGREMAPPER_EXPORT MEDLOADER_EXPORT
 +SKIP_FUNCTION_MACROS   = YES
 +#---------------------------------------------------------------------------
 +# Configuration::additions related to external references
 +#---------------------------------------------------------------------------
 +TAGFILES               =
 +GENERATE_TAGFILE       =
 +ALLEXTERNALS           = NO
 +PERL_PATH              = /usr/bin/perl
 +#---------------------------------------------------------------------------
 +# Configuration options related to the dot tool
 +#---------------------------------------------------------------------------
 +CLASS_DIAGRAMS         = YES
 +HAVE_DOT               = YES
 +CLASS_GRAPH            = YES
 +COLLABORATION_GRAPH    = YES
 +TEMPLATE_RELATIONS     = YES
 +HIDE_UNDOC_RELATIONS   = YES
 +INCLUDE_GRAPH          = YES
 +INCLUDED_BY_GRAPH      = YES
 +GRAPHICAL_HIERARCHY    = YES
 +DOT_PATH               =
 +DOT_FONTNAME           = Arial
 +DOTFILE_DIRS           =
 +GENERATE_LEGEND        = YES
 +DOT_CLEANUP            = YES
 +#---------------------------------------------------------------------------
 +# Configuration::additions related to the search engine
 +#---------------------------------------------------------------------------
 +SEARCHENGINE           = NO
index e094324739f7c6238709ed1db7c06c2cf43fe675,0000000000000000000000000000000000000000..166b7a209a002ddc31e9da797666f2a6a45a89e0
mode 100644,000000..100644
--- /dev/null
@@@ -1,675 -1,0 +1,676 @@@
- When this mesh is no more needed simply call decrRef to decrement its reference counter.
 +
 +\section ExamplesMeshes Meshes
 +
 +\subsection ExamplesMeshesCreate Create
 +
 +\subsubsection medcouplingcppexamplesUmeshStdBuild1 Standard build of an unstructured mesh from scratch
 +
 +Firstly retrieve basic data in full interlace mode for coordinates, and nodal connectivity cell per cell.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_1
 +
 +Then create ParaMEDMEM::MEDCouplingUMesh instance giving its mesh dimension (2 here) and a name.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_2
 +
 +Gives an upper bound of the number of cells to be inserted into the unstructured mesh.
 +\n Then enter nodal connectivity of all cells, cell per cell using ParaMEDMEM::MEDCouplingUMesh::insertNextCell method.
 +\n When the nodal connectivity cell per cell has been finished, call ParaMEDMEM::MEDCouplingUMesh::finishInsertingCells method in order to restore \b mesh instance.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_3
 +
 +At this level the connectivity part of the mesh \b mesh as been defined. Now let's set the coordinates using array \b coords defined above.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_4
 +
 +At this level mesh is usable. When this mesh is no more needed simply call decrRef to decrement its reference counter.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_5
 +
 +
 +\subsubsection medcouplingcppexamplesUmeshAdvBuild1 Advanced build of an unstructured mesh from scratch
 +
 +Firstly retrieve basic data in full interlace mode for coordinates, and nodal connectivity cell per cell, cell type \b included (3 for INTERP_KERNEL::NORM_TRI3 and 4 for INTERP_KERNEL::QUAD4).
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_1
 +
 +Then create ParaMEDMEM::MEDCouplingUMesh instance giving its mesh dimension (2 here) and a name.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_2
 +
 +Then enter nodal connectivity at once.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_3
 +
 +At this level the connectivity part of the mesh \b mesh as been defined. Now let's set the coordinates using array \b coords defined above.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_4
 +
 +At this level mesh is usable. When this mesh is no more needed simply call decrRef() to decrement its reference counter.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_5
 +
 +
 +\subsubsection medcouplingcppexamplesCmeshStdBuild1 Standard build of an cartesian mesh from scratch
 +
 +We are going to build a 2D cartesian mesh, constituted from 9 nodes along X axis, and 7 nodes along Y axis.
 +
 +Firstly retrieve for each direction the discretization and build a \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble instance" on the corresponding direction.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_1
 +
 +Then create ParaMEDMEM::MEDCouplingCMesh instance giving the 2 instances of \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" obtained above.
 +
 +There are 2 techniques to get it.
 +
 +Either :
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_2
 +
 +Or :
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_2bis
 +
 +\c mesh is now available for use :
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_3
 +
++When this mesh is no more needed simply call decrRef to decrement its reference counter (nothing
++to be done in Python).
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_4
 +
 +
 +\subsubsection cpp_mcumesh_buildBoundaryMesh Getting a bounding mesh
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildBoundaryMesh "buildBoundaryMesh()" to get a mesh
 +of lower dimension bounding \b mesh.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2
 +Depending on the value of a parameter,
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildBoundaryMesh "buildBoundaryMesh()"
 +creates the mesh sharing the node coordinates array with \b mesh or not.
 +
 +
 +\subsubsection cpp_mcumesh_buildFacePartOfMySelfNode Retrieving a lower dimension mesh based on given nodes
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1
 +In the following code we retrieve nodes of the cell #0 an then we call
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()"
 +twice with these nodes and with varying last parameter \b allNodes as input.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2
 +<br>If the last parameter is \c true
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" looks
 +for segements whose all nodes are given to it, hence it finds segments bounding the cell #0 only.
 +<br>If the last parameter is \c false
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" looks
 +for any segment whose nodes are given to it, hence it adds more segments to \b mesh2.
 +
 +
 +\subsubsection cpp_mcumesh_buildPartOfMySelfNode Copying cells selected by nodes
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1
 +In the following code we retrieve nodes of the cell #0 an then we call
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()"
 +twice with these nodes and with varying last parameter \b allNodes as input.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2
 +<br>If the last parameter is \c true
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" looks
 +for cells whose all nodes are given to it, hence it finds the cell #0 only.
 +<br>If the last parameter is \c false
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" looks
 +for any cell whose nodes are given to it, hence it finds all cells of \b mesh because all
 +cells share the node #4.
 +
 +
 +\subsubsection cpp_mcumesh_buildPartOfMySelf Getting a part of mesh
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelf "buildPartOfMySelf()" to get a mesh
 +containing only two cells of \b mesh.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2
 +
 +
 +\subsection ExamplesMeshesModify Modify
 +
 +\subsubsection cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells Fixing orientation of "extruded" volumes
 +
 +First, we create a mesh with 2 incorrectly oriented "extruded" volumes.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1
 +Now we check that
 +\ref ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells "findAndCorrectBadOriented3DExtrudedCells()"
 +finds and fixes the reversed cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2
 +
 +
 +\subsubsection cpp_mcumesh_arePolyhedronsNotCorrectlyOriented Fixing orientation of polyhedra
 +
 +First, we create a mesh with 2 polyhedra, one of which is incorrectly oriented. We create
 +two "extruded" polyhedra and then convert them to correctly defined polyhedra.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1
 +Now we check that
 +\ref ParaMEDMEM::MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented "arePolyhedronsNotCorrectlyOriented()"
 +finds one reversed cell. After that we fix it using
 +\ref ParaMEDMEM::MEDCouplingUMesh::orientCorrectlyPolyhedrons "orientCorrectlyPolyhedrons()" and
 +re-check the orientation of polyhedra.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2
 +
 +
 +\subsubsection cpp_mcumesh_are2DCellsNotCorrectlyOriented Fixing orientation of faces
 +
 +First, we create a 2D mesh in 3D space with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is
 +reversed comparing with others.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1
 +Now we check that
 +\ref ParaMEDMEM::MEDCouplingUMesh::are2DCellsNotCorrectlyOriented "are2DCellsNotCorrectlyOriented()"
 +finds one reversed face. After that we fix the incorrectly oriented cell using
 +\ref ParaMEDMEM::MEDCouplingUMesh::orientCorrectly2DCells "orientCorrectly2DCells()" and
 +re-check the orientation of cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2
 +
 +
 +\subsubsection cpp_mcumesh_renumberNodesInConn Renumbering nodes in the connectivity array
 +
 +First, we create a 2D mesh with 1 QUAD4 cell and with undefined coordinates of nodes.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn()"
 +to get the following nodal connectivity of a sole cell: 0,1,2,3.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2
 +\b old2newIds array defines how node ids are changed:
 +- new id of node #0 is -1,
 +- new id of node #1 is 3,
 +- new id of node #2 is 4,
 +- new id of node #3 is 1,
 +- new id of node #4 is 0.
 +
 +
 +\subsubsection cpp_mcumesh_renumberNodes Renumbering nodes
 +
 +First, we create a 2D mesh with 4 nodes and no cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_1
 +Next, we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()"
 +to permute nodes so that
 +- old node #0 becomes #2,
 +- old node #1 remains #1,
 +- old node #2 becomes #0,
 +- old node #3 is removed.
 +
 +Number of nodes becomes 3.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_2
 +
 +Next we compare behavior of
 +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()" and that of
 +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes2 "renumberNodes2()" which, in contrast to
 +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()",
 +moves merged nodes to their barycenter.<br>
 +We set #2 as new id of old node #3 and expect that
 +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes2 "renumberNodes2()" moves old nodes #0
 +and #3 to their barycenter (-0.3,0.0) which becomes position of node #2.<br>
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_3
 +
 +
 +\subsubsection cpp_mcumesh_mergeNodes Merging equal nodes
 +
 +First, we create a 2D mesh with 1 QUAD4 and 2 TRI3 cells. The cells are based on 6 nodes
 +of which 2 nodes fully coincide (#3 and #4) and 3 nodes are equal with precision 0.003.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_1
 +Now we merge node duplicates using
 +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" and check values it returns.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_2
 +Contents of \b arr shows ids of old nodes after the merging. The nodes considered equal
 +one to the other have the same id in \b arr.
 +
 +Next we compare behavior of
 +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" and that of
 +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes2 "mergeNodes2()" which, in contrast to
 +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()",
 +moves merged nodes to their barycenter.<br> We expect that
 +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes2 "mergeNodes2()" moves old nodes #0, #2
 +and #5 to their barycenter equal to position of node #2.<br>
 +First we check that
 +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" does not move nodes
 +coincident with the node #2 to the position of node #2, and then we check that
 +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes2()" does move.
 +(We check only the second (Y) component of node coordinates since the first component of
 +these nodes is exactly same.)
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_3
 +
 +
 +\subsubsection cpp_mcumesh_zipConnectivityTraducer Removing cell duplicates
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells, so that
 +- the cell #2 has the same nodal connectivity as the cell #1 does,
 +- the cell #3 has the same nodal connectivity as the cell #0 does,
 +- the cell #4 is based on the same nodes as the cell #0 but nodes order is different.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer "zipConnectivityTraducer()"
 +to remove duplicate cells. Then we check that two cells, having exactly same nodal
 +connectivity with other cells, have been removed.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2
 +Contents of \b arr shows ids of cells after duplicates removal. If a value (cell id)
 +equals to its index in \b arr, this means that the cell is not a duplicate of any cell
 +with lower id. Else, the value gives a cell id to which this cell is equal. <br>
 +Thus, the cells #0 and #1 have no preceding equal cell since \b arr[i] == i.<br>
 +The cell #2 equals to the cell #1 (== \b arr[2] ).<br>
 +The cell #3 equals to the cell #0 (== \b arr[3] ).<br>
 +The cell #4 has no equal cell. This is because the cell comparison technique specified
 +when we called
 +\ref ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer "zipConnectivityTraducer()"
 +was 0 ("exact"), if we had used the technique 2 ("nodal"), \b arr[4] would be 0.
 +
 +
 +\subsubsection cpp_mcumesh_zipCoordsTraducer Removing unused nodes
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1
 +Now we create \b mesh2 including all nodes but only two cells of \b mesh, and we use \ref
 +ParaMEDMEM::MEDCouplingUMesh::zipCoordsTraducer "zipCoordsTraducer()" to remove unused
 +nodes from \b mesh2.
 +\ref ParaMEDMEM::MEDCouplingUMesh::zipCoordsTraducer "zipCoordsTraducer()" returns an array
 +with -1 for unused nodes and new ids for used ones.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2
 +
 +
 +\subsubsection cpp_mcumesh_getNodeIdsInUse Retrieving unused nodes
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1
 +Now we create \b mesh2 including all nodes but only two cells of \b mesh, and we use \ref
 +ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" to get nodes of \b mesh2
 +used in its two cells.
 +\ref ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" returns an array
 +with -1 for unused nodes and new ids for used ones.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2
 +Now we use \b newNbOfNodes returned by
 +\ref ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" to convert \b arr
 +to "New to Old" mode.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3
 +
 +
 +\subsubsection cpp_mcumesh_convertToPolyTypes Conversion of cells to "poly" types
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1
 +Now we convert cells #1 and #3 to type POLYGON and check the result
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2
 +
 +
 +\subsubsection cpp_mcpointset_scale Scaling the mesh
 +
 +First, we create a 2D mesh with 4 nodes and no cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_1
 +Then we scale it by a factor of 2 with a center (0.,0.).
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_2
 +Finally we check that all node coordinates have changed by more than 0.9.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_3
 +
 +
 +\subsubsection cpp_mcpointset_translate Translating the mesh
 +
 +First, we create a 2D mesh with 4 nodes and no cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_1
 +Then we translate it by a vector (1.,1.).
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_2
 +Finally we check that all node coordinates have changed by more than 0.9.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_3
 +
 +
 +\subsubsection cpp_mcpointset_rotate Rotating the mesh
 +
 +First, we create a 2D mesh with 4 nodes and no cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_1
 +Then we rotate it around a point (0.,0.) by 90 degrees clockwise.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_2
 +Next, we make a 3D mesh from the 2D one and rotate it around the Z axis by 90 degrees
 +counter-clockwise.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_3
 +Finally we transform the mesh back to 2D space and check that all nodes get back to the
 +initial location.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_4
 +
 +
 +\subsection ExamplesMeshesAccess Access
 +
 +\subsubsection cpp_mccmesh_getCoordsAt Getting node coordinates along an axis
 +
 +We create an 1D Cartesian mesh and retrieves node coordinates using
 +\ref ParaMEDMEM::MEDCouplingCMesh::getCoordsAt "getCoordsAt()".
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingCMesh_getCoordsAt_1
 +
 +
 +\subsubsection cpp_mcpointset_getcoordinatesofnode Getting coordinates of a node
 +
 +The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh
 +"MEDCouplingUMesh" with 3 nodes and no cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1
 +Here we get coordinates of the second node and check its two coordinates.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2
 +
 +
 +\subsubsection cpp_mcumesh_areCellsIncludedIn Cells correspondence in two meshes
 +
 +First, we create a 2D \b mesh1 with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1
 +Then we create a \b mesh2 which includes cells #4, #2 and #0 of \b mesh1. The two meshes
 +share the same node coordinates array.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2
 +Now we ascertain that
 +- \ref ParaMEDMEM::MEDCouplingUMesh::areCellsIncludedIn "areCellsIncludedIn()"
 +detects that all cells of \b mesh2 are present in \b mesh1,
 +-  the correspondence array \b corr2to1, which gives cell ids of \b mesh2 within
 +\b mesh1, is equal to the array \b cells2 which selected cells from \b mesh1 for creation
 +of \b mesh2.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3
 +Now we apply
 +\ref ParaMEDMEM::MEDCouplingUMesh::areCellsIncludedIn "areCellsIncludedIn()"
 +in a reverse direction and ascertain that it returns \c false.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4
 +The contents of the correspondence
 +array \b corr1to2 [2, 3, 1, 4, 0] means the following.
 +- The cell #0 of \b mesh1 is equal to the cell #2 (== \b corr1to2[ 0 ]) of \b mesh2.
 +- The cell #1 of \b mesh1 is missing from \b mesh2 (as \b corr1to2[ 1 ] >= \b mesh2->getNumberOfCells()).
 +- The cell #2 of \b mesh1 is equal to the cell #1 (== \b corr1to2[ 2 ]) of \b mesh2.
 +- The cell #3 of \b mesh1 is missing from \b mesh2 (as \b corr1to2[ 3 ] >= \b mesh2->getNumberOfCells()).
 +- The cell #4 of \b mesh1 is equal to the cell #0 (== \b corr1to2[ 4 ]) of \b mesh2.
 +
 +
 +\subsubsection cpp_mcumesh_checkDeepEquivalWith Deep comparison of meshes
 +
 +First, we create two 2D meshes with two triangles, so that
 +- their nodes are almost same but permuted,
 +- the first triangle is based exactly on the same nodes (taking the permutation into account),
 +- an order of nodes in the second triangle is changed.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1
 +Then we check that
 +- \ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalWith "checkDeepEquivalWith()"
 +considers the meshes equal (i.e. it does not throw any exception) if it is called with a cell
 +comparison policy \b cellCompPol == 1
 +-  mapping from \b mesh1 to \b mesh2 for both nodes and cells is as expected.
 +
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2
 +Next we ascertain that
 +\ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith "checkDeepEquivalOnSameNodesWith()"
 +consider \b mesh1 and \b mesh2 different as they do not share the same nodal connectivity
 +array. <br>
 +After that we make the meshes share the node coordinates array and insert new
 +triangles based on the same nodes but in different order. This is to ascertain that
 +\ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith "checkDeepEquivalOnSameNodesWith()"
 +called with the weakest cell comparison policy considers the meshes equal.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3
 +
 +
 +\subsubsection cpp_mcumesh_getPartBarycenterAndOwner Getting barycenters of cells
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::getPartBarycenterAndOwner "getPartBarycenterAndOwner()" to get
 +barycenters of all but the first cell.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_3
 +The returned array contains 4 tuples per 2 components.
 +
 +
 +\subsubsection cpp_mcumesh_getCellsContainingPoints Finding cells containing a point (multi-point case)
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1
 +Then we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::getCellsContainingPoints "getCellsContainingPoints()" to
 +get cells in contact with tree points. Two of them are in contact with some cells and one is not.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2
 +The contents of the result arrays \b cells ([4, 0, 1]) and \b cellsIndex ([0, 0, 1, 3])
 +mean the following.
 +- Point #0 is in contact with none (== \b cellsIndx[1] - \b cellsIndx[0]) cell.
 +- Point #1 is in contact with 1 (== \b cellsIndx[2] - \b cellsIndx[1]) cell whose id is #4
 +  (== \b cells[ \b cellsIndx[ 1 ]]).
 +- Point #2 is in contact with 2 (== \b cellsIndx[3] - \b cellsIndx[2]) cells whose ids are #0
 +  (== \b cells[ \b cellsIndx[ 2 ]]) and #1 (== \b cells[ \b cellsIndx[ 2 ] + 1 ]).
 +
 +
 +\subsubsection cpp_mcumesh_getCellsContainingPoint Finding cells containing a point
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1
 +Then we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::getCellsContainingPoint "getCellsContainingPoint()" to
 +get cells in contact with a small ball (point with precision) located near the node #4 and
 +shifted from this node by its radius \b eps.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2
 +Since the node #4 is shared by all cells, size of the vector \b cellIds must be equal to
 +the number of cells in \b mesh.
 +
 +
 +\subsubsection cpp_mcumesh_buildPartOrthogonalField Getting normals of cells
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is
 +reversed.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField "buildPartOrthogonalField()" to get
 +normal vectors to the cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2
 +
 +
 +\subsubsection cpp_mcumesh_getPartMeasureField Getting volumes of cells
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is
 +reversed.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField "getPartMeasureField()" to get
 +volumes of all but the first cell. If we call
 +\ref ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField "getPartMeasureField()" with \b
 +isAbs == \c true, the area of the cell #1 is returned positive, else, negative that
 +reflects its inverse orientation.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_2
 +
 +
 +\subsubsection cpp_mcumesh_getCellsInBoundingBox Getting cells using the bounding box
 +
 +First, we create a 2D mesh with 1 TRI3 cell. Bounding box of this cell is [0.,0., 1.,1].
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1
 +Now we check how
 +\ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()"
 +searches for cells using the bounding box. We use a bounding box touching the bounding box
 +of the sole cell at one point (1.,1.).
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2
 +If \ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" is
 +called with parameter \b eps == 0.0, the cell is not found because the two bounding boxes
 +(one of the cell and the one passed as parameter) do not overlap. <br>
 +If \ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" is
 +called with parameter \b eps == 0.1, the cell is found because \b eps is used to increase
 +the bounding box of the cell and thus the two bounding boxes intersect each other. <br>
 +
 +
 +\subsubsection cpp_mcumesh_findBoundaryNodes Getting boundary nodes
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1
 +Now we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::findBoundaryNodes "findBoundaryNodes()" to get ids
 +of boundary nodes.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2
 +\ref ParaMEDMEM::MEDCouplingUMesh::findBoundaryNodes "findBoundaryNodes()" returns all
 +node ids except the node #4 which is in the middle of \b mesh.
 +
 +
 +\subsubsection cpp_mcumesh_getCellIdsLyingOnNodes Getting cells by nodes
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1
 +In the following code we retrieve nodes of the cell #0 an then we call
 +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()"
 +twice with these nodes and with varying last parameter \b allNodes as input.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2
 +<br>If the last parameter is \c true
 +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" looks
 +for cells whose all nodes are given to it, hence it finds the cell #0 only.
 +<br>If the last parameter is \c false
 +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" looks
 +for any cell whose nodes are given to it, hence it finds all cells of \b mesh because all
 +cells share the node #4.
 +
 +
 +\subsubsection cpp_mcumesh_getCellIdsFullyIncludedInNodeIds Getting cells by nodes
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1
 +In the following code we retrieve nodes of two cells an then we use
 +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds
 +"getCellIdsFullyIncludedInNodeIds()" to find these cells by their nodes.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2
 +
 +
 +\subsubsection cpp_mcumesh_buildDescendingConnectivity2 Retrieving the descending connectivity with orientation
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1
 +Now we get and check the descending connectivity.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2
 +Here we get connectivity of the cell #2 (#3 in FORTRAN mode) of \b mesh2 to see how
 +mutual orientation of cells in \b mesh and \b mesh2 is defined.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3
 +The contents of the result arrays \b desc and \b descIndx mean the following.
 +- The cell #0 of \b mesh (QUAD4) is bound by 4 (== \b descIndx[1] - \b descIndx[0])
 +  segments (SEG2) of \b mesh2 whose ids in FORTRAN mode are
 +  - #1 (== \b desc[ \b descIndx[ 0 ]]),
 +  - #2 (== \b desc[ \b descIndx[ 0 ] + 1 ]),
 +  - #3 (== \b desc[ \b descIndx[ 0 ] + 2 ]) and
 +  - #4 (== \b desc[ \b descIndx[ 0 ] + 3 ]).
 +  <br>Ids are positive since order of nodes in the corresponding cells of \b mesh and \b mesh2
 +  are same. For example nodes of SEG2 #3 are [4,1] and nodes of QUAD4 #0 are [0,3,\b 4,\b 1].
 +- The cell #1 of \b mesh (TRI3) is bound by 3 (== \b descIndx[2] - \b descIndx[1]) segements of
 +  \b mesh2 whose ids in FORTRAN mode are:
 +  - #-3 (== \b desc[ \b descIndx[ 1 ]]),
 +  - #5 (== \b desc[ \b descIndx[ 1 ] + 1 ]) and
 +  - #6 (== \b desc[ \b descIndx[ 1 ] + 2 ]).
 +  <br>The id -3 means that order of nodes in SEG2 #3 ([4,1]) is different from the order of
 +  these nodes in TRI3 #1: [\b 1,\b 4,2].
 +- etc.
 +
 +The contents of the result arrays \b revDesc and \b revDescIndx mean the following.
 +- The cell #0 of \b mesh2 (SEG2) bounds 1 (== \b revDescIndx[1] - \b revDescIndx[0]) cell of \b
 +  mesh whose id is:
 +  - # 0 (== \b revDesc[ \b revDescIndx[ 0 ]]).
 +- The cell #1 of \b mesh2 bounds 2 (== \b revDescIndx[2] - \b revDescIndx[1]) cells of \b
 +  mesh whose ids are:
 +  - # 0 (== \b revDesc[ \b revDescIndx[ 1 ]]) and
 +  - # 1 (== \b revDesc[ \b revDescIndx[ 1 ] + 1 ]).
 +- etc.
 +
 +
 +\subsubsection cpp_mcumesh_buildDescendingConnectivity Retrieving the descending connectivity
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1
 +Now we get and check the descending connectivity.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2
 +The contents of the result arrays \b desc and \b descIndx mean the following.
 +- The cell #0 of \b mesh (QUAD4) is bound by 4 (== \b descIndx[1] - \b descIndx[0])
 +  segments (SEG2) of \b mesh2 whose ids are
 +  - #0 (== \b desc[ \b descIndx[ 0 ]]),
 +  - #1 (== \b desc[ \b descIndx[ 0 ] + 1 ]),
 +  - #2 (== \b desc[ \b descIndx[ 0 ] + 2 ]) and
 +  - #3 (== \b desc[ \b descIndx[ 0 ] + 3 ]).
 +- The cell #1 of \b mesh (TRI3) is bound by 3 (== \b descIndx[2] - \b descIndx[1]) segements of
 +  \b mesh2 whose ids are:
 +  - #2 (== \b desc[ \b descIndx[ 1 ]]),
 +  - #4 (== \b desc[ \b descIndx[ 1 ] + 1 ]) and
 +  - #5 (== \b desc[ \b descIndx[ 1 ] + 2 ]).
 +- etc.
 +
 +The contents of the result arrays \b revDesc and \b revDescIndx mean the following.
 +- The cell #0 of \b mesh2 (SEG2) bounds 1 (== \b revDescIndx[1] - \b revDescIndx[0]) cell of \b
 +  mesh whose id is:
 +  - # 0 (== \b revDesc[ \b revDescIndx[ 0 ]]).
 +- The cell #1 of \b mesh2 bounds 2 (== \b revDescIndx[2] - \b revDescIndx[1]) cells of \b
 +  mesh whose ids are:
 +  - # 0 (== \b revDesc[ \b revDescIndx[ 1 ]]) and
 +  - # 1 (== \b revDesc[ \b revDescIndx[ 1 ] + 1 ]).
 +- etc.
 +
 +
 +\subsubsection cpp_mcumesh_getReverseNodalConnectivity Getting the reverse nodal connectivity
 +
 +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1
 +Now we get and check its reverse nodal connectivity.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2
 +The contents of the result arrays mean the following.
 +- Node #0 is shared by 1 (== \b revNodalIndx[1] - \b revNodalIndx[0]) cell whose id is #0
 +  (== \b revNodal[ \b revNodalIndx[ 0 ]]).
 +- Node #1 is shared by 2 (== \b revNodalIndx[2] - \b revNodalIndx[1]) cells whose ids are #0
 +  (== \b revNodal[ \b revNodalIndx[ 1 ]]) and #1 (== \b revNodal[ \b revNodalIndx[ 1 ] + 1 ]).
 +- etc.
 +
 +
 +\subsubsection cpp_mcpointset_getBoundingBox Getting a minimum box bounding nodes
 +
 +First, we create a 3D mesh with 2 nodes, so that the first one has minimal coordinates and
 +the second one has maximal coordinates.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getBoundingBox_1
 +Now we get a bounding box enclosing these nodes. This bounding box should contain
 +coordinates of our two nodes (but in "no interlace" mode), as the nodes coincide with
 +points returned by the bounding box.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getBoundingBox_2
 +
 +
 +\subsubsection cpp_mcpointset_getnodeidsnearpoint Getting nodes close to a point
 +
 +The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh
 +"MEDCouplingUMesh" with 5 nodes and no cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1
 +Now we define an array of coordinates of a point close to nodes #0, #2 and #4.
 +
 +Thus we expect that
 +\ref ParaMEDMEM::MEDCouplingPointSet::getNodeIdsNearPoint "getNodeIdsNearPoint()" that
 +we are going to use,
 +if called with \b eps = 0.003, would return ids of nodes #0, #2 and #4.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2
 +
 +
 +\subsubsection cpp_mcpointset_getnodeidsnearpoints Getting nodes close to some points
 +
 +The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh
 +"MEDCouplingUMesh" with 7 nodes and no cells.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1
 +Now we define an array of coordinates of 3 points near which we want to find nodes of the mesh.
 +- Point #0 is at distance 0.001 from the node #1.
 +- Point #1 is rather far from all nodes.
 +- Point #2 is close to nodes #3, #4 and #5.
 +
 +Thus we expect that
 +\ref ParaMEDMEM::MEDCouplingPointSet::getNodeIdsNearPoints "getNodeIdsNearPoints()" that
 +we are going to use,
 +if called with \b eps = 0.003, would return ids of close nodes #1, #3, #4 and #5.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2
 +\b idsIndex returns [0, 1, 1, 4] which means that:
 +- Point #0 is close to 1 (== \b idsIndex[1] - \b idsIndex[0]) node whose id is
 +\b ids[ \b idsIndex[ 0 ]].
 +- Point #1 is close to 0 (== \b idsIndex[2] - \b idsIndex[1]) nodes.
 +- Point #2 is close to 3 (== \b idsIndex[3] - \b idsIndex[2]) nodes whose ids are
 +\b ids[ \b idsIndex[ 2 ]], \b ids[ \b idsIndex[ 2 ] + 1 ] and \b ids[ \b idsIndex[ 2 ] + 2 ].
 +
 +
 +\subsubsection cpp_mcpointset_findcommonnodes Finding coincident nodes
 +
 +First, we create a mesh with 6 nodes, of which two nodes (#3 and #4) are fully coincident
 +and 3 nodes (#0, #2 and #5) have distance less than 0.004 between them.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_findCommonNodes_1
 +Then, we use \ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes()" to find
 +coincident nodes, and check that (1) calling
 +\ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes()" with \b prec
 +== 1e-13 finds the two fully coincident nodes only and (2)
 +\ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes"(0.004) finds 5
 +equal nodes.
 +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_findCommonNodes_2
index d53c9965fe2f0e682a9647d38c3862d373b953cd,0000000000000000000000000000000000000000..0c197817a02a6a3071c462af5d6939dbdc8110b6
mode 100644,000000..100644
--- /dev/null
@@@ -1,33 -1,0 +1,81 @@@
- \section para-over Base elements
 +/*!
 +\page parallel Parallelism 
 +
- in a parallel context.
- For historical reasons, they are all in the same namespace as the non-parallel MEDCoupling functionalities,
++\section para-over Building blocks
 +
 +Several classes and methods are available in the MED library to ease the exchange of information
- - \ref ParaFIELD-det "ParaFIELD", the parallel instanciation of a MEDCoupling field
- - \ref CommInterface-det "CommInterface", communication interface to the gateway to the MPI library
- - \ref MPIProcessorGroup-det "MPIProcessorGroup", a group of processor in a parallel computation
- along with all the DEC explained below.
++in a parallel context. The DECs (\ref para-dec "detailed further down") then use those classes to enable 
++the parallel remapping (projection) of a field.
++For historical reasons, all those items are in the same namespace as the non-parallel MEDCoupling functionalities,
 +<b>%ParaMEDMEM</b>.
 +
 +The core elements of the API are:
- A Data Exchange Channel allows the transfer of information between two processor groups.
- There are several variants of DEC depending on what you are aiming at:
++- \ref CommInterface-det "CommInterface", this is the wrapper around the MPI library, and an instance
++of this object is required in many constructors of the following objects.  
++- \ref ParaMESH-det "ParaMESH", the parallel instanciation of a \ref meshes "MEDCoupling mesh" 
++- \ref ParaFIELD-det "ParaFIELD", the parallel instanciation of a \ref fields "MEDCoupling field"
++- \ref MPIProcessorGroup-det "MPIProcessorGroup" (which inherits from the abstract 
++\ref ParaMEDMEM::ProcessorGroup "ProcessorGroup"), a group of processors (typically MPI nodes)
 +
++In an advanced usage, the topology of the nodes in the computation is accessed through the following elements:
++- \ref BlockTopology-det "BlockTopology", specification of a topology based on the (structured) mesh.
++The mesh is divided in block (typically a split along the first axis) which are allocated on the various
++processors.
++- <b> %ExplicitTopology </b> (not fully supported yet and only used internally), specification of user-defined
++topology, still based on the mesh.
++- \ref ComponentTopology-det "ComponentTopology", specification of a topology allowing the split of 
++several field *components* among different processors. The mesh is not the support of the topology anymore.   
++ 
 +\section para-dec Data Exchange Channel - DEC
 +
- - \ref DisjointDEC-det "DisjointDEC"
- - \ref InterpKernelDEC-det "InterpKernelDEC"
- - \ref NonCoincidentDEC-det "NonCoincidentDEC" 
- - \ref OverlapDEC-det "OverlapDEC"
- - \ref ExplicitCoincidentDEC-det "ExplicitCoincidentDEC"
- - \ref StructuredCoincidentDEC-det "StructuredCoincidentDEC"
-  
-   TODO: more on DEC.
++A Data Exchange Channel (%DEC) allows the transfer and/or the interpolation (remapping) of field data between several
++processors in a parallel (MPI) context.
++Some DECs perform a simple renumbering and copy of the data, and some are capable of functionalities similar to the
++\ref remapper "sequential remapper".
 +
++We list here the main characteristics of the DECs, the list being structured in the same 
++way as the class hierarchy:
++
++- \ref DisjointDEC-det "DisjointDEC", works with two disjoint groups of processors. This is an abstract class.
++    - \ref InterpKernelDEC-det "InterpKernelDEC", inherits the properties of the \c %DisjointDEC. The projection
++    methodology is based on the algorithms of %INTERP_KERNEL, that is to say, they work in a similar fashion than
++    what the \ref remapper "sequential remapper" does. The following \ref discretization "projection methods"
++    are supported: P0->P0 (the most common case), P1->P0, P0->P1.
++    - \ref StructuredCoincidentDEC-det "StructuredCoincidentDEC", also inherits the properties 
++    of the \c %DisjointDEC, but this one is \b not based on the %INTERP_KERNEL algorithms. 
++    This DEC does a simple data transfer between two fields having a common (coincident) structured support,
++    but different topologies (i.e. the structured domain is split differently among the processors for the 
++    two fields). Only the cell identifiers are handled, and no kind of interpolation (in the sense of the 
++    computation of a weight matrix) is performed. It is a "mere" reallocation of data from one domain 
++    partitioning to another.
++    - \b ExplicitCoincidentDEC : as above, but based on an explicit topology. This DEC is used internally but
++    rarely directly in the public API.
++- \ref OverlapDEC-det "OverlapDEC", works with a single processor group, but each processor detains 
++both (part of) the source and target fields. This %DEC can really be seen as the true parallelisation of the 
++\ref remapper "sequential remapper". Similarly to the \ref InterpKernelDEC-det "InterpKernelDEC"
++the projection methodology is based on the algorithms of %INTERP_KERNEL, that is to say, 
++it works in a similar fashion than what the \ref remapper "sequential remapper" does. 
++- \b NonCoincidentDEC (deprecated for now)
++
++Besides, all the DECs inherit from the class \ref ParaMEDMEM::DECOptions "DECOptions" which provides 
++the necessary methods to adjust the parameters used in the transfer/remapping.
++
++The most commonly used %DEC is the \c %InterpKernelDEC, and here is a simple example to of its usage:
++
++ \code
++...
++InterpKernelDEC dec(groupA, groupB);   // groupA and groupB are two MPIProcessorGroup
++dec.attachLocalField(field);           // field is a ParaFIELD, a MEDCouplingField or an ICoCo::MEDField
++dec.synchronize();                     // compute the distributed interpolation matrix
++if (groupA.containsMyRank())
++dec.recvData();                        // effectively transfer the field (receiving side)
++else if (groupB.containsMyRank())
++dec.sendData();                        // effectively transfer the field (sending side) 
++...
++\endcode
 +
++\n
++\n
++\n
 +
 +*/
index 907890bae49754b4c3593a7111100a88aa171f78,0000000000000000000000000000000000000000..6789241ce837008e419d268018a72268f7a0846e
mode 100644,000000..100644
--- /dev/null
@@@ -1,21 -1,0 +1,56 @@@
- TODO: enhance this page
 +/*!
 +\page discretization Spatial and temporal discretizations
 +
- - the nodes (vertices) of the mesh: built with the 
- \ref ParaMEDMEM::MEDCouplingFieldDouble::New "ON_NODES" keyword. This is sometimes called a P1 field.
++When defining a field in MEDCoupling, the notions of spatial and temporal discretizations play 
++a crucial role. 
++
++The spatial discretization details the relationship between the field and its support mesh
++and the temporal discretization gives an indication of the time coverage represented
++by the field.
 +
 +\section field-space Spatial discretization
 +A field can be supported by: 
- \ref ParaMEDMEM::MEDCouplingFieldDouble::New "ON_CELLS" keyword. This is sometimes called a P0 field.
- - or more complex items (Gauss points, etc ...)
++- the nodes (vertices) of the mesh: this is built with the 
++\ref ParaMEDMEM::TypeOfField "ON_NODES" keyword in the 
++\ref ParaMEDMEM::MEDCouplingFieldDouble::New(TypeOfField , TypeOfTimeDiscretization) "constructor of a field". 
++
 +- the cells (or "elements") of the mesh: built with the 
- A field has a temporal discretization. It can be one of:
- - \ref ParaMEDMEM::MEDCouplingFieldDouble::New "NO_TIME"
- - \ref ParaMEDMEM::MEDCouplingFieldDouble::New "ONE_TIME"
- - \ref ParaMEDMEM::MEDCouplingFieldDouble::New "CONST_ON_TIME_INTERVAL"
++\ref ParaMEDMEM::TypeOfField "ON_CELLS" keyword in the 
++\ref ParaMEDMEM::MEDCouplingFieldDouble::New(TypeOfField , TypeOfTimeDiscretization) "constructor of a field". 
++- or more complex items:
++    - Gauss points: built with \ref ParaMEDMEM::TypeOfField "ON_GAUSS_PT"
++    - Gauss points on nodes per element: built with \ref ParaMEDMEM::TypeOfField "ON_GAUSS_NE"
++    - Kriging points:  built with \ref ParaMEDMEM::TypeOfField "ON_NODES_KR"
++
++The spatial discretization is at the center of the \ref interpolation "interpolation" mechanisms,
++since one of the main interpolation paramter is indeed specifying from which source discretization
++to which target discretization one wants to go. For example:
++- a P0->P0 interpolation means that a field on cells will be transfered to another cell-based field;
++- a P1->P0 interpolation means that a field on nodes this time will be transfered to a cell-based field. 
++- etc ...
++
++Finally, in the code itself, the class \ref ParaMEDMEM::MEDCouplingFieldDiscretization "MEDCouplingFieldDiscretization"
++is the concrete representation of this concept.
 +
 +\section field-time Temporal discretization
 +
++Similarly to the spatial discretization, a field object in MEDCoupling has a time discretization
++representing the time range that is covered by the data. It is also specified in the 
++\ref ParaMEDMEM::MEDCouplingFieldDouble::New(TypeOfField , TypeOfTimeDiscretization) "constructor of a field".
++
++It can be one of:
++- \ref ParaMEDMEM::TypeOfTimeDiscretization "NO_TIME", in this case no time is attached to the field, and no
++time-related operation is permitted (for example unable to call 
++\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOn "getValueOn()") 
++- \ref ParaMEDMEM::TypeOfTimeDiscretization "ONE_TIME", the field data represent a single time step. 
++- \ref ParaMEDMEM::TypeOfTimeDiscretization "LINEAR_TIME", the field data contains \b two arrays, stamped with two
++different time points. A linear interpolation of the field values between those two time steps is then possible. 
++- \ref ParaMEDMEM::TypeOfTimeDiscretization "CONST_ON_TIME_INTERVAL", the field data contains a single array
++of data, but a start- and end-time can be specified, thus declaring that the field represent a constant
++set of data during this time interval. All time evaluation function then just check that the given time
++fits in the interval.  
++
++Finally, in the code itself, the class \ref ParaMEDMEM::MEDCouplingTimeDiscretization "MEDCouplingTimeDiscretization"
++is the concrete representation of this concept.
 +
 +*/
index eb0e25dafb5f33ec3823450006f87b3ac8bdcdbd,0000000000000000000000000000000000000000..a00934f610a6b5b46be544de68fee676f2d8364a
mode 100644,000000..100644
--- /dev/null
@@@ -1,237 -1,0 +1,237 @@@
-   - \ref INTERP_KERNEL::ComposedEdge::getAreaOfZone "area" computation is available.
-   - \ref INTERP_KERNEL::QuadraticPolygon::getPerimeterFast "perimeter" computation.
-   - \ref INTERP_KERNEL::QuadraticPolygon::getHydraulicDiameter "Hydraulic diameter" computation.
 +/*!
 +\page interpkernelGeo2D Geometric2D Intersector
 +
 +Like other intersectors the aim of this intersector is to compute intersection between 2
 +polygons.\n
 +The specificity of this intersector is to deal with \b any \b type of
 +polygons even those with \b quadratic \b edges.
 +Its quite generic architecture allows him to deal with some other
 +potentially useful functions.\n
 +This page described Geometric2D intersector basic principles and
 +specific usage.
 +
 +\section interpkernelGeo2DIntro Introduction
 +
 +The principle used in this intersector to perform boolean operation on geometry is geometric-modeler like.
 +The data structure used to describe polygons is boundary description. That is to say the internal
 +representation of a polygon is its edges composing it.
 +
 +\subsection interpkernelGeo2DNamingConv Naming conventions
 +
 +  - An \ref INTERP_KERNEL::Edge "edge" is defined by a start
 +    node, a end node and a curve equation (linear or arc of
 +    circle). \b WARNING : start node and end node \b HAVE \b TO \b BE
 +    different and distant at least equal to precision set.
 +  - An \ref INTERP_KERNEL::ElementaryEdge "elementary edge" is an edge \b NOT \b splittable \b without \b applying
 +    \b mathematical \b intersection \b computation.
 +  - A \ref INTERP_KERNEL::ComposedEdge "composed edge" is a collection of consecutive edges hierarchically \b splittable
 +    \b without \b any \b mathematical \b intersection \b computation.
 +
 +Consecutive means that in a composed edge if edge \a e2 follows edge
 +\a e1, the end node of \a e1 is geometrically equal to start node of
 +\a e2.
 +
 +\subsection interpkernelGeo2DBasicConcepts Basic concepts
 +
 +A \ref INTERP_KERNEL::QuadraticPolygon "quadratic polygon" is a
 +specialization of a
 +\ref INTERP_KERNEL::ComposedEdge "composed edge" in that it is
 +closed. Closed means that the start node of first edge is equal to end
 +node of last edge.\n
 +A \ref INTERP_KERNEL::ComposedEdge "composed edge" is considered as a
 +collection of \ref INTERP_KERNEL::Edge "abstract edges". An
 +\ref INTERP_KERNEL::Edge "abstract edge" is either an \ref
 +INTERP_KERNEL::ElementaryEdge "elementary edge" or itself a \ref
 +INTERP_KERNEL::ComposedEdge "composed edge".\n A composite pattern has
 +been used here.
 +
 +Each \ref INTERP_KERNEL::ElementaryEdge " elementary edge" and each
 +\ref INTERP_KERNEL::Node "nodes" have a flag that states if during
 +the split process if it is \b out, \b on, \b in or \b unknown.
 +
 +\section interpkernelGeo2DBoolOp Boolean operation algorithm
 +
 +\subsection interpkernelGeo2DBoolOpPrinc Basics
 +
 +The boolean operation (intersection) between two polygons is used in P0 P0 interpolation.
 +
 +The process of boolean operations between two polygons P1 and P2 is done in three steps :
 +
 +  -# \ref interpkernelGeo2DBoolOpStep1 "splitting".
 +  -# \ref interpkernelGeo2DBoolOpStep2 "edges localization".
 +  -# \ref interpkernelGeo2DBoolOpStep3 "result polygons building".
 +
 +\subsection interpkernelGeo2DBoolOpStep1 Step1 : splitting.
 +
 +The principle used to do boolean operations between 2 polygons P1 and
 +P2 is to intersect each edge of P1 with each edge of P2. \n After this
 +edge-splitting, polygon P1 is splitted, so that each
 +\ref INTERP_KERNEL::ElementaryEdge "elementary edge" constituting P1
 +is either \b in, \b out or \b on polygon P2. And inversely, polygon P2 is splitted so that each
 +\ref INTERP_KERNEL::ElementaryEdge "elementary edge" constituting P2
 +is either \b in, \b out or \b on polygon P1.
 +
 +During split process, when, without any CPU overhead, the location can be
 +deduced, the nodes and edges are localized.
 +
 +This step of splitting is common to all boolean operations.\n
 +The method in charge of that is INTERP_KERNEL::QuadraticPolygon::splitPolygonsEachOther.
 +
 +\subsection interpkernelGeo2DBoolOpStep2 Step2 : Edges localization.
 +
 +Perform localization of each splitted edge. As \ref interpkernelGeo2DBoolOpStep1 "split process" it
 +     is common to all boolean operations.
 +
 +When the location of edges has \b not been
 +already deduced in previous computation and there is no predecessor, the
 +\ref interpkernelGeo2DAlgLoc "localization is done in absolute".
 +After it deduces the localization relatively to the previous edge
 +thanks to node localization.\n The relative localization is done
 +following these rules :
 +
 + * <TABLE BORDER=1 >
 + * <TR><TD>Previous Edge Loc</TD><TD>Current start node Loc</TD><TD> Current edge Loc</TD></TR>
 + * <TR><TD> UNKNOWN </TD><TD> ANY </TD><TD> UNKNOWN -> \ref interpkernelGeo2DAlgLoc "Absolute search" </TD></TR>
 + * <TR><TD> OUT </TD><TD> ON </TD><TD> IN  </TD></TR>
 + * <TR><TD> OUT </TD><TD> ON_TANGENT </TD><TD> OUT  </TD></TR>
 + * <TR><TD> IN </TD><TD> ON </TD><TD> OUT </TD></TR>
 + * <TR><TD> IN </TD><TD> ON_TANGENT </TD><TD> IN </TD></TR>
 + * <TR><TD> OUT </TD><TD> OUT </TD><TD> OUT </TD></TR>
 + * <TR><TD> IN </TD><TD> IN </TD><TD> IN </TD></TR>
 + * <TR><TD> ON </TD><TD> ANY </TD><TD> UNKNOWN -> \ref interpkernelGeo2DAlgLoc "Absolute search" </TD></TR>
 + *</TABLE>
 +
 +The method in charge of that is INTERP_KERNEL::QuadraticPolygon::performLocatingOperation.
 +
 +\subsection interpkernelGeo2DBoolOpStep3 Step3 : Result polygon building.
 +
 +This stage links each edge with wanted loc. \b Contrary to last 2 steps it is obviously boolean
 +operation dependant. Let's take the case of the intersection that is used in
 +P0->P0 interpolation. \n The principle of result polygon building is to build polygon by taking
 +edges localized as \b in or \b on.
 +
 +Generally, the principle is to take an edge in \a P1 with wanted loc and linking
 +direct neighbour-edges (with correct loc) until closing a polygon. If
 +not, using \a P2 edges to try to close polygon. The process is
 +repeated until all edges with correct loc have been consumed.
 +
 +The method in charge of that is INTERP_KERNEL::QuadraticPolygon::buildIntersectionPolygons.
 +
 +\section interpkernelGeo2DAlg Underlying algorithms
 +
 +\subsection interpkernelGeo2DAlgLoc Absolute localization algorithm
 +
 +This algorithm is called when splitting process has been done, and
 +that we are sure that the edge is either \b fully \b in ,or \b fully \b on or \b fully
 +\b out.
 +
 +The principle chosen to know if an edge \a E is completely included in an
 +any polygon \a P is to see if its barycenter \a B is inside this any
 +polygon \a P.
 +After, for each nodes \f$ P_i \f$ of polygon \a P we store angle in \f$ [-\pi/2,\pi/2 ] \f$
 +that represents the slope of line \f$ (BP_i) \f$.\n
 +Then a line \a L going through \a B with a slope being as far as
 +possible from all slopes found above. Then the algorithm goes along \a L
 +and number of times \a N it intersects \b non-tangentially the any polygon \a P.
 +
 +If \a N is odd \a B (and then \a E) is IN.
 +If \a N is even \a B (and then \a E) is OUT.
 +
 +This computation is \b very \b expensive, that why some tricks as described in
 +\ref interpkernelGeo2DBoolOpStep2 "localization techniques" are used to call as few as possible
 +during intersecting process.
 +
 +\subsection interpkernelGeo2DAlgIntsect Intersection algorithms
 +
 +The only mathematical intersections performed are edges intersections.
 +The algorithms used are :
 +
 +  -# Lin-Lin intersection : http://mathworld.wolfram.com/Line-LineIntersection.html
 +  -# Lin-Arc intersection : http://mathworld.wolfram.com/Circle-LineIntersection.html
 +  -# Arc-Arc intersection : http://mathworld.wolfram.com/Circle-CircleIntersection.html
 +
 +\subsection interpkernelGeo2DAlgOthers Other algorithms
 +
 +As internal architecture is quite general, it is possible to have more than classical intersection on any polygons :
 +
++  - \ref INTERP_KERNEL::ComposedEdge::getArea "area" computation is available.
++  - \ref INTERP_KERNEL::ComposedEdge::getPerimeter "perimeter" computation.
++  - \ref INTERP_KERNEL::ComposedEdge::getHydraulicDiameter "Hydraulic diameter" computation.
 +
 +\section interpkernelGeo2DUsage Usage
 +
 +This intersector is usable standalone. To use a set of user friendly methods have been implemented.
 +
 +  - INTERP_KERNEL::QuadraticPolygon::buildArcCirclePolygon method builds from a \c std::vector of INTERP_KERNEL::Node* \a V, an instance of QuadraticPolygon \a P.
 +  \a P will have \f$ N_{edges} = V.size()/2 \f$ edges. Quadratic edge \f$ Edge_i i \in [0,N_{edges}-1] \f$ starts with node V[i], ends with node V[i+1] and has a middle in
 +   \f$ V[i+N_{edge}] \f$. \n If start, end and middle nodes of edge \f$ Edge_i \f$ are aligned by a precision specified by INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision.
 +  - INTERP_KERNEL::QuadraticPolygon::buildLinearPolygon method builds from a \c std::vector of INTERP_KERNEL::Node* \a V, an instance of QuadraticPolygon \a
 +  P. \a P will have \f$ N_edges = V.size() \f$ edges. Linear edge \f$ Edge_i i \in [0,N_{edges}-1] \f$ starts with node V[i] and ends with node V[i+1].
 +
 +The orientation of polygons (clockwise, inverse clockwise) impact computation only on the sign of areas. During intersection of 2 polygons their orientation can be different.
 +
 +The usage is simple :
 +
 +\code
 +...
 +// defining a precision
 +INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-5);
 +INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5);
 +//
 +INTERP_KERNEL::QuadraticPolygon *polygon1=...;
 +bool isQuadratic=...//Depends on the nature of your cell. If your cell is MED_QUAD8 or MED_TRIA6 for example isQuadratic=true.
 +const double *externalTabXCoords=...;
 +const double *externalTabYCoords=...;
 +std::vector<INTERP_KERNEL::Node *> nodes;
 +INTERP_KERNEL::QuadraticPolygon *polygon2=0;
 +for(int i=0;i<nbOfNodes;i++)
 +  nodes.push_back(new INTERP_KERNEL::Node(externalTabXCoords[i],externalTabYCoords[i]));// First param of Node constructor is its X-axis and the second its Y-axis.
 +if(isQuadratic)
 +  polygon2=INTERP_KERNEL::QuadraticPolygon::buildArcCirclePolygon(nodes);
 +else
 +  polygon2=INTERP_KERNEL::QuadraticPolygon::buildLinearPolygon(nodes);
 +//play with polygons
 +double intersection=polygon1->intersectWith(*polygon2);
 +double dhydPol1=polygon1->getHydraulicDiameter();
 +double areaPol1=polygon1->getAreaOfZone();
 +//clean-up
 +delete polygon1;
 +delete polygon2;
 +...
 +\endcode
 +
 +\section interpkernelGeo2DExample Example of result
 +
 +Here an example of 2 polygons. The left one \a P1 has 4 edges and the
 +right one \a P2 has 4 edges too.
 +
 +\anchor interpkernelGeo2DEx1
 +\image html SampGeo2D1.png "An example of intersection of 2 polygons."
 +\image latex SampGeo2D1.eps "An example of intersection of 2 polygons."
 +
 +After \ref interpkernelGeo2DBoolOpStep1 "spliting process" \a P1 has 6 edges and \a P2 has 6 edges too.
 +
 +\anchor interpkernelGeo2DEx2
 +\image html SampGeo2D2.png "After spliting process two edges of P1 have been located has out."
 +\image latex SampGeo2D2.eps "After spliting process two edges of P1 have been located has out."
 +
 +\note BLUE is for OUT, GREEN for IN and RED for ON.
 +
 +For each 6 edges \ref interpkernelGeo2DBoolOpStep2 "locate" them.
 +
 +\anchor interpkernelGeo2DEx3
 +\image html SampGeo2D3.png "Result after locating phase."
 +\image latex SampGeo2D3.eps "Result after locating phase."
 +
 +Too finish \ref interpkernelGeo2DBoolOpStep3 "closing" polygons.
 +
 +\anchor interpkernelGeo2DEx4
 +\image html SampGeo2D4.png "Close-up of final result after close polygons phase."
 +\image latex SampGeo2D4.eps "Close-up of final result after close polygons phase."
 +
 +\note The result polygon is constituted of 2 sub-edges coming from \a P1
 +and 1 sub-edge from \a P2 closing the polygon. For the 2 edges of \a P1
 +they are green because they are fully included in \a P2. Inversely,
 +the only sub-edge coming from \a P2 is fully included in \a P1.
 +
 +*/
index ef9db963e6e955c8a36f19c6d7b02fea2c59aaa9,0000000000000000000000000000000000000000..e8319c70d3f55871835c7fc511b39956cdee3996
mode 100644,000000..100644
--- /dev/null
@@@ -1,25 -1,0 +1,27 @@@
- Interpolation (or projection) methods is a key feature of the MEDCoupling library.
 +/*!
 +
 +\page interpolation Interpolation
 +
++Interpolation (or projection) methods are a key feature of the MEDCoupling library.
 +It allows to "transfer" the values of a field on a given source mesh to another, newly created field
 +on a target mesh. 
 +
 +The two meshes/fields need not to have the same \ref MEDCouplingMeshes "mesh/spatial dimension", nor do they need to have the same \ref discretization "discretization".
 +
++
++
 +- \subpage intro-interp
 +- \subpage InterpKerRemapGlobal
 +- \subpage NatureOfField
 +- \subpage remapper
 +- \subpage InterpKerIntersectors
 +
 +If you are looking for a parallel utilisation of the above, take a look at:
 +
 +- \ref parallel
 +
 +Some implementation details of the C++ code can be found in appendix:
 +
 +- \ref interpkernel
 +
 +*/
index c38a879658779ab9101c3c61136475a8a1c26142,0000000000000000000000000000000000000000..1729060bd3609d0b5cd00840a4e8459c6d7c4115
mode 100644,000000..100644
--- /dev/null
@@@ -1,17 -1,0 +1,18 @@@
- \page InterpKerIntersectors Intersectors
 +/*!
 +
- a cell of the source mesh and a cell of the target mesh. The intersectors implemented in the
++\page InterpKerIntersectors Intersectors and point locators
 +
 +The various interpolation methods often require the computation of the intersection between
- - \subpage barycoords (used in some P1 intersectors) 
++a cell of the source mesh and a cell of the target mesh, or the localization of a point
++inside another mesh. The intersectors implemented in the
 +library take care of this job. 
 +
 +Before reading on, remember the definition of a \ref glossary "P0 and P1 field".
 +
 +- \subpage intersec-specifics
 +- \subpage interpkernelGeo2D
++- \subpage barycoords (used in some P1 intersectors/locators) 
 +
 +Some implementation details of the C++ code can also be found here: \ref interpkernel 
 +
 +*/
index 1e3ed568a4252c4d53778f684d2bc937402a0c68,0000000000000000000000000000000000000000..b497ef358074ead4670623db50b352e01e005f0c
mode 100644,000000..100644
--- /dev/null
@@@ -1,113 -1,0 +1,113 @@@
-     ParaMEDMEM_1_1MEDCouplingPointSet
-     ParaMEDMEM_1_1MEDCouplingUMesh
-     ParaMEDMEM_1_1MEDCouplingCMesh
-     ParaMEDMEM_1_1MEDCouplingRemapper
-     ParaMEDMEM_1_1DataArray
-     ParaMEDMEM_1_1DataArrayInt
 +# Copyright (C) 2012-2015  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, or (at your option) any later version.
 +#
 +# 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
 +#
 +
 +##
 +## This module is dedicated to the generation of specific SWIG files (".i") containing
 +## the docstrings built from the C++ doxygen documentation.
 +##
 +
 +SET(_DOXY2SWIG ${PROJECT_SOURCE_DIR}/doc/user/doxygen/doxy2swig/doxy2swig.py)
 +SET(_SWIG_DOC_SUFFIX "doc_class_")
 +
 +#
 +# MEDCoupling classes to include
 +#
 +SET(_classes_MEDCoupling
-     MEDLoader
-     ParaMEDMEM_1_1MEDFileMeshes
-     ParaMEDMEM_1_1MEDFileMesh
-     ParaMEDMEM_1_1MEDFileUMesh
++#    ParaMEDMEM_1_1MEDCouplingPointSet
++#    ParaMEDMEM_1_1MEDCouplingUMesh
++#    ParaMEDMEM_1_1MEDCouplingCMesh
++#    ParaMEDMEM_1_1MEDCouplingRemapper
++#    ParaMEDMEM_1_1DataArray
++#    ParaMEDMEM_1_1DataArrayInt
 +    ParaMEDMEM_1_1DataArrayDouble
 +    )
 +
 +#
 +# MEDLoader classes to include
 +#
 +SET(_classes_MEDLoader
++#    MEDLoader
++#    ParaMEDMEM_1_1MEDFileMeshes
++#    ParaMEDMEM_1_1MEDFileMesh
++#    ParaMEDMEM_1_1MEDFileUMesh
 +    ParaMEDMEM_1_1MEDFileCMesh
 +    )
 +
 +##
 +## Generates the ".i" files from a list of C++ classes.
 +##
 +## \param[in] target_doc main target for the stantard doxygen generation
 +## \param[in] target_swig dummy target encompassing the final build of all SWIG files
 +## \param[in] cls_list list of classes for which to generate SWIG files
 +## \param[in] swig_main_file main SWIG file including the other generated SWIG files
 +## \param[out] swig_files list of generated SWIG files 
 +##
 +MACRO(SALOME_MED_SWIG_DOCSTRING_GENERATE target_doc target_swig cls_list swig_main_file swig_files)
 +    # List of generated SWIG files (.i) for doc purposes only:
 +    SET(${swig_files})
 +    FOREACH(_cls IN LISTS ${cls_list})
 +      SET(_xml_file "${CMAKE_CURRENT_BINARY_DIR}/../doxygen/doc_ref_user/xml/class${_cls}.xml")
 +      SET(_swig_file_base "${_SWIG_DOC_SUFFIX}${_cls}.i")
 +      SET(_swig_file "${PROJECT_BINARY_DIR}/doc/${_swig_file_base}" )
 +  
 +      # SWIG doc files will always be generated *after* Doxygen is run:
 +      ### WARNING: ADD_CUSTOM_COMMAND(TARGET xxx POST_BUILD ...) command
 +      ### must be in exactly the same subdir as the initial target construction command.
 +      ### That's why this file is included with an INCLUDE() rather than using ADD_SUBDIRECTORY
 +      # Note: we touch the main .i file to be sure to retrigger swig when the doc in a included 
 +      # class changes. 
 +      ADD_CUSTOM_COMMAND(OUTPUT ${_swig_file}
 +        COMMAND ${PYTHON_EXECUTABLE} ${_DOXY2SWIG} "-n" ${_xml_file} ${_swig_file}
 +        COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${swig_main_file}
 +        DEPENDS ${_xml_file}
 +        COMMENT "Generating docstring SWIG file (from Doxygen's XML): ${_swig_file_base}"
 +        VERBATIM
 +      )
 +      ADD_CUSTOM_TARGET(${_swig_file_base} DEPENDS ${_swig_file})
 +      # The doxy2swig script is executed once the doxygen documentation has been generated ...
 +      ADD_DEPENDENCIES(${_swig_file_base} ${target_doc})
 +      # ... and the meta target 'swig_ready' (here ${target_swig}) is ready when all .i files 
 +      # have been generated:
 +      ADD_DEPENDENCIES(${target_swig} ${_swig_file_base})
 +       
 +      LIST(APPEND ${swig_files} ${_swig_file_base})
 +    ENDFOREACH()
 +ENDMACRO(SALOME_MED_SWIG_DOCSTRING_GENERATE)
 +
 +
 +##
 +## Configures the MEDCoupling_doc.i or MEDLoader_doc.i file so that they include
 +## the list of SWIG files generated by the macro above.
 +##
 +## \param[in] target_doc main target for the stantard doxygen generation
 +## \param[in] target_swig dummy target encompassing the final build of all SWIG files
 +## \param[in] root_name either 'MEDCoupling' or 'MEDLoader'
 +## 
 +MACRO(SALOME_MED_SWIG_DOCSTRING_CONFIGURE target_doc target_swig root_name)
 +    SET(_all_swig_docs)
 +    SET(_swig_include_set)
 +    SET(_in_file doxy2swig/${root_name}_doc.i.in)
 +    SET(_out_file ${PROJECT_BINARY_DIR}/doc/${root_name}_doc.i)
 +    SALOME_MED_SWIG_DOCSTRING_GENERATE(${target_doc} ${target_swig} _classes_${root_name} ${_out_file} _all_swig_docs)  
 +    FOREACH(f IN LISTS _all_swig_docs)
 +        SET(_swig_include_set "${_swig_include_set}\n%include \"${f}\"")
 +    ENDFOREACH()
 +    CONFIGURE_FILE(${_in_file} ${_out_file} @ONLY)
 +ENDMACRO(SALOME_MED_SWIG_DOCSTRING_CONFIGURE)
 +
index b5d74a3a92666cba49f2fde731708f343215bd36,0000000000000000000000000000000000000000..69e14afcdcf450bea15949dd5d663bb0c528fc1a
mode 100644,000000..100644
--- /dev/null
@@@ -1,394 -1,0 +1,393 @@@
- MEDCouplingFieldDouble::getHeapMemorySize() const;
 +// Copyright (C) 2013-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 +//
 +// 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, or (at your option) any later version.
 +//
 +// 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
 +//
 +
 +// This file contains some code used only for
 +// * generation of documentation for inline methods,
 +// * groupping methods into "Basic API", "Advanced" and "Others..." sections
 +
 +
 +namespace ParaMEDMEM
 +{
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
 +   * \a this and a given field ( _f_ [ i, j ] = _this_ [ i, j ] + _other_ [ i, j ] ).
 +   * Number of tuples and components in the two fields must be the same.
 +   *  \param [in] other - the input field.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
 +   *         differ not only in values.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
 +   * \a this and a given field ( _f_ [ i, j ] = _this_ [ i, j ] - _other_ [ i, j ] ).
 +   * Number of tuples and components in the two fields must be the same.
 +   *  \param [in] other - the field to subtract from \a this one.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
 +   *         differ not only in values.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing product values of \a this and a
 +   * given field. There are 2 valid cases.
 +   * 1.  The fields have same number of tuples and components. Then each value of
 +   *   the result field (_f_) is a product of the corresponding values of _this_ and
 +   *   _other_, i.e. _f_ [ i, j ] = _this_ [ i, j ] * _other_ [ i, j ].
 +   * 2.  The fields have same number of tuples and one field, say _other_, has one
 +   *   component. Then
 +   *   _f_ [ i, j ] = _this_ [ i, j ] * _other_ [ i, 0 ].
 +   *
 +   * The two fields must have same number of tuples and same underlying mesh.
 +   *  \param [in] other - a factor field.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If the fields are not compatible for production (areCompatibleForMul()),
 +   *         i.e. they differ not only in values and possibly number of components.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing division of \a this and a given
 +   * field. There are 2 valid cases.
 +   * 1.  The fields have same number of tuples and components. Then each value of
 +   *   the result field (_f_) is a division of the corresponding values of \a this and
 +   *   \a other, i.e. _f_ [ i, j ] = _this_ [ i, j ] / _other_ [ i, j ].
 +   * 2.  The fields have same number of tuples and _other_ has one component. Then
 +   *   _f_ [ i, j ] = _this_ [ i, j ] / _other_ [ i, 0 ].
 +   *
 +   *  \param [in] other - a denominator field.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If the fields are not compatible for division (areCompatibleForDiv()),
 +   *         i.e. they differ not only in values and possibly in number of components.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing a dot product of \a this and a given field, 
 +   * so that the i-th tuple of the result field (_f_) is a sum of products of j-th components of
 +   * i-th tuples of two fields (\f$ f_i = \sum_ {}^n f1_j * f2_j \f$). 
 +   * Number of tuples and components in the two fields must be the same.
 +   *  \param [in] other - the input field.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
 +   *         differ not only in values.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing a cross product of \a this and 
 +   * a given field, so that the i-th tuple of the result field is a 3D vector which 
 +   * is a cross product of two vectors defined by the i-th tuples of the two fields.
 +   * Number of tuples in the fields must be the same.
 +   * Number of components in the fields must be 3.
 +   *  \param [in] other - the input field.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If \a this->getNumberOfComponents() != 3
 +   *  \throw If \a other->getNumberOfComponents() != 3
 +   *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
 +   *         differ not only in values.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing maximal values of \a this and a
 +   * given field. Number of tuples and components in the two fields must be the same.
 +   *  \param [in] other - the field to compare values with \a this one.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
 +   *         differ not only in values.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a new MEDCouplingFieldDouble containing minimal values of \a this and a
 +   * given field. Number of tuples and components in the two fields must be the same.
 +   *  \param [in] other - the field to compare values with \a this one.
 +   *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
 +   *          The caller is to delete this result field using decrRef() as it is no more
 +   *          needed.
 +   *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
 +   *         differ not only in values.
 +   */
 +  MEDCouplingFieldDouble *MEDCouplingFieldDouble::min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns the data array of \a this field.
 +   *  \return const DataArrayDouble * - a const pointer to the data array of \a this field.
 +   */
 +  const DataArrayDouble *MEDCouplingFieldDouble::getArray() const {}
 +  /*!
 +   * Returns the data array of \a this field apt for modification.
 +   *  \return DataArrayDouble * - a non-const pointer to the data array of \a this field.
 +   */
 +  DataArrayDouble *MEDCouplingFieldDouble::getArray() {}
 +  /*!
 +   * Sets a precision used to compare time values.
 +   *  \param [in] val - the precision value.
 +   */
 +  void MEDCouplingFieldDouble::setTimeTolerance(double val) {}
 +  /*!
 +   * Returns a precision used to compare time values.
 +   *  \return double - the precision value.
 +   */
 +  double MEDCouplingFieldDouble::getTimeTolerance() const {}
 +  /*!
 +   * Sets the number of iteration where the data array of \a this field has been calculated.
 +   * For examples of field construction, see \ref MEDCouplingFirstSteps3.
 +   *  \param [in] it - the iteration number.
 +   */
 +  void MEDCouplingFieldDouble::setIteration(int it) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Sets the number of iteration where the second data array of \a this field has been calculated.
 +   * For examples of field construction, see \ref MEDCouplingFirstSteps3.
 +   *  \param [in] it - the iteration number.
 +   */
 +  void MEDCouplingFieldDouble::setEndIteration(int it) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Sets the order number of iteration where the data array of \a this field has been calculated.
 +   * For examples of field construction, see \ref MEDCouplingFirstSteps3.
 +   *  \param [in] order - the order number.
 +   */
 +  void MEDCouplingFieldDouble::setOrder(int order) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Sets the order number of iteration where the second data array of \a this field has
 +   * been calculated. 
 +   *  \param [in] order - the order number.
 +   */
 +  void MEDCouplingFieldDouble::setEndOrder(int order) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Sets the time when the data array of \a this field has been calculated.
 +   * For examples of field construction, see \ref MEDCouplingFirstSteps3.
 +   *  \param [in] val - the time value.
 +   */
 +  void MEDCouplingFieldDouble::setTimeValue(double val) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Sets the time when the second data array of \a this field has been calculated.
 +   *  \param [in] val - the time value.
 +   */
 +  void MEDCouplingFieldDouble::setEndTimeValue(double val) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Sets time, number of iteration and order number of iteration when the data array
 +   * of \a this field has been calculated.
 +   * For examples of field construction, see \ref MEDCouplingFirstSteps3.
 +   *  \param [in] val - the time value.
 +   *  \param [in] iteration - the iteration number.
 +   *  \param [in] order - the order number.
 +   */
 +  void MEDCouplingFieldDouble::setTime(double val, int iteration, int order) {}
 +  /*!
 +   * Returns time, number of iteration and order number of iteration when the data array
 +   * of \a this field has been calculated.
 +   * For examples of field construction, see \ref MEDCouplingFirstSteps3.
 +   *  \param [out] iteration - the iteration number.
 +   *  \param [out] order - the order number.
 +   *  \return double - the time value.
 +   */
 +  double MEDCouplingFieldDouble::getTime(int& iteration, int& order) const {}
 +  /*!
 +   * Returns a value indexed by a tuple id and a component id.
 +   *  \param [in] tupleId - the id of the tuple of interest.
 +   *  \param [in] compoId - the id of the component of interest.
 +   *  \return double - the field value.
 +   */
 +  double MEDCouplingFieldDouble::getIJ(int tupleId, int compoId) const {}
 +}
 +
 +namespace ParaMEDMEM
 +{
 +/*! \name Basic API   */
 +///@{
 +MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a);
 +MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME);
 +MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME);
 +MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector<const MEDCouplingFieldDouble *>& fs);
 +MEDCouplingFieldDouble::accumulate(double *res) const;
 +MEDCouplingFieldDouble::accumulate(int compId) const;
 +MEDCouplingFieldDouble::advancedRepr() const;
 +MEDCouplingFieldDouble::applyFunc(const std::string &func);
 +MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func);
 +MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string &func);
 +MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val);
 +MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string &func);
 +MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string &func);
 +MEDCouplingFieldDouble::applyLin(double a, double b, int compoId);
 +MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const;
 +MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const;
 +MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const;
 +MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue=0.);
 +MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15);
 +MEDCouplingFieldDouble::checkCoherency() const;
 +MEDCouplingFieldDouble::clone(bool recDeepCpy) const;
 +MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const;
 +MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other);
 +MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other);
 +MEDCouplingFieldDouble::crossProduct(const MEDCouplingFieldDouble& other) const;
 +MEDCouplingFieldDouble::deepCpy() const;
 +MEDCouplingFieldDouble::determinant() const;
 +MEDCouplingFieldDouble::deviator() const;
 +MEDCouplingFieldDouble::dot(const MEDCouplingFieldDouble& other) const;
 +MEDCouplingFieldDouble::doublyContractedProduct() const;
 +MEDCouplingFieldDouble::eigenValues() const;
 +MEDCouplingFieldDouble::eigenVectors() const;
 +MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func);
 +MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string &func);
 +MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string &func);
 +MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string &func);
 +MEDCouplingFieldDouble::getArray() const;
 +MEDCouplingFieldDouble::getArray();
 +MEDCouplingFieldDouble::getAverageValue() const;
 +MEDCouplingFieldDouble::getIJ(int tupleId, int compoId) const;
 +MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const;
 +MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const;
 +MEDCouplingFieldDouble::getMaxValue() const;
 +MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const;
 +MEDCouplingFieldDouble::getMinValue() const;
 +MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const;
 +MEDCouplingFieldDouble::getNumberOfComponents() const;
 +MEDCouplingFieldDouble::getNumberOfTuples() const;
 +MEDCouplingFieldDouble::getNumberOfValues() const;
 +MEDCouplingFieldDouble::getTime(int& iteration, int& order) const;
 +MEDCouplingFieldDouble::getTimeDiscretization() const;
 +MEDCouplingFieldDouble::getTimeTolerance() const;
 +MEDCouplingFieldDouble::getTimeUnit() const;
 +MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const;
 +MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const;
 +MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const;
 +MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const;
 +MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs=true) const;
 +MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs=true) const;
 +MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const;
 +MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const;
 +MEDCouplingFieldDouble::inverse() const;
 +MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
 +MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const;
 +MEDCouplingFieldDouble::magnitude() const;
 +MEDCouplingFieldDouble::max(const MEDCouplingFieldDouble& other) const;
 +MEDCouplingFieldDouble::maxPerTuple() const;
 +MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals=1e-15);
 +MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals=1e-15);
 +MEDCouplingFieldDouble::min(const MEDCouplingFieldDouble& other) const;
 +MEDCouplingFieldDouble::norm2() const;
 +MEDCouplingFieldDouble::normL1(double *res) const;
 +MEDCouplingFieldDouble::normL1(int compId) const;
 +MEDCouplingFieldDouble::normL2(double *res) const;
 +MEDCouplingFieldDouble::normL2(int compId) const;
 +MEDCouplingFieldDouble::normMax() const;
 +MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check=true);
 +MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps=1e-15);
 +MEDCouplingFieldDouble::setArray(DataArrayDouble *array);
 +MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs);
 +MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array);
 +MEDCouplingFieldDouble::setEndIteration(int it);
 +MEDCouplingFieldDouble::setIteration(int it);
 +MEDCouplingFieldDouble::setNature(NatureOfField nat);
 +MEDCouplingFieldDouble::setOrder(int order);
 +MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds);
 +MEDCouplingFieldDouble::setTime(double val, int iteration, int order);
 +MEDCouplingFieldDouble::setTimeTolerance(double val);
 +MEDCouplingFieldDouble::setTimeUnit(const char *unit);
 +MEDCouplingFieldDouble::setTimeValue(double val);
 +MEDCouplingFieldDouble::simpleRepr() const;
 +MEDCouplingFieldDouble::simplexize(int policy);
 +MEDCouplingFieldDouble::sortPerTuple(bool asc);
 +MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15);
 +MEDCouplingFieldDouble::trace() const;
 +MEDCouplingFieldDouble::updateTime() const;
 +MEDCouplingFieldDouble::writeVTK(const char *fileName) const;
 +MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals=1e-15);
 +MEDCouplingFieldDouble::zipCoords(double epsOnVals=1e-15);
 +    MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator=(double value);
 +    MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator*(const MEDCouplingFieldDouble& other) const;
 +    MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator+(const MEDCouplingFieldDouble& other) const;
 +    MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator-(const MEDCouplingFieldDouble& other) const;
 +    MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator/(const MEDCouplingFieldDouble& other) const;
 +    const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other);
 +    const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other);
 +    const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other);
 +    const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other);
 +///@} 
 +/*! \name   Advanced API   */
 +///@{
 +MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check=true);
 +MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15);
 +///@} 
 +
 +/*! \name Others... */
 +///@{
 +  MEDCouplingFieldDouble::negate() const;
 +  MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const;
 +  MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other);
 +  MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
 +MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const;
 +MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type);
 +MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td);
 +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy);
 +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td);
 +MEDCouplingFieldDouble::applyFuncFast32(const std::string &func);
 +MEDCouplingFieldDouble::applyFuncFast64(const std::string &func);
 +MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const;
 +MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const;
 +MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const;
 +MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const;
 +MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const;
 +MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other);
 +MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const;
 +MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
 +MEDCouplingFieldDouble::getArrays() const;
 +MEDCouplingFieldDouble::getEndArray() const;
 +MEDCouplingFieldDouble::getEndArray();
 +MEDCouplingFieldDouble::getEndTime(int& iteration, int& order) const;
 +MEDCouplingFieldDouble::getStartTime(int& iteration, int& order) const;
 +MEDCouplingFieldDouble::getTimeDiscretizationUnderGround() const;
 +MEDCouplingFieldDouble::getTimeDiscretizationUnderGround();
 +MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
 +MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
 +MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
 +MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const;
 +MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const;
 +MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays);
 +MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const;
 +MEDCouplingFieldDouble::setEndOrder(int order);
 +MEDCouplingFieldDouble::setEndTime(double val, int iteration, int order);
 +MEDCouplingFieldDouble::setEndTimeValue(double val);
 +MEDCouplingFieldDouble::setStartTime(double val, int iteration, int order);
 +MEDCouplingFieldDouble::synchronizeTimeWithMesh();
 +MEDCouplingFieldDouble::synchronizeTimeWithSupport();
 +MEDCouplingFieldDouble::~MEDCouplingFieldDouble();
 +MEDCouplingFieldDouble::_time_discr;
 +///@} 
 +}
index fa7bac3f8f2e076d064f0335f352af6f74f57218,0000000000000000000000000000000000000000..26f45eab2c41f6d4b59c52332ba574c7fd4fdad0
mode 100644,000000..100644
--- /dev/null
@@@ -1,611 -1,0 +1,611 @@@
- DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception);
- DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception);
 +// Copyright (C) 2013-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 +//
 +// 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, or (at your option) any later version.
 +//
 +// 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
 +//
 +
 +// This file contains some code used only for
 +// * generation of documentation for inline methods of DataArray* classes
 +// * groupping methods into "Basic API", "Advanced" and "Others..." sections
 +
 +
 +namespace ParaMEDMEM
 +{
 +/*!
 + * Returns the attribute \a _name of \a this array.
 + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
 + *  \return std::string - array name
 + */
 +std::string DataArray::getName() const {}
 +
 +/*!
 + * Returns number of components of \a this array.
 + * See \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
 + *  \return int - number of components
 + */
 +int DataArray::getNumberOfComponents() const {}
 +
 +/*!
 + * Returns number of tuples of \a this array.
 + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
 + *  \return int - number of tuples
 + */
 +int DataArray::getNumberOfTuples() const {}
 +
 +/*!
 + * Returns number of elements of \a this array.
 + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
 + *  \return int - number of elements == <em> this->getNumberOfTuples() * 
 + *          this->getNumberOfComponents() </em>
 + */
 +int DataArray::getNbOfElems() const {}
 +
 +/*!
 + * Throws an exception if number of elements in \a this array differs from a given one.
 + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
 + *  \param [in] nbOfElems - expected array size.
 + *  \param [in] msg - message to return within the thrown exception.
 + *  \throw if <em> this->getNbOfElems() != nbOfElems</em>.
 + */
 +void DataArray::checkNbOfElems(int nbOfElems, const char *msg) const {}
 +
 +/*!
 + * Returns values of a specified tuple.
 + *  \param [in] tupleId - index of the tuple of interest.
 + *  \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res
 + *         must be allocated by the caller and be of size not less than \a
 + *         this->getNumberOfComponents().
 + */
 +void DataArrayDouble::getTuple(int tupleId, double *res) const {}
 +
 +/*!
 + * Returns a value of a specified element of \a this array.
 + *  \param [in] tupleId - index of the tuple of interest.
 + *  \param [in] compoId - index of the component of interest.
 + *  \return double - the value of \a compoId-th component of \a tupleId-th tuple.
 + */
 +double DataArrayDouble::getIJ(int tupleId, int compoId) const {}
 +
 +/*!
 + * Returns a pointer to the first element of the raw data of \a this array.
 + *  \return double* - the pointer to the value of 0-th tuple and 0-th component.
 + */
 +double * DataArrayDouble::getPointer() {}
 +
 +/*!
 + * Returns a const pointer to the first element of the raw data of \a this array.
 + *  \return const double* - the pointer to the value of 0-th tuple and 0-th component.
 + */
 +const double * DataArrayDouble::getConstPointer() const {}
 +
 +/*!
 + * Assigns a given value to a specified element of \a this array.
 + *  \param [in] tupleId - index of the tuple to modify.
 + *  \param [in] compoId - index of the component to modify.
 + *  \param [in] newVal - the value to assign to the value at \a compoId-th component
 + *              of \a tupleId-th tuple. 
 + */
 +void DataArrayDouble::setIJ(int tupleId, int compoId, double newVal) {}
 +
 +/*!
 + * Assigns a given value to a specified element of \a this array which is not marked
 + * as changed.
 + *  \param [in] tupleId - index of the tuple to modify.
 + *  \param [in] compoId - index of the component to modify.
 + *  \param [in] newVal - the value to assign to the value at \a compoId-th component
 + *              of \a tupleId-th tuple.
 + */
 +void DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal) {}
 +
 +/*!
 + * Copies values from another array starting from a specified element of \a this.
 + *  \param [in] id - index of element to assign the value \a element0 to.
 + *  \param [in] element0 - value to assign to the \a id-th element of \a this.
 + *  \param [in] others - values to assign to elements following the \a id-th
 + *         element of \a this.
 + *  \param [in] sizeOfOthers - number of values to copy from \a others.
 + */
 +void DataArrayDouble::writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) {}
 +
 +/*!
 + * Does nothing because this class does not aggregate any TimeLabel instance.
 + */
 +void DataArrayDouble::updateTime() const {}
 +
 +/*!
 + * Returns values of a specified tuple.
 + *  \param [in] tupleId - index of the tuple of interest.
 + *  \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res
 + *         must be allocated by the caller and be of size not less than \a
 + *         this->getNumberOfComponents().
 + *  \if ENABLE_EXAMPLES
 + *  \ref py_mcdataarrayint_getTuple "Here is a Python example".
 + *  \endif
 + */
 +void DataArrayInt::getTuple(int tupleId, int *res) const {}
 +
 +/*!
 + * Returns a value of a specified element of \a this array.
 + *  \param [in] tupleId - index of the tuple of interest.
 + *  \param [in] compoId - index of the component of interest.
 + *  \return int - the value of \a compoId-th component of \a tupleId-th tuple.
 + */
 +int DataArrayInt::getIJ(int tupleId, int compoId) const {}
 +
 +
 +/*!
 + * Assigns a given value to a specified element of \a this array.
 + *  \param [in] tupleId - index of the tuple to modify.
 + *  \param [in] compoId - index of the component to modify.
 + *  \param [in] newVal - the value to assign to the value at \a compoId-th component
 + *              of \a tupleId-th tuple.
 + * \warning As this method declares \a this array as modified, it is more optimal to use
 + *          setIJSilent() for modification of muliple values of array and to call
 + *          declareAsNew() after the modification is done.
 + */
 +void DataArrayInt::setIJ(int tupleId, int compoId, int newVal) {}
 +
 +
 +/*!
 + * Assigns a given value to a specified element of \a this array which is \b not marked
 + * as changed.
 + *  \param [in] tupleId - index of the tuple to modify.
 + *  \param [in] compoId - index of the component to modify.
 + *  \param [in] newVal - the value to assign to the value at \a compoId-th component
 + *              of \a tupleId-th tuple.
 + */
 +void DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal) {}
 +
 +/*!
 + * Returns a pointer to the first element of the raw data of \a this array.
 + *  \return int* - the pointer to the value of 0-th tuple and 0-th component.
 + */
 +int * DataArrayInt::getPointer() {}
 +
 +/*!
 + * Returns a const pointer to the first element of the raw data of \a this array.
 + *  \return const int* - the pointer to the value of 0-th tuple and 0-th component.
 + */
 +const int * DataArrayInt::getConstPointer() const {}
 +
 +/*!
 + * Copies values from another array starting from a given element of \a this.
 + *  \param [in] id - index of element to assign the value \a element0 to.
 + *  \param [in] element0 - value to assign to the \a id-th element of \a this.
 + *  \param [in] others - values to assign to elements following the \a id-th
 + *         element of \a this.
 + *  \param [in] sizeOfOthers - number of values to copy from \a others.
 + */
 +void DataArrayInt::writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) {}
 +
 +}
 +
 +namespace ParaMEDMEM
 +{
 +//================================================================================
 +/////////////////////// DataArray GROUPPING //////////////////////////////////////
 +//================================================================================
 +
 +/*! \name Basic API   */
 +///@{
 +DataArray::setName(const char *name);
 +DataArray::copyStringInfoFrom(const DataArray& other);
 +DataArray::areInfoEquals(const DataArray& other) const;
 +DataArray::getName() const;
 +DataArray::setInfoOnComponents(const std::vector<std::string>& info);
 +DataArray::getVarOnComponent(int i) const;
 +DataArray::getUnitOnComponent(int i) const;
 +DataArray::setInfoOnComponent(int i, const char *info);
 +DataArray::getNumberOfComponents() const;
 +DataArray::getNumberOfTuples() const;
 +DataArray::getNbOfElems() const;
 +DataArray::checkNbOfElems(int nbOfElems, const char *msg) const;
 +DataArray::GetVarNameFromInfo(const std::string& info);
 +DataArray::GetUnitFromInfo(const std::string& info);
 +///@} 
 +
 +/*! \name Others... */
 +///@{
 +DataArray::getHeapMemorySizeWithoutChildren() const;
 +DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds);
 +DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other);
 +DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const;
 +DataArray::reprWithoutNameStream(std::ostream& stream) const;
 +DataArray::cppRepr(const char *varName) const;
 +DataArray::getInfoOnComponents() const;
 +DataArray::getInfoOnComponents();
 +DataArray::getVarsOnComponent() const;
 +DataArray::getUnitsOnComponent() const;
 +DataArray::getInfoOnComponent(int i) const;
 +DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const;
 +DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const;
- DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info);
++//DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception);
++//DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception);
 +DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg);
 +DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg);
 +DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step);
 +DataArray::reprCppStream(const char *varName, std::ostream& stream) const;
 +DataArray::DataArray();
 +DataArray::CheckValueInRange(int ref, int value, const char *msg);
 +DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg);
 +DataArray::CheckClosingParInRange(int ref, int value, const char *msg);
 +std::string              DataArray::_name;
 +std::vector<std::string> DataArray::_info_on_compo;
 +///@} 
 +
 +//================================================================================
 +/////////////////////// DataArrayDouble GROUPPING ////////////////////////////////
 +//================================================================================
 +
 +/*! \name Basic API   */
 +///@{
 +DataArrayDouble::isAllocated() const;
- DataArrayDouble::applyFunc(int nbOfComp, const char* func) const;
- DataArrayDouble::applyFunc(const char* func) const;
- DataArrayDouble::applyFunc2(int nbOfComp, const char* func) const;
- DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char* func) const;
++//DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info);
 +DataArrayDouble::doubleValue() const;
 +DataArrayDouble::empty() const;
 +DataArrayDouble::deepCpy() const;
 +DataArrayDouble::performCpy(bool deepCpy) const;
 +DataArrayDouble::cpyFrom(const DataArrayDouble& other);
 +DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo);
 +DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo);
 +DataArrayDouble::fillWithZero();
 +DataArrayDouble::fillWithValue(double val);
 +DataArrayDouble::iota(double init=0.);
 +DataArrayDouble::isUniform(double val, double eps) const;
 +DataArrayDouble::sort(bool asc=true);
 +DataArrayDouble::reverse();
 +DataArrayDouble::checkMonotonic(bool increasing, double eps) const;
 +DataArrayDouble::isMonotonic(bool increasing, double eps) const;
 +DataArrayDouble::repr() const;
 +DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const;
 +DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const;
 +DataArrayDouble::reAlloc(int nbOfTuples);
 +DataArrayDouble::convertToIntArr() const;
 +DataArrayDouble::fromNoInterlace() const;
 +DataArrayDouble::toNoInterlace() const;
 +DataArrayDouble::renumberInPlace(const int* old2New);
 +DataArrayDouble::renumberInPlaceR(const int* new2Old);
 +DataArrayDouble::renumber(const int* old2New) const;
 +DataArrayDouble::renumberR(const int* new2Old) const;
 +DataArrayDouble::renumberAndReduce(const int* old2New, int newNbOfTuple) const;
 +DataArrayDouble::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const;
 +DataArrayDouble::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const;
 +DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const;
 +DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const;
 +DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd=-1) const;
 +DataArrayDouble::rearrange(int newNbOfCompo);
 +DataArrayDouble::transpose();
 +DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const;
 +DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const;
 +DataArrayDouble::meldWith(const DataArrayDouble* other);
 +DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const;
 +DataArrayDouble::getDifferentValues(double prec, int limitTupleId=-1) const;
 +DataArrayDouble::setSelectedComponents(const DataArrayDouble* a, const std::vector<int>& compoIds);
 +DataArrayDouble::setPartOfValues1(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true);
 +DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp);
 +DataArrayDouble::setPartOfValues2(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true);
 +DataArrayDouble::setPartOfValuesSimple2(double a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp);
 +DataArrayDouble::setPartOfValues3(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true);
 +DataArrayDouble::setPartOfValuesSimple3(double a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp);
 +DataArrayDouble::getTuple(int tupleId, double* res) const;
 +DataArrayDouble::getIJ(int tupleId, int compoId) const;
 +DataArrayDouble::back() const;
 +DataArrayDouble::getIJSafe(int tupleId, int compoId) const;
 +DataArrayDouble::setIJ(int tupleId, int compoId, double newVal);
 +DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal);
 +DataArrayDouble::writeOnPlace(int id, double element0, const double* others, int sizeOfOthers);
 +DataArrayDouble::checkNoNullValues() const;
 +DataArrayDouble::getMinMaxPerComponent(double* bounds) const;
 +DataArrayDouble::getMaxValue(int& tupleId) const;
 +DataArrayDouble::getMaxValueInArray() const;
 +DataArrayDouble::getMinValue(int& tupleId) const;
 +DataArrayDouble::getMinValueInArray() const;
 +DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const;
 +DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const;
 +DataArrayDouble::getAverageValue() const;
 +DataArrayDouble::norm2() const;
 +DataArrayDouble::normMax() const;
 +DataArrayDouble::accumulate(double* res) const;
 +DataArrayDouble::accumulate(int compId) const;
 +DataArrayDouble::fromPolarToCart() const;
 +DataArrayDouble::fromCylToCart() const;
 +DataArrayDouble::fromSpherToCart() const;
 +DataArrayDouble::doublyContractedProduct() const;
 +DataArrayDouble::determinant() const;
 +DataArrayDouble::eigenValues() const;
 +DataArrayDouble::eigenVectors() const;
 +DataArrayDouble::inverse() const;
 +DataArrayDouble::trace() const;
 +DataArrayDouble::deviator() const;
 +DataArrayDouble::magnitude() const;
 +DataArrayDouble::maxPerTuple() const;
 +DataArrayDouble::sortPerTuple(bool asc);
 +DataArrayDouble::abs();
 +DataArrayDouble::applyLin(double a, double b, int compoId);
 +DataArrayDouble::applyLin(double a, double b);
 +DataArrayDouble::applyInv(double numerator);
 +DataArrayDouble::negate() const;
- DataArrayDouble::getHeapMemorySize() const;
++DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const;
++DataArrayDouble::applyFunc(const std::string& func, bool isSafe=true) const;
++DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const;
++DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe=true) const;
 +DataArrayDouble::getIdsInRange(double vmin, double vmax) const;
 +DataArrayDouble::addEqual(const DataArrayDouble* other);
 +DataArrayDouble::substractEqual(const DataArrayDouble* other);
 +DataArrayDouble::multiplyEqual(const DataArrayDouble* other);
 +DataArrayDouble::divideEqual(const DataArrayDouble* other);
 +DataArrayDouble::updateTime() const;
 +DataArrayDouble::New();
 +DataArrayDouble::Aggregate(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr);
 +DataArrayDouble::Meld(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr);
 +DataArrayDouble::Dot(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::CrossProduct(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Max(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Min(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Add(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Substract(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Multiply(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +DataArrayDouble::Divide(const DataArrayDouble* a1, const DataArrayDouble* a2);
 +///@}
 +
 +/*! \name   Advanced API   */
 +///@{
 +DataArrayDouble::checkAllocated() const;
 +DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble* a, const DataArrayInt* tuplesSelec);
 +DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble* a, const DataArrayInt* tuplesSelec);
 +DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble* a, int bg, int end2, int step);
 +DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const;
 +///@} 
 +
 +/*! \name Others... */
 +///@{
 +DataArrayDouble::getNumberOfTuples() const;
 +DataArrayDouble::getNbOfElems() const;
- DataArrayDouble::applyFuncFast32(const char* func);
- DataArrayDouble::applyFuncFast64(const char* func);
++//DataArrayDouble::getHeapMemorySize() const;
 +DataArrayDouble::reserve(int nbOfElems);
 +DataArrayDouble::pushBackSilent(double val);
 +DataArrayDouble::popBackSilent();
 +DataArrayDouble::pack() const;
 +DataArrayDouble::getNbOfElemAllocated() const;
 +DataArrayDouble::reprZip() const;
 +DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char* nameInFile) const;
 +DataArrayDouble::reprStream(std::ostream& stream) const;
 +DataArrayDouble::reprZipStream(std::ostream& stream) const;
 +DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const;
 +DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const;
 +DataArrayDouble::reprCppStream(const char* varName, std::ostream& stream) const;
 +DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const;
 +DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const;
 +DataArrayDouble::setPartOfValues4(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true);
 +DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp);
 +DataArrayDouble::getPointer();
 +DataArrayDouble::SetArrayIn(DataArrayDouble* newArray, DataArrayDouble* &arrayToSet);
 +DataArrayDouble::iterator();
 +DataArrayDouble::getConstPointer() const;
 +DataArrayDouble::begin() const;
 +DataArrayDouble::end() const;
 +DataArrayDouble::useArray(const double* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
 +DataArrayDouble::useExternalArrayWithRWAccess(const double* array, int nbOfTuple, int nbOfCompo);
 +DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last);
 +DataArrayDouble::computeBBoxPerTuple(double epsilon=0.0) const;
 +DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble* other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const;
 +DataArrayDouble::recenterForMaxPrecision(double eps);
 +DataArrayDouble::distanceToTuple(const double* tupleBg, const double* tupleEnd, int& tupleId) const;
 +DataArrayDouble::buildEuclidianDistanceDenseMatrix() const;
 +DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble* other) const;
- DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info);
++DataArrayDouble::applyFuncFast32(const std::string& func);
++DataArrayDouble::applyFuncFast64(const std::string& func);
 +DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
 +DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
 +DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI);
 +DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS);
 +
 +DataArrayDouble::findCommonTuplesAlg(const double* bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt* c, DataArrayInt* cI) const;
 +
 +DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double* pos, int nbOfTuples, double eps, DataArrayInt* c, DataArrayInt* cI);
 +DataArrayDouble::DataArrayDouble();
 +MemArray<double> DataArrayDouble::_mem;
 +///@} 
 +
 +//================================================================================
 +/////////////////////// DataArrayInt GROUPPING ///////////////////////////////////
 +//================================================================================
 +
 +/*! \name Advanced API  */
 +///@{
 +DataArrayInt::checkAllocated() const;
 +DataArrayInt::getHashCode() const;
 +DataArrayInt::buildPermutationArr(const DataArrayInt& other) const;
 +DataArrayInt::transformWithIndArr(const int* indArrBg, const int* indArrEnd);
 +DataArrayInt::transformWithIndArrR(const int* indArrBg, const int* indArrEnd) const;
 +DataArrayInt::splitByValueRange(const int* arrBg, const int* arrEnd,DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const;
 +DataArrayInt::setPartOfValuesAdv(const DataArrayInt* a, const DataArrayInt* tuplesSelec);
 +DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt* tuplesSelec);
 +DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt* a, int bg, int end2, int step);
 +DataArrayInt::SetArrayIn(DataArrayInt* newArray, DataArrayInt* &arrayToSet);
 +///@} 
 +
 +/*! \name Basic API   */
 +///@{
 +DataArrayInt::isAllocated() const;
- DataArrayInt::getHeapMemorySize() const;
++//DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info);
 +DataArrayInt::intValue() const;
 +DataArrayInt::empty() const;
 +DataArrayInt::deepCpy() const;
 +DataArrayInt::performCpy(bool deepCpy) const;
 +DataArrayInt::cpyFrom(const DataArrayInt& other);
 +DataArrayInt::alloc(int nbOfTuple, int nbOfCompo);
 +DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo);
 +DataArrayInt::isEqual(const DataArrayInt& other) const;
 +DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const;
 +DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const;
 +DataArrayInt::sort(bool asc=true);
 +DataArrayInt::reverse();
 +DataArrayInt::fillWithZero();
 +DataArrayInt::fillWithValue(int val);
 +DataArrayInt::iota(int init=0);
 +DataArrayInt::repr() const;
 +DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const;
 +DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const;
 +DataArrayInt::reAlloc(int nbOfTuples);
 +DataArrayInt::convertToDblArr() const;
 +DataArrayInt::fromNoInterlace() const;
 +DataArrayInt::toNoInterlace() const;
 +DataArrayInt::renumberInPlace(const int* old2New);
 +DataArrayInt::renumberInPlaceR(const int* new2Old);
 +DataArrayInt::renumber(const int* old2New) const;
 +DataArrayInt::renumberR(const int* new2Old) const;
 +DataArrayInt::renumberAndReduce(const int* old2NewBg, int newNbOfTuple) const;
 +DataArrayInt::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const;
 +DataArrayInt::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const;
 +DataArrayInt::selectByTupleId2(int bg, int end, int step) const;
 +DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const;
 +DataArrayInt::checkAndPreparePermutation() const;
 +DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const;
 +DataArrayInt::buildPermArrPerLevel() const;
 +DataArrayInt::isIdentity() const;
 +DataArrayInt::isUniform(int val) const;
 +DataArrayInt::substr(int tupleIdBg, int tupleIdEnd=-1) const;
 +DataArrayInt::rearrange(int newNbOfCompo);
 +DataArrayInt::transpose();
 +DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const;
 +DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const;
 +DataArrayInt::meldWith(const DataArrayInt* other);
 +DataArrayInt::setSelectedComponents(const DataArrayInt* a, const std::vector<int>& compoIds);
 +DataArrayInt::setPartOfValues1(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true);
 +DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp);
 +DataArrayInt::setPartOfValues2(const DataArrayInt* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true);
 +DataArrayInt::setPartOfValuesSimple2(int a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp);
 +DataArrayInt::setPartOfValues3(const DataArrayInt* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true);
 +DataArrayInt::setPartOfValuesSimple3(int a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp);
 +DataArrayInt::getTuple(int tupleId, int* res) const;
 +DataArrayInt::getIJ(int tupleId, int compoId) const;
 +DataArrayInt::getIJSafe(int tupleId, int compoId) const;
 +DataArrayInt::back() const;
 +DataArrayInt::setIJ(int tupleId, int compoId, int newVal);
 +DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal);
 +DataArrayInt::getPointer();
 +DataArrayInt::getConstPointer() const;
 +DataArrayInt::getIdsEqual(int val) const;
 +DataArrayInt::getIdsNotEqual(int val) const;
 +DataArrayInt::getIdsEqualList(const int* valsBg, const int* valsEnd) const;
 +DataArrayInt::getIdsNotEqualList(const int* valsBg, const int* valsEnd) const;
 +DataArrayInt::changeValue(int oldValue, int newValue);
 +DataArrayInt::presenceOfValue(int value) const;
 +DataArrayInt::presenceOfValue(const std::vector<int>& vals) const;
 +DataArrayInt::getMaxValue(int& tupleId) const;
 +DataArrayInt::getMaxValueInArray() const;
 +DataArrayInt::getMinValue(int& tupleId) const;
 +DataArrayInt::getMinValueInArray() const;
 +DataArrayInt::abs();
 +DataArrayInt::applyLin(int a, int b, int compoId);
 +DataArrayInt::applyLin(int a, int b);
 +DataArrayInt::applyInv(int numerator);
 +DataArrayInt::negate() const;
 +DataArrayInt::applyDivideBy(int val);
 +DataArrayInt::applyModulus(int val);
 +DataArrayInt::applyRModulus(int val);
 +DataArrayInt::buildComplement(int nbOfElement) const;
 +DataArrayInt::buildSubstraction(const DataArrayInt* other) const;
 +DataArrayInt::buildUnion(const DataArrayInt* other) const;
 +DataArrayInt::buildIntersection(const DataArrayInt* other) const;
 +DataArrayInt::deltaShiftIndex() const;
 +DataArrayInt::computeOffsets();
 +DataArrayInt::computeOffsets2();
 +DataArrayInt::buildExplicitArrByRanges(const DataArrayInt* offsets) const;
 +DataArrayInt::useArray(const int* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
 +DataArrayInt::writeOnPlace(int id, int element0, const int* others, int sizeOfOthers);
 +DataArrayInt::addEqual(const DataArrayInt* other);
 +DataArrayInt::substractEqual(const DataArrayInt* other);
 +DataArrayInt::multiplyEqual(const DataArrayInt* other);
 +DataArrayInt::divideEqual(const DataArrayInt* other);
 +DataArrayInt::modulusEqual(const DataArrayInt* other);
 +DataArrayInt::updateTime() const;
 +DataArrayInt::New();
 +DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int* arr, const int* arrIBg, const int* arrIEnd, int &newNbOfTuples);
 +DataArrayInt::Aggregate(const DataArrayInt* a1, const DataArrayInt* a2, int offsetA2);
 +DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr);
 +DataArrayInt::Meld(const DataArrayInt* a1, const DataArrayInt* a2);
 +DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr);
 +DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups);
 +DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr);
 +DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr);
 +DataArrayInt::Add(const DataArrayInt* a1, const DataArrayInt* a2);
 +DataArrayInt::Substract(const DataArrayInt* a1, const DataArrayInt* a2);
 +DataArrayInt::Multiply(const DataArrayInt* a1, const DataArrayInt* a2);
 +DataArrayInt::Divide(const DataArrayInt* a1, const DataArrayInt* a2);
 +DataArrayInt::Modulus(const DataArrayInt* a1, const DataArrayInt* a2);
 +DataArrayInt::CheckAndPreparePermutation(const int* start, const int* end);
 +DataArrayInt::Range(int begin, int end, int step);
 +///@} 
 +
 +/*! \name Others... */
 +///@{
 +DataArrayInt::getNumberOfTuples() const;
 +DataArrayInt::getNbOfElems() const;
++//DataArrayInt::getHeapMemorySize() const;
 +DataArrayInt::reserve(int nbOfElems);
 +DataArrayInt::pushBackSilent(int val);
 +DataArrayInt::popBackSilent();
 +DataArrayInt::pack() const;
 +DataArrayInt::getNbOfElemAllocated() const;
 +DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const;
 +DataArrayInt::checkMonotonic(bool increasing) const;
 +DataArrayInt::isMonotonic(bool increasing) const;
 +DataArrayInt::checkStrictlyMonotonic(bool increasing) const;
 +DataArrayInt::isStrictlyMonotonic(bool increasing) const;
 +DataArrayInt::reprZip() const;
 +DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char* type, const char* nameInFile) const;
 +DataArrayInt::reprStream(std::ostream& stream) const;
 +DataArrayInt::reprZipStream(std::ostream& stream) const;
 +DataArrayInt::reprWithoutNameStream(std::ostream& stream) const;
 +DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const;
 +DataArrayInt::reprCppStream(const char* varName, std::ostream& stream) const;
 +DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const;
 +DataArrayInt::setPartOfValues4(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true);
 +DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp);
 +DataArrayInt::iterator();
 +DataArrayInt::begin() const;
 +DataArrayInt::end() const;
 +DataArrayInt::locateTuple(const std::vector<int>& tupl) const;
 +DataArrayInt::locateValue(int value) const;
 +DataArrayInt::locateValue(const std::vector<int>& vals) const;
 +DataArrayInt::search(const std::vector<int>& vals) const;
 +DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const;
 +DataArrayInt::accumulate(int* res) const;
 +DataArrayInt::accumulate(int compId) const;
 +DataArrayInt::getIdsInRange(int vmin, int vmax) const;
 +DataArrayInt::buildSubstractionOptimized(const DataArrayInt* other) const;
 +DataArrayInt::buildUnique() const;
 +DataArrayInt::findRangeIdForEachTuple(const DataArrayInt* ranges) const;
 +DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt* ranges) const;
 +DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const;
 +DataArrayInt::getDifferentValues() const;
 +> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const;
 +DataArrayInt::useExternalArrayWithRWAccess(const int* array, int nbOfTuple, int nbOfCompo);
 +tor>
 +DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last);
 +DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
 +DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
 +DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI);
 +DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS);
 +DataArrayInt::DataArrayInt();
 +MemArray<int> DataArrayInt::_mem;
 +///@}
 +
 +}
index eabd7a9ca545e8be962e51afc58b7114113970b2,0000000000000000000000000000000000000000..4809eec6bb14922b3d1cdbe3475d1ce903deee93
mode 100644,000000..100644
--- /dev/null
@@@ -1,178 -1,0 +1,178 @@@
-   MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const;
-   MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const;
-   MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const;
 +// Copyright (C) 2013-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 +//
 +// 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, or (at your option) any later version.
 +//
 +// 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
 +//
 +
 +// This file contains some code used only for
 +// * generation of documentation for inline methods of DataArray* classes
 +// * groupping methods into "Basic API", "Advanced" and "Others..." sections
 +
 +
 +namespace ParaMEDMEM
 +{
 +  //================================================================================
 +  /*!
 +   * Checks if \a this and another MEDCouplingMesh are equal without considering
 +   * textual data like mesh name, names of spatial components etc.
 +   *  \param [in] other - an instance of MEDCouplingMesh to compare with \a this one.
 +   *  \param [in] prec - precision value used to compare node coordinates.
 +   *  \return bool - \c true if the two meshes are equal, \c false else.
 +   */
 +  //================================================================================
 +
 +  bool MEDCouplingMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const {}
 +
 +  /*!
 +   * Checks if \a this and \a other meshes are geometrically equivalent, else an
 +   * exception is thrown. The meshes are
 +   * considered equivalent if (1) \a this mesh contains the same nodes as the \a other
 +   * mesh (with a specified precision) and (2) \a this mesh contains the same cells as
 +   * the \a other mesh (with use of a specified cell comparison technique). The mapping 
 +   * from \a other to \a this for nodes and cells is returned via out parameters.
 +   *  \param [in] other - the mesh to compare with.
 +   *  \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of
 +   *         each method in description of MEDCouplingUMesh::zipConnectivityTraducer().
 +   *  \param [in] prec - the precision used to compare nodes of the two meshes.
 +   *  \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is
 +   *         to delete this array using decrRef() as it is no more needed.
 +   *  \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is
 +   *         to delete this array using decrRef() as it is no more needed.
 +   *  \throw If the two meshes do not match.
 +   */
 +  void MEDCouplingMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) {}
 +
 +  /*!
 +   * Checks if \a this and \a other meshes are geometrically equivalent, else an
 +   * exception is thrown. The meshes are considered equivalent if (1) they share the same
 +   * node coordinates array(s) and (2) they contain the same cells (with use of a specified
 +   * cell comparison technique). The mapping from cells of the \a other to ones of \a this 
 +   * is returned via an out parameter.
 +   *  \param [in] other - the mesh to compare with.
 +   *  \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of
 +   *         each method in description of MEDCouplingUMesh::zipConnectivityTraducer().
 +   *  \param [in] prec - a not used parameter.
 +   *  \param [out] cellCor - the permutation array in "Old to New" mode. The caller is
 +   *         to delete this array using decrRef() as it is no more needed.
 +   *  \throw If the two meshes do not match.
 +   */
 +  void MEDCouplingMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) {}
 +}
 +
 +namespace ParaMEDMEM
 +{
 +//================================================================================
 +/////////////////////// GROUPPING members of MEDCouplingMesh /////////////////////
 +//================================================================================
 +/*! \name Basic API   */
 +///@{
 +  MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2);
 +  MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes);
 +  MEDCouplingMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const;
 +  MEDCouplingMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const;
 +  MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const;
-   MEDCouplingMesh::getHeapMemorySize() const;
++  MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const;
++  MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const;
++  MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const;
 +  MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const;
 +  MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const;
 +  MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const;
 +  MEDCouplingMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0;
 +  MEDCouplingMesh::writeVTK(const char *fileName) const;
 +///@} 
 +
 +/*! \name   Advanced API   */
 +///@{
 +  MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const;
 +///@} 
 +
 +/*! \name Others... */
 +///@{
 +  MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type);
 +  MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type);
 +  MEDCouplingMesh::MEDCouplingMesh();
 +  MEDCouplingMesh::~MEDCouplingMesh();
 +  MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other);
 +  MEDCouplingMesh::advancedRepr() const = 0;
 +  MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const;
 +  MEDCouplingMesh::buildOrthogonalField() const = 0;
 +  MEDCouplingMesh::buildPart(const int *start, const int *end) const = 0;
 +  MEDCouplingMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0;
 +  MEDCouplingMesh::buildUnstructured() const;
 +  MEDCouplingMesh::checkCoherency() const;
 +  MEDCouplingMesh::checkCoherency1(double eps=1e-12) const;
 +  MEDCouplingMesh::checkCoherency2(double eps=1e-12) const;
 +  MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const;
 +  MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const;
 +  MEDCouplingMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const;
 +  MEDCouplingMesh::computeIsoBarycenterOfNodesPerCell() const;
 +  MEDCouplingMesh::computeNbOfNodesPerCell() const;
 +  MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other);
 +  MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other);
 +  MEDCouplingMesh::deepCpy() const = 0;
 +  MEDCouplingMesh::getAllGeoTypes() const = 0;
 +  MEDCouplingMesh::getBarycenterAndOwner() const = 0;
 +  MEDCouplingMesh::getBoundingBox(double *bbox) const = 0;
 +  MEDCouplingMesh::getCellContainingPoint(const double *pos, double eps) const = 0;
 +  MEDCouplingMesh::getCoordinatesAndOwner() const = 0;
 +  MEDCouplingMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const;
 +  MEDCouplingMesh::getDescription() const;
 +  MEDCouplingMesh::getDistributionOfTypes() const;
-   MEDCouplingMesh::writeVTKAdvanced(const char *fileName, const std::string& cda, const std::string& pda) const;
++//  MEDCouplingMesh::getHeapMemorySize() const;
 +  MEDCouplingMesh::getMeasureField(bool isAbs) const = 0;
 +  MEDCouplingMesh::getMeasureFieldOnNode(bool isAbs) const = 0;
 +  MEDCouplingMesh::getMeshDimension() const = 0;
 +  MEDCouplingMesh::getName() const;
 +  MEDCouplingMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const = 0;
 +  MEDCouplingMesh::getNumberOfCells() const = 0;
 +  MEDCouplingMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0;
 +  MEDCouplingMesh::getNumberOfNodes() const = 0;
 +  MEDCouplingMesh::getSpaceDimension() const = 0;
 +  MEDCouplingMesh::getTime(int& iteration, int& order) const;
 +  MEDCouplingMesh::getTimeUnit() const;
 +  MEDCouplingMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const = 0;
 +  MEDCouplingMesh::getType() const = 0;
 +  MEDCouplingMesh::getTypeOfCell(int cellId) const = 0;
 +  MEDCouplingMesh::getVTKDataSetType() const;
 +  MEDCouplingMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const;
 +  MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const;
 +  MEDCouplingMesh::isStructured() const;
 +  MEDCouplingMesh::mergeMyselfWith(const MEDCouplingMesh *other) const = 0;
 +  MEDCouplingMesh::renumberCells(const int *old2NewBg, bool check=true);
 +  MEDCouplingMesh::reprQuickOverview(std::ostream& stream) const;
 +  MEDCouplingMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const = 0;
 +  MEDCouplingMesh::rotate(const double *center, const double *vector, double angle) = 0;
 +  MEDCouplingMesh::scale(const double *point, double factor) = 0;
 +  MEDCouplingMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0;
 +  MEDCouplingMesh::setDescription(const char *descr);
 +  MEDCouplingMesh::setName(const char *name);
 +  MEDCouplingMesh::setTime(double val, int iteration, int order);
 +  MEDCouplingMesh::setTimeUnit(const char *unit);
 +  MEDCouplingMesh::simpleRepr() const = 0;
 +  MEDCouplingMesh::simplexize(int policy);
 +  MEDCouplingMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const;
 +  MEDCouplingMesh::translate(const double *vector) = 0;
 +  MEDCouplingMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,const std::vector<std::string>& littleStrings) = 0;
++  //MEDCouplingMesh::writeVTKAdvanced(const char *fileName, const std::string& cda, const std::string& pda) const;
 +  MEDCouplingMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const;
 +  MEDCouplingMesh::_description;
 +  MEDCouplingMesh::_iteration;
 +  MEDCouplingMesh::_name;
 +  MEDCouplingMesh::_order;
 +  MEDCouplingMesh::_time;
 +  MEDCouplingMesh::_time_unit;
 +///@}
 +}
index c17e7b29673df50eb47f60e105a482df3ed2cd9e,0000000000000000000000000000000000000000..443b632c7ea3f196bbe8b20830dc08d0bbef47ac
mode 100644,000000..100644
--- /dev/null
@@@ -1,343 -1,0 +1,343 @@@
- MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
 +// Copyright (C) 2013-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 +//
 +// 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, or (at your option) any later version.
 +//
 +// 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
 +//
 +
 +// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 +//
 +// 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
 +//
 +
 +// This file contains some code used only for
 +// * generation of documentation for inline methods of MEDCouplingUMesh class,
 +// * groupping methods into "Basic API", "Advanced" and "Others..." sections
 +
 +namespace ParaMEDMEM
 +{
 +  /*!
 +   * Returns the nodal connectivity array. For more info on how data in stored in
 +   * this array, see \ref MEDCouplingUMeshAdvBuild.
 +   *  \return const DataArrayInt * - a pointer to the nodal connectivity array
 +   *          referred by \a this mesh.
 +   */
 +  const DataArrayInt * MEDCouplingUMesh::getNodalConnectivity() const {}
 +  /*!
 +   * Returns the nodal connectivity index array. For more info on how data in stored in
 +   * this array, see \ref MEDCouplingUMeshAdvBuild.
 +   *  \return const DataArrayInt * - a pointer to the nodal connectivity index array
 +   *          referred by \a this mesh.
 +   */
 +  const DataArrayInt * MEDCouplingUMesh::getNodalConnectivityIndex() const {}
 +  /*!
 +   * Returns the nodal connectivity array. For more info on how data in stored in
 +   * this array, see \ref MEDCouplingUMeshAdvBuild.
 +   *  \return const DataArrayInt * - a pointer to the nodal connectivity array
 +   *          referred by \a this mesh.
 +   */
 +  DataArrayInt * MEDCouplingUMesh::getNodalConnectivity() {}
 +  /*!
 +   * Returns the nodal connectivity index array. For more info on how data in stored in
 +   * this array, see \ref MEDCouplingUMeshAdvBuild.
 +   *  \return const DataArrayInt * - a pointer to the nodal connectivity index array
 +   *          referred by \a this mesh.
 +   */
 +  DataArrayInt * MEDCouplingUMesh::getNodalConnectivityIndex() {}
 +}
 +
 +namespace ParaMEDMEM
 +{
 +//================================================================================
 +/////////////////////// MEDCouplingUMesh GROUPPING ///////////////////////////////
 +//================================================================================
 +
 +/*! \name Basic API   */
 +///@{
 +MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr);
 +MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2);
 +MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps);
 +MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2);
 +MEDCouplingUMesh::MergeUMeshes(std::vector<const MEDCouplingUMesh *>& a);
 +MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2);
 +MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes);
 +MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCouplingUMesh *>& meshes);
 +MEDCouplingUMesh::allocateCells(int nbOfCells);
 +MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const;
 +MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const;
 +MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const;
 +MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const;
 +MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
 +MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
 +MEDCouplingUMesh::buildDirectionVectorField() const;
 +MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
 +MEDCouplingUMesh::buildOrthogonalField() const;
 +MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const;
- MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const;
- MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const;
++//MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
 +MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const;
 +MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const;
 +MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const;
 +MEDCouplingUMesh::checkCoherency() const;
 +MEDCouplingUMesh::checkCoherency1(double eps=1e-12) const;
 +MEDCouplingUMesh::checkCoherency2(double eps=1e-12) const;
- MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const;
- MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const;
++//MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const;
++//MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const;
 +MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const;
 +MEDCouplingUMesh::clone(bool recDeepCpy) const;
 +MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const;
 +MEDCouplingUMesh::convertAllToPoly();
 +MEDCouplingUMesh::convertQuadraticCellsToLinear();
 +MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd);
 +MEDCouplingUMesh::deepCpy() const;
 +MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells();
 +MEDCouplingUMesh::findBoundaryNodes() const;
 +MEDCouplingUMesh::finishInsertingCells();
 +MEDCouplingUMesh::getAllGeoTypes() const;
 +MEDCouplingUMesh::getAspectRatioField() const;
 +MEDCouplingUMesh::getBarycenterAndOwner() const;
 +MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const;
 +MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const;
- MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
- MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
++//MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const;
++//MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const;
 +MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const;
 +MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const;
 +MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps);
 +MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const;
 +MEDCouplingUMesh::getEdgeRatioField() const;
 +MEDCouplingUMesh::getMeasureField(bool isAbs) const;
 +MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const;
 +MEDCouplingUMesh::getMeshDimension() const;
 +MEDCouplingUMesh::getNodalConnectivity() const;
 +MEDCouplingUMesh::getNodalConnectivity();
 +MEDCouplingUMesh::getNodalConnectivityIndex() const;
 +MEDCouplingUMesh::getNodalConnectivityIndex();
 +MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const;
 +MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const;
 +MEDCouplingUMesh::getNumberOfCells() const;
 +MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const;
 +MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const;
 +MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
 +MEDCouplingUMesh::getSkewField() const;
 +MEDCouplingUMesh::getTypeOfCell(int cellId) const;
 +MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const;
 +MEDCouplingUMesh::getWarpField() const;
 +MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell);
 +MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const;
- MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
- MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes);
++//MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
++//MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
 +MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly);
 +MEDCouplingUMesh::orientCorrectlyPolyhedrons();
- MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon);
++//MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
++//MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes);
 +MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N);
 +MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const;
 +MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true);
 +MEDCouplingUMesh::setMeshDimension(int meshDim);
 +MEDCouplingUMesh::sortCellsInMEDFileFrmt();
- MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId=0);
++//MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon);
 +MEDCouplingUMesh::unPolyze();
- MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret);
++//MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId=0);
 +MEDCouplingUMesh::zipCoordsTraducer();
 +  ///@} 
 +
 +  /*! \name Advanced API  */
 +///@{
 +MEDCouplingUMesh::areOnlySimplexCells() const;
 +MEDCouplingUMesh::checkButterflyCells(std::vector<int>& cells, double eps=1e-12) const;
 +MEDCouplingUMesh::computeTypes();
 +MEDCouplingUMesh::convertDegeneratedCells();
 +MEDCouplingUMesh::convertExtrudedPolyhedra();
 +MEDCouplingUMesh::getMeshLength() const;
 +MEDCouplingUMesh::isFullyQuadratic() const;
 +MEDCouplingUMesh::isPresenceOfQuadratic() const;
 +MEDCouplingUMesh::simplexize(int policy);
 +MEDCouplingUMesh::tessellate2D(double eps);
 +MEDCouplingUMesh::tessellate2DCurve(double eps);
 +  ///@
 +
 +/*! \name Others... */
 +///@{
 +MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& ms,DataArrayInt *&szOfCellGrpOfSameType,DataArrayInt *&idInMsOfCellGrpOfSameType);
- MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,const int *nodal3DCurve, const int *nodalIndx3DCurve,const int *desc, const int *descIndx, std::vector< std::pair<int,int> >& cut3DSurf);
++//MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret);
 +MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType);
 +MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2);
 +MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2);
 +MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2);
 +MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2);
 +MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2);
 +MEDCouplingUMesh::AreCellsEqualInPool(const std::vector<int>& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ;
- MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector<double>& addCoo, const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge);
- MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,const std::vector<double>& addCoords,std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2);
++//MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,const int *nodal3DCurve, const int *nodalIndx3DCurve,const int *desc, const int *descIndx, std::vector< std::pair<int,int> >& cut3DSurf);
 +MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da);
 +MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut);
- MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector<int>& code);
++//MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector<double>& addCoo, const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge);
++//MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,const std::vector<double>& addCoords,std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2);
 +MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI,DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx);
- MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed);
++//MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector<int>& code);
 +MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn);
 +MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed);
- MEDCouplingUMesh::CorrectExtrudedCell(int *begin, int *end);
++//MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed);
 +MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p);
- MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt);
++//MEDCouplingUMesh::CorrectExtrudedCell(int *begin, int *end);
 +MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end);
 +MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut);
- MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2,MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2,std::vector<double>& addCoo);
- MEDCouplingUMesh::Is3DExtrudedCellWellOriented(const int *begin, const int *end, const double *coords);
++//MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt);
 +MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI,DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr);
- MEDCouplingUMesh::MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a);
++//MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2,MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2,std::vector<double>& addCoo);
++//MEDCouplingUMesh::Is3DExtrudedCellWellOriented(const int *begin, const int *end, const double *coords);
 +MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords);
 +MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords);
 +MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords);
 +MEDCouplingUMesh::IsPyra5WellOriented(const int *begin, const int *end, const double *coords);
 +MEDCouplingUMesh::IsTetra4WellOriented(const int *begin, const int *end, const double *coords);
 +MEDCouplingUMesh::MEDCouplingUMesh();
 +MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy);
- MEDCouplingUMesh::New(const char *meshName, int meshDim);
++//MEDCouplingUMesh::MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a);
 +MEDCouplingUMesh::New();
- MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const;
++MEDCouplingUMesh::New(const std::string& meshName, int meshDim);
 +MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0);
 +MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut);
 +MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut);
 +MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex);
 +MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex);
 +MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res);
 +MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords);
 +MEDCouplingUMesh::advancedRepr() const;
- MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const;
++//MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const;
 +MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const;
- MEDCouplingUMesh::distanceToPoint2DCurveAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const;
- MEDCouplingUMesh::distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const;
++//MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const;
 +MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy);
 +MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const;
 +MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const;
 +MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const;
 +MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const;
 +MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const;
 +MEDCouplingUMesh::buildSpreadZonesWithPoly() const;
 +MEDCouplingUMesh::buildUnionOf2DMesh() const;
 +MEDCouplingUMesh::buildUnionOf3DMesh() const;
 +MEDCouplingUMesh::buildUnstructured() const;
 +MEDCouplingUMesh::cellIterator();
 +MEDCouplingUMesh::cellsByType();
 +MEDCouplingUMesh::checkConnectivityFullyDefined() const;
 +MEDCouplingUMesh::checkConsecutiveCellTypes() const;
 +MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const;
 +MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const;
 +MEDCouplingUMesh::checkFullyDefined() const;
 +MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const;
 +MEDCouplingUMesh::computeFetchedNodeIds() const;
 +MEDCouplingUMesh::computeNbOfNodesPerCell() const;
 +MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const;
 +MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const;
 +MEDCouplingUMesh::computeSkin() const;
 +MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const;
 +MEDCouplingUMesh::convertLinearCellsToQuadratic(int conversionType=0);
 +MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const;
 +MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const;
 +MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const;
 +MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const;
 +MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const;
 +MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const;
 +MEDCouplingUMesh::convexEnvelop2D();
 +MEDCouplingUMesh::cppRepr() const;
 +MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId, int& nodeId) const;
- MEDCouplingUMesh::getAllTypes() const;
++//MEDCouplingUMesh::distanceToPoint2DCurveAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const;
++//MEDCouplingUMesh::distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const;
 +MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd);
 +MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset);
 +MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const;
 +MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
 +MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const;
 +MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const;
 +MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const;
 +MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const;
 +MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const;
 +MEDCouplingUMesh::findAndCorrectBadOriented3DCells();
 +MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const;
 +MEDCouplingUMesh::findCellIdsOnBoundary() const;
 +MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const;
 +MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate,DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const;
- MEDCouplingUMesh::getHeapMemorySize() const;
++//MEDCouplingUMesh::getAllTypes() const;
 +MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector<double>& bbox) const;
 +MEDCouplingUMesh::getDistributionOfTypes() const;
 +MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const;
- template<class SonsGenerator> MEDCouplingUMesh * MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const;
++//MEDCouplingUMesh::getHeapMemorySize() const;
 +MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const;
 +MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const;
 +MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const;
 +MEDCouplingUMesh::getQuadraticStatus() const;
 +MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const;
 +MEDCouplingUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
 +MEDCouplingUMesh::getType() const { return UNSTRUCTURED; }
 +MEDCouplingUMesh::getVTKDataSetType() const;
 +MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const;
 +MEDCouplingUMesh::isContiguous1D() const;
 +MEDCouplingUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const;
 +MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const;
 +MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const;
 +MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const;
 +MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const;
 +MEDCouplingUMesh::partitionBySpreadZone() const;
 +MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const;
 +MEDCouplingUMesh::rearrange2ConsecutiveCellTypes();
 +MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check=true);
 +MEDCouplingUMesh::reprConnectivityOfThis() const;
 +MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const;
 +MEDCouplingUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const;
 +MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const;
 +MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis);
 +MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis);
 +MEDCouplingUMesh::shiftNodeNumbersInConn(int delta);
 +MEDCouplingUMesh::simpleRepr() const;
 +MEDCouplingUMesh::simplexizePlanarFace5();
 +MEDCouplingUMesh::simplexizePlanarFace6();
 +MEDCouplingUMesh::simplexizePol0();
 +MEDCouplingUMesh::simplexizePol1();
 +MEDCouplingUMesh::simplifyPolyhedra(double eps);
 +MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve);
 +MEDCouplingUMesh::splitByType() const;
 +MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const;
 +MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex);
 +MEDCouplingUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings);
 +MEDCouplingUMesh::updateTime() const;
 +MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const;
 +MEDCouplingUMesh::~MEDCouplingUMesh();
- const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER];
- const int MEDCouplingUMesh::N_MEDMEM_ORDER=24;
++//template<class SonsGenerator> MEDCouplingUMesh * MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const;
 +template<int SPACEDIM> void MEDCouplingUMesh::getCellsContainingPointsAlg
 +(const double *coords, const double *pos, int nbOfPoints,double eps, std::vector<int>& elts,
 + std::vector<int>& eltsIndex) const;
 +
++//const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER];
++//const int MEDCouplingUMesh::N_MEDMEM_ORDER=24;
 +double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION;
 +int MEDCouplingUMesh::_mesh_dim;
 +std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::_types;
 +DataArrayInt * MEDCouplingUMesh::_nodal_connec;
 +DataArrayInt * MEDCouplingUMesh::_nodal_connec_index;
 +  ///@} 
 +}
 +
index 4919e4a4820d725fc598d63a179744b41d0d3f60,0000000000000000000000000000000000000000..9e9365db6d69f4d27248d76e980d03b160d69735
mode 100644,000000..100644
--- /dev/null
@@@ -1,106 -1,0 +1,106 @@@
-   int MEDFileField1TSWithoutSDA::getIteration() const {}
 +// Copyright (C) 2013-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 +//
 +// 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, or (at your option) any later version.
 +//
 +// 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
 +//
 +
 +// This file contains some code used only for
 +// generation of documentation for inline methods.
 +
 +
 +namespace ParaMEDMEM // inline methods of MEDFileField1TSWithoutSDA
 +{
 +  /*!
 +   * Returns the number of iteration where \a this field has been calculated.
 +   *  \return int - the iteration number.
 +   */
-   int MEDFileField1TSWithoutSDA::getOrder() const {}
++//  int MEDFileField1TSWithoutSDA::getIteration() const {}
 +  /*!
 +   * Returns the order number of iteration where \a this field has been calculated.
 +   *  \return int - the order number.
 +   */
-   double MEDFileField1TSWithoutSDA::getTime(int& iteration, int& order) const {}
++//  int MEDFileField1TSWithoutSDA::getOrder() const {}
 +  /*!
 +   * Returns time, number of iteration and order number of iteration when
 +   * \a this field has been calculated.
 +   *  \param [out] iteration - the iteration number.
 +   *  \param [out] order - the order number.
 +   *  \return double - the time value.
 +   */
-   void MEDFileField1TSWithoutSDA::setTime(int iteration, int order, double val) {}
++//  double MEDFileField1TSWithoutSDA::getTime(int& iteration, int& order) const {}
 +  /*!
 +   * Sets time, number of iteration and order number of iteration when
 +   * \a this field has been calculated.
 +   *  \param [in] val - the time value.
 +   *  \param [in] iteration - the iteration number.
 +   *  \param [in] order - the order number.
 +   */
-   const std::string& MEDFileField1TSWithoutSDA::getDtUnit() const {}
++//  void MEDFileField1TSWithoutSDA::setTime(int iteration, int order, double val) {}
 +  /*!
 +   * Returns units in which the time is measured.
 +   *  \return const char * - the time unit name.
 +   */
++//  const std::string& MEDFileField1TSWithoutSDA::getDtUnit() const {}
 +}
 +
 +namespace ParaMEDMEM // inline methods of MEDFileFieldGlobsReal
 +{
 +  /*!
 +   * Returns non empty names of all used profiles. To get all profiles call getPfls().
 +   *  \warning If a profile is used several times, its name is returned **only once**.
 +   *           To have a profile name in the result each time it is used, call
 +   *           getPflsReallyUsedMulti().
 +   *  \return std::vector<std::string> - a sequence of names of used profiles.
 +   */
 +  std::vector<std::string> MEDFileFieldGlobsReal::getPflsReallyUsed() const {}
 +  /*!
 +   * Returns non empty names of all used localizations. To get all localizations call getLocs().
 +   *  \warning If a localization is used several times, its name is returned **only once**.
 +   *           To have a localization name in the result each time it is used, call
 +   *           getLocsReallyUsedMulti().
 +   *  \return std::vector<std::string> - a sequence of names of used localizations.
 +   */
 +  std::vector<std::string> MEDFileFieldGlobsReal::getLocsReallyUsed() const {}
 +  /*!
 +   * Returns non empty names of all used profiles as many times as they are used.
 +   *  \return std::vector<std::string> - a sequence of names of used profiles.
 +   */
 +  std::vector<std::string> MEDFileFieldGlobsReal::getPflsReallyUsedMulti() const {}
 +  /*!
 +   * Returns non empty names of all used localizations as many times as they are used.
 +   *  \return std::vector<std::string> - a sequence of names of used localizations.
 +   */
 +  std::vector<std::string> MEDFileFieldGlobsReal::getLocsReallyUsedMulti() const {}
 +  /*!
 +   * Replaces references to some profiles (a reference is a profile name) by references
 +   * to other profiles.
 +   * \param [in] mapOfModif - a sequence describing required replacements. Each element of
 +   *        this sequence is a pair whose 
 +   *        - the first item is a vector of profile names to replace by the second item,
 +   *        - the second item is a profile name to replace every profile of the first item.
 +   */
 +  void MEDFileFieldGlobsReal::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Replaces references to some localizations (a reference is a localization name) by references
 +   * to other localizations.
 +   * \param [in] mapOfModif - a sequence describing required replacements. Each element of
 +   *        this sequence is a pair whose 
 +   *        - the first item is a vector of localization names to replace by the second item,
 +   *        - the second item is a localization name to replace every localization of the first
 +   *          item.
 +   */
 +  void MEDFileFieldGlobsReal::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) {}
 +}
index 80f85fe860bf690197c60920721b01b3ceea66f2,0000000000000000000000000000000000000000..10565363b602b67d2be82a3aaf62552236192486
mode 100644,000000..100644
--- /dev/null
@@@ -1,353 -1,0 +1,353 @@@
-   void MEDFileMesh::setName(const char *name) {}
 +// Copyright (C) 2013-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 +//
 +// 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, or (at your option) any later version.
 +//
 +// 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
 +//
 +
 +// This file contains some code used only for
 +// * generation of documentation for inline methods,
 +// * groupping methods into "Basic API", "Advanced" and "Others..." sections
 +
 +
 +namespace ParaMEDMEM
 +{
 +  /*!
 +   * Sets the name of \a this mesh.
 +   *  \param [in] name - the new mesh name.
 +   */
-   const char *MEDFileMesh::getName() const {}
++  void MEDFileMesh::setName(const std::string& name) {}
 +  /*!
 +   * Returns the name of \a this mesh.
 +   *  \return const char* name - the mesh name.
 +   */
-   void MEDFileMesh::setUnivName(const char *name) {}
++  const std::string& MEDFileMesh::getName() const {}
 +  /*!
 +   * Sets the universal name of \a this mesh. The universal name uniquely identifies the mesh.
 +   *  \param [in] name - the new universal mesh name.
 +   */
-    *  \return const char * - the universal mesh name.
++  void MEDFileMesh::setUnivName(const std::string& name) {}
 +  /*!
 +   * Returns the universal name of \a this mesh. The universal name uniquely identifies the mesh.
-   const char *MEDFileMesh::getUnivName() const {}
++   *  \return const std::string&  - the universal mesh name.
 +   */
-   void MEDFileMesh::setDescription(const char *name) {}
++  const std::string& MEDFileMesh::getUnivName() const {}
 +  /*!
 +   * Sets the description of \a this mesh.
 +   *  \param [in] name - the new mesh description.
 +   */
-   const char *MEDFileMesh::getDescription() const {}
++  void MEDFileMesh::setDescription(const std::string& name) {}
 +  /*!
 +   * Returns the description of \a this mesh.
 +   *  \return const char* - the mesh description.
 +   */
-   void MEDFileMesh::setTimeUnit(const char *unit) {}
++  const std::string& MEDFileMesh::getDescription() const {}
 +  /*!
 +   * Sets the order number of iteration of \a this mesh state.
 +   *  \param [in] order - the order number.
 +   */
 +  void MEDFileMesh::setOrder(int order) {}
 +  /*!
 +   * Returns the order number of iteration of \a this mesh state.
 +   *  \return int - the order number.
 +   */
 +  int MEDFileMesh::getOrder() const {}
 +  /*!
 +   * Sets the number of iteration of \a this mesh state.
 +   *  \param [in] it - the iteration number.
 +   */
 +  void MEDFileMesh::setIteration(int it) {}
 +  /*!
 +   * Returns the number of iteration of \a this mesh state.
 +   *  \return int - the iteration number.
 +   */
 +  int MEDFileMesh::getIteration() const {}
 +  /*!
 +   * Sets the time of \a this mesh state.
 +   *  \param [in] val - the time value.
 +   */
 +  void MEDFileMesh::setTimeValue(double time) {}
 +  /*!
 +   * Sets time, the number of iteration and the order number of iteration 
 +   * of \a this mesh state.
 +   *  \param [in] val - the time value.
 +   *  \param [in] iteration - the iteration number.
 +   *  \param [in] order - the order number.
 +   */
 +  void MEDFileMesh::setTime(int dt, int it, double time) {}
 +  /*!
 +   * Returns time, the number of iteration and the order number of iteration 
 +   * of \a this mesh state.
 +   *  \param [out] iteration - the iteration number.
 +   *  \param [out] order - the order number.
 +   *  \return double - the time value.
 +   */
 +  double MEDFileMesh::getTime(int& dt, int& it) {}
 +  /*!
 +   * Returns the time of \a this mesh state.
 +   *  \return double - the time value.
 +   */
 +  double MEDFileMesh::getTimeValue() const {}
 +  /*!
 +   * Sets units in which the time is measured.
 +   *  \param [in] unit - the time unit name.
 +   */
-    *  \return const char * - the time unit name.
++  void MEDFileMesh::setTimeUnit(const std::string& unit) {}
 +  /*!
 +   * Returns units in which the time is measured.
-   const char *MEDFileMesh::getTimeUnit() const {}
++   *  \return const std::string&  - the time unit name.
 +   */
- MEDFileMesh::New(const char *fileName);
- MEDFileMesh::New(const char *fileName, const char *mName, int dt=-1, int it=-1);
- MEDFileMesh::addFamily(const char *familyName, int id);
- MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName);
++  const std::string& MEDFileMesh::getTimeUnit() const {}
 +  /*!
 +   * Returns names and ids of all families in \a this mesh.
 +   *  \return const std::map<std::string,int>& - a map of a family name to a family id.
 +   */
 +  const std::map<std::string,int>& MEDFileMesh::getFamilyInfo() const {}
 +  /*!
 +   * Returns names of all groups and families constituting them in \a this mesh.
 +   *  \return const std::map<std::string, std::vector<std::string> >& - 
 +   *  a map of a group name to a vector of names of families constituting the group.
 +   */
 +  const std::map<std::string, std::vector<std::string> >& MEDFileMesh::getGroupInfo() const {}
 +  /*!
 +   * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
 +   *  \return std::vector<int> - a sequence of the relative dimensions.
 +   */
 +  std::vector<int> MEDFileMesh::getNonEmptyLevels() const {}
 +  /*!
 +   * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
 +   *  \return std::vector<int> - a sequence of the relative dimensions.
 +   */
 +  std::vector<int> MEDFileMesh::getNonEmptyLevelsExt() const {}
 +  /*!
 +   * Returns number of mesh entities of a given relative dimension in \a this mesh.
 +   *  \param [in] meshDimRelToMaxExt - the relative dimension of interest.
 +   *  \return int - the number of entities.
 +   *  \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
 +   */
 +  int MEDFileMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a MEDCouplingMesh of a given relative dimension.
 +   *  \param [in] meshDimRelToMax - the relative dimension of interest.
 +   *  \param [in] renum - if \c true, the returned mesh is permuted according to the
 +   *          optional numbers of mesh entities.
 +   *  \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
 +   *          delete using decrRef() as it is no more needed. 
 +   *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
 +   *  \throw If \a renum == \c true but permutation is impossible.
 +   */
 +  MEDCouplingMesh *MEDFileMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns the dimension on cells in \a this mesh.
 +   *  \return int - the mesh dimension.
 +   *  \throw If there are no cells in this mesh.
 +   */
 +  int MEDFileMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns a full textual description of \a this mesh.
 +   *  \return std::string - the string holding the mesh description.
 +   */
 +  std::string MEDFileMesh::advancedRepr() const {}
 +  /*!
 +   * Sets the family field of a given relative dimension.
 +   *  \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
 +   *          the family field is set.
 +   *  \param [in] famArr - the array of the family field.
 +   *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
 +   *  \throw If \a famArr has an invalid size.
 +   */
 +  void MEDFileMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Sets the optional numbers of mesh entities of a given dimension.
 +   *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
 +   *  \param [in] renumArr - the array of the numbers.
 +   *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
 +   *  \throw If \a renumArr has an invalid size.
 +   */
 +  void MEDFileMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns the family field for mesh entities of a given dimension.
 +   *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
 +   *  \return const DataArrayInt * - the family field. It is an array of ids of families
 +   *          each mesh entity belongs to. It can be NULL.
 +   */
 +  const DataArrayInt *MEDFileMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns the optional numbers of mesh entities of a given dimension.
 +   *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
 +   *  \return const DataArrayInt * - the array of the entity numbers.
 +   *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
 +   */
 +  const DataArrayInt *MEDFileMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns the optional numbers of mesh entities of a given dimension transformed using
 +   * DataArrayInt::invertArrayN2O2O2N().
 +   *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
 +   *  \return const DataArrayInt * - the array of the entity numbers transformed using
 +   *          DataArrayInt::invertArrayN2O2O2N().
 +   *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
 +   */
 +  const DataArrayInt *MEDFileMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {}
 +  /*!
 +   * Returns ids of mesh entities contained in given families of a given dimension.
 +   *  \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
 +   *          are required.
 +   *  \param [in] fams - the names of the families of interest.
 +   *  \param [in] renum - if \c true, the optional numbers of entities, if available, are
 +   *          returned instead of ids.
 +   *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
 +   *          numbers, if available and required, of mesh entities of the families. The caller
 +   *          is to delete this array using decrRef() as it is no more needed. 
 +   *  \throw If the family field is missing for \a meshDimRelToMaxExt.
 +   */
 +  DataArrayInt *MEDFileMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception) {}
 +}
 +
 +
 +namespace ParaMEDMEM
 +{
 +  /*! \name Basic API   */
 +  ///@{
 +  MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created);
- MEDFileMesh::changeFamilyName(const char *oldName, const char *newName);
- MEDFileMesh::changeGroupName(const char *oldName, const char *newName);
++//MEDFileMesh::New(const std::string& fileName);
++//MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1);
++MEDFileMesh::addFamily(const std::string& familyName, int id);
++MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName);
 +MEDFileMesh::advancedRepr() const = 0;
 +MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const;
 +MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const;
 +MEDFileMesh::assignFamilyNameWithGroupName();
 +MEDFileMesh::changeFamilyId(int oldId, int newId);
- MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName);
- MEDFileMesh::existsFamily(const char *familyName) const;
++MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName);
++MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName);
 +MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other);
- MEDFileMesh::existsGroup(const char *groupName) const;
++MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName);
++MEDFileMesh::existsFamily(const std::string& familyName) const;
 +MEDFileMesh::existsFamily(int famId) const;
- MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const;
++MEDFileMesh::existsGroup(const std::string& groupName) const;
 +MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created);
 +MEDFileMesh::getDescription() const;
 +MEDFileMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const;
 +MEDFileMesh::getFamiliesIds(const std::vector<std::string>& famNames) const;
- MEDFileMesh::getFamiliesOnGroup(const char *name) const;
++MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const;
 +MEDFileMesh::getFamiliesNames() const;
- MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum=false) const;
++MEDFileMesh::getFamiliesOnGroup(const std::string& name) const;
 +MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const;
- MEDFileMesh::getFamilyId(const char *name) const;
++MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const;
 +MEDFileMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const;
- MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum=false) const;
++MEDFileMesh::getFamilyId(const std::string& name) const;
 +MEDFileMesh::getFamilyInfo() const;
 +MEDFileMesh::getFamilyNameGivenId(int id) const;
 +MEDFileMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const;
- MEDFileMesh::getGroupsOnFamily(const char *name) const;
++MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const;
 +MEDFileMesh::getGroupInfo() const;
 +MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const;
 +MEDFileMesh::getGroupsNames() const;
- MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum=false) const;
- MEDFileMesh::getNodeGroupArr(const char *grp, bool renum=false) const;
++MEDFileMesh::getGroupsOnFamily(const std::string& name) const;
 +MEDFileMesh::getIteration() const;
 +MEDFileMesh::getMaxFamilyId() const;
 +MEDFileMesh::getMeshDimension() const;
 +MEDFileMesh::getName() const;
 +MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum=false) const;
- MEDFileMesh::removeFamily(const char *name);
- MEDFileMesh::removeGroup(const char *name);
- MEDFileMesh::setDescription(const char *name);
- MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector<int>& famIds);
- MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector<std::string>& fams);
++MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum=false) const;
++MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum=false) const;
 +MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const;
 +MEDFileMesh::getNonEmptyLevels() const = 0;
 +MEDFileMesh::getNonEmptyLevelsExt() const = 0;
 +MEDFileMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const;
 +MEDFileMesh::getOrder() const;
 +MEDFileMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const;
 +MEDFileMesh::getSizeAtLevel(int meshDimRelToMaxExt) const;
 +MEDFileMesh::getTime(int& dt, int& it);
 +MEDFileMesh::getTimeUnit() const;
 +MEDFileMesh::getTimeValue() const;
 +MEDFileMesh::getUnivName() const;
 +MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
 +MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& levs);
- MEDFileMesh::setFamilyId(const char *familyName, int id);
++MEDFileMesh::removeFamily(const std::string& name);
++MEDFileMesh::removeGroup(const std::string& name);
++MEDFileMesh::setDescription(const std::string& name);
++MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds);
++MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams);
 +MEDFileMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr);
- MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector<std::string>& grps);
++MEDFileMesh::setFamilyId(const std::string& familyName, int id);
 +MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info);
 +MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info);
 +MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum=false);
- MEDFileMesh::setName(const char *name);
++MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps);
 +MEDFileMesh::setIteration(int it);
- MEDFileMesh::setTimeUnit(const char *unit);
++MEDFileMesh::setName(const std::string& name);
 +MEDFileMesh::setOrder(int order);
 +MEDFileMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr);
 +MEDFileMesh::setTime(int dt, int it, double time);
- MEDFileMesh::setUnivName(const char *name);
++MEDFileMesh::setTimeUnit(const std::string& unit);
 +MEDFileMesh::setTimeValue(double time);
- MEDFileMesh::write(const char *fileName, int mode) const;
++MEDFileMesh::setUnivName(const std::string& name);
 +MEDFileMesh::simpleRepr() const;
- MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames);
++MEDFileMesh::write(const std::string& fileName, int mode) const;
 +MEDFileMesh::write(med_idt fid) const;
 +///@}
 +
 +/*! \name   Advanced API   */
 +///@{
 +MEDFileMesh::clearNonDiscrAttributes() const;
 +///@} 
 +
 +/*! \name Others... */
 +///@{
- MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName);
++MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames);
 +MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid);
 +MEDFileMesh::MEDFileMesh();
 +MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt);
 +MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp);
- MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames);
++MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName);
 +MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames);
- MEDFileMesh::getHeapMemorySize() const;
++MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames);
 +MEDFileMesh::changeFamilyIdArr(int oldId, int newId);
 +MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab);
 +MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m);
 +MEDFileMesh::deepCpy() const;
 +MEDFileMesh::ensureDifferentFamIdsPerLevel();
 +MEDFileMesh::getAllFamiliesIdsReferenced() const;
 +MEDFileMesh::getFamilyRepr(std::ostream& oss) const;
- MEDFileMesh::setFamilyIdUnique(const char *familyName, int id);
++//MEDFileMesh::getHeapMemorySize() const;
 +MEDFileMesh::getMaxFamilyIdInArrays() const;
 +MEDFileMesh::getMinFamilyId() const;
 +MEDFileMesh::getMinFamilyIdInArrays() const;
 +MEDFileMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const;
 +MEDFileMesh::getNumberOfNodes() const;
 +MEDFileMesh::getTheMaxFamilyId() const;
 +MEDFileMesh::getTheMinFamilyId() const;
 +MEDFileMesh::normalizeFamIdsMEDFile();
 +MEDFileMesh::normalizeFamIdsTrio();
++MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id);
 +MEDFileMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr);
 +MEDFileMesh::shallowCpy() const;
 +MEDFileMesh::synchronizeTinyInfoOnLeaves() const = 0;
 +MEDFileMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell);
 +MEDFileMesh::writeLL(med_idt fid) const;
 +int MEDFileMesh::_order;
 +int MEDFileMesh::_iteration;
 +double MEDFileMesh::_time;
 +std::string MEDFileMesh::_dt_unit;
 +std::string MEDFileMesh::_name;
 +std::string MEDFileMesh::_univ_name;
 +std::string MEDFileMesh::_desc_name;
 +std::map<std::string, std::vector<std::string> > MEDFileMesh::_groups;
 +std::map<std::string,int> MEDFileMesh::_families;
 +static const char MEDFileMesh::DFT_FAM_NAME[];
 +///@} 
 +}
 +
index aaeeabf14874036c52752b5cded32ee75f7d8056,0000000000000000000000000000000000000000..081cab63399650e356b988fe25c31439cfd837cf
mode 100644,000000..100644
--- /dev/null
@@@ -1,495 -1,0 +1,499 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#include "InterpKernelAsmX86.hxx"
 +
 +#include <cstring>
 +#include <sstream>
 +#include <algorithm>
 +
 +#ifdef _POSIX_MAPPED_FILES
 +#include <sys/mman.h>
 +#else
 +#ifdef WIN32
 +#include <windows.h>
 +#endif
 +#endif
 +
 +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
 +{
 +  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::copyToExecMemZone(const std::vector<char>& ml, unsigned& offset) const
 +{
 +  char *ret=0;
 +  int lgth=ml.size();
 +#ifdef _POSIX_MAPPED_FILES
++# ifdef __APPLE__
++  ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANON | MAP_PRIVATE,-1,0);
++# else
 +  ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0);
++# endif
 +#else
 +#ifdef WIN32
 +  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(ml.begin(),ml.end(),ret);
 +  return ret;
 +}
 +
 +void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector<char>& ml) const
 +{
 +  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)
 +{
 +  const char ASM1[]="ebp,esp";
 +  const unsigned char ML1[2]={0x89,0xe5};
 +  if(inst==ASM1)
 +    {
 +      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
 +      return ;
 +    }
 +  const char ASM2[]="rbp,rsp";
 +  const unsigned 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)
 +{
 +  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 unsigned 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 unsigned 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 unsigned 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 unsigned 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)
 +{
 +  std::string::size_type pos=inst.find_first_of(' ');
 +  std::string inst2=inst.substr(pos+1);
 +  const char ASM1[]="ebp";
 +  const unsigned char ML1[1]={0x55};
 +  if(inst2==ASM1)
 +    {//push ebp
 +      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
 +      return ;
 +    }
 +  const char ASM2[]="ebx";
 +  const unsigned char ML2[1]={0x53};
 +  if(inst2==ASM2)
 +    {//push ebx
 +      ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
 +      return ;
 +    }
 +  const char ASM3[]="rbp";
 +  const unsigned 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)
 +{
 +  std::string::size_type pos=inst.find_first_of(' ');
 +  std::string inst2=inst.substr(pos+1);
 +  const char ASM1[]="ebp";
 +  const unsigned char ML1[1]={0x5d};
 +  if(inst2==ASM1)
 +    {//push ebp
 +      ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
 +      return ;
 +    }
 +  const char ASM2[]="ebx";
 +  const unsigned 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)
 +{
 +  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 unsigned 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 unsigned 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 unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  if(inst.substr(0,4)=="esp,")
 +    {
 +      const unsigned 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 unsigned 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)
 +{
 +  if(inst.substr(0,4)=="esp,")
 +    {
 +      const unsigned 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 unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const unsigned 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)
 +{
 +  const char ASM1[]="[rsp],xmm0";
 +  const unsigned 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 unsigned 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)
 +{
 +  const char ASM1[]="qword [rsp]";
 +  const unsigned 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)
 +{
 +  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;
 +    }
 +}
index 61fc7141ba02117ae107f37deac944cf8f7f6e27,0000000000000000000000000000000000000000..dcd10d5dc3e7efec973942497cd6ea84fa0f1622
mode 100644,000000..100644
--- /dev/null
@@@ -1,154 -1,0 +1,154 @@@
-    * \class InterpolationOptions
-    * Class defining the options for all interpolation algorithms.
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __INTERPOLATIONOPTIONS_HXX__
 +#define __INTERPOLATIONOPTIONS_HXX__
 +
 +#include "INTERPKERNELDefines.hxx"
 +#include "NormalizedUnstructuredMesh.hxx"
 +
 +#include <string>
 +
 +namespace INTERP_KERNEL
 +{
 +  typedef enum { Triangulation, Convex, Geometric2D, PointLocator, Barycentric, BarycentricGeo2D } IntersectionType;
 +  
 +  /*!
++   * Class defining the options for all interpolation algorithms used in the \ref remapper "remapper" and
++   * in some of the \ref para-dec "DECs".
 +   * 
 +   * List of options, possible values and default values can be found on this page:
 +   * \ref InterpKerIntersectors
 +   */
 +  class INTERPKERNEL_EXPORT InterpolationOptions
 +  {
 +  private:
 +    int _print_level ;
 +    IntersectionType _intersection_type;
 +    double _precision;
 +    double _median_plane ;
 +    bool _do_rotate ;
 +    //! this measure is relative to the caracteristic dimension
 +    double _bounding_box_adjustment ;
 +    //! this measure is absolute \b not relative to the cell size
 +    double _bounding_box_adjustment_abs ;
 +    double _max_distance_for_3Dsurf_intersect;
 +    double _min_dot_btw_3Dsurf_intersect;
 +    int _orientation ;
 +    bool _measure_abs;
 +    SplittingPolicy _splitting_policy ;
 +  public:
 +    InterpolationOptions() { init(); }
 +    int getPrintLevel() const { return _print_level; }
 +    void setPrintLevel(int pl) { _print_level=pl; }
 +
 +    IntersectionType getIntersectionType() const { return _intersection_type; }
 +    void setIntersectionType(IntersectionType it) { _intersection_type=it; }
 +    std::string getIntersectionTypeRepr() const;
 +
 +    double getPrecision() const { return _precision; }
 +    void setPrecision(double p) { _precision=p; }
 +
 +    double getArcDetectionPrecision() const;
 +    void setArcDetectionPrecision(double p);
 +
 +    double getMedianPlane() const { return _median_plane; }
 +    void setMedianPlane(double mp) { _median_plane=mp; }
 +    
 +    bool getDoRotate() const { return _do_rotate; }
 +    void setDoRotate( bool dr) { _do_rotate = dr; }
 +    
 +    double getBoundingBoxAdjustment() const { return _bounding_box_adjustment; }
 +    void setBoundingBoxAdjustment(double bba) { _bounding_box_adjustment=bba; }
 +
 +    double getBoundingBoxAdjustmentAbs() const { return _bounding_box_adjustment_abs; }
 +    void setBoundingBoxAdjustmentAbs(double bba) { _bounding_box_adjustment_abs=bba; }
 +    
 +    double getMaxDistance3DSurfIntersect() const { return _max_distance_for_3Dsurf_intersect; }
 +    void setMaxDistance3DSurfIntersect(double bba) { _max_distance_for_3Dsurf_intersect=bba; }
 +
 +    double getMinDotBtwPlane3DSurfIntersect() const { return _min_dot_btw_3Dsurf_intersect; }
 +    void setMinDotBtwPlane3DSurfIntersect(double v) { _min_dot_btw_3Dsurf_intersect=v; }
 +
 +    int getOrientation() const { return _orientation; }
 +    void setOrientation(int o) { _orientation=o; }
 +
 +    bool getMeasureAbsStatus() const { return _measure_abs; }
 +    void setMeasureAbsStatus(bool newStatus) { _measure_abs=newStatus; }
 +    
 +    SplittingPolicy getSplittingPolicy() const { return _splitting_policy; }
 +    void setSplittingPolicy(SplittingPolicy sp) { _splitting_policy=sp; }
 +    std::string getSplittingPolicyRepr() const;
 +
 +    std::string filterInterpolationMethod(const std::string& meth) const;
 +
 +    void init();
 +    
 +    bool setInterpolationOptions(long print_level,
 +                                 std::string intersection_type,
 +                                 double precision,
 +                                 double median_plane,
 +                                 bool do_rotate,
 +                                 double bounding_box_adjustment,
 +                                 double bounding_box_adjustment_abs,
 +                                 double max_distance_for_3Dsurf_intersect,
 +                                 long orientation,
 +                                 bool measure_abs,
 +                                 std::string splitting_policy);
 +    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, const std::string& value);
 +    std::string printOptions() const;
 +  public:
 +    static void CheckAndSplitInterpolationMethod(const std::string& method, std::string& srcMeth, std::string& trgMeth);
 +  private:
 +    static const double DFT_MEDIAN_PLANE;
 +    static const double DFT_SURF3D_ADJ_EPS;
 +    static const double DFT_MAX_DIST_3DSURF_INTERSECT;
 +    static const double DFT_MIN_DOT_BTW_3DSURF_INTERSECT;
 +  public:
 +    static const char PRECISION_STR[];
 +    static const char ARC_DETECTION_PRECISION_STR[];
 +    static const char MEDIANE_PLANE_STR[];
 +    static const char BOUNDING_BOX_ADJ_STR[];
 +    static const char BOUNDING_BOX_ADJ_ABS_STR[];
 +    static const char MAX_DISTANCE_3DSURF_INSECT_STR[];
 +    static const char MIN_DOT_BTW_3DSURF_INSECT_STR[];
 +    static const char PRINT_LEV_STR[];
 +    static const char DO_ROTATE_STR[];
 +    static const char ORIENTATION_STR[];
 +    static const char MEASURE_ABS_STR[];
 +    static const char INTERSEC_TYPE_STR[];
 +    static const char SPLITTING_POLICY_STR[];
 +    static const char TRIANGULATION_INTERSECT2D_STR[];
 +    static const char CONVEX_INTERSECT2D_STR[];
 +    static const char GEOMETRIC_INTERSECT2D_STR[];
 +    static const char POINTLOCATOR_INTERSECT_STR[];
 +    static const char BARYCENTRIC_INTERSECT_STR[];
 +    static const char BARYCENTRICGEO2D_INTERSECT_STR[];
 +    static const char PLANAR_SPLIT_FACE_5_STR[];
 +    static const char PLANAR_SPLIT_FACE_6_STR[];
 +    static const char GENERAL_SPLIT_24_STR[];
 +    static const char GENERAL_SPLIT_48_STR[];
 +  };
 +
 +}
 +#endif
index dd3ffef94fa558c5012b0286b7fe91a0f1da38d1,0000000000000000000000000000000000000000..a96072b7841713f8be3ee53764edd3c49a3d58cf
mode 100644,000000..100644
--- /dev/null
@@@ -1,1110 -1,0 +1,1110 @@@
-     bool operator()(std::pair<double,double>theta1, std::pair<double,double> theta2) 
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __INTERPOLATIONUTILS_HXX__
 +#define __INTERPOLATIONUTILS_HXX__
 +
 +#include "INTERPKERNELDefines.hxx"
 +#include "InterpKernelException.hxx"
 +
 +#include "NormalizedUnstructuredMesh.hxx"
 +
 +#include <deque>
 +#include <map>
 +#include <cmath>
 +#include <string>
 +#include <vector>
 +#include <algorithm>
 +#include <iostream>
 +#include <limits>
 +#include <functional>
 +
 +namespace INTERP_KERNEL
 +{
 +  template<class ConnType, NumberingPolicy numPol>
 +  class OTT//OffsetToolTrait
 +  {
 +  };
 +  
 +  template<class ConnType>
 +  class OTT<ConnType,ALL_C_MODE>
 +  {
 +  public:
 +    static ConnType indFC(ConnType i) { return i; }
 +    static ConnType ind2C(ConnType i) { return i; }
 +    static ConnType conn2C(ConnType i) { return i; }
 +    static ConnType coo2C(ConnType i) { return i; }
 +  };
 +  
 +  template<class ConnType>
 +  class OTT<ConnType,ALL_FORTRAN_MODE>
 +  {
 +  public:
 +    static ConnType indFC(ConnType i) { return i+1; }
 +    static ConnType ind2C(ConnType i) { return i-1; }
 +    static ConnType conn2C(ConnType i) { return i-1; }
 +    static ConnType coo2C(ConnType i) { return i-1; }
 +  };
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /*   calcul la surface d'un triangle                  */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +
 +  inline double Surf_Tri(const double* P_1,const double* P_2,const double* P_3)
 +  {
 +    double A=(P_3[1]-P_1[1])*(P_2[0]-P_1[0])-(P_2[1]-P_1[1])*(P_3[0]-P_1[0]);
 +    double Surface = 0.5*fabs(A);
 +    return Surface;
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /*     fonction qui calcul le determinant            */
 +  /*      de deux vecteur(cf doc CGAL).                */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +
 +  //fonction qui calcul le determinant des vecteurs: P3P1 et P3P2
 +  //(cf doc CGAL).
 +
 +  inline double mon_determinant(const double* P_1,
 +                                const double*  P_2,
 +                                const double* P_3)
 +  {
 +    double mon_det=(P_1[0]-P_3[0])*(P_2[1]-P_3[1])-(P_2[0]-P_3[0])*(P_1[1]-P_3[1]);
 +    return mon_det;
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  //calcul la norme du vecteur P1P2
 +
 +  inline double norme_vecteur(const double* P_1,const double* P_2)
 +  {
 +    double X=P_1[0]-P_2[0];
 +    double Y=P_1[1]-P_2[1];
 +    double norme=sqrt(X*X+Y*Y);
 +    return norme;
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /*         calcul le cos et le sin de l'angle P1P2,P1P3     */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +
 +  inline std::vector<double> calcul_cos_et_sin(const double* P_1,
 +                                               const double* P_2,
 +                                               const double* P_3)
 +  {
 +       
 +    std::vector<double> Vect;
 +    double P1_P2=norme_vecteur(P_1,P_2);
 +    double P2_P3=norme_vecteur(P_2,P_3);
 +    double P3_P1=norme_vecteur(P_3,P_1);
 +       
 +    double N=P1_P2*P1_P2+P3_P1*P3_P1-P2_P3*P2_P3;
 +    double D=2.0*P1_P2*P3_P1;
 +    double COS=N/D;
 +    if (COS>1.0) COS=1.0;
 +    if (COS<-1.0) COS=-1.0;
 +    Vect.push_back(COS);
 +    double V=mon_determinant(P_2,P_3,P_1);
 +    double D_1=P1_P2*P3_P1;
 +    double SIN=V/D_1;
 +    if (SIN>1.0) SIN=1.0;
 +    if (SIN<-1.0) SIN=-1.0;
 +    Vect.push_back(SIN);
 +       
 +    return Vect;
 +       
 +  }
 +
 +  /*!
 +   * This method builds a quadrangle built with the first point of 'triIn' the barycenter of two edges starting or ending with
 +   * the first point of 'triIn' and the barycenter of 'triIn'.
 +   *
 +   * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle.
 +   * @param quadOut is a 8 doubles array filled after the following call.
 +   */
 +  template<int SPACEDIM>
 +  inline void fillDualCellOfTri(const double *triIn, double *quadOut)
 +  {
 +    //1st point
 +    std::copy(triIn,triIn+SPACEDIM,quadOut);
 +    double tmp[SPACEDIM];
 +    std::transform(triIn,triIn+SPACEDIM,triIn+SPACEDIM,tmp,std::plus<double>());
 +    //2nd point
 +    std::transform(tmp,tmp+SPACEDIM,quadOut+SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5));
 +    std::transform(tmp,tmp+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus<double>());
 +    //3rd point
 +    std::transform(tmp,tmp+SPACEDIM,quadOut+2*SPACEDIM,std::bind2nd(std::multiplies<double>(),1/3.));
 +    //4th point
 +    std::transform(triIn,triIn+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus<double>());
 +    std::transform(tmp,tmp+SPACEDIM,quadOut+3*SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5));
 +  }
 +
 +  /*!
 +   * This method builds a potentially non-convex polygon cell built with the first point of 'triIn' the barycenter of two edges starting or ending with
 +   * the first point of 'triIn' and the barycenter of 'triIn'.
 +   *
 +   * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle.
 +   * @param quadOut is a 8 doubles array filled after the following call.
 +   */
 +  template<int SPACEDIM>
 +  inline void fillDualCellOfPolyg(const double *polygIn, int nPtsPolygonIn, double *polygOut)
 +  {
 +    //1st point
 +    std::copy(polygIn,polygIn+SPACEDIM,polygOut);
 +    std::transform(polygIn,polygIn+SPACEDIM,polygIn+SPACEDIM,polygOut+SPACEDIM,std::plus<double>());
 +    //2nd point
 +    std::transform(polygOut+SPACEDIM,polygOut+2*SPACEDIM,polygOut+SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5));
 +    double tmp[SPACEDIM];
 +    //
 +    for(int i=0;i<nPtsPolygonIn-2;i++)
 +      {
 +        std::transform(polygIn,polygIn+SPACEDIM,polygIn+(i+2)*SPACEDIM,tmp,std::plus<double>());
 +        std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+3)*SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5));
 +        std::transform(polygIn+(i+1)*SPACEDIM,polygIn+(i+2)*SPACEDIM,tmp,tmp,std::plus<double>());
 +        std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+2)*SPACEDIM,std::bind2nd(std::multiplies<double>(),1./3.));
 +      }
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /*     calcul les coordonnees du barycentre d'un polygone   */ 
 +  /*     le vecteur en entree est constitue des coordonnees   */
 +  /*     des sommets du polygone                              */                             
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +
 +  inline std::vector<double> bary_poly(const std::vector<double>& V)
 +  {
 +    std::vector<double> Bary;
 +    long taille=V.size();
 +    double x=0;
 +    double y=0;
 +
 +    for(long i=0;i<taille/2;i++)
 +      {
 +        x=x+V[2*i];
 +        y=y+V[2*i+1];
 +      }
 +    double A=2*x/((double)taille);
 +    double B=2*y/((double)taille);
 +    Bary.push_back(A);//taille vecteur=2*nb de points.
 +    Bary.push_back(B);
 +
 +
 +    return Bary;
 +  }
 +  
 +  /*!
 +   * Given 6 coeffs of a Tria6 returns the corresponding value of a given pos
 +   */
 +  inline double computeTria6RefBase(const double *coeffs, const double *pos)
 +  {
 +    return coeffs[0]+coeffs[1]*pos[0]+coeffs[2]*pos[1]+coeffs[3]*pos[0]*pos[0]+coeffs[4]*pos[0]*pos[1]+coeffs[5]*pos[1]*pos[1];
 +  }
 +  
 +  /*!
 +   * Given xsi,eta in refCoo (length==2) return 6 coeffs in weightedPos.
 +   */
 +  inline void computeWeightedCoeffsInTria6FromRefBase(const double *refCoo, double *weightedPos)
 +  {
 +    weightedPos[0]=(1.-refCoo[0]-refCoo[1])*(1.-2*refCoo[0]-2.*refCoo[1]);
 +    weightedPos[1]=refCoo[0]*(2.*refCoo[0]-1.);
 +    weightedPos[2]=refCoo[1]*(2.*refCoo[1]-1.);
 +    weightedPos[3]=4.*refCoo[0]*(1.-refCoo[0]-refCoo[1]);
 +    weightedPos[4]=4.*refCoo[0]*refCoo[1];
 +    weightedPos[5]=4.*refCoo[1]*(1.-refCoo[0]-refCoo[1]);
 +  }
 +
 +  /*!
 +   * Given 10 coeffs of a Tetra10 returns the corresponding value of a given pos
 +   */
 +  inline double computeTetra10RefBase(const double *coeffs, const double *pos)
 +  {
 +    return coeffs[0]+coeffs[1]*pos[0]+coeffs[2]*pos[1]+coeffs[3]*pos[2]+
 +      coeffs[4]*pos[0]*pos[0]+coeffs[5]*pos[0]*pos[1]+coeffs[6]*pos[0]*pos[2]+
 +      coeffs[7]*pos[1]*pos[1]+coeffs[8]*pos[1]*pos[2]+coeffs[9]*pos[2]*pos[2];
 +  }
 +
 +  /*!
 +   * Given xsi,eta,z in refCoo (length==3) return 10 coeffs in weightedPos.
 +   */
 +  inline void computeWeightedCoeffsInTetra10FromRefBase(const double *refCoo, double *weightedPos)
 +  {
 +    //http://www.cadfamily.com/download/CAE/ABAQUS/The%20Finite%20Element%20Method%20-%20A%20practical%20course%20abaqus.pdf page 217
 +    //L1=1-refCoo[0]-refCoo[1]-refCoo[2]
 +    //L2=refCoo[0] L3=refCoo[1] L4=refCoo[2]
 +    weightedPos[0]=(-2.*(refCoo[0]+refCoo[1]+refCoo[2])+1)*(1-refCoo[0]-refCoo[1]-refCoo[2]);//(2*L1-1)*L1
 +    weightedPos[1]=(2.*refCoo[0]-1.)*refCoo[0];//(2*L2-1)*L2
 +    weightedPos[2]=(2.*refCoo[1]-1.)*refCoo[1];//(2*L3-1)*L3
 +    weightedPos[3]=(2.*refCoo[2]-1.)*refCoo[2];//(2*L4-1)*L4
 +    weightedPos[4]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[0];//4*L1*L2
 +    weightedPos[5]=4.*refCoo[0]*refCoo[1];//4*L2*L3
 +    weightedPos[6]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[1];//4*L1*L3
 +    weightedPos[7]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[2];//4*L1*L4
 +    weightedPos[8]=4.*refCoo[0]*refCoo[2];//4*L2*L4
 +    weightedPos[9]=4.*refCoo[1]*refCoo[2];//4*L3*L4
 +  }
 +
 +  /*!
 +   * \brief Solve system equation in matrix form using Gaussian elimination algorithm
 +   *  \param M - N x N+1 matrix
 +   *  \param sol - vector of N solutions
 +   *  \retval bool - true if succeeded
 +   */
 +  template<unsigned nbRow>
 +  bool solveSystemOfEquations(double M[nbRow][nbRow+1], double* sol)
 +  {
 +    const int nbCol=nbRow+1;
 +
 +    // make upper triangular matrix (forward elimination)
 +
 +    int iR[nbRow];// = { 0, 1, 2 };
 +    for ( int i = 0; i < (int) nbRow; ++i )
 +      iR[i] = i;
 +    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 < (int)nbRow; ++r )
 +          {
 +            double m = std::fabs( M[ iR[r] ][i] );
 +            if ( m > max )
 +              {
 +                max = m;
 +                std::swap( iR[r], iR[i] );
 +              }
 +          }
 +        if ( max < std::numeric_limits<double>::min() )
 +          {
 +            //sol[0]=1; sol[1]=sol[2]=sol[3]=0;
 +            return false; // no solution
 +          }
 +        // 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 < (int)nbRow; ++r )
 +          {
 +            double* mRow = M[ iR[r] ];
 +            double coef = mRow[ i ] / tUpRow[ i ];
 +            for ( int c = i+1; c < nbCol; ++c )
 +              mRow[ c ] -= tUpRow[ c ] * coef;
 +          }
 +      }
 +    double* mRow = M[ iR[nbRow-1] ];
 +    if ( std::fabs( mRow[ nbRow-1 ] ) < std::numeric_limits<double>::min() )
 +      {
 +        //sol[0]=1; sol[1]=sol[2]=sol[3]=0;
 +        return false; // no solution
 +      }
 +    mRow[ nbRow ] /= mRow[ nbRow-1 ];
 +
 +    // calculate solution (back substitution)
 +
 +    sol[ nbRow-1 ] = mRow[ nbRow ];
 +
 +    for ( int i = nbRow-2; i+1; --i )
 +      {
 +        mRow = M[ iR[i] ];
 +        sol[ i ] = mRow[ nbRow ];
 +        for ( int j = nbRow-1; j > i; --j )
 +          sol[ i ] -= sol[j]*mRow[ j ];
 +        sol[ i ] /= mRow[ i ];
 +      }
 +
 +    return true;
 +  }
 +
 +  
 +  /*!
 +   * \brief Solve system equation in matrix form using Gaussian elimination algorithm
 +   *  \param M - N x N+NB_OF_VARS matrix
 +   *  \param sol - vector of N solutions
 +   *  \retval bool - true if succeeded
 +   */
 +  template<unsigned SZ, unsigned NB_OF_RES>
 +  bool solveSystemOfEquations2(const double *matrix, double *solutions, double eps)
 +  {
 +    unsigned k,j;
 +    int nr,n,m,np;
 +    double s,g;
 +    int mb;
 +    //
 +    double B[SZ*(SZ+NB_OF_RES)];
 +    std::copy(matrix,matrix+SZ*(SZ+NB_OF_RES),B);
 +    //
 +    nr=SZ+NB_OF_RES;
 +    for(k=0;k<SZ;k++)
 +      {
 +        np=nr*k+k;
 +        if(fabs(B[np])<eps)
 +          {
 +            n=k;
 +            do
 +              {
 +                n++;
 +                if(fabs(B[nr*k+n])>eps)
 +                  {/* Rows permutation */
 +                    for(m=0;m<nr;m++)
 +                      std::swap(B[nr*k+m],B[nr*n+m]);
 +                  }
 +              }
 +            while (n<(int)SZ);
 +          }
 +        s=B[np];//s is the Pivot
 +        std::transform(B+k*nr,B+(k+1)*nr,B+k*nr,std::bind2nd(std::divides<double>(),s));
 +        for(j=0;j<SZ;j++)
 +          {
 +            if(j!=k)
 +              {
 +                g=B[j*nr+k];
 +                for(mb=k;mb<nr;mb++)
 +                  B[j*nr+mb]-=B[k*nr+mb]*g;
 +              }
 +          }
 +      }
 +    for(j=0;j<NB_OF_RES;j++)
 +      for(k=0;k<SZ;k++)
 +        solutions[j*SZ+k]=B[nr*k+SZ+j];
 +    //
 +    return true;
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /*     Calculate barycentric coordinates of a 2D point p */ 
 +  /*     with respect to the triangle verices.             */
 +  /*     triaCoords are in full interlace                  */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +
 +  template<int SPACEDIM>
 +  inline void barycentric_coords(const double* triaCoords, const double* p, double* bc)
 +  {
 +    // matrix 2x2
 +    double
 +      T11 = triaCoords[0]-triaCoords[2*SPACEDIM], T12 = triaCoords[SPACEDIM]-triaCoords[2*SPACEDIM],
 +      T21 = triaCoords[1]-triaCoords[2*SPACEDIM+1], T22 = triaCoords[SPACEDIM+1]-triaCoords[2*SPACEDIM+1];
 +    // matrix determinant
 +    double Tdet = T11*T22 - T12*T21;
 +    if ( fabs( Tdet ) < std::numeric_limits<double>::min() ) {
 +      bc[0]=1; bc[1]=0; bc[2]=0;
 +      return;
 +    }
 +    // matrix inverse
 +    double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11;
 +    // vector
 +    double r11 = p[0]-triaCoords[2*SPACEDIM], r12 = p[1]-triaCoords[2*SPACEDIM+1];
 +    // barycentric coordinates: mutiply matrix by vector
 +    bc[0] = (t11 * r11 + t12 * r12)/Tdet;
 +    bc[1] = (t21 * r11 + t22 * r12)/Tdet;
 +    bc[2] = 1. - bc[0] - bc[1];
 +  }
 +
 +  /*!
 +   * Calculate barycentric coordinates of a point p with respect to triangle or tetra verices.
 +   * This method makes 2 assumptions :
 +   *    - this is a simplex
 +   *    - spacedim == meshdim. For TRI3 and TRI6 spaceDim is expected to be equal to 2 and for TETRA4 spaceDim is expected to be equal to 3.
 +   *      If not the case (3D surf for example) a previous projection should be done before.
 +   */
 +  inline void barycentric_coords(const std::vector<const double*>& n, const double *p, double *bc)
 +  {
 +    enum { _X, _Y, _Z };
 +    switch(n.size())
 +      {
 +      case 2:
 +        {// SEG 2
 +          double delta=n[0][0]-n[1][0];
 +          bc[0]=fabs((*p-n[1][0])/delta);
 +          bc[1]=fabs((*p-n[0][0])/delta);
 +          break;
 +        }
 +      case 3:
 +        { // TRIA3
 +          // matrix 2x2
 +          double
 +            T11 = n[0][_X]-n[2][_X], T12 = n[1][_X]-n[2][_X],
 +            T21 = n[0][_Y]-n[2][_Y], T22 = n[1][_Y]-n[2][_Y];
 +          // matrix determinant
 +          double Tdet = T11*T22 - T12*T21;
 +          if ( (std::fabs( Tdet) ) < (std::numeric_limits<double>::min()) )
 +            {
 +              bc[0]=1; bc[1]=bc[2]=0; // no solution
 +              return;
 +            }
 +          // matrix inverse
 +          double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11;
 +          // vector
 +          double r11 = p[_X]-n[2][_X], r12 = p[_Y]-n[2][_Y];
 +          // barycentric coordinates: mutiply matrix by vector
 +          bc[0] = (t11 * r11 + t12 * r12)/Tdet;
 +          bc[1] = (t21 * r11 + t22 * r12)/Tdet;
 +          bc[2] = 1. - bc[0] - bc[1];
 +          break;
 +        }
 +      case 4:
 +        { // TETRA4
 +          // Find bc by solving system of 3 equations using Gaussian elimination algorithm
 +          // bc1*( x1 - x4 ) + bc2*( x2 - x4 ) + bc3*( x3 - x4 ) = px - x4
 +          // bc1*( y1 - y4 ) + bc2*( y2 - y4 ) + bc3*( y3 - y4 ) = px - y4
 +          // bc1*( z1 - z4 ) + bc2*( z2 - z4 ) + bc3*( z3 - z4 ) = px - z4
 +          
 +          double T[3][4]=
 +            {{ n[0][_X]-n[3][_X], n[1][_X]-n[3][_X], n[2][_X]-n[3][_X], p[_X]-n[3][_X] },
 +             { n[0][_Y]-n[3][_Y], n[1][_Y]-n[3][_Y], n[2][_Y]-n[3][_Y], p[_Y]-n[3][_Y] },
 +             { n[0][_Z]-n[3][_Z], n[1][_Z]-n[3][_Z], n[2][_Z]-n[3][_Z], p[_Z]-n[3][_Z] }};
 +          
 +          if ( !solveSystemOfEquations<3>( T, bc ) )
 +            bc[0]=1., bc[1] = bc[2] = bc[3] = 0;
 +          else
 +            bc[ 3 ] = 1. - bc[0] - bc[1] - bc[2];
 +          break;
 +        }
 +      case 6:
 +        {
 +          // TRIA6
 +          double matrix2[48]={1., 0., 0., 0., 0., 0., 0., 0.,
 +                              1., 0., 0., 0., 0., 0., 1., 0., 
 +                              1., 0., 0., 0., 0., 0., 0., 1.,
 +                              1., 0., 0., 0., 0., 0., 0.5, 0.,
 +                              1., 0., 0., 0., 0., 0., 0.5, 0.5,
 +                              1., 0., 0., 0., 0., 0., 0.,0.5};
 +          for(int i=0;i<6;i++)
 +            {
 +              matrix2[8*i+1]=n[i][0];
 +              matrix2[8*i+2]=n[i][1];
 +              matrix2[8*i+3]=n[i][0]*n[i][0];
 +              matrix2[8*i+4]=n[i][0]*n[i][1];
 +              matrix2[8*i+5]=n[i][1]*n[i][1];
 +            }
 +          double res[12];
 +          solveSystemOfEquations2<6,2>(matrix2,res,std::numeric_limits<double>::min());
 +          double refCoo[2];
 +          refCoo[0]=computeTria6RefBase(res,p);
 +          refCoo[1]=computeTria6RefBase(res+6,p);
 +          computeWeightedCoeffsInTria6FromRefBase(refCoo,bc);
 +          break;
 +        }
 +      case 10:
 +        {//TETRA10
 +          double matrix2[130]={1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0.,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5, 0.,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0.5, 0.,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0.5,
 +                               1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5};
 +          for(int i=0;i<10;i++)
 +            {
 +              matrix2[13*i+1]=n[i][0];
 +              matrix2[13*i+2]=n[i][1];
 +              matrix2[13*i+3]=n[i][2];
 +              matrix2[13*i+4]=n[i][0]*n[i][0];
 +              matrix2[13*i+5]=n[i][0]*n[i][1];
 +              matrix2[13*i+6]=n[i][0]*n[i][2];
 +              matrix2[13*i+7]=n[i][1]*n[i][1];
 +              matrix2[13*i+8]=n[i][1]*n[i][2];
 +              matrix2[13*i+9]=n[i][2]*n[i][2];
 +            }
 +          double res[30];
 +          solveSystemOfEquations2<10,3>(matrix2,res,std::numeric_limits<double>::min());
 +          double refCoo[3];
 +          refCoo[0]=computeTetra10RefBase(res,p);
 +          refCoo[1]=computeTetra10RefBase(res+10,p);
 +          refCoo[2]=computeTetra10RefBase(res+20,p);
 +          computeWeightedCoeffsInTetra10FromRefBase(refCoo,bc);
 +          break;
 +        }
 +      default:
 +        throw INTERP_KERNEL::Exception("INTERP_KERNEL::barycentric_coords : unrecognized simplex !");
 +      }
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /*         calcul la surface d'un polygone.                 */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +
 +  inline double  Surf_Poly(const std::vector<double>& Poly)
 +  { 
 +
 +    double Surface=0;
 +    for(unsigned long i=0; i<(Poly.size())/2-2; i++)
 +      {
 +        double Surf=Surf_Tri( &Poly[0],&Poly[2*(i+1)],&Poly[2*(i+2)] ); 
 +        Surface=Surface + Surf ;
 +      }
 +    return Surface ;
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /*   fonction qui teste si un point est dans une maille     */
 +  /*   point: P_0                                             */
 +  /*   P_1, P_2, P_3 sommet des mailles                       */   
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +
 +  inline bool point_dans_triangle(const double* P_0,const double* P_1,
 +                                  const double* P_2,const double* P_3,
 +                                  double eps)
 +  {
 +
 +    bool A=false;
 +    double det_1=mon_determinant(P_1,P_3,P_0);
 +    double det_2=mon_determinant(P_3,P_2,P_0);
 +    double det_3=mon_determinant(P_2,P_1,P_0);
 +    if( (det_1>=-eps && det_2>=-eps && det_3>=-eps) || (det_1<=eps && det_2<=eps && det_3<=eps) )
 +      {
 +        A=true;
 +      }
 +
 +    return A;
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /*fonction pour verifier qu'un point n'a pas deja ete considerer dans   */ 
 +  /*      le vecteur et le rajouter au vecteur sinon.                     */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +
 +  inline void verif_point_dans_vect(const double* P, std::vector<double>& V, double absolute_precision )
 +  {
 +    long taille=V.size();
 +    bool isPresent=false;
 +    for(long i=0;i<taille/2;i++) 
 +      {
 +        if (sqrt(((P[0]-V[2*i])*(P[0]-V[2*i])+(P[1]-V[2*i+1])*(P[1]-V[2*i+1])))<absolute_precision)
 +          isPresent=true;
 +      
 +      }
 +    if(!isPresent)
 +      {
 +      
 +        V.push_back(P[0]);
 +        V.push_back(P[1]);    
 +      }
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  /* fonction qui rajoute les sommet du triangle P dans le vecteur V        */ 
 +  /* si ceux-ci sont compris dans le triangle S et ne sont pas deja dans    */
 +  /* V.                                                                     */
 +  /*sommets de P: P_1, P_2, P_3                                             */
 +  /*sommets de S: P_4, P_5, P_6                                             */  
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ 
 +
 +  inline void rajou_sommet_triangl(const double* P_1,const double* P_2,const double* P_3,
 +                                   const double* P_4,const double* P_5,const double* P_6,
 +                                   std::vector<double>& V, double dim_caracteristic, double precision)
 +  {
 +
 +    double absolute_precision = precision*dim_caracteristic;
 +    bool A_1=INTERP_KERNEL::point_dans_triangle(P_1,P_4,P_5,P_6,absolute_precision);
 +    if(A_1)
 +      verif_point_dans_vect(P_1,V,absolute_precision);
 +    bool A_2=INTERP_KERNEL::point_dans_triangle(P_2,P_4,P_5,P_6,absolute_precision);
 +    if(A_2)
 +      verif_point_dans_vect(P_2,V,absolute_precision);
 +    bool A_3=INTERP_KERNEL::point_dans_triangle(P_3,P_4,P_5,P_6,absolute_precision);
 +    if(A_3)
 +      verif_point_dans_vect(P_3,V,absolute_precision);
 +  }
 +
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  _ _ _ _ _ _ _ _*/
 +  /*  calcul de l'intersection de deux segments: segments P1P2 avec P3P4      */
 +  /*  . Si l'intersection est non nulle et si celle-ci n'est                  */
 +  /*  n'est pas deja contenue dans Vect on la rajoute a Vect                  */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  _ _ _ _ _ _ _ _*/ 
 +
 +  inline void inters_de_segment(const double * P_1,const double * P_2,
 +                                const double * P_3,const double * P_4,
 +                                std::vector<double>& Vect, 
 +                                double dim_caracteristic, double precision)
 +  {
 +    // calcul du determinant de P_1P_2 et P_3P_4.
 +    double det=(P_2[0]-P_1[0])*(P_4[1]-P_3[1])-(P_4[0]-P_3[0])*(P_2[1]-P_1[1]);
 +
 +    double absolute_precision = dim_caracteristic*precision;
 +    if(fabs(det)>absolute_precision)
 +      {
 +        double k_1=-((P_3[1]-P_4[1])*(P_3[0]-P_1[0])+(P_4[0]-P_3[0])*(P_3[1]-P_1[1]))/det;
 +
 +        if (k_1 >= -absolute_precision && k_1 <= 1+absolute_precision)
 +          //if( k_1 >= -precision && k_1 <= 1+precision)
 +          {
 +            double k_2= ((P_1[1]-P_2[1])*(P_1[0]-P_3[0])+(P_2[0]-P_1[0])*(P_1[1]-P_3[1]))/det;
 +
 +            if (k_2 >= -absolute_precision && k_2 <= 1+absolute_precision)
 +              //if( k_2 >= -precision && k_2 <= 1+precision)
 +              {
 +                double P_0[2];
 +                P_0[0]=P_1[0]+k_1*(P_2[0]-P_1[0]);
 +                P_0[1]=P_1[1]+k_1*(P_2[1]-P_1[1]);
 +                verif_point_dans_vect(P_0,Vect,absolute_precision);
 +              }
 +          }
 +      }
 +  }
 +
 +
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +  /*      calcul l'intersection de deux triangles            */
 +  /* P_1, P_2, P_3: sommets du premier triangle              */
 +  /* P_4, P_5, P_6: sommets du deuxi�me triangle             */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ 
 +
 +  inline void intersec_de_triangle(const double* P_1,const double* P_2, const double* P_3,
 +                                   const double* P_4,const double* P_5,const double* P_6, 
 +                                   std::vector<double>& Vect, double dim_caracteristic, double precision)
 +  {
 +    inters_de_segment(P_1,P_2,P_4,P_5,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_1,P_2,P_5,P_6,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_1,P_2,P_6,P_4,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_2,P_3,P_4,P_5,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_2,P_3,P_5,P_6,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_2,P_3,P_6,P_4,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_3,P_1,P_4,P_5,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_3,P_1,P_5,P_6,Vect, dim_caracteristic, precision);
 +    inters_de_segment(P_3,P_1,P_6,P_4,Vect, dim_caracteristic, precision);
 +    rajou_sommet_triangl(P_1,P_2,P_3,P_4,P_5,P_6,Vect, dim_caracteristic, precision);
 +    rajou_sommet_triangl(P_4,P_5,P_6,P_1,P_2,P_3,Vect, dim_caracteristic, precision);
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* fonction pour verifier qu'un node maille n'a pas deja ete considerer  */
 +  /*  dans le vecteur et le rajouter au vecteur sinon.                     */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +
 +  inline void verif_maill_dans_vect(int Num, std::vector<int>& V)
 +  {
 +    long taille=V.size();
 +    int A=0;
 +    for(long i=0;i<taille;i++)
 +      {
 +        if(Num==V[i])
 +          {
 +            A=1;
 +            break;
 +          } 
 +      }
 +    if(A==0)
 +      {V.push_back(Num); }
 +  }
 +
 +  /*! Function that compares two angles from the values of the pairs (sin,cos)*/
 +  /*! Angles are considered in [0, 2Pi] bt are not computed explicitely */
 +  class AngleLess
 +  {
 +  public:
++    bool operator()(std::pair<double,double>theta1, std::pair<double,double> theta2) const
 +    {
 +      double norm1 = sqrt(theta1.first*theta1.first +theta1.second*theta1.second);
 +      double norm2 = sqrt(theta2.first*theta2.first +theta2.second*theta2.second);
 +      
 +      double epsilon = 1.e-12;
 +      
 +      if( norm1 < epsilon || norm2 < epsilon  ) 
 +        std::cout << "Warning InterpolationUtils.hxx: AngleLess : Vector with zero norm, cannot define the angle !!!! " << std::endl;
 +      
 +      return theta1.second*(norm2 + theta2.first) < theta2.second*(norm1 + theta1.first);
 +    
 +    }
 +  };
 +
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */  
 +  /* fonction pour reconstituer un polygone convexe a partir  */
 +  /*              d'un nuage de point.                        */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */  
 +
 +  inline std::vector<double> reconstruct_polygon(const std::vector<double>& V)
 +  {
 +
 +    int taille((int)V.size());
 +
 +    //VB : why 6 ?
 +
 +    if(taille<=6)
 +      {return V;}
 +    else
 +      {
 +        double *COS=new double[taille/2];
 +        double *SIN=new double[taille/2];
 +        //double *angle=new double[taille/2];
 +        std::vector<double> Bary=bary_poly(V);
 +        COS[0]=1.0;
 +        SIN[0]=0.0;
 +        //angle[0]=0.0;
 +        for(int i=0; i<taille/2-1;i++)
 +          {
 +            std::vector<double> Trigo=calcul_cos_et_sin(&Bary[0],&V[0],&V[2*(i+1)]);
 +            COS[i+1]=Trigo[0];
 +            SIN[i+1]=Trigo[1];
 +            //if(SIN[i+1]>=0)
 +            //    {angle[i+1]=atan2(SIN[i+1],COS[i+1]);}
 +            //             else
 +            //               {angle[i+1]=-atan2(SIN[i+1],COS[i+1]);}
 +          }
 +                     
 +        //ensuite on ordonne les angles.
 +        std::vector<double> Pt_ordonne;
 +        Pt_ordonne.reserve(taille);
 +        //        std::multimap<double,int> Ordre;
 +        std::multimap<std::pair<double,double>,int, AngleLess> CosSin;
 +        for(int i=0;i<taille/2;i++)       
 +          {
 +            //  Ordre.insert(std::make_pair(angle[i],i));
 +            CosSin.insert(std::make_pair(std::make_pair(SIN[i],COS[i]),i));
 +          }
 +        //        std::multimap <double,int>::iterator mi;
 +        std::multimap<std::pair<double,double>,int, AngleLess>::iterator   micossin;
 +        //         for(mi=Ordre.begin();mi!=Ordre.end();mi++)
 +        //           {
 +        //             int j=(*mi).second;
 +        //             Pt_ordonne.push_back(V[2*j]);
 +        //             Pt_ordonne.push_back(V[2*j+1]);
 +        //           }
 +        for(micossin=CosSin.begin();micossin!=CosSin.end();micossin++)
 +          {
 +            int j=(*micossin).second;
 +            Pt_ordonne.push_back(V[2*j]);
 +            Pt_ordonne.push_back(V[2*j+1]);
 +          }
 +        delete [] COS;
 +        delete [] SIN;
 +        //        delete [] angle;
 +        return Pt_ordonne;
 +      }
 +  }
 +
 +  template<int DIM, NumberingPolicy numPol, class MyMeshType>
 +  inline void getElemBB(double* bb, const double *coordsOfMesh, int iP, int nb_nodes)
 +  {
 +    bb[0]=std::numeric_limits<double>::max();
 +    bb[1]=-std::numeric_limits<double>::max();
 +    bb[2]=std::numeric_limits<double>::max();
 +    bb[3]=-std::numeric_limits<double>::max();
 +    bb[4]=std::numeric_limits<double>::max();
 +    bb[5]=-std::numeric_limits<double>::max();
 +    
 +    for (int i=0; i<nb_nodes; i++)
 +      {
 +        double x = coordsOfMesh[3*(iP+i)];
 +        double y = coordsOfMesh[3*(iP+i)+1];
 +        double z = coordsOfMesh[3*(iP+i)+2];
 +        bb[0]=(x<bb[0])?x:bb[0];
 +        bb[1]=(x>bb[1])?x:bb[1];
 +        bb[2]=(y<bb[2])?y:bb[2];
 +        bb[3]=(y>bb[3])?y:bb[3];
 +        bb[4]=(z<bb[4])?z:bb[4];
 +        bb[5]=(z>bb[5])?z:bb[5];
 +      }              
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Computes the dot product of a and b */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  template<int dim> 
 +  inline double dotprod( const double * a, const double * b)
 +  {
 +    double result=0;
 +    for(int idim = 0; idim < dim ; idim++) result += a[idim]*b[idim];
 +    return result;
 +  }
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Computes the norm of vector v */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +  template<int dim> 
 +  inline double norm(const double * v)
 +  {   
 +    double result =0;
 +    for(int idim =0; idim<dim; idim++) result+=v[idim]*v[idim];
 +    return sqrt(result);
 +  }
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Computes the square norm of vector a-b */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +  template<int dim> 
 +  inline double distance2( const double * a, const double * b)
 +  {   
 +    double result =0;
 +    for(int idim =0; idim<dim; idim++) result+=(a[idim]-b[idim])*(a[idim]-b[idim]);
 +    return result;
 +  }
 +  template<class T, int dim> 
 +  inline double distance2(  T * a, int inda, T * b, int indb)
 +  {   
 +    double result =0;
 +    for(int idim =0; idim<dim; idim++) result += ((*a)[inda+idim] - (*b)[indb+idim])* ((*a)[inda+idim] - (*b)[indb+idim]);
 +    return result;
 +  }
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Computes the determinant of a and b */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  inline double determinant ( double *  a, double * b)
 +  {
 +    return a[0]*b[1]-a[1]*b[0];
 +  }
 +  inline double determinant ( double *  a, double * b, double * c)
 +  {
 +    return a[0]*determinant(b+1,c+1)-b[0]*determinant(a+1,c+1)+c[0]*determinant(a+1,b+1);
 +  }
 +  
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Computes the cross product of AB and AC */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +
 +  template<int dim> inline void crossprod( const double * A, const double * B, const double * C, double * V);
 +  
 +  template<> inline
 +  void crossprod<2>( const double * A, const double * B, const double * C, double * V)
 +  {   
 +    double AB[2];
 +    double AC[2];
 +    for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A
 +    for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A;
 +
 +    V[0]=determinant(AB,AC);
 +    V[1]=0;
 +  }
 +  template<> inline
 +  void crossprod<3>( const double * A, const double * B, const double * C, double * V)
 +  {   
 +    double AB[3];
 +    double AC[3];
 +    for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A
 +    for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A;
 +
 +    V[0]=AB[1]*AC[2]-AB[2]*AC[1];
 +    V[1]=-AB[0]*AC[2]+AB[2]*AC[0];
 +    V[2]=AB[0]*AC[1]-AB[1]*AC[0];    
 +  }
 +  template<> inline
 +  void crossprod<1>( const double * /*A*/, const double * /*B*/, const double * /*C*/, double * /*V*/)
 +  {
 +    // just to be able to compile
 +  }
 +  
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Checks wether point A is inside the quadrangle BCDE */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +
 +  template<int dim> inline double check_inside(const double* A,const double* B,const double* C,const double* D,
 +                                               const double* E,double* ABC, double* ADE)
 +  {
 +    crossprod<dim>(A,B,C,ABC);
 +    crossprod<dim>(A,D,E,ADE);
 +    return dotprod<dim>(ABC,ADE);
 +  }   
 +
 +  
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Computes the geometric angle (in [0,Pi]) between two non zero vectors AB and AC */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +  template<int dim> inline double angle(const double * A, const double * B, const double * C, double * n)
 +  {   
 +    double AB[dim];
 +    double AC[dim];
 +    double orthAB[dim];
 +
 +    for(int idim =0; idim<dim; idim++) AB[idim] = B[idim]-A[idim];//B-A;
 +    for(int idim =0; idim<dim; idim++) AC[idim] = C[idim]-A[idim];//C-A;
 +
 +    double normAB= norm<dim>(AB);
 +    for(int idim =0; idim<dim; idim++) AB[idim]/=normAB;
 +
 +    double normAC= norm<dim>(AC);
 +    double AB_dot_AC=dotprod<dim>(AB,AC);
 +    for(int idim =0; idim<dim; idim++) orthAB[idim] = AC[idim]-AB_dot_AC*AB[idim];
 +
 +    double denom= normAC+AB_dot_AC;
 +    double numer=norm<dim>(orthAB);
 +    
 +    return 2*atan2(numer,denom);
 +  }    
 +  
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
 +  /* Tells whether the frame constituted of vectors AB, AC and n is direct */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +  template<int dim> inline double direct_frame(const double * A, const double * B, const double * C, double * n);
 +  template<> inline
 +  double direct_frame<2>(const double * A, const double * B, const double * C, double * n)
 +  {
 +    double AB[2];
 +    double AC[2];
 +    for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A;
 +    for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A;
 +    
 +    return  determinant(AB,AC)*n[0];
 +  }
 +  template<> inline
 +  double direct_frame<3>(const double * A, const double * B, const double * C, double * n)
 +  {
 +    double AB[3];
 +    double AC[3];
 +    for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A;
 +    for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A;
 +    
 +    return determinant(AB,AC,n)>0;
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/  
 +  /*      calcul l'intersection de deux polygones COPLANAIRES */
 +  /* en dimension DIM (2 ou 3). Si DIM=3 l'algorithme ne considere*/
 +  /* que les deux premieres coordonnees de chaque point */
 +  /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ 
 +  template<int DIM> inline void intersec_de_polygone(const double * Coords_A, const double * Coords_B, 
 +                                                     int nb_NodesA, int nb_NodesB,
 +                                                     std::vector<double>& inter,
 +                                                     double dim_caracteristic, double precision)
 +  {
 +    for(int i_A = 1; i_A<nb_NodesA-1; i_A++)
 +      {
 +        for(int i_B = 1; i_B<nb_NodesB-1; i_B++)
 +          {
 +            INTERP_KERNEL::intersec_de_triangle(&Coords_A[0],&Coords_A[DIM*i_A],&Coords_A[DIM*(i_A+1)],
 +                                                &Coords_B[0],&Coords_B[DIM*i_B],&Coords_B[DIM*(i_B+1)],
 +                                                inter, dim_caracteristic, precision);
 +          }
 +      }
 +    int nb_inter=((int)inter.size())/DIM;
 +    if(nb_inter >3) inter=INTERP_KERNEL::reconstruct_polygon(inter);
 +  }
 +
 +  /*_ _ _ _ _ _ _ _ _
 +   *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
 +   *  fonctions qui calcule l'aire d'un polygone en dimension 2 ou 3    
 +   *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 +  template<int DIM> inline double polygon_area(std::vector<double>& inter)
 +  {
 +    double result=0.;
 +    double area[DIM];
 +                  
 +    for(int i = 1; i<(int)inter.size()/DIM-1; i++)
 +      {
 +        INTERP_KERNEL::crossprod<DIM>(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area);
 +        result +=0.5*norm<DIM>(area);
 +      }
 +    return result;
 +  }
 +         
 +  template<int DIM> inline double polygon_area(std::deque<double>& inter)
 +  {
 +    double result=0.;
 +    double area[DIM];
 +                  
 +    for(int i = 1; i<(int)inter.size()/DIM-1; i++)
 +      {
 +        INTERP_KERNEL::crossprod<DIM>(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area);
 +        result +=0.5*norm<DIM>(area);
 +      }
 +    return result;
 +  }
 +  
 +  /*! Computes the triple product (XA^XB).XC (in 3D)*/
 +  inline double triple_product(const double* A, const double*B, const double*C, const double*X)
 +  {
 +    double XA[3];
 +    XA[0]=A[0]-X[0];
 +    XA[1]=A[1]-X[1];
 +    XA[2]=A[2]-X[2];
 +    double XB[3];
 +    XB[0]=B[0]-X[0];
 +    XB[1]=B[1]-X[1];
 +    XB[2]=B[2]-X[2];
 +    double XC[3];
 +    XC[0]=C[0]-X[0];
 +    XC[1]=C[1]-X[1];
 +    XC[2]=C[2]-X[2];
 +    
 +    return 
 +      (XA[1]*XB[2]-XA[2]*XB[1])*XC[0]+
 +      (XA[2]*XB[0]-XA[0]*XB[2])*XC[1]+
 +      (XA[0]*XB[1]-XA[1]*XB[0])*XC[2];
 +  }
 +  
 +  /*! Subroutine of checkEqualPolygins that tests if two list of nodes (not necessarily distincts) describe the same polygon, assuming they share a comon point.*/
 +  /*! Indexes istart1 and istart2 designate two points P1 in L1 and P2 in L2 that have identical coordinates. Generally called with istart1=0.*/
 +  /*! Integer sign ( 1 or -1) indicate the direction used in going all over L2. */
 +  template<class T, int dim> 
 +  bool checkEqualPolygonsOneDirection(T * L1, T * L2, int size1, int size2, int istart1, int istart2, double epsilon, int sign)
 +  {
 +    int i1 = istart1;
 +    int i2 = istart2;
 +    int i1next = ( i1 + 1 ) % size1;
 +    int i2next = ( i2 + sign +size2) % size2;
 +    
 +    while(true)
 +      {
 +        while( i1next!=istart1 && distance2<T,dim>(L1,i1*dim, L1,i1next*dim) < epsilon ) i1next = (  i1next + 1 ) % size1;  
 +        while( i2next!=istart2 && distance2<T,dim>(L2,i2*dim, L2,i2next*dim) < epsilon ) i2next = (  i2next + sign +size2 ) % size2;  
 +        
 +        if(i1next == istart1)
 +          {
 +            if(i2next == istart2)
 +              return true;
 +            else return false;
 +          }
 +        else
 +          if(i2next == istart2)
 +            return false;
 +          else 
 +            {
 +              if(distance2<T,dim>(L1,i1next*dim, L2,i2next*dim) > epsilon )
 +                return false;
 +              else
 +                {
 +                  i1 = i1next;
 +                  i2 = i2next;
 +                  i1next = ( i1 + 1 ) % size1;
 +                  i2next = ( i2 + sign + size2 ) % size2;
 +                }
 +            }
 +      }
 +  }
 +
 +  /*! Tests if two list of nodes (not necessarily distincts) describe the same polygon.*/
 +  /*! Existence of multiple points in the list is considered.*/
 +  template<class T, int dim> 
 +  bool checkEqualPolygons(T * L1, T * L2, double epsilon)
 +  {
 +    if(L1==NULL || L2==NULL) 
 +      {
 +        std::cout << "Warning InterpolationUtils.hxx:checkEqualPolygonsPointer: Null pointer " << std::endl;
 +        throw(Exception("big error: not closed polygon..."));
 +      }
 +    
 +    int size1 = (*L1).size()/dim;
 +    int size2 = (*L2).size()/dim;
 +    int istart1 = 0;
 +    int istart2 = 0;
 +    
 +    while( istart2 < size2  && distance2<T,dim>(L1,istart1*dim, L2,istart2*dim) > epsilon ) istart2++;
 +  
 +    if(istart2 == size2)
 +      {  
 +        return (size1 == 0) && (size2 == 0);
 +      }
 +    else 
 +      return   checkEqualPolygonsOneDirection<T,dim>( L1, L2, size1, size2, istart1, istart2, epsilon,  1)
 +        || checkEqualPolygonsOneDirection<T,dim>( L1, L2, size1, size2, istart1, istart2, epsilon, -1);
 +
 +  }
 +}
 +
 +
 +#endif
index bbb49362aee6f22c9ee1ee11c499b3a7d177b2ac,0000000000000000000000000000000000000000..5d9f9d8185a11cb27cd08bdc5752af5524453a2b
mode 100644,000000..100644
--- /dev/null
@@@ -1,94 -1,0 +1,94 @@@
-     bool operator()(const double * P_1, const double * P_2) 
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __POLYGONALGORITHMS_HXX__
 +#define __POLYGONALGORITHMS_HXX__
 +
 +#include <vector>
 +#include <deque>
 +#include <map>
 +
 +namespace INTERP_KERNEL
 +{
 +  template<int DIM>
 +  class VertexLess
 +  {
 +  public:
++    bool operator()(const double * P_1, const double * P_2) const
 +    {
 +      for(int idim=0; idim<DIM; idim++)
 +        {        
 +          if(P_1[idim] < P_2[idim] )  return true;
 +          else if( P_1[idim] > P_2[idim]) return false;
 +        }
 +      return false;
 +    }
 +  };
 +  
 +  template<int DIM>
 +  class PolygonAlgorithms
 +  {
 +  public:
 +    PolygonAlgorithms(double epsilon, double precision);
 +    std::deque<double> intersectConvexPolygons(const double* P_1,const double* P_2, int N1, int N2);
 +
 +    //Not yet tested
 +    int convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components,
 +                            std::vector< int >& components_index, const double epsilon);
 +  private:
 +    void defineIndices(int& i_loc, int& i_next, int& i_prev, 
 +                       const double *& Poly1, const double *& Poly2,
 +                       int& j1, int& j1_glob, int& j2, int& j2_glob,
 +                       int& j3, int& j3_glob, int& j4, int& j4_glob, 
 +                       int& i_glob, int& i_next_glob, int& i_prev_glob, 
 +                       const double * P_1, const double * P_2, 
 +                       int N1, int N2, int sign);
 +    void addCrossings( const double * A, const double * B, int i , int i_next,
 +                       const double * C, const double * D, int j1, int j2,
 +                       const double * E, const double * F, int j3, int j4,
 +                       const double * G);
 +    void addCrossing0(const double * A, const double * B, int i, int i_next,
 +                      const double * C, const double * D, int j, int j_next);
 +    void addCrossing( double * ABCD, std::pair< int,int > i_i_next, std::pair< int,int > j_j_next);
 +    void addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, const double * P);
 +    bool intersectSegmentSegment(const double * A,  const double * B, const double * C,
 +                                 const double * D,  const double * E, double * V);
 +
 +
 +    //Not yet tested
 +    void convexDecomposition(const double* P, int N, double* n,  std::vector< int > subP, int NsubP, 
 +                             std::vector< std::map< int,int > >& components, std::vector< int >& components_index,
 +                             int& Ncomp, int sign, const double epsilon);
 +    void convHull(const double *P, int N, double * n,  std::map< int,int >& subP,
 +                  std::map< int,int >& not_in_hull, int& NsubP, const double epsilon);
 +  private:
 +    std::deque< double > _Inter;/* vertices of the intersection  P1^P2 */
 +    std::vector< std::pair< int,int > > _End_segments; /* segments containing inter final edges */   
 +    /* status list of segments (ending point, starting point) intersected by the sweeping line */
 +    /* and a boolean true if the ending point is in the intersection */
 +    std::multimap< int, std::pair< int,bool> > _Status;
 +    bool _is_in_intersection;
 +    bool _terminus;
 +    double _vdouble[DIM];
 +    double _epsilon;
 +    double _precision;
 +  };
 +}
 +
 +#endif
index 0a98446690049ecd21e20ce9ae23d77d4a1aea9f,0000000000000000000000000000000000000000..f49b7bf9d7e456622bb9d08625be607a14acb25f
mode 100644,000000..100644
--- /dev/null
@@@ -1,1537 -1,0 +1,1540 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay
 +
 +#include "MEDCouplingAMRAttribute.hxx"
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +#include "MEDCouplingIMesh.hxx"
 +
 +#include <sstream>
 +#include <fstream>
 +
 +using namespace ParaMEDMEM;
 +
++/// @cond INTERNAL
 +DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
 +{
 +  return new DataArrayDoubleCollection(fieldNames);
 +}
 +
 +DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
 +{
 +  return new DataArrayDoubleCollection(*this);
 +}
 +
 +void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
 +{
 +  std::size_t sz(_arrs.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    _arrs[i].first->reAlloc(nbOfTuples);
 +}
 +
 +void DataArrayDoubleCollection::dellocTuples()
 +{
 +  std::size_t sz(_arrs.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    _arrs[i].first->reAlloc(0);
 +}
 +
 +void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
 +{
 +  std::size_t sz(_arrs.size());
 +  if(sz!=other._arrs.size())
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      DataArrayDouble *thisArr(_arrs[i].first);
 +      const DataArrayDouble *otherArr(other._arrs[i].first);
 +      if(!thisArr || !otherArr)
 +        throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
 +      thisArr->cpyFrom(*otherArr);
 +    }
 +}
 +
 +void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
 +{
 +  std::size_t sz(_arrs.size());
 +  if(sz!=compNames.size())
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const std::vector<std::string>& names(compNames[i]);
 +      _arrs[i].first->setInfoOnComponents(names);
 +    }
 +}
 +
 +void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
 +{
 +  std::size_t sz(_arrs.size());
 +  if(sz!=nfs.size())
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      CheckValidNature(nfs[i]);
 +      _arrs[i].second=nfs[i];
 +    }
 +}
 +
 +std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
 +{
 +  std::size_t sz(_arrs.size());
 +  std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const DataArrayDouble *elt(_arrs[i].first);
 +      if(!elt)
 +        throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
 +      ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
 +    }
 +  return ret;
 +}
 +
 +std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
 +{
 +  std::size_t sz(_arrs.size());
 +  std::vector<NatureOfField> ret(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    ret[i]=_arrs[i].second;
 +  return ret;
 +}
 +
 +std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
 +{
 +  std::size_t sz(_arrs.size());
 +  std::vector<DataArrayDouble *> ret(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const DataArrayDouble *tmp(_arrs[i].first);
 +      ret[i]=const_cast<DataArrayDouble *>(tmp);
 +      if(ret[i])
 +        ret[i]->incrRef();
 +    }
 +  return ret;
 +}
 +
 +const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
 +{
 +  std::vector<std::string> vec;
 +  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
 +    {
 +      const DataArrayDouble *obj((*it).first);
 +      if(obj)
 +        {
 +          if(obj->getName()==name)
 +            return obj;
 +          else
 +            vec.push_back(obj->getName());
 +        }
 +    }
 +  std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
 +  std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
 +  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +}
 +
 +DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
 +{
 +  std::vector<std::string> vec;
 +  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
 +    {
 +      DataArrayDouble *obj((*it).first);
 +      if(obj)
 +        {
 +          if(obj->getName()==name)
 +            return obj;
 +          else
 +            vec.push_back(obj->getName());
 +        }
 +    }
 +  std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
 +  std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
 +  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +}
 +
 +DataArrayDouble *DataArrayDoubleCollection::at(int pos)
 +{
 +  if(pos<0 || pos>=(int)_arrs.size())
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
 +  return _arrs[pos].first;
 +}
 +
 +const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
 +{
 +  if(pos<0 || pos>=(int)_arrs.size())
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
 +  return _arrs[pos].first;
 +}
 +
 +int DataArrayDoubleCollection::size() const
 +{
 +  return (int)_arrs.size();
 +}
 +
 +void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
 +{
 +  if(!fine || !coarse)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
 +  std::size_t sz(coarse->_arrs.size());
 +  if(fine->_arrs.size()!=sz)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
 +      fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
 +    }
 +}
 +
 +void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
 +{
 +  if(!fine || !coarse)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
 +  std::size_t sz(coarse->_arrs.size());
 +  if(fine->_arrs.size()!=sz)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
 +      fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
 +    }
 +}
 +
 +void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
 +{
 +  if(!fatherOfFineMesh)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
 +  std::size_t sz(children.size());
 +  if(fieldsOnFine.size()!=sz)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
 +  if(sz<=1)
 +    return ;
 +  std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
 +      throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
 +  for(std::size_t i=1;i<sz;i++)
 +    if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
 +      throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
 +  for(std::size_t i=0;i<nbOfCall;i++)
 +    {
 +      std::vector<const DataArrayDouble *> arrs(sz);
 +      for(std::size_t j=0;j<sz;j++)
 +        arrs[j]=fieldsOnFine[j]->_arrs[i].first;
 +      fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
 +    }
 +}
 +
 +/*!
 + * This method updates \a p1dac ghost zone parts using \a p2dac (which is really const). \a p2 is in the neighborhood of \a p1 (which size is defined by \a ghostLev).
 + */
 +void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
 +{
 +  if(!p1 || !p1dac || !p2 || !p2dac)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
 +  std::size_t sz(p1dac->_arrs.size());
 +  if(p2dac->_arrs.size()!=sz)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
 +      DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
 +      bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
 +      MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
 +    }
 +}
 +
 +void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
 +{
 +  if(!fine || !coarse)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
 +  std::size_t sz(coarse->_arrs.size());
 +  if(fine->_arrs.size()!=sz)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
 +  for(std::size_t i=0;i<sz;i++)
 +    fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
 +}
 +
 +void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
 +{
 +  DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
 +  std::size_t sz(_arrs.size());
 +  if(other._arrs.size()!=sz)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
 +  for(std::size_t i=0;i<sz;i++)
 +    father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
 +}
 +
 +void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
 +{
 +  DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
 +  std::size_t sz(_arrs.size());
 +  if(other._arrs.size()!=sz)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
 +  for(std::size_t i=0;i<sz;i++)
 +    MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
 +}
 +
 +DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
 +{
 +  std::size_t sz(fieldNames.size());
 +  std::vector<std::string> names(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const std::pair<std::string,int>& info(fieldNames[i]);
 +      if(info.second<=0)
 +        {
 +          std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
 +          oss << " It has to be >=1 !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +      _arrs[i].first=DataArrayDouble::New();
 +      _arrs[i].first->alloc(0,info.second);
 +      _arrs[i].first->setName(info.first);
 +      names[i]=info.second;
 +      _arrs[i].second=ConservativeVolumic;
 +    }
 +  CheckDiscriminantNames(names);
 +}
 +
 +DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
 +{
 +  std::size_t sz(other._arrs.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      _arrs[i].second=other._arrs[i].second;
 +      const DataArrayDouble *da(other._arrs[i].first);
 +      if(da)
 +        _arrs[i].first=da->deepCpy();
 +    }
 +}
 +
 +std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
 +{
 +  std::size_t ret(sizeof(DataArrayDoubleCollection));
 +  ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
 +  return ret;
 +}
 +
 +std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const
 +{
 +  std::vector<const BigMemoryObject *> ret;
 +  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
 +    ret.push_back((const DataArrayDouble *)(*it).first);
 +  return ret;
 +}
 +
 +void DataArrayDoubleCollection::updateTime() const
 +{
 +  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
 +    {
 +      const DataArrayDouble *pt((*it).first);
 +      if(pt)
 +        updateTimeWith(*pt);
 +    }
 +}
 +
 +void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
 +{
 +  std::set<std::string> s(names.begin(),names.end());
 +  if(s.size()!=names.size())
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
 +}
 +
 +bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
 +{
 +  CheckValidNature(n);
 +  return n==RevIntegral || n==IntegralGlobConstraint;
 +}
 +
 +void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
 +{
 +  CheckValidNature(n1);
 +  CheckValidNature(n2);
 +  if(n1!=n2)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
 +}
 +
 +void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
 +{
 +  if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
 +    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
 +}
 +
 +MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
 +{
 +  return new MEDCouplingGridCollection(ms,fieldNames);
 +}
 +
 +MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
 +{
 +  return new MEDCouplingGridCollection(*this,newGf,oldGf);
 +}
 +
 +void MEDCouplingGridCollection::alloc(int ghostLev)
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    {
 +      int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
 +      DataArrayDoubleCollection *dadc((*it).second);
 +      if(dadc)
 +        dadc->allocTuples(nbTuples);
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
 +    }
 +}
 +
 +void MEDCouplingGridCollection::dealloc()
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    {
 +      DataArrayDoubleCollection *dadc((*it).second);
 +      if(dadc)
 +        dadc->dellocTuples();
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
 +    }
 +}
 +
 +void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    (*it).second->spillInfoOnComponents(compNames);
 +}
 +
 +void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    (*it).second->spillNatures(nfs);
 +}
 +
 +std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
 +{
 +  if(_map_of_dadc.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
 +  const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
 +  if(!elt)
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
 +  return elt->getInfoOnComponents();
 +}
 +
 +std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
 +{
 +  if(_map_of_dadc.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
 +  const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
 +  if(!elt)
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
 +  return elt->getNatures();
 +}
 +
 +bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
 +{
 +  int ret(0);
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
 +    {
 +      if((*it).first==m)
 +        {
 +          pos=ret;
 +          return true;
 +        }
 +    }
 +  return false;
 +}
 +
 +const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
 +{
 +  if(pos<0 || pos>(int)_map_of_dadc.size())
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
 +  return *_map_of_dadc[pos].second;
 +}
 +
 +DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
 +{
 +  if(pos<0 || pos>(int)_map_of_dadc.size())
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
 +  return *_map_of_dadc[pos].second;
 +}
 +
 +/*!
 + * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
 + * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
 + * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure.
 + */
 +void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    {
 +      std::vector<int> deltaThis,deltaOther;
 +      std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
 +      std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
 +      std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
 +      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
 +        {
 +          std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
 +          if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
 +            {
 +              std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
 +              std::vector< std::pair<int,int> > pThis,pOther;
 +              MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
 +              MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
 +              std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
 +              MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
 +              MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
 +              std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
 +              int sz((*it2).second->size());
 +              for(int i=0;i<sz;i++)
 +                {
 +                  const DataArrayDouble *otherArr((*it2).second->at(i));
 +                  DataArrayDouble *thisArr((*it).second->at(i));
 +                  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
 +                  MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
 +                }
 +            }
 +        }
 +    }
 +}
 +
 +void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
 +{
 +  if(!fine || !coarse)
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
 +    {
 +      const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
 +      const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
 +      bool found(false);
 +      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
 +        {
 +          if((*it0).first==fatherOfFineMesh)
 +            {
 +              found=true;
 +              int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
 +              const DataArrayDoubleCollection *coarseDaCol((*it0).second);
 +              DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
 +              DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
 +            }
 +        }
 +      if(!found)
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
 +    }
 +}
 +
 +void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
 +{
 +  if(!fine || !coarse)
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
 +    {
 +      const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
 +      const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
 +      bool found(false);
 +      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
 +        {
 +          if((*it0).first==fatherOfFineMesh)
 +            {
 +              found=true;
 +              int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
 +              const DataArrayDoubleCollection *fineDaCol((*it).second);
 +              DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
 +              DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
 +            }
 +        }
 +      if(!found)
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
 +    }
 +}
 +
 +/*!
 + * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
 + *
 + * \sa synchronizeFineEachOtherExt
 + */
 +void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
 +    {
 +      int p1,p2;
 +      if(!presenceOf((*it).first->getMesh(),p1))
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
 +      if(!presenceOf((*it).second->getMesh(),p2))
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
 +      const DataArrayDoubleCollection& col1(getFieldsAt(p1));
 +      const DataArrayDoubleCollection& col2(getFieldsAt(p2));
 +      col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
 +    }
 +}
 +
 +/*!
 + * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
 + *
 + * \sa synchronizeFineEachOther
 + */
 +void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
 +    {
 +      int p1,p2;
 +      if(!presenceOf((*it).first->getMesh(),p1))
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
 +      if(!presenceOf((*it).second->getMesh(),p2))
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
 +      const DataArrayDoubleCollection& col1(getFieldsAt(p1));
 +      const DataArrayDoubleCollection& col2(getFieldsAt(p2));
 +      col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
 +    }
 +}
 +
 +/*!
 + * The pairs returned share the same direct father. The number of returned elements must be even.
 + */
 +std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
 +{
 +  std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
 +  std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    {
 +      const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
 +      const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
 +      m[fatherOfFineMesh].push_back(fineMesh);
 +    }
 +  for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
 +    {
 +      for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
 +        {
 +          int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
 +          std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
 +          const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
 +          for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
 +            {
 +              const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
 +              ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
 +            }
 +        }
 +    }
 +  if(ret.size()%2!=0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
 +  return ret;
 +}
 +
 +void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
 +{
 +  if(!fine || !coarse)
 +    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
 +    {
 +      const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
 +      const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
 +      bool found(false);
 +      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
 +        {
 +          if((*it0).first==fatherOfFineMesh)
 +            {
 +              found=true;
 +              int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
 +              const DataArrayDoubleCollection *fineDaCol((*it).second);
 +              DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
 +              DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
 +            }
 +        }
 +      if(!found)
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
 +    }
 +}
 +
 +void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    {
 +      const MEDCouplingCartesianAMRMeshGen *a((*it).first);
 +      if(head==a || head->isObjectInTheProgeny(a))
 +        {
 +          const DataArrayDoubleCollection *gc((*it).second);
 +          recurseArrs.push_back(gc->getFieldWithName(fieldName));
 +        }
 +    }
 +}
 +
 +MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
 +{
 +  std::size_t sz(ms.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      if(!ms[i])
 +        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
 +      _map_of_dadc[i].first=ms[i];
 +      _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
 +    }
 +}
 +
 +MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
 +{
 +  std::size_t sz(other._map_of_dadc.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
 +      _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
 +      const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
 +      if(dac)
 +        _map_of_dadc[i].second=dac->deepCpy();
 +    }
 +}
 +
 +std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
 +{
 +  std::size_t ret(sizeof(MEDCouplingGridCollection));
 +  ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
 +  return ret;
 +}
 +
 +std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const
 +{
 +  std::vector<const BigMemoryObject *> ret;
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    ret.push_back((const DataArrayDoubleCollection *)(*it).second);
 +  return ret;
 +}
 +
 +void MEDCouplingGridCollection::updateTime() const
 +{
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
 +    {
 +      const MEDCouplingCartesianAMRMeshGen *a((*it).first);
 +      if(a)
 +        updateTimeWith(*a);
 +      const DataArrayDoubleCollection *b((*it).second);
 +      if(b)
 +        updateTimeWith(*b);
 +    }
 +}
 +
++/// @endcond
++
 +MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
 +{
 +  return _gf;
 +}
 +
 +const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
 +{
 +  return _gf;
 +}
 +
 +MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
 +{
 +  if(!gf)
 +    throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
 +  gf->incrRef();
 +}
 +
 +void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
 +{
 +  _tlc.checkConst();
 +}
 +
 +bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
 +{
 +  bool ret(_tlc.keepTrackOfNewTL(gf));
 +  if(ret)
 +    {
 +      _gf=gf;
 +      if(gf)
 +        gf->incrRef();
 +    }
 +  return ret;
 +}
 +
 +MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
 +{
 +  other._tlc.checkConst();
 +  if(deepCpyGF)
 +    {
 +      const MEDCouplingCartesianAMRMesh *gf(other._gf);
 +      if(gf)
 +        _gf=gf->deepCpy(0);
 +      _tlc.keepTrackOfNewTL(_gf);
 +    }
 +}
 +
 +/*!
 + * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation.
 + */
 +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
 +{
 +  return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
 +}
 +
 +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
 +{
 +  std::size_t sz(fieldNames.size());
 +  std::vector< std::pair<std::string,int> > fieldNames2(sz);
 +  std::vector< std::vector<std::string> > compNames(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      fieldNames2[i].first=fieldNames[i].first;
 +      fieldNames2[i].second=(int)fieldNames[i].second.size();
 +      compNames[i]=fieldNames[i].second;
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
 +  ret->spillInfoOnComponents(compNames);
 +  return ret.retn();
 +}
 +
 +/*!
 + * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
 + * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New.
 + * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
 + * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
 + */
 +void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
 +{
 +  _tlc.checkConst();
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
 +    (*it)->spillInfoOnComponents(compNames);
 +}
 +
 +/*!
 + * Assign nature for each fields in \a this.
 + * \param [in] nfs
 + */
 +void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
 +{
 +  _tlc.checkConst();
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
 +    (*it)->spillNatures(nfs);
 +}
 +
 +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
 +{
 +  return new MEDCouplingAMRAttribute(*this,true);
 +}
 +
 +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
 +{
 +  return new MEDCouplingAMRAttribute(*this,false);
 +}
 +
 +/*!
 + * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this).
 + *
 + */
 +int MEDCouplingAMRAttribute::getNumberOfLevels() const
 +{
 +  checkGodFatherFrozen();
 +  return (int)_levs.size();
 +}
 +
 +/*!
 + * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
 + * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
 + *
 + * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
 + * \sa retrieveFieldOn
 + */
 +std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      int tmp(-1);
 +      if((*it)->presenceOf(mesh,tmp))
 +        {
 +          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
 +          return ddc.retrieveFields();
 +        }
 +    }
 +  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
 +}
 +
 +/*!
 + * \sa retrieveFieldsOn
 + */
 +const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      int tmp(-1);
 +      if((*it)->presenceOf(mesh,tmp))
 +        {
 +          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
 +          return ddc.getFieldWithName(fieldName);
 +        }
 +    }
 +  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
 +}
 +
 +DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      int tmp(-1);
 +      if((*it)->presenceOf(mesh,tmp))
 +        {
 +          DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
 +          return ddc.getFieldWithName(fieldName);
 +        }
 +    }
 +  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
 +}
 +
 +/*!
 + * This method returns a field on an unstructured mesh the most refined as possible without overlap.
 + * Ghost part are not visible here.
 + *
 + * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
 + */
 +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 +{
 +  std::vector<const DataArrayDouble *> recurseArrs;
 +  std::size_t lev(0);
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
 +    {
 +      int tmp(-1);
 +      if((*it)->presenceOf(mesh,tmp))
 +        {
 +          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
 +          recurseArrs.push_back(ddc.getFieldWithName(fieldName));
 +          break;
 +        }
 +    }
 +  lev++;
 +  for(std::size_t i=lev;i<_levs.size();i++)
 +    {
 +      const MEDCouplingGridCollection *gc(_levs[i]);
 +      gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
 +    }
 +  return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
 +}
 +
 +/*!
 + * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
 + * The output field also displays ghost cells.
 + *
 + * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
 + *
 + * \sa buildCellFieldOnWithoutGhost
 + */
 +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 +{
 +  const DataArrayDouble *arr(0);
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      int tmp(-1);
 +      if((*it)->presenceOf(mesh,tmp))
 +        {
 +          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
 +          arr=ddc.getFieldWithName(fieldName);
 +        }
 +    }
 +  if(!arr)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
 +  ret->setMesh(im);
 +  ret->setArray(const_cast<DataArrayDouble *>(arr));
 +  ret->setName(arr->getName());
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
 + * The output field does not display ghost cells.
 + *
 + * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
 + *
 + * \sa buildCellFieldOnWithGhost
 + */
 +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 +{
 +  const DataArrayDouble *arr(0);
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      int tmp(-1);
 +      if((*it)->presenceOf(mesh,tmp))
 +        {
 +          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
 +          arr=ddc.getFieldWithName(fieldName);
 +        }
 +    }
 +  if(!arr)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
 +  std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
 +  arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
 +  std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
 +  MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
 +  std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
 +  MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
 +  arr2->copyStringInfoFrom(*arr);
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
 +  ret->setMesh(mesh->getImageMesh());
 +  ret->setArray(arr2);
 +  ret->setName(arr->getName());
 +  return ret.retn();
 +}
 +
 +
 +std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
 +{
 +  static const char EXT[]=".vthb";
 +  std::string baseName,extName,zeFileName;
 +  MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
 +  if(extName==EXT)
 +    zeFileName=fileName;
 +  else
 +    { zeFileName=baseName; zeFileName+=EXT; }
 +  //
 +  std::ofstream ofs(fileName.c_str());
 +  ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
 +  const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
 +  ofs << "  <vtkOverlappingAMR origin=\"";
 +  const MEDCouplingIMesh *gfm(gf->getImageMesh());
 +  std::vector<double> orig(gfm->getOrigin());
 +  std::vector<double> spacing(gfm->getDXYZ());
 +  int dim((int)orig.size());
 +  std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
 +  for(int i=0;i<dim;i++)
 +    {
 +      char tmp[2]; tmp[0]='X'+i; tmp[1]='\0';
 +      ofs << tmp;
 +    }
 +  ofs << "\">\n";
 +  //
 +  int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
 +  for(int i=0;i<maxLev;i++)
 +    {
 +      std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
 +      std::size_t sz(patches.size());
 +      std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
 +      for(std::size_t j=0;j<sz;j++)
 +        patchesSafe[j]=patches[j];
 +      if(sz==0)
 +        continue;
 +      ofs << "    <Block level=\"" << i << "\" spacing=\"";
 +      std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
 +      ofs << "\">\n";
 +      if(i!=maxLev-1)
 +        {
 +          std::vector<int> factors(patches[0]->getMesh()->getFactors());
 +          for(int k=0;k<dim;k++)
 +            spacing[k]*=1./((double) factors[k]);
 +        }
 +      std::size_t jj(0);
 +      for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
 +        {
 +          ofs << "      <DataSet index=\"" << jj << "\" amr_box=\"";
 +          const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
 +          const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
 +          if(patchCast)
 +            {
 +              const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF());
 +              for(int pp=0;pp<dim;pp++)
 +                ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
 +            }
 +          else
 +            {
 +              const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
 +              std::vector<int> cgs(im->getCellGridStructure());
 +              for(int pp=0;pp<dim;pp++)
 +                ofs << "0 " << cgs[pp]-1 << " ";
 +            }
 +          ofs << "\" file=\"";
 +          //
 +          int tmp(-1);
 +          if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
 +            {
 +              const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
 +              std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
 +              std::size_t nbFields(arrs.size());
 +              std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
 +              std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
 +              std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
 +              for(std::size_t pp=0;pp<nbFields;pp++)
 +                arrsSafe[pp]=arrs[pp];
 +              for(std::size_t pp=0;pp<nbFields;pp++)
 +                {
 +                  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
 +                  std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
 +                  arrs2Safe[pp]=DataArrayDouble::New();
 +                  arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
 +                  std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
 +                  MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
 +                  std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
 +                  MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
 +                  arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
 +                  //
 +                  fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
 +                  fieldsSafe[pp]->setMesh(mesh->getImageMesh());
 +                  fieldsSafe[pp]->setArray(arrs2Safe[pp]);
 +                  fieldsSafe[pp]->setName(arrs[pp]->getName());
 +                }
 +              std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
 +              MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
 +              //
 +              ofs << vtiFileName.str() << "\">\n";
 +              ofs << "      \n      </DataSet>\n";
 +            }
 +        }
 +      ofs << "    </Block>\n";
 +    }
 +  //
 +  ofs << "  </vtkOverlappingAMR>\n";
 +  ofs << "</VTKFile>\n";
 +  return zeFileName;
 +}
 +
 +  /*!
 +   * This method is useful just after a remesh after a time step computation to project values in \a this to the new
 +   * mesh \a targetGF.
 +   *
 +   * This method performs a projection from \a this to a target AMR mesh \a targetGF.
 +   * This method performs the projection by trying to transfer the finest information to \a targetGF.
 + * \b WARNING this method does not update the ghost zone, if any.
 + * The level0 of \a this god father must have the same structure than those of \a targetGF.
 + *
 + * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
 + * the number of levels in \a this and in \a targetGF are also the same.
 + */
 +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
 +{
 +  if(!targetGF)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
 +  if(_levs.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
 +  const MEDCouplingGridCollection *lev0(_levs[0]);
 +  if(!lev0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
 +  std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
 +  ret->spillNatures(lev0->getNatures());
 +  ret->alloc();
 +  int nbLevs(getNumberOfLevels());
 +  if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
 +  // first step copy level0
 +  if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
 +  const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
 +  DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
 +  colTarget.copyFrom(col);
 +  // then go deeper and deeper
 +  for(int i=1;i<nbLevs;i++)
 +    {
 +      ret->synchronizeCoarseToFineByOneLevel(i-1);
 +      MEDCouplingGridCollection *targetCol(ret->_levs[i]);
 +      if(!targetCol)
 +        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
 +      const MEDCouplingGridCollection *thisCol(_levs[i]);
 +      if(!thisCol)
 +        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
 +      targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
 + * MEDCouplingAMRAttribute::alloc method.
 + * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
 + *
 + * \sa synchronizeFineToCoarseBetween
 + */
 +void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
 +{
 +  if(_levs.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
 +  std::size_t sz(_levs.size());
 +  //
 +  while(sz>1)
 +    {
 +      sz--;
 +      synchronizeFineToCoarseByOneLevel((int)sz);
 +    }
 +}
 +
 +/*!
 + * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
 + * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
 + * until reaching \a toLev level.
 + * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
 + *
 + * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
 + * \param [in] toLev - an existing level considered as the target level to reach.
 + *
 + */
 +void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
 +{
 +  int nbl(getNumberOfLevels());
 +  if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
 +  if(fromLev==toLev)
 +    return ;//nothing to do
 +  if(fromLev<toLev)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
 +  for(int i=fromLev;i>toLev;i--)
 +    synchronizeFineToCoarseByOneLevel(i);
 +}
 +
 +/*!
 + * This method synchronizes from coarse to fine arrays and fine to fine each other (if _ghost_lev is >0). This method makes the hypothesis that \a this has been allocated before using
 + * MEDCouplingAMRAttribute::alloc method.
 + * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
 + */
 +void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
 +{
 +  if(_levs.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
 +  std::size_t sz(_levs.size());
 +  //
 +  for(std::size_t i=0;i<sz-1;i++)
 +    synchronizeCoarseToFineByOneLevel((int)i);
 +}
 +
 +/*!
 + * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
 + * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
 + * until reaching \a toLev level.
 + * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
 + *
 + * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
 + * \param [in] toLev - an existing level considered as the target level to reach.
 + */
 +void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
 +{
 +  int nbl(getNumberOfLevels());
 +  if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
 +  if(fromLev==toLev)
 +    return ;//nothing to do
 +  if(fromLev>toLev)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
 +  for(int i=fromLev;i<toLev;i++)
 +    synchronizeCoarseToFineByOneLevel(i);
 +}
 +
 +/*!
 + * This method synchronizes the ghost zone of all patches (excepted the god father one).
 + * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
 + *
 + * - firstly coarse to fine with no interactions between brother patches.
 + * - secondly connected brother patches in a same master patch are updated.
 + * - thirdly connected nephew patches are updated each other.
 + * - forthly nth generation cousin patches are updated each other.
 + *
 + * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
 + * So if \a _ghost_lev == 0 this method has no effect.
 + */
 +void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
 +{
 +  int sz(getNumberOfLevels());
 +  if(sz==0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
 +  // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
 +  for(int i=1;i<sz;i++)
 +    {
 +      const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
 +      MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
 +    }
 +  // 2nd - classical direct sublevel inside common patch
 +  for(int i=1;i<sz;i++)
 +    {
 +      const MEDCouplingGridCollection *curLev(_levs[i]);
 +      if(!curLev)
 +        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
 +      curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
 +    }
 +  // 3rd - mixed level
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
 +    {
 +      const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
 +      DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
 +    }
 +  // 4th - same level but with far ancestor.
 +  for(int i=1;i<sz;i++)
 +    {
 +      const MEDCouplingGridCollection *fine(_levs[i]);
 +      fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
 +    }
 +}
 +
 +/*!
 + * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here.
 + * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh).
 + * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father.
 + * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead.
 + *
 + * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other.
 + *
 + */
 +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
 +{
 +  if(!mesh)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
 +  int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
 +  if(level<0 || level>=sz-1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
 +  std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
 +  for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
 +    {
 +      if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
 +        itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
 +    }
 +  const MEDCouplingGridCollection *curLev(_levs[level+1]);
 +  if(!curLev)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
 +  curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
 +}
 +
 +/*!
 + * This method updates \b all the patches at level \a level each other without consideration of their father.
 + * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
 + */
 +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
 +{
 +  int maxLev(getNumberOfLevels());
 +  if(level<0 || level>=maxLev)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
 +  if(level==0)
 +    return ;//at level 0 only one patch -> no need to update
 +  // 1st step - updates all patches pairs at level \a level sharing the same father
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
 +  const MEDCouplingGridCollection *curLev(_levs[level]);
 +  if(!curLev)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
 +  curLev->synchronizeFineEachOther(_ghost_lev,items);
 +  //2nd step - updates all patches pairs at level \a level not sharing the same father
 +  const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
 +  curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
 +}
 +
 +/*!
 + * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1).
 + * This method is useful to propagate to the ghost zone of childhood the modification.
 + */
 +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
 +{
 +  int maxLev(getNumberOfLevels());
 +  if(level<=0 || level>=maxLev)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
 +  const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
 +  MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
 +  //_cross_lev_neighbors is not needed.
 +}
 +
 +/*!
 + * This method allocates all DataArrayDouble instances stored recursively in \a this.
 + *
 + * \sa dealloc
 + */
 +void MEDCouplingAMRAttribute::alloc()
 +{
 +  _tlc.resetState();
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      MEDCouplingGridCollection *elt(*it);
 +      if(elt)
 +        elt->alloc(_ghost_lev);
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
 +    }
 +}
 +
 +/*!
 + * This method deallocates all DataArrayDouble instances stored recursively in \a this.
 + * \sa alloc
 + */
 +void MEDCouplingAMRAttribute::dealloc()
 +{
 +  _tlc.checkConst();
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      MEDCouplingGridCollection *elt(*it);
 +      if(elt)
 +        elt->dealloc();
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
 +    }
 +}
 +
 +bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
 +{
 +  bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
 +  return ret;
 +}
 +
 +std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
 +{
 +  std::size_t ret(sizeof(MEDCouplingAMRAttribute));
 +  ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
 +  return ret;
 +}
 +
 +std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const
 +{
 +  std::vector<const BigMemoryObject *> ret;
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
 +    ret.push_back((const MEDCouplingGridCollection *)*it);
 +  return ret;
 +}
 +
 +void MEDCouplingAMRAttribute::updateTime() const
 +{//tony
 +}
 +
 +MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
 +{
 +  //gf non empty, checked by constructor
 +  int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
 +  _levs.resize(maxLev);
 +  for(int i=0;i<maxLev;i++)
 +    {
 +      std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
 +      std::size_t sz(patches.size());
 +      std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
 +      for(std::size_t j=0;j<sz;j++)
 +        patchesSafe[j]=patches[j];
 +      std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
 +      for(std::size_t j=0;j<sz;j++)
 +        {
 +          ms[j]=patches[j]->getMesh();
 +        }
 +      _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
 +    }
 +  // updates cross levels neighbors
 +  _neighbors.resize(_levs.size());
 +  _cross_lev_neighbors.resize(_levs.size());
 +  if(_levs.empty())
 +    throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
 +  std::size_t sz(_levs.size());
 +  for(std::size_t i=1;i<sz;i++)
 +    {
 +      const MEDCouplingGridCollection *fine(_levs[i]);
 +      if(!fine)
 +        throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
 +      _neighbors[i]=fine->findNeighbors(_ghost_lev);
 +      if(i!=sz-1)
 +        {
 +          for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
 +            {
 +              MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
 +              std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
 +              std::size_t fullLev(i+neighs2.size());
 +              if(fullLev>=sz)
 +                throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
 +              std::size_t ii(i+1);
 +              for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
 +                _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
 +            }
 +        }
 +    }
 +}
 +
 +MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF):MEDCouplingDataForGodFather(other,deepCpyGF),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors)
 +{
 +  std::size_t sz(other._levs.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const MEDCouplingGridCollection *elt(other._levs[i]);
 +      if(elt)
 +        {
 +          _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
 +        }
 +    }
 +  //_cross_lev_neighbors(other._cross_lev_neighbors)
 +  sz=other._neighbors.size();
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
 +      std::size_t sz2(neigh2.size());
 +      std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
 +      for(std::size_t j=0;j<sz2;j++)
 +        {
 +          const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
 +          std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
 +          neigh3[j].first=_gf->getPatchAtPosition(pp1);
 +          neigh3[j].second=_gf->getPatchAtPosition(pp2);
 +        }
 +    }
 +  //
 +  sz=other._mixed_lev_neighbors.size();
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
 +      std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
 +      _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
 +      _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
 +    }
 +  //
 +  sz=other._cross_lev_neighbors.size();
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
 +      std::size_t sz2(neigh2.size());
 +      std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
 +      for(std::size_t j=0;j<sz2;j++)
 +        {
 +          const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
 +          std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
 +          neigh3[j].first=_gf->getPatchAtPosition(pp1);
 +          neigh3[j].second=_gf->getPatchAtPosition(pp2);
 +        }
 +    }
 +}
 +
 +const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
 +    {
 +      const MEDCouplingGridCollection *elt(*it);
 +      if(elt)
 +        {
 +          int tmp(-1);
 +          if(elt->presenceOf(m,tmp))
 +            {
 +              return elt->getFieldsAt(tmp);
 +            }
 +        }
 +    }
 +  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
 +}
 +
 +void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
 +{
 +  int nbl(getNumberOfLevels());
 +  if(level<=0 || level>=nbl)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
 +  const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
 +  MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
 +}
 +
 +void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
 +{
 +  int nbl(getNumberOfLevels());
 +  if(level<0 || level>=nbl-1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
 +  const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
 +  MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
 +}
index 8b3a3c8ddc1a7eeba9bf62641798b170376331b0,0000000000000000000000000000000000000000..6fa402cf6c6d1ddbeeb673007273a9b03757c398
mode 100644,000000..100644
--- /dev/null
@@@ -1,59 -1,0 +1,62 @@@
-    * \brief A field template can be seen as a field without array of values.
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __PARAMEDMEM_MEDCOUPLINGFIELDTEMPLATE_HXX__
 +#define __PARAMEDMEM_MEDCOUPLINGFIELDTEMPLATE_HXX__
 +
 +#include "MEDCouplingField.hxx"
 +
 +namespace ParaMEDMEM
 +{
 +  class MEDCouplingFieldDouble;
 +  /*!
-    * A field template instance aggregates a MEDCouplingMesh instance and a spatial discretization object (instance of MEDCouplingFieldDiscretization).
++   * \brief A field template can be seen as a field without the array of values.
 +   *
-    * Instances of type MEDCouplingFieldTemplate are the most appropriate for preparation of matrix using MEDCouplingRemapper::prepareEx.
++   * A field template aggregates a MEDCouplingMesh and a spatial discretization object (instance of
++   * MEDCouplingFieldDiscretization).
 +   * 
++   * MEDCouplingFieldTemplate is the most appropriate type for the preparation of matrix using
++   * MEDCouplingRemapper::prepareEx, since it contains the minimal information requireds to prepare
++   * the interpolation matrix.
 +   */
 +  class MEDCouplingFieldTemplate : public MEDCouplingField
 +  {
 +  public:
 +    MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f);
 +    MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(TypeOfField type);
 +    MEDCOUPLING_EXPORT std::string simpleRepr() const;
 +    MEDCOUPLING_EXPORT std::string advancedRepr() const;
 +    MEDCOUPLING_EXPORT void checkCoherency() const;
 +    //
 +    MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
 +    MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
 +    MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
 +    MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt);
 +    MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
 +    MEDCOUPLING_EXPORT void serialize(DataArrayInt *&dataInt) const;
 +    //
 +    MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const;
 +  private:
 +    MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f);
 +    MEDCouplingFieldTemplate(TypeOfField type);
 +  };
 +}
 +
 +#endif
index ea60f27deac2474620603a7c76a71d495b93057c,0000000000000000000000000000000000000000..3de265f1fe3ee0b81bfbd6a40f94a3aed7e6100b
mode 100644,000000..100644
--- /dev/null
@@@ -1,760 -1,0 +1,762 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#include "MEDCouplingMesh.hxx"
 +#include "MEDCouplingUMesh.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "MEDCouplingFieldDiscretization.hxx"
 +#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 +
 +#include <set>
 +#include <cmath>
 +#include <sstream>
 +#include <fstream>
 +#include <iterator>
 +
 +using namespace ParaMEDMEM;
 +
 +MEDCouplingMesh::MEDCouplingMesh():_time(0.),_iteration(-1),_order(-1)
 +{
 +}
 +
 +MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):RefCountObject(other),_name(other._name),_description(other._description),
 +                                                               _time(other._time),_iteration(other._iteration),
 +                                                               _order(other._order),_time_unit(other._time_unit)
 +{
 +}
 +
 +std::size_t MEDCouplingMesh::getHeapMemorySizeWithoutChildren() const
 +{
 +  return _name.capacity()+_description.capacity()+_time_unit.capacity();
 +}
 +
 +/*!
 + * This method is only for ParaMEDMEM in ParaFIELD constructor.
 + */
 +bool MEDCouplingMesh::isStructured() const
 +{
 +  return getType()==CARTESIAN;
 +}
 +
 +bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
 +{
 +  if(!other)
 +    throw INTERP_KERNEL::Exception("MEDCouplingMesh::isEqualIfNotWhy : other instance is NULL !");
 +  std::ostringstream oss; oss.precision(15);
 +  if(_name!=other->_name)
 +    {
 +      oss << "Mesh names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !";
 +      reason=oss.str();
 +      return false;
 +    }
 +  if(_description!=other->_description)
 +    {
 +      oss << "Mesh descriptions differ : this description = \"" << _description << "\" and other description = \"" << other->_description << "\" !";
 +      reason=oss.str();
 +      return false;
 +    }
 +  if(_iteration!=other->_iteration)
 +    {
 +      oss << "Mesh iterations differ : this iteration = \"" << _iteration << "\" and other iteration = \"" << other->_iteration << "\" !";
 +      reason=oss.str();
 +      return false;
 +    }
 +  if(_order!=other->_order)
 +    {
 +      oss << "Mesh orders differ : this order = \"" << _order << "\" and other order = \"" << other->_order << "\" !";
 +      reason=oss.str();
 +      return false;
 +    }
 +  if(_time_unit!=other->_time_unit)
 +    {
 +      oss << "Mesh time units differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !";
 +      reason=oss.str();
 +      return false;
 +    }
 +  if(fabs(_time-other->_time)>=1e-12)
 +    {
 +      oss << "Mesh times differ : this time = \"" << _time << "\" and other time = \"" << other->_time << "\" !";
 +      reason=oss.str();
 +      return false;
 +    }
 +  return true;
 +}
 +
 +/*!
 + * Checks if \a this and another MEDCouplingMesh are fully equal.
 + *  \param [in] other - an instance of MEDCouplingMesh to compare with \a this one.
 + *  \param [in] prec - precision value used to compare node coordinates.
 + *  \return bool - \c true if the two meshes are equal, \c false else.
 + */
 +bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const
 +{
 +  std::string tmp;
 +  return isEqualIfNotWhy(other,prec,tmp);
 +}
 +
 +/*!
 + * This method checks geo equivalence between two meshes : \a this and \a other.
 + * If no exception is thrown \a this and \a other are geometrically equivalent regarding \a levOfCheck level.
 + * This method is typically used to change the mesh of a field "safely" depending the \a levOfCheck level considered.
 + * 
 + * In case of success cell \c other[i] is equal to the cell \c this[cellCor[i]].
 + * In case of success node \c other->getCoords()[i] is equal to the node \c this->getCoords()[nodeCor[i]].
 + *
 + * If \a cellCor is null (or Py_None) it means that for all #i cell in \a other is equal to cell # i in \a this.
 + *
 + * If \a nodeCor is null (or Py_None) it means that for all #i node in \a other is equal to node # i in \a this.
 + *
 + * So null (or Py_None) returned in \a cellCor and/or \a nodeCor means identity array. This is for optimization reason to avoid to build useless arrays
 + * for some \a levOfCheck (for example 0).
 + *
 + * **Warning a not null output does not mean that it is not identity !**
 + *
 + * \param [in] other - the mesh to be compared with \a this.
 + * \param [in] levOfCheck - input that specifies the level of check specified. The possible values are listed below.
 + * \param [in] prec - input that specifies precision for double float data used for comparison in meshes.
 + * \param [out] cellCor - output array not always informed (depending \a levOfCheck param) that gives the corresponding array for cells from \a other to \a this.
 + * \param [out] nodeCor - output array not always informed (depending \a levOfCheck param) that gives the corresponding array for nodes from \a other to \a this.
 + *
 + * Possible values for levOfCheck :
 + *   - 0 for strict equality. This is the strongest level. \a cellCor and \a nodeCor params are never informed.
 + *   - 10,11,12 (10+x) for less strict equality. Two meshes are compared geometrically. In case of success \a cellCor and \a 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 (20+x), 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 \a 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.
 + *
 + * So the most strict level of check is 0 (equality). The least strict is 12. If the level of check 12 throws, the 2 meshes \a this and \a other are not similar enough
 + * to be compared. An interpolation using MEDCouplingRemapper class should be then used.
 + */
 +void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,
 +                                          DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
 +{
 +  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.");
 +    }
 +}
 +
 +/*!
 + * Finds cells whose all nodes are in a given array of node ids.
 + *  \param [in] partBg - the array of node ids.
 + *  \param [in] partEnd - end of \a partBg, i.e. a pointer to a (last+1)-th element
 + *          of \a partBg.
 + *  \return DataArrayInt * - a new instance of DataArrayInt holding ids of found
 + *          cells. The caller is to delete this array using decrRef() as it is no
 + *          more needed.
 + */
 +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((int)crest.size(),1);
 +  std::copy(crest.begin(),crest.end(),ret->getPointer());
 +  return ret;
 +}
 +
 +/*!
 + * This method checks fastly that \a this and \a other are equal. All common checks are done here.
 + */
 +void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
 +{
 +  if(!other)
 +    throw INTERP_KERNEL::Exception("MEDCouplingMesh::checkFastEquivalWith : input mesh is null !");
 +  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 \a this and \a other are candidate for merge of fields lying repectively on them.
 + */
 +bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const
 +{
 +  if(!other)
 +    throw INTERP_KERNEL::Exception("MEDCouplingMesh::areCompatibleForMerge : input mesh is null !");
 +  if(getMeshDimension()!=other->getMeshDimension())
 +    return false;
 +  if(getSpaceDimension()!=other->getSpaceDimension())
 +    return false;
 +  return true;
 +}
 +
 +/*!
 + * This method is equivalent to MEDCouplingMesh::buildPart method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds.
 + * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method.
 + * If the input range is equal all cells in \a this, \a this is returned !
 + *
 + * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order.
 + *
 + * \sa MEDCouplingMesh::buildPart
 + */
 +MEDCouplingMesh *MEDCouplingMesh::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const
 +{
 +  if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1)
 +    {
 +      MEDCouplingMesh *ret(const_cast<MEDCouplingMesh *>(this));
 +      ret->incrRef();
 +      return ret;
 +    }
 +  else
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds);
 +      return buildPart(cellIds->begin(),cellIds->end());
 +    }
 +}
 +
 +/*!
 + * This method is equivalent to MEDCouplingMesh::buildPartAndReduceNodes method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds.
 + *
 + * \sa MEDCouplingMesh::buildPartAndReduceNodes
 + */
 +MEDCouplingMesh *MEDCouplingMesh::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds);
 +  return buildPartAndReduceNodes(cellIds->begin(),cellIds->end(),arr);
 +}
 +
 +/*!
 + * This method builds a field lying on \a this with 'nbOfComp' components.
 + * 'func' is a pointer that points to a function that takes 2 arrays in parameter and returns a boolean.
 + * The first array is a in-param of size this->getSpaceDimension and the second an out param of size 'nbOfComp'.
 + * The return field will have type specified by 't'. 't' is also used to determine where values of field will be
 + * evaluate.
 + * Contrary to other fillFromAnalytic methods this method requests a C++ function pointer as input.
 + * The 'func' is a callback that takes as first parameter an input array of size 'this->getSpaceDimension()',
 + * the second parameter is a pointer on a valid zone of size at least equal to 'nbOfComp' values. And too finish
 + * the returned value is a boolean that is equal to False in case of invalid evaluation (log(0) for example...)
 + * 
 + * \param t type of field returned and specifies where the evaluation of func will be done.
 + * \param nbOfComp number of components of returned field.
 + * \param func pointer to a function that should return false if the evaluation failed. (division by 0. for example)
 + * \return field with counter = 1.
 + */
 +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
 +  ret->setMesh(this);
 +  ret->fillFromAnalytic(nbOfComp,func);
 +  ret->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * 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)
 +{
 +  if(!other)
 +    throw INTERP_KERNEL::Exception("MEDCouplingMesh::copyTinyStringsFrom : input mesh is null !");
 +  _name=other->_name;
 +  _description=other->_description;
 +  _time_unit=other->_time_unit;
 +}
 +
 +/*!
 + * This method copies all attributes that are \b NOT arrays in this.
 + * All tiny attributes not usefully for state of \a this are ignored.
 + */
 +void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other)
 +{
 +  _time=other->_time;
 +  _iteration=other->_iteration;
 +  _order=other->_order;
 +  copyTinyStringsFrom(other);
 +}
 +
 +/*!
 + * \anchor mcmesh_fillFromAnalytic
 + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of
 + * components, lying on \a this mesh, with contents got by applying a specified
 + * function to coordinates of field location points (defined by the given field type).
 + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell
 + * barycenters.<br>
 + * For more info on supported expressions that can be used in the function, see \ref
 + * MEDCouplingArrayApplyFuncExpr. The function can include arbitrary named variables
 + * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of
 + * variables are sorted in \b alphabetical \b order to associate a variable name with a
 + * component. For example, in the expression "2*x+z", "x" stands for the component #0
 + * and "z" stands for the component #1 (\b not #2)!<br>
 + * In a general case, a value resulting from the function evaluation is assigned to all
 + * components of the field. But there is a possibility to have its own expression for
 + * each component within one function. For this purpose, there are predefined variable
 + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
 + * the component #0 etc). A factor of such a variable is added to the
 + * corresponding component only.<br>
 + * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, coordinates of a
 + * point are (1.,3.,7.), then
 + *   - "2*x + z"               produces (5.,5.,5.,5.)
 + *   - "2*x + 0*y + z"         produces (9.,9.,9.,9.)
 + *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
 + *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
 + *
 + *  \param [in] t - the field type. It defines, apart from other things, points to
 + *         coordinates of which the function is applied to get field values.
 + *  \param [in] nbOfComp - the number of components in the result field.
 + *  \param [in] func - a string defining the expression which is evaluated to get
 + *         field values.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
 + *         caller is to delete this field using decrRef() as it is no more needed. 
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If computing \a func fails.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".<br>
 + *  \ref  py_mcmesh_fillFromAnalytic "Here is a Python example".
 + *  \endif
 + */
 +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
 +  ret->setMesh(this);
 +  ret->fillFromAnalytic(nbOfComp,func);
 +  ret->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of
 + * components, lying on \a this mesh, with contents got by applying a specified
 + * function to coordinates of field location points (defined by the given field type).
 + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell
 + * barycenters. This method differs from
 + * \ref MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const "fillFromAnalytic()"
 + * by the way how variable
 + * names, used in the function, are associated with components of coordinates of field
 + * location points; here, a variable name corresponding to a component is retrieved from
 + * a corresponding node coordinates array (where it is set via
 + * DataArrayDouble::setInfoOnComponent()).<br>
 + * For more info on supported expressions that can be used in the function, see \ref
 + * MEDCouplingArrayApplyFuncExpr. <br> 
 + * In a general case, a value resulting from the function evaluation is assigned to all
 + * components of a field value. But there is a possibility to have its own expression for
 + * each component within one function. For this purpose, there are predefined variable
 + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
 + * the component #0 etc). A factor of such a variable is added to the
 + * corresponding component only.<br>
 + * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of
 + * spatial components are "x", "y" and "z", coordinates of a
 + * point are (1.,3.,7.), then
 + *   - "2*x + z"               produces (9.,9.,9.,9.)
 + *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
 + *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
 + *
 + *  \param [in] t - the field type. It defines, apart from other things, the points to
 + *         coordinates of which the function is applied to get field values.
 + *  \param [in] nbOfComp - the number of components in the result field.
 + *  \param [in] func - a string defining the expression which is evaluated to get
 + *         field values.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
 + *         caller is to delete this field using decrRef() as it is no more needed. 
 + *  \throw If the node coordinates are not defined.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If computing \a func fails.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".<br>
 + *  \ref  py_mcmesh_fillFromAnalytic2 "Here is a Python example".
 + *  \endif
 + */
 +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
 +  ret->setMesh(this);
 +  ret->fillFromAnalytic2(nbOfComp,func);
 +  ret->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of
 + * components, lying on \a this mesh, with contents got by applying a specified
 + * function to coordinates of field location points (defined by the given field type).
 + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell
 + * barycenters. This method differs from \ref  \ref mcmesh_fillFromAnalytic
 + * "fillFromAnalytic()" by the way how variable
 + * names, used in the function, are associated with components of coordinates of field
 + * location points; here, a component index of a variable is defined by a
 + * rank of the variable within the input array \a varsOrder.<br>
 + * For more info on supported expressions that can be used in the function, see \ref
 + * MEDCouplingArrayApplyFuncExpr.
 + * In a general case, a value resulting from the function evaluation is assigned to all
 + * components of the field. But there is a possibility to have its own expression for
 + * each component within one function. For this purpose, there are predefined variable
 + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
 + * the component #0 etc). A factor of such a variable is added to the
 + * corresponding component only.<br>
 + * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of
 + * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a
 + * point are (1.,3.,7.), then
 + *   - "2*x + z"               produces (9.,9.,9.,9.)
 + *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
 + *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
 + *
 + *  \param [in] t - the field type. It defines, apart from other things, the points to
 + *         coordinates of which the function is applied to get field values.
 + *  \param [in] nbOfComp - the number of components in the result field.
 + *  \param [in] varsOrder - the vector defining names of variables used to refer to
 + *         components of coordinates of field location points. A variable named
 + *         varsOrder[0] refers to the component #0 etc.
 + *  \param [in] func - a string defining the expression which is evaluated to get
 + *         field values.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
 + *         caller is to delete this field using decrRef() as it is no more needed. 
 + *  \throw If the node coordinates are not defined.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If computing \a func fails.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".<br>
 + *  \ref  py_mcmesh_fillFromAnalytic3 "Here is a Python example".
 + *  \endif
 + */
 +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
 +  ret->setMesh(this);
 +  ret->fillFromAnalytic3(nbOfComp,varsOrder,func);
 +  ret->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Creates a new MEDCouplingMesh by concatenating two given meshes, if possible.
 + * Cells and nodes of
 + * the first mesh precede cells and nodes of the second mesh within the result mesh.
 + * The meshes must be of the same mesh type, else, an exception is thrown. The method
 + * MergeMeshes(), accepting a vector of input meshes, has no such a limitation.
 + *  \param [in] mesh1 - the first mesh.
 + *  \param [in] mesh2 - the second mesh.
 + *  \return MEDCouplingMesh * - the result mesh. It is a new instance of
 + *          MEDCouplingMesh. The caller is to delete this mesh using decrRef() as it
 + *          is no more needed.
 + *  \throw If the meshes are of different mesh type.
 + */
 +MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2)
 +{
 +  if(!mesh1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : first parameter is an empty mesh !");
 +  if(!mesh2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : second parameter is an empty mesh !");
 +  return mesh1->mergeMyselfWith(mesh2);
 +}
 +
 +/*!
 + * Creates a new MEDCouplingMesh by concatenating all given meshes, if possible.
 + * Cells and nodes of
 + * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh.
 + * This method performs a systematic conversion to unstructured meshes before
 + * performing aggregation contrary to the other MergeMeshes()
 + * with two parameters that works only on the same type of meshes. So here it is possible
 + * to mix different type of meshes. 
 + *  \param [in] meshes - a vector of meshes to concatenate.
 + *  \return MEDCouplingMesh * - the result mesh. It is a new instance of
 + *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
 + *          is no more needed.
 + *  \throw If \a meshes.size() == 0.
 + *  \throw If \a size[ *i* ] == NULL.
 + *  \throw If the coordinates is not set in none of the meshes.
 + *  \throw If \a meshes[ *i* ]->getMeshDimension() < 0.
 + *  \throw If the \a meshes are of different dimension (getMeshDimension()).
 + */
 +MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes)
 +{
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms1(meshes.size());
 +  std::vector< const MEDCouplingUMesh * > ms2(meshes.size());
 +  for(std::size_t i=0;i<meshes.size();i++)
 +    {
 +      if(meshes[i])
 +        {
 +          MEDCouplingUMesh *cur=meshes[i]->buildUnstructured();
 +          ms1[i]=cur;  ms2[i]=cur;
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes) : mesh at pos #" << i << " of input vector of size " << meshes.size() << " is empty !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  return MEDCouplingUMesh::MergeUMeshes(ms2);
 +}
 +
 +/*!
 + * For example if \a type is INTERP_KERNEL::NORM_TRI3 , INTERP_KERNEL::NORM_POLYGON is returned.
 + * If \a type is INTERP_KERNEL::NORM_HEXA8 , INTERP_KERNEL::NORM_POLYHED is returned.
 + * 
 + * \param [in] type the geometric type for which the corresponding dynamic type, is asked.
 + * \return the corresponding dynamic type, able to store the input \a type.
 + * 
 + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
 + */
 +INTERP_KERNEL::NormalizedCellType MEDCouplingMesh::GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type)
 +{
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  return cm.getCorrespondingPolyType();
 +}
 +
 +/*!
 + * \param [in] type the geometric type for which the number of nodes consituting it, is asked.
 + * \return number of nodes consituting the input geometric type \a type.
 + * 
 + * \throw if type is dynamic as \c INTERP_KERNEL::NORM_POLYHED , \c INTERP_KERNEL::NORM_POLYGON , \c INTERP_KERNEL::NORM_QPOLYG
 + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
 + */
 +int MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type)
 +{
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  if(cm.isDynamic())
 +    throw INTERP_KERNEL::Exception("MEDCouplingMesh::GetNumberOfNodesOfGeometricType : the input geometric type is dynamic ! Impossible to return a fixed number of nodes constituting it !");
 +  return (int) cm.getNumberOfNodes();
 +}
 +
 +/*!
 + * \param [in] type the geometric type for which the status static/dynamic is asked.
 + * \return true for static geometric type, false for dynamic geometric type.
 + * 
 + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
 + */
 +bool MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type)
 +{
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  return !cm.isDynamic();
 +}
 +
 +bool MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type)
 +{
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  return !cm.isQuadratic();
 +}
 +
 +/*!
 + * \param [in] type the geometric type for which the dimension is asked.
 + * \return the dimension associated to the input geometric type \a type.
 + * 
 + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
 + */
 +int MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type)
 +{
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  return (int) cm.getDimension();
 +}
 +
 +/*!
 + * \param [in] type the geometric type for which the representation is asked.
 + * \return the string representation corresponding to the input geometric type \a type.
 + * 
 + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
 + */
 +const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type)
 +{
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  return cm.getRepr();
 +}
 +
 +/*!
 + * Finds cells in contact with a ball (i.e. a point with precision).
 + * \warning This method is suitable if the caller intends to evaluate only one
 + *          point, for more points getCellsContainingPoints() is recommended as it is
 + *          faster. 
 + *  \param [in] pos - array of coordinates of the ball central point.
 + *  \param [in] eps - ball radius.
 + *  \param [in,out] elts - vector returning ids of the found cells. It is cleared
 + *         before inserting ids.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getCellsContainingPoint "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
 +{
 +  int ret=getCellContainingPoint(pos,eps);
 +  elts.push_back(ret);
 +}
 +
 +/*!
 + * Finds cells in contact with several balls (i.e. points with precision).
 + * This method is an extension of getCellContainingPoint() and
 + * getCellsContainingPoint() for the case of multiple points.
 + *  \param [in] pos - an array of coordinates of points in full interlace mode :
 + *         X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a
 + *         this->getSpaceDimension() * \a nbOfPoints 
 + *  \param [in] nbOfPoints - number of points to locate within \a this mesh.
 + *  \param [in] eps - radius of balls (i.e. the precision).
 + *  \param [out] elts - vector returning ids of found cells.
 + *  \param [out] eltsIndex - an array, of length \a nbOfPoints + 1,
 + *         dividing cell ids in \a elts into groups each referring to one
 + *         point. Its every element (except the last one) is an index pointing to the
 + *         first id of a group of cells. For example cells in contact with the *i*-th
 + *         point are described by following range of indices:
 + *         [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are
 + *         \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ...
 + *         Number of cells in contact with the *i*-th point is
 + *         \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ].
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getCellsContainingPoints "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const
 +{
 +  eltsIndex=DataArrayInt::New(); elts=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1);
 +  int *eltsIndexPtr(eltsIndex->getPointer());
 +  int spaceDim(getSpaceDimension());
 +  const double *work(pos);
 +  for(int i=0;i<nbOfPoints;i++,work+=spaceDim)
 +    {
 +      int ret=getCellContainingPoint(work,eps);
 +      if(ret>=0)
 +        {
 +          elts->pushBackSilent(ret);
 +          eltsIndexPtr[i+1]=eltsIndexPtr[i]+1;
 +        }
 +      else
 +        eltsIndexPtr[i+1]=eltsIndexPtr[i];
 +    }
 +}
 +
 +/*!
 + * Writes \a this mesh into a VTK format file named as specified.
 + *  \param [in] fileName - the name of the file to write in. If the extension is OK the fileName will be used directly.
 + *                         If extension is invalid or no extension the right extension will be appended.
 + *  \return - the real fileName
 + *  \throw If \a fileName is not a writable file.
 + *  \sa getVTKFileNameOf
 + */
 +std::string MEDCouplingMesh::writeVTK(const std::string& fileName, bool isBinary) const
 +{
 +  std::string ret(getVTKFileNameOf(fileName));
 +  //
 +  std::string cda,pda;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayByte> byteArr;
 +  if(isBinary)
 +    { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
 +  writeVTKAdvanced(ret,cda,pda,byteArr);
 +  return ret;
 +}
 +
 +/*!
 + * This method takes in input a file name \a fileName and considering the VTK extension of \a this (depending on the type of \a this)
 + * returns a right file name. If the input \a fileName has a valid extension the returned string is equal to \a fileName.
 + *
 + * \sa  getVTKFileExtension
 + */
 +std::string MEDCouplingMesh::getVTKFileNameOf(const std::string& fileName) const
 +{
 +  std::string ret;
 +  std::string part0,part1;
 +  SplitExtension(fileName,part0,part1);
 +  std::string ext("."); ext+=getVTKFileExtension();
 +  if(part1==ext)
 +    ret=fileName;
 +  else
 +    ret=fileName+ext;
 +  return ret;
 +}
 +
++/// @cond INTERNAL
 +void MEDCouplingMesh::writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const
 +{
 +  std::ofstream ofs(fileName.c_str());
 +  ofs << "<VTKFile type=\""  << getVTKDataSetType() << "\" version=\"0.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
 +  writeVTKLL(ofs,cda,pda,byteData);
 +  if(byteData)
 +    {
 +      ofs << "<AppendedData encoding=\"raw\">\n_1234";
 +      ofs << std::flush; ofs.close();
 +      std::ofstream ofs2(fileName.c_str(),std::ios_base::binary | std::ios_base::app);
 +      ofs2.write(byteData->begin(),byteData->getNbOfElems()); ofs2 << std::flush; ofs2.close();
 +      std::ofstream ofs3(fileName.c_str(),std::ios_base::app); ofs3 << "\n</AppendedData>\n</VTKFile>\n"; ofs3.close();
 +    }
 +  else
 +    {
 +      ofs << "</VTKFile>\n";
 +      ofs.close();
 +    }
 +}
 +
 +void MEDCouplingMesh::SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension)
 +{
 +  std::size_t pos(fileName.find_last_of('.'));
 +  if(pos==std::string::npos)
 +    {
 +      baseName=fileName;
 +      extension.clear();
 +      return ;
 +    }
 +  baseName=fileName.substr(0,pos);
 +  extension=fileName.substr(pos);
 +}
++/// @endcond
index 4eea72a52a81f1886c5781481a0fc38b964b86f3,0000000000000000000000000000000000000000..897cdc6f749c3eb681cf174580825b2669c9d6ba
mode 100644,000000..100644
--- /dev/null
@@@ -1,106 -1,0 +1,108 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __PARAMEDMEM_MEDCOUPLINGREFCOUNTOBJECT_HXX__
 +#define __PARAMEDMEM_MEDCOUPLINGREFCOUNTOBJECT_HXX__
 +
 +#include "MEDCoupling.hxx"
 +
 +#include <set>
 +#include <vector>
 +#include <string>
 +#include <cstddef>
 +
 +namespace ParaMEDMEM
 +{
 +  typedef enum
 +  {
 +    C_DEALLOC = 2,
 +    CPP_DEALLOC = 3
 +  } DeallocType;
 +
++  //! The various spatial discretization of a field
 +  typedef enum
 +  {
 +    ON_CELLS = 0,
 +    ON_NODES = 1,
 +    ON_GAUSS_PT = 2,
 +    ON_GAUSS_NE = 3,
 +    ON_NODES_KR = 4
 +  } TypeOfField;
 +
++  //! The various temporal discretization of a field
 +  typedef enum
 +  {
 +    NO_TIME = 4,
 +    ONE_TIME = 5,
 +    LINEAR_TIME = 6,
 +    CONST_ON_TIME_INTERVAL = 7
 +  } TypeOfTimeDiscretization;
 +
 +  typedef bool (*FunctionToEvaluate)(const double *pos, double *res);
 +
 +  MEDCOUPLING_EXPORT const char *MEDCouplingVersionStr();
 +  MEDCOUPLING_EXPORT int MEDCouplingVersion();
 +  MEDCOUPLING_EXPORT void MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas);
 +  MEDCOUPLING_EXPORT int MEDCouplingSizeOfVoidStar();
 +  MEDCOUPLING_EXPORT bool MEDCouplingByteOrder();
 +  MEDCOUPLING_EXPORT const char *MEDCouplingByteOrderStr();
 +
 +  class BigMemoryObject
 +  {
 +  public:
 +    MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const;
 +    MEDCOUPLING_EXPORT std::string getHeapMemorySizeStr() const;
 +    MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildren() const;
 +    MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getAllTheProgeny() const;
 +    MEDCOUPLING_EXPORT bool isObjectInTheProgeny(const BigMemoryObject *obj) const;
 +    MEDCOUPLING_EXPORT static std::size_t GetHeapMemorySizeOfObjs(const std::vector<const BigMemoryObject *>& objs);
 +    MEDCOUPLING_EXPORT virtual std::size_t getHeapMemorySizeWithoutChildren() const = 0;
 +    MEDCOUPLING_EXPORT virtual std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const = 0;
 +    MEDCOUPLING_EXPORT virtual ~BigMemoryObject();
 +  private:
 +    static std::size_t GetHeapMemoryOfSet(std::set<const BigMemoryObject *>& s1, std::set<const BigMemoryObject *>& s2);
 +  };
 +
 +  class RefCountObjectOnly
 +  {
 +  protected:
 +    MEDCOUPLING_EXPORT RefCountObjectOnly();
 +    MEDCOUPLING_EXPORT RefCountObjectOnly(const RefCountObjectOnly& other);
 +  public:
 +    MEDCOUPLING_EXPORT bool decrRef() const;
 +    MEDCOUPLING_EXPORT void incrRef() const;
 +    MEDCOUPLING_EXPORT int getRCValue() const;
 +    MEDCOUPLING_EXPORT RefCountObjectOnly& operator=(const RefCountObjectOnly& other);
 +  protected:
 +    virtual ~RefCountObjectOnly();
 +  private:
 +    mutable int _cnt;
 +  };
 +
 +  class RefCountObject : public RefCountObjectOnly, public BigMemoryObject
 +  {
 +  protected:
 +    MEDCOUPLING_EXPORT RefCountObject();
 +    MEDCOUPLING_EXPORT RefCountObject(const RefCountObject& other);
 +    MEDCOUPLING_EXPORT virtual ~RefCountObject();
 +  };
 +}
 +
 +#endif
index d50bf73c257e0c5b1224da089a71538fea7ce103,0000000000000000000000000000000000000000..81e8295b479a9fd2054fcde7b39e89026db21a73
mode 100644,000000..100644
--- /dev/null
@@@ -1,11916 -1,0 +1,11921 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#include "MEDCouplingUMesh.hxx"
 +#include "MEDCoupling1GTUMesh.hxx"
 +#include "MEDCouplingMemArray.txx"
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "MEDCouplingSkyLineArray.hxx"
 +#include "CellModel.hxx"
 +#include "VolSurfUser.txx"
 +#include "InterpolationUtils.hxx"
 +#include "PointLocatorAlgos.txx"
 +#include "BBTree.txx"
 +#include "BBTreeDst.txx"
 +#include "SplitterTetra.hxx"
 +#include "DiameterCalculator.hxx"
 +#include "DirectedBoundingBox.hxx"
 +#include "InterpKernelMatrixTools.hxx"
 +#include "InterpKernelMeshQuality.hxx"
 +#include "InterpKernelCellSimplify.hxx"
 +#include "InterpKernelGeo2DEdgeArcCircle.hxx"
 +#include "InterpKernelAutoPtr.hxx"
 +#include "InterpKernelGeo2DNode.hxx"
 +#include "InterpKernelGeo2DEdgeLin.hxx"
 +#include "InterpKernelGeo2DEdgeArcCircle.hxx"
 +#include "InterpKernelGeo2DQuadraticPolygon.hxx"
 +
 +#include <sstream>
 +#include <fstream>
 +#include <numeric>
 +#include <cstring>
 +#include <limits>
 +#include <list>
 +
 +using namespace ParaMEDMEM;
 +
 +double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14;
 +
++/// @cond INTERNAL
 +const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_SEG4, INTERP_KERNEL::NORM_POLYL, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_TRI7, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_QUAD9, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_HEXA27, INTERP_KERNEL::NORM_POLYHED };
++/// @endcond
 +
 +MEDCouplingUMesh *MEDCouplingUMesh::New()
 +{
 +  return new MEDCouplingUMesh;
 +}
 +
 +MEDCouplingUMesh *MEDCouplingUMesh::New(const std::string& meshName, int meshDim)
 +{
 +  MEDCouplingUMesh *ret=new MEDCouplingUMesh;
 +  ret->setName(meshName);
 +  ret->setMeshDimension(meshDim);
 +  return ret;
 +}
 +
 +/*!
 + * Returns a new MEDCouplingMesh which is a full copy of \a this one. No data is shared
 + * between \a this and the new mesh.
 + *  \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to
 + *          delete this mesh using decrRef() as it is no more needed. 
 + */
 +MEDCouplingMesh *MEDCouplingUMesh::deepCpy() const
 +{
 +  return clone(true);
 +}
 +
 +/*!
 + * Returns a new MEDCouplingMesh which is a copy of \a this one.
 + *  \param [in] recDeepCpy - if \a true, the copy is deep, else all data arrays of \a
 + * this mesh are shared by the new mesh.
 + *  \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to
 + *          delete this mesh using decrRef() as it is no more needed. 
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const
 +{
 +  return new MEDCouplingUMesh(*this,recDeepCpy);
 +}
 +
 +/*!
 + * This method behaves mostly like MEDCouplingUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
 + * The coordinates are shared between \a this and the returned instance.
 + * 
 + * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
 + * \sa MEDCouplingUMesh::deepCpy
 + */
 +MEDCouplingPointSet *MEDCouplingUMesh::deepCpyConnectivityOnly() const
 +{
 +  checkConnectivityFullyDefined();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=clone(false);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(getNodalConnectivity()->deepCpy()),ci(getNodalConnectivityIndex()->deepCpy());
 +  ret->setConnectivity(c,ci);
 +  return ret.retn();
 +}
 +
 +void MEDCouplingUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
 +{
 +  if(!other)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is null !");
 +  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
 +  if(!otherC)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCouplingUMesh instance !");
 +  MEDCouplingUMesh *otherC2=const_cast<MEDCouplingUMesh *>(otherC);//sorry :(
 +  setConnectivity(otherC2->getNodalConnectivity(),otherC2->getNodalConnectivityIndex(),true);
 +}
 +
 +std::size_t MEDCouplingUMesh::getHeapMemorySizeWithoutChildren() const
 +{
 +  std::size_t ret(MEDCouplingPointSet::getHeapMemorySizeWithoutChildren());
 +  return ret;
 +}
 +
 +std::vector<const BigMemoryObject *> MEDCouplingUMesh::getDirectChildrenWithNull() const
 +{
 +  std::vector<const BigMemoryObject *> ret(MEDCouplingPointSet::getDirectChildrenWithNull());
 +  ret.push_back(_nodal_connec);
 +  ret.push_back(_nodal_connec_index);
 +  return ret;
 +}
 +
 +void MEDCouplingUMesh::updateTime() const
 +{
 +  MEDCouplingPointSet::updateTime();
 +  if(_nodal_connec)
 +    {
 +      updateTimeWith(*_nodal_connec);
 +    }
 +  if(_nodal_connec_index)
 +    {
 +      updateTimeWith(*_nodal_connec_index);
 +    }
 +}
 +
 +MEDCouplingUMesh::MEDCouplingUMesh():_mesh_dim(-2),_nodal_connec(0),_nodal_connec_index(0)
 +{
 +}
 +
 +/*!
 + * Checks if \a this mesh is well defined. If no exception is thrown by this method,
 + * then \a this mesh is most probably is writable, exchangeable and available for most
 + * of algorithms. When a mesh is constructed from scratch, it is a good habit to call
 + * this method to check that all is in order with \a this mesh.
 + *  \throw If the mesh dimension is not set.
 + *  \throw If the coordinates array is not set (if mesh dimension != -1 ).
 + *  \throw If \a this mesh contains elements of dimension different from the mesh dimension.
 + *  \throw If the connectivity data array has more than one component.
 + *  \throw If the connectivity data array has a named component.
 + *  \throw If the connectivity index data array has more than one component.
 + *  \throw If the connectivity index data array has a named component.
 + */
 +void MEDCouplingUMesh::checkCoherency() const
 +{
 +  if(_mesh_dim<-1)
 +    throw INTERP_KERNEL::Exception("No mesh dimension specified !");
 +  if(_mesh_dim!=-1)
 +    MEDCouplingPointSet::checkCoherency();
 +  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
 +    {
 +      if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim)
 +        {
 +          std::ostringstream message;
 +          message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter);
 +          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 !");
 +    }
 +  else
 +    if(_mesh_dim!=-1)
 +      throw INTERP_KERNEL::Exception("Nodal connectivity array is not defined !");
 +  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 !");
 +    }
 +  else
 +    if(_mesh_dim!=-1)
 +      throw INTERP_KERNEL::Exception("Nodal connectivity index array is not defined !");
 +}
 +
 +/*!
 + * Checks if \a this mesh is well defined. If no exception is thrown by this method,
 + * then \a this mesh is most probably is writable, exchangeable and available for all
 + * algorithms. <br> In addition to the checks performed by checkCoherency(), this
 + * method thoroughly checks the nodal connectivity.
 + *  \param [in] eps - a not used parameter.
 + *  \throw If the mesh dimension is not set.
 + *  \throw If the coordinates array is not set (if mesh dimension != -1 ).
 + *  \throw If \a this mesh contains elements of dimension different from the mesh dimension.
 + *  \throw If the connectivity data array has more than one component.
 + *  \throw If the connectivity data array has a named component.
 + *  \throw If the connectivity index data array has more than one component.
 + *  \throw If the connectivity index data array has a named component.
 + *  \throw If number of nodes defining an element does not correspond to the type of element.
 + *  \throw If the nodal connectivity includes an invalid node id.
 + */
 +void MEDCouplingUMesh::checkCoherency1(double eps) const
 +{
 +  checkCoherency();
 +  if(_mesh_dim==-1)
 +    return ;
 +  int meshDim=getMeshDimension();
 +  int nbOfNodes=getNumberOfNodes();
 +  int nbOfCells=getNumberOfCells();
 +  const int *ptr=_nodal_connec->getConstPointer();
 +  const int *ptrI=_nodal_connec_index->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)ptr[ptrI[i]]);
 +      if((int)cm.getDimension()!=meshDim)
 +        {
 +          std::ostringstream oss;
 +          oss << "MEDCouplingUMesh::checkCoherency1 : cell << #" << i<< " with type Type " << cm.getRepr() << " in 'this' whereas meshdim == " << meshDim << " !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +      int nbOfNodesInCell=ptrI[i+1]-ptrI[i]-1;
 +      if(!cm.isDynamic())
 +        if(nbOfNodesInCell!=(int)cm.getNumberOfNodes())
 +          {
 +            std::ostringstream oss;
 +            oss << "MEDCouplingUMesh::checkCoherency1 : cell #" << i << " with static Type '" << cm.getRepr() << "' has " <<  cm.getNumberOfNodes();
 +            oss << " nodes whereas in connectivity there is " << nbOfNodesInCell << " nodes ! Looks very bad !";
 +            throw INTERP_KERNEL::Exception(oss.str().c_str());
 +          }
 +      if(cm.isQuadratic() && cm.isDynamic() && meshDim == 2)
 +        if (nbOfNodesInCell % 2 || nbOfNodesInCell < 4)
 +          {
 +            std::ostringstream oss;
 +            oss << "MEDCouplingUMesh::checkCoherency1 : cell #" << i << " with quadratic type '" << cm.getRepr() << "' has " <<  nbOfNodesInCell;
 +            oss << " nodes. This should be even, and greater or equal than 4!! Looks very bad!";
 +            throw INTERP_KERNEL::Exception(oss.str().c_str());
 +          }
 +      for(const int *w=ptr+ptrI[i]+1;w!=ptr+ptrI[i+1];w++)
 +        {
 +          int nodeId=*w;
 +          if(nodeId>=0)
 +            {
 +              if(nodeId>=nbOfNodes)
 +                {
 +                  std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " whereas there are only " << nbOfNodes << " nodes in the mesh !";
 +                  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +                }
 +            }
 +          else if(nodeId<-1)
 +            {
 +              std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " in connectivity ! sounds bad !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +          else
 +            {
 +              if((INTERP_KERNEL::NormalizedCellType)(ptr[ptrI[i]])!=INTERP_KERNEL::NORM_POLYHED)
 +                {
 +                  std::ostringstream oss; oss << "Cell #" << i << " is built with node #-1 in connectivity ! sounds bad !";
 +                  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +                }
 +            }
 +        }
 +    }
 +}
 +
 +
 +/*!
 + * Checks if \a this mesh is well defined. If no exception is thrown by this method,
 + * then \a this mesh is most probably is writable, exchangeable and available for all
 + * algorithms. <br> This method performs the same checks as checkCoherency1() does. 
 + *  \param [in] eps - a not used parameter.
 + *  \throw If the mesh dimension is not set.
 + *  \throw If the coordinates array is not set (if mesh dimension != -1 ).
 + *  \throw If \a this mesh contains elements of dimension different from the mesh dimension.
 + *  \throw If the connectivity data array has more than one component.
 + *  \throw If the connectivity data array has a named component.
 + *  \throw If the connectivity index data array has more than one component.
 + *  \throw If the connectivity index data array has a named component.
 + *  \throw If number of nodes defining an element does not correspond to the type of element.
 + *  \throw If the nodal connectivity includes an invalid node id.
 + */
 +void MEDCouplingUMesh::checkCoherency2(double eps) const
 +{
 +  checkCoherency1(eps);
 +}
 +
 +/*!
 + * Sets dimension of \a this mesh. The mesh dimension in general depends on types of
 + * elements contained in the mesh. For more info on the mesh dimension see
 + * \ref MEDCouplingUMeshPage.
 + *  \param [in] meshDim - a new mesh dimension.
 + *  \throw If \a meshDim is invalid. A valid range is <em> -1 <= meshDim <= 3</em>.
 + */
 +void MEDCouplingUMesh::setMeshDimension(int meshDim)
 +{
 +  if(meshDim<-1 || meshDim>3)
 +    throw INTERP_KERNEL::Exception("Invalid meshDim specified ! Must be greater or equal to -1 and lower or equal to 3 !");
 +  _mesh_dim=meshDim;
 +  declareAsNew();
 +}
 +
 +/*!
 + * Allocates memory to store an estimation of the given number of cells. The closer is the estimation to the number of cells effectively inserted,
 + * the less will the library need to reallocate memory. If the number of cells to be inserted is not known simply put 0 to this parameter.
 + * If a nodal connectivity previouly existed before the call of this method, it will be reset.
 + *
 + *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br>
 + *  \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::allocateCells(int nbOfCells)
 +{
 +  if(nbOfCells<0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::allocateCells : the input number of cells should be >= 0 !");
 +  if(_nodal_connec_index)
 +    {
 +      _nodal_connec_index->decrRef();
 +    }
 +  if(_nodal_connec)
 +    {
 +      _nodal_connec->decrRef();
 +    }
 +  _nodal_connec_index=DataArrayInt::New();
 +  _nodal_connec_index->reserve(nbOfCells+1);
 +  _nodal_connec_index->pushBackSilent(0);
 +  _nodal_connec=DataArrayInt::New();
 +  _nodal_connec->reserve(2*nbOfCells);
 +  _types.clear();
 +  declareAsNew();
 +}
 +
 +/*!
 + * Appends a cell to the connectivity array. For deeper understanding what is
 + * happening see \ref MEDCouplingUMeshNodalConnectivity.
 + *  \param [in] type - type of cell to add.
 + *  \param [in] size - number of nodes constituting this cell.
 + *  \param [in] nodalConnOfCell - the connectivity of the cell to add.
 + * 
 + *  \if ENABLE_EXAMPLES
 + *  \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br>
 + *  \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell)
 +{
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  if(_nodal_connec_index==0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !");
 +  if((int)cm.getDimension()==_mesh_dim)
 +    {
 +      if(!cm.isDynamic())
 +        if(size!=(int)cm.getNumberOfNodes())
 +          {
 +            std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : Trying to push a " << cm.getRepr() << " cell with a size of " << size;
 +            oss << " ! Expecting " << cm.getNumberOfNodes() << " !";
 +            throw INTERP_KERNEL::Exception(oss.str().c_str());
 +          }
 +      int idx=_nodal_connec_index->back();
 +      int val=idx+size+1;
 +      _nodal_connec_index->pushBackSilent(val);
 +      _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size);
 +      _types.insert(type);
 +    }
 +  else
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : cell type " << cm.getRepr() << " has a dimension " << cm.getDimension();
 +      oss << " whereas Mesh Dimension of current UMesh instance is set to " << _mesh_dim << " ! Please invoke \"setMeshDimension\" method before or invoke ";
 +      oss << "\"MEDCouplingUMesh::New\" static method with 2 parameters name and meshDimension !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +}
 +
 +/*!
 + * Compacts data arrays to release unused memory. This method is to be called after
 + * finishing cell insertion using \a this->insertNextCell().
 + * 
 + *  \if ENABLE_EXAMPLES
 + *  \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br>
 + *  \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::finishInsertingCells()
 +{
 +  _nodal_connec->pack();
 +  _nodal_connec_index->pack();
 +  _nodal_connec->declareAsNew();
 +  _nodal_connec_index->declareAsNew();
 +  updateTime();
 +}
 +
 +/*!
 + * Entry point for iteration over cells of this. Warning the returned cell iterator should be deallocated.
 + * Useful for python users.
 + */
 +MEDCouplingUMeshCellIterator *MEDCouplingUMesh::cellIterator()
 +{
 +  return new MEDCouplingUMeshCellIterator(this);
 +}
 +
 +/*!
 + * Entry point for iteration over cells groups geo types per geotypes. Warning the returned cell iterator should be deallocated.
 + * If \a this is not so that that cells are grouped by geo types this method will throw an exception.
 + * In this case MEDCouplingUMesh::sortCellsInMEDFileFrmt or MEDCouplingUMesh::rearrange2ConsecutiveCellTypes methods for example can be called before invoking this method.
 + * Useful for python users.
 + */
 +MEDCouplingUMeshCellByTypeEntry *MEDCouplingUMesh::cellsByType()
 +{
 +  if(!checkConsecutiveCellTypes())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::cellsByType : this mesh is not sorted by type !");
 +  return new MEDCouplingUMeshCellByTypeEntry(this);
 +}
 +
 +/*!
 + * Returns a set of all cell types available in \a this mesh.
 + * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
 + * \warning this method does not throw any exception even if \a this is not defined.
 + * \sa MEDCouplingUMesh::getAllGeoTypesSorted
 + */
 +std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getAllGeoTypes() const
 +{
 +  return _types;
 +}
 +
 +/*!
 + * This method returns the sorted list of geometric types in \a this.
 + * Sorted means in the same order than the cells in \a this. A single entry in return vector means the maximal chunk of consecutive cells in \a this
 + * having the same geometric type. So a same geometric type can appear more than once if the cells are not sorted per geometric type.
 + *
 + * \throw if connectivity in \a this is not correctly defined.
 + *  
 + * \sa MEDCouplingMesh::getAllGeoTypes
 + */
 +std::vector<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getAllGeoTypesSorted() const
 +{
 +  std::vector<INTERP_KERNEL::NormalizedCellType> ret;
 +  checkConnectivityFullyDefined();
 +  int nbOfCells(getNumberOfCells());
 +  if(nbOfCells==0)
 +    return ret;
 +  if(getMeshLength()<1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAllGeoTypesSorted : the connectivity in this seems invalid !");
 +  const int *c(_nodal_connec->begin()),*ci(_nodal_connec_index->begin());
 +  ret.push_back((INTERP_KERNEL::NormalizedCellType)c[*ci++]);
 +  for(int i=1;i<nbOfCells;i++,ci++)
 +    if(ret.back()!=((INTERP_KERNEL::NormalizedCellType)c[*ci]))
 +      ret.push_back((INTERP_KERNEL::NormalizedCellType)c[*ci]);
 +  return ret;
 +}
 +
 +/*!
 + * This method is a method that compares \a this and \a other.
 + * This method compares \b all attributes, even names and component names.
 + */
 +bool MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
 +{
 +  if(!other)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isEqualIfNotWhy : input other pointer is null !");
 +  std::ostringstream oss; oss.precision(15);
 +  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
 +  if(!otherC)
 +    {
 +      reason="mesh given in input is not castable in MEDCouplingUMesh !";
 +      return false;
 +    }
 +  if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
 +    return false;
 +  if(_mesh_dim!=otherC->_mesh_dim)
 +    {
 +      oss << "umesh dimension mismatch : this mesh dimension=" << _mesh_dim << " other mesh dimension=" <<  otherC->_mesh_dim;
 +      reason=oss.str();
 +      return false;
 +    }
 +  if(_types!=otherC->_types)
 +    {
 +      oss << "umesh geometric type mismatch :\nThis geometric types are :";
 +      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); oss << cm.getRepr() << ", "; }
 +      oss << "\nOther geometric types are :";
 +      for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=otherC->_types.begin();iter!=otherC->_types.end();iter++)
 +        { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; }
 +      reason=oss.str();
 +      return false;
 +    }
 +  if(_nodal_connec!=0 || otherC->_nodal_connec!=0)
 +    if(_nodal_connec==0 || otherC->_nodal_connec==0)
 +      {
 +        reason="Only one UMesh between the two this and other has its nodal connectivity DataArrayInt defined !";
 +        return false;
 +      }
 +  if(_nodal_connec!=otherC->_nodal_connec)
 +    if(!_nodal_connec->isEqualIfNotWhy(*otherC->_nodal_connec,reason))
 +      {
 +        reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
 +        return false;
 +      }
 +  if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0)
 +    if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0)
 +      {
 +        reason="Only one UMesh between the two this and other has its nodal connectivity index DataArrayInt defined !";
 +        return false;
 +      }
 +  if(_nodal_connec_index!=otherC->_nodal_connec_index)
 +    if(!_nodal_connec_index->isEqualIfNotWhy(*otherC->_nodal_connec_index,reason))
 +      {
 +        reason.insert(0,"Nodal connectivity index DataArrayInt differ : ");
 +        return false;
 +      }
 +  return true;
 +}
 +
 +/*!
 + * Checks if data arrays of this mesh (node coordinates, nodal
 + * connectivity of cells, etc) of two meshes are same. Textual data like name etc. are
 + * not considered.
 + *  \param [in] other - the mesh to compare with.
 + *  \param [in] prec - precision value used to compare node coordinates.
 + *  \return bool - \a true if the two meshes are same.
 + */
 +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;
 +}
 +
 +/*!
 + * Checks if \a this and \a other meshes are geometrically equivalent with high
 + * probability, else an exception is thrown. The meshes are considered equivalent if
 + * (1) meshes contain the same number of nodes and the same number of elements of the
 + * same types (2) three cells of the two meshes (first, last and middle) are based
 + * on coincident nodes (with a specified precision).
 + *  \param [in] other - the mesh to compare with.
 + *  \param [in] prec - the precision used to compare nodes of the two meshes.
 + *  \throw If the two meshes do not match.
 + */
 +void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
 +{
 +  MEDCouplingPointSet::checkFastEquivalWith(other,prec);
 +  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
 +  if(!otherC)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkFastEquivalWith : Two meshes are not not unstructured !"); 
 +}
 +
 +/*!
 + * Returns the reverse nodal connectivity. The reverse nodal connectivity enumerates
 + * cells each node belongs to.
 + * \warning For speed reasons, this method does not check if node ids in the nodal
 + *          connectivity correspond to the size of node coordinates array.
 + * \param [in,out] revNodal - an array holding ids of cells sharing each node.
 + * \param [in,out] revNodalIndx - an array, of length \a this->getNumberOfNodes() + 1,
 + *        dividing cell ids in \a revNodal into groups each referring to one
 + *        node. Its every element (except the last one) is an index pointing to the
 + *         first id of a group of cells. For example cells sharing the node #1 are 
 + *        described by following range of indices: 
 + *        [ \a revNodalIndx[1], \a revNodalIndx[2] ) and the cell ids are
 + *        \a revNodal[ \a revNodalIndx[1] ], \a revNodal[ \a revNodalIndx[1] + 1], ...
 + *        Number of cells sharing the *i*-th node is
 + *        \a revNodalIndx[ *i*+1 ] - \a revNodalIndx[ *i* ].
 + * \throw If the coordinates array is not set.
 + * \throw If the nodal connectivity of cells is not defined.
 + * 
 + * \if ENABLE_EXAMPLES
 + * \ref cpp_mcumesh_getReverseNodalConnectivity "Here is a C++ example".<br>
 + * \ref  py_mcumesh_getReverseNodalConnectivity "Here is a Python example".
 + * \endif
 + */
 +void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
 +{
 +  checkFullyDefined();
 +  int nbOfNodes=getNumberOfNodes();
 +  int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
 +  revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
 +  std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  int nbOfEltsInRevNodal=0;
 +  for(int eltId=0;eltId<nbOfCells;eltId++)
 +    {
 +      const int *strtNdlConnOfCurCell=conn+connIndex[eltId]+1;
 +      const int *endNdlConnOfCurCell=conn+connIndex[eltId+1];
 +      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
 +        if(*iter>=0)//for polyhedrons
 +          {
 +            nbOfEltsInRevNodal++;
 +            revNodalIndxPtr[(*iter)+1]++;
 +          }
 +    }
 +  std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
 +  int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
 +  revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
 +  std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
 +  for(int eltId=0;eltId<nbOfCells;eltId++)
 +    {
 +      const int *strtNdlConnOfCurCell=conn+connIndex[eltId]+1;
 +      const int *endNdlConnOfCurCell=conn+connIndex[eltId+1];
 +      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
 +        if(*iter>=0)//for polyhedrons
 +          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
 +    }
 +}
 +
 +/// @cond INTERNAL
 +
 +int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
 +{
 +  return id;
 +}
 +
 +int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
 +{
 +  if(!compute)
 +    return id+1;
 +  else
 +    {
 +      if(cm.getOrientationStatus(nb,conn1,conn2))
 +        return id+1;
 +      else
 +        return -(id+1);
 +    }
 +}
 +
 +class MinusOneSonsGenerator
 +{
 +public:
 +  MinusOneSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
 +  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); }
 +  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
 +  static const int DELTA=1;
 +private:
 +  const INTERP_KERNEL::CellModel& _cm;
 +};
 +
 +class MinusOneSonsGeneratorBiQuadratic
 +{
 +public:
 +  MinusOneSonsGeneratorBiQuadratic(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
 +  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); }
 +  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity4(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
 +  static const int DELTA=1;
 +private:
 +  const INTERP_KERNEL::CellModel& _cm;
 +};
 +
 +class MinusTwoSonsGenerator
 +{
 +public:
 +  MinusTwoSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
 +  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfEdgesIn3D(conn,lgth); }
 +  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonEdgesNodalConnectivity3D(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
 +  static const int DELTA=2;
 +private:
 +  const INTERP_KERNEL::CellModel& _cm;
 +};
 +
 +/// @endcond
 +
 +/*!
 + * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a
 + * this->getMeshDimension(), that bound cells of \a this mesh. In addition arrays
 + * describing correspondence between cells of \a this and the result meshes are
 + * returned. The arrays \a desc and \a descIndx (\ref numbering-indirect) describe the descending connectivity,
 + * i.e. enumerate cells of the result mesh bounding each cell of \a this mesh. The
 + * arrays \a revDesc and \a revDescIndx (\ref numbering-indirect) describe the reverse descending connectivity,
 + * i.e. enumerate cells of  \a this mesh bounded by each cell of the result mesh. 
 + * \warning For speed reasons, this method does not check if node ids in the nodal
 + *          connectivity correspond to the size of node coordinates array.
 + * \warning Cells of the result mesh are \b not sorted by geometric type, hence,
 + *          to write this mesh to the MED file, its cells must be sorted using
 + *          sortCellsInMEDFileFrmt().
 + *  \param [in,out] desc - the array containing cell ids of the result mesh bounding
 + *         each cell of \a this mesh.
 + *  \param [in,out] descIndx - the array, of length \a this->getNumberOfCells() + 1,
 + *        dividing cell ids in \a desc into groups each referring to one
 + *        cell of \a this mesh. Its every element (except the last one) is an index
 + *        pointing to the first id of a group of cells. For example cells of the
 + *        result mesh bounding the cell #1 of \a this mesh are described by following
 + *        range of indices:
 + *        [ \a descIndx[1], \a descIndx[2] ) and the cell ids are
 + *        \a desc[ \a descIndx[1] ], \a desc[ \a descIndx[1] + 1], ...
 + *        Number of cells of the result mesh sharing the *i*-th cell of \a this mesh is
 + *        \a descIndx[ *i*+1 ] - \a descIndx[ *i* ].
 + *  \param [in,out] revDesc - the array containing cell ids of \a this mesh bounded
 + *         by each cell of the result mesh.
 + *  \param [in,out] revDescIndx - the array, of length one more than number of cells
 + *        in the result mesh,
 + *        dividing cell ids in \a revDesc into groups each referring to one
 + *        cell of the result mesh the same way as \a descIndx divides \a desc.
 + *  \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
 + *        delete this mesh using decrRef() as it is no more needed.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is node defined.
 + *  \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a
 + *         revDescIndx == NULL.
 + * 
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_buildDescendingConnectivity "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_buildDescendingConnectivity "Here is a Python example".
 + *  \endif
 + * \sa buildDescendingConnectivity2()
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const
 +{
 +  return buildDescendingConnectivityGen<MinusOneSonsGenerator>(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer);
 +}
 +
 +/*!
 + * \a this has to have a mesh dimension equal to 3. If it is not the case an INTERP_KERNEL::Exception will be thrown.
 + * This behaves exactly as MEDCouplingUMesh::buildDescendingConnectivity does except that this method compute directly the transition from mesh dimension 3 to sub edges (dimension 1)
 + * in one shot. That is to say that this method is equivalent to 2 successive calls to MEDCouplingUMesh::buildDescendingConnectivity.
 + * This method returns 4 arrays and a mesh as MEDCouplingUMesh::buildDescendingConnectivity does.
 + * \sa MEDCouplingUMesh::buildDescendingConnectivity
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::explode3DMeshTo1D : This has to have a mesh dimension to 3 !");
 +  return buildDescendingConnectivityGen<MinusTwoSonsGenerator>(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer);
 +}
 +
 +/*!
 + * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a
 + * this->getMeshDimension(), that bound cells of \a this mesh. In
 + * addition arrays describing correspondence between cells of \a this and the result
 + * meshes are returned. The arrays \a desc and \a descIndx (\ref numbering-indirect) describe the descending
 + * connectivity, i.e. enumerate cells of the result mesh bounding each cell of \a this
 + *  mesh. This method differs from buildDescendingConnectivity() in that apart
 + * from cell ids, \a desc returns mutual orientation of cells in \a this and the
 + * result meshes. So a positive id means that order of nodes in corresponding cells
 + * of two meshes is same, and a negative id means a reverse order of nodes. Since a
 + * cell with id #0 can't be negative, the array \a desc returns ids in FORTRAN mode,
 + * i.e. cell ids are one-based.
 + * Arrays \a revDesc and \a revDescIndx (\ref numbering-indirect) describe the reverse descending connectivity,
 + * i.e. enumerate cells of  \a this mesh bounded by each cell of the result mesh. 
 + * \warning For speed reasons, this method does not check if node ids in the nodal
 + *          connectivity correspond to the size of node coordinates array.
 + * \warning Cells of the result mesh are \b not sorted by geometric type, hence,
 + *          to write this mesh to the MED file, its cells must be sorted using
 + *          sortCellsInMEDFileFrmt().
 + *  \param [in,out] desc - the array containing cell ids of the result mesh bounding
 + *         each cell of \a this mesh.
 + *  \param [in,out] descIndx - the array, of length \a this->getNumberOfCells() + 1,
 + *        dividing cell ids in \a desc into groups each referring to one
 + *        cell of \a this mesh. Its every element (except the last one) is an index
 + *        pointing to the first id of a group of cells. For example cells of the
 + *        result mesh bounding the cell #1 of \a this mesh are described by following
 + *        range of indices:
 + *        [ \a descIndx[1], \a descIndx[2] ) and the cell ids are
 + *        \a desc[ \a descIndx[1] ], \a desc[ \a descIndx[1] + 1], ...
 + *        Number of cells of the result mesh sharing the *i*-th cell of \a this mesh is
 + *        \a descIndx[ *i*+1 ] - \a descIndx[ *i* ].
 + *  \param [in,out] revDesc - the array containing cell ids of \a this mesh bounded
 + *         by each cell of the result mesh.
 + *  \param [in,out] revDescIndx - the array, of length one more than number of cells
 + *        in the result mesh,
 + *        dividing cell ids in \a revDesc into groups each referring to one
 + *        cell of the result mesh the same way as \a descIndx divides \a desc.
 + *  \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This result mesh
 + *        shares the node coordinates array with \a this mesh. The caller is to
 + *        delete this mesh using decrRef() as it is no more needed.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is node defined.
 + *  \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a
 + *         revDescIndx == NULL.
 + * 
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_buildDescendingConnectivity2 "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_buildDescendingConnectivity2 "Here is a Python example".
 + *  \endif
 + * \sa buildDescendingConnectivity()
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const
 +{
 +  return buildDescendingConnectivityGen<MinusOneSonsGenerator>(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer);
 +}
 +
 +/*!
 + * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
 + * For speed reasons no check of this will be done. This method calls
 + * MEDCouplingUMesh::buildDescendingConnectivity to compute the result.
 + * This method lists cell by cell in \b this which are its neighbors. To compute the result
 + * only connectivities are considered.
 + * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]].
 + * The format of return is hence \ref numbering-indirect.
 + *
 + * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly
 + * allocated and should be dealt by the caller. \b neighborsIndx 2nd output
 + * parameter allows to select the right part in this array (\ref numbering-indirect). The number of tuples
 + * is equal to the last values in \b neighborsIndx.
 + * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be
 + * dealt by the caller. This arrays allow to use the first output parameter \b neighbors (\ref numbering-indirect).
 + */
 +void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
 +  meshDM1=0;
 +  ComputeNeighborsOfCellsAdv(desc,descIndx,revDesc,revDescIndx,neighbors,neighborsIndx);
 +}
 +
 +/*!
 + * This method is called by MEDCouplingUMesh::computeNeighborsOfCells. This methods performs the algorithm
 + * of MEDCouplingUMesh::computeNeighborsOfCells.
 + * This method is useful for users that want to reduce along a criterion the set of neighbours cell. This is
 + * typically the case to extract a set a neighbours,
 + * excluding a set of meshdim-1 cells in input descending connectivity.
 + * Typically \b desc, \b descIndx, \b revDesc and \b revDescIndx (\ref numbering-indirect) input params are
 + * the result of MEDCouplingUMesh::buildDescendingConnectivity.
 + * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities
 + * are considered.
 + * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]].
 + *
 + * \param [in] desc descending connectivity array.
 + * \param [in] descIndx descending connectivity index array used to walk through \b desc (\ref numbering-indirect).
 + * \param [in] revDesc reverse descending connectivity array.
 + * \param [in] revDescIndx reverse descending connectivity index array used to walk through \b revDesc (\ref numbering-indirect).
 + * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output
 + *                        parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx.
 + * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors.
 + */
 +void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descIndx, const DataArrayInt *revDesc, const DataArrayInt *revDescIndx,
 +                                                  DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx)
 +{
 +  if(!desc || !descIndx || !revDesc || !revDescIndx)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeNeighborsOfCellsAdv some input array is empty !");
 +  const int *descPtr=desc->getConstPointer();
 +  const int *descIPtr=descIndx->getConstPointer();
 +  const int *revDescPtr=revDesc->getConstPointer();
 +  const int *revDescIPtr=revDescIndx->getConstPointer();
 +  //
 +  int nbCells=descIndx->getNumberOfTuples()-1;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out0=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out1=DataArrayInt::New(); out1->alloc(nbCells+1,1);
 +  int *out1Ptr=out1->getPointer();
 +  *out1Ptr++=0;
 +  out0->reserve(desc->getNumberOfTuples());
 +  for(int i=0;i<nbCells;i++,descIPtr++,out1Ptr++)
 +    {
 +      for(const int *w1=descPtr+descIPtr[0];w1!=descPtr+descIPtr[1];w1++)
 +        {
 +          std::set<int> s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]);
 +          s.erase(i);
 +          out0->insertAtTheEnd(s.begin(),s.end());
 +        }
 +      *out1Ptr=out0->getNumberOfTuples();
 +    }
 +  neighbors=out0.retn();
 +  neighborsIndx=out1.retn();
 +}
 +
 +/*!
 + * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
 + * For speed reasons no check of this will be done. This method calls
 + * MEDCouplingUMesh::buildDescendingConnectivity to compute the result.
 + * This method lists node by node in \b this which are its neighbors. To compute the result
 + * only connectivities are considered.
 + * The neighbor nodes of node having id 'nodeId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]].
 + *
 + * \param [out] neighbors is an array storing all the neighbors of all nodes in \b this. This array
 + * is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output
 + * parameter allows to select the right part in this array (\ref numbering-indirect).
 + * The number of tuples is equal to the last values in \b neighborsIndx.
 + * \param [out] neighborsIdx is an array of size this->getNumberOfCells()+1 newly allocated and should
 + * be dealt by the caller. This arrays allow to use the first output parameter \b neighbors.
 + */
 +void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const
 +{
 +  checkFullyDefined();
 +  int mdim(getMeshDimension()),nbNodes(getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descIndx(DataArrayInt::New()),revDesc(DataArrayInt::New()),revDescIndx(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1D;
 +  switch(mdim)
 +  {
 +    case 3:
 +      {
 +        mesh1D=explode3DMeshTo1D(desc,descIndx,revDesc,revDescIndx);
 +        break;
 +      }
 +    case 2:
 +      {
 +        mesh1D=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
 +        break;
 +      }
 +    case 1:
 +      {
 +        mesh1D=const_cast<MEDCouplingUMesh *>(this);
 +        mesh1D->incrRef();
 +        break;
 +      }
 +    default:
 +      {
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computeNeighborsOfNodes : Mesh dimension supported are [3,2,1] !");
 +      }
 +  }
 +  desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=0; revDescIndx=0;
 +  mesh1D->getReverseNodalConnectivity(desc,descIndx);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New());
 +  ret0->alloc(desc->getNumberOfTuples(),1);
 +  int *r0Pt(ret0->getPointer());
 +  const int *c1DPtr(mesh1D->getNodalConnectivity()->begin()),*rn(desc->begin()),*rni(descIndx->begin());
 +  for(int i=0;i<nbNodes;i++,rni++)
 +    {
 +      for(const int *oneDCellIt=rn+rni[0];oneDCellIt!=rn+rni[1];oneDCellIt++)
 +        *r0Pt++=c1DPtr[3*(*oneDCellIt)+1]==i?c1DPtr[3*(*oneDCellIt)+2]:c1DPtr[3*(*oneDCellIt)+1];
 +    }
 +  neighbors=ret0.retn();
 +  neighborsIdx=descIndx.retn();
 +}
 +
 +/// @cond INTERNAL
 +
 +/*!
 + * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
 + * For speed reasons no check of this will be done.
 + */
 +template<class SonsGenerator>
 +MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const
 +{
 +  if(!desc || !descIndx || !revDesc || !revDescIndx)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildDescendingConnectivityGen : present of a null pointer in input !");
 +  checkConnectivityFullyDefined();
 +  int nbOfCells=getNumberOfCells();
 +  int nbOfNodes=getNumberOfNodes();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodalIndx=DataArrayInt::New(); revNodalIndx->alloc(nbOfNodes+1,1); revNodalIndx->fillWithZero();
 +  int *revNodalIndxPtr=revNodalIndx->getPointer();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  std::string name="Mesh constituent of "; name+=getName();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(name,getMeshDimension()-SonsGenerator::DELTA);
 +  ret->setCoords(getCoords());
 +  ret->allocateCells(2*nbOfCells);
 +  descIndx->alloc(nbOfCells+1,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells);
 +  int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0;
 +  for(int eltId=0;eltId<nbOfCells;eltId++,descIndxPtr++)
 +    {
 +      int pos=connIndex[eltId];
 +      int posP1=connIndex[eltId+1];
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[pos]);
 +      SonsGenerator sg(cm);
 +      unsigned nbOfSons=sg.getNumberOfSons2(conn+pos+1,posP1-pos-1);
 +      INTERP_KERNEL::AutoPtr<int> tmp=new int[posP1-pos];
 +      for(unsigned i=0;i<nbOfSons;i++)
 +        {
 +          INTERP_KERNEL::NormalizedCellType cmsId;
 +          unsigned nbOfNodesSon=sg.fillSonCellNodalConnectivity2(i,conn+pos+1,posP1-pos-1,tmp,cmsId);
 +          for(unsigned k=0;k<nbOfNodesSon;k++)
 +            if(tmp[k]>=0)
 +              revNodalIndxPtr[tmp[k]+1]++;
 +          ret->insertNextCell(cmsId,nbOfNodesSon,tmp);
 +          revDesc2->pushBackSilent(eltId);
 +        }
 +      descIndxPtr[0]=descIndxPtr[-1]+(int)nbOfSons;
 +    }
 +  int nbOfCellsM1=ret->getNumberOfCells();
 +  std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal=DataArrayInt::New(); revNodal->alloc(revNodalIndx->back(),1);
 +  std::fill(revNodal->getPointer(),revNodal->getPointer()+revNodalIndx->back(),-1);
 +  int *revNodalPtr=revNodal->getPointer();
 +  const int *connM1=ret->getNodalConnectivity()->getConstPointer();
 +  const int *connIndexM1=ret->getNodalConnectivityIndex()->getConstPointer();
 +  for(int eltId=0;eltId<nbOfCellsM1;eltId++)
 +    {
 +      const int *strtNdlConnOfCurCell=connM1+connIndexM1[eltId]+1;
 +      const int *endNdlConnOfCurCell=connM1+connIndexM1[eltId+1];
 +      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
 +        if(*iter>=0)//for polyhedrons
 +          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
 +    }
 +  //
 +  DataArrayInt *commonCells=0,*commonCellsI=0;
 +  FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
 +  const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer());
 +  int newNbOfCellsM1=-1;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nM1=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfCellsM1,commonCells->begin(),
 +                                                                                                            commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1);
 +  std::vector<bool> isImpacted(nbOfCellsM1,false);
 +  for(const int *work=commonCellsI->begin();work!=commonCellsI->end()-1;work++)
 +    for(int work2=work[0];work2!=work[1];work2++)
 +      isImpacted[commonCellsPtr[work2]]=true;
 +  const int *o2nM1Ptr=o2nM1->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1);
 +  const int *n2oM1Ptr=n2oM1->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret2=static_cast<MEDCouplingUMesh *>(ret->buildPartOfMySelf(n2oM1->begin(),n2oM1->end(),true));
 +  ret2->copyTinyInfoFrom(this);
 +  desc->alloc(descIndx->back(),1);
 +  int *descPtr=desc->getPointer();
 +  const INTERP_KERNEL::CellModel& cmsDft=INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1);
 +  for(int i=0;i<nbOfCellsM1;i++,descPtr++)
 +    {
 +      if(!isImpacted[i])
 +        *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
 +      else
 +        {
 +          if(i!=n2oM1Ptr[o2nM1Ptr[i]])
 +            {
 +              const INTERP_KERNEL::CellModel& cms=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connM1[connIndexM1[i]]);
 +              *descPtr=nbrer(o2nM1Ptr[i],connIndexM1[i+1]-connIndexM1[i]-1,cms,true,connM1+connIndexM1[n2oM1Ptr[o2nM1Ptr[i]]]+1,connM1+connIndexM1[i]+1);
 +            }
 +          else
 +            *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
 +        }
 +    }
 +  revDesc->reserve(newNbOfCellsM1);
 +  revDescIndx->alloc(newNbOfCellsM1+1,1);
 +  int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0;
 +  const int *revDesc2Ptr=revDesc2->getConstPointer();
 +  for(int i=0;i<newNbOfCellsM1;i++,revDescIndxPtr++)
 +    {
 +      int oldCellIdM1=n2oM1Ptr[i];
 +      if(!isImpacted[oldCellIdM1])
 +        {
 +          revDesc->pushBackSilent(revDesc2Ptr[oldCellIdM1]);
 +          revDescIndxPtr[0]=revDescIndxPtr[-1]+1;
 +        }
 +      else
 +        {
 +          for(int j=commonCellsIPtr[0];j<commonCellsIPtr[1];j++)
 +            revDesc->pushBackSilent(revDesc2Ptr[commonCellsPtr[j]]);
 +          revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0];
 +          commonCellsIPtr++;
 +        }
 +    }
 +  //
 +  return ret2.retn();
 +}
 +
 +struct MEDCouplingAccVisit
 +{
 +  MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
 +  int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
 +  int _new_nb_of_nodes;
 +};
 +
 +/// @endcond
 +
 +/*!
 + * Converts specified cells to either polygons (if \a this is a 2D mesh) or
 + * polyhedrons (if \a this is a 3D mesh). The cells to convert are specified by an
 + * array of cell ids. Pay attention that after conversion all algorithms work slower
 + * with \a this mesh than before conversion. <br> If an exception is thrown during the
 + * conversion due presence of invalid ids in the array of cells to convert, as a
 + * result \a this mesh contains some already converted elements. In this case the 2D
 + * mesh remains valid but 3D mesh becomes \b inconsistent!
 + *  \warning This method can significantly modify the order of geometric types in \a this,
 + *          hence, to write this mesh to the MED file, its cells must be sorted using
 + *          sortCellsInMEDFileFrmt().
 + *  \param [in] cellIdsToConvertBg - the array holding ids of cells to convert.
 + *  \param [in] cellIdsToConvertEnd - a pointer to the last-plus-one-th element of \a
 + *         cellIdsToConvertBg.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is node defined.
 + *  \throw If dimension of \a this mesh is not either 2 or 3.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_convertToPolyTypes "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_convertToPolyTypes "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd)
 +{
 +  checkFullyDefined();
 +  int dim=getMeshDimension();
 +  if(dim<2 || dim>3)
 +    throw INTERP_KERNEL::Exception("Invalid mesh dimension : must be 2 or 3 !");
 +  int nbOfCells(getNumberOfCells());
 +  if(dim==2)
 +    {
 +      const int *connIndex=_nodal_connec_index->getConstPointer();
 +      int *conn=_nodal_connec->getPointer();
 +      for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++)
 +        {
 +          if(*iter>=0 && *iter<nbOfCells)
 +            {
 +              const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*iter]]);
 +              if(!cm.isQuadratic())
 +                conn[connIndex[*iter]]=INTERP_KERNEL::NORM_POLYGON;
 +              else
 +                conn[connIndex[*iter]]=INTERP_KERNEL::NORM_QPOLYG;
 +            }
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::convertToPolyTypes : On rank #" << std::distance(cellIdsToConvertBg,iter) << " value is " << *iter << " which is not";
 +              oss << " in range [0," << nbOfCells << ") !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +    }
 +  else
 +    {
 +      int *connIndex(_nodal_connec_index->getPointer());
 +      const int *connOld(_nodal_connec->getConstPointer());
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew(DataArrayInt::New()),connNewI(DataArrayInt::New()); connNew->alloc(0,1); connNewI->alloc(1,1); connNewI->setIJ(0,0,0);
 +      std::vector<bool> toBeDone(nbOfCells,false);
 +      for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++)
 +        {
 +          if(*iter>=0 && *iter<nbOfCells)
 +            toBeDone[*iter]=true;
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::convertToPolyTypes : On rank #" << std::distance(cellIdsToConvertBg,iter) << " value is " << *iter << " which is not";
 +              oss << " in range [0," << nbOfCells << ") !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +      for(int cellId=0;cellId<nbOfCells;cellId++)
 +        {
 +          int pos(connIndex[cellId]),posP1(connIndex[cellId+1]);
 +          int lgthOld(posP1-pos-1);
 +          if(toBeDone[cellId])
 +            {
 +              const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connOld[pos]);
 +              unsigned nbOfFaces(cm.getNumberOfSons2(connOld+pos+1,lgthOld));
 +              int *tmp(new int[nbOfFaces*lgthOld+1]);
 +              int *work=tmp; *work++=INTERP_KERNEL::NORM_POLYHED;
 +              for(unsigned j=0;j<nbOfFaces;j++)
 +                {
 +                  INTERP_KERNEL::NormalizedCellType type;
 +                  unsigned offset=cm.fillSonCellNodalConnectivity2(j,connOld+pos+1,lgthOld,work,type);
 +                  work+=offset;
 +                  *work++=-1;
 +                }
 +              std::size_t newLgth(std::distance(tmp,work)-1);//-1 for last -1
 +              connNew->pushBackValsSilent(tmp,tmp+newLgth);
 +              connNewI->pushBackSilent(connNewI->back()+(int)newLgth);
 +              delete [] tmp;
 +            }
 +          else
 +            {
 +              connNew->pushBackValsSilent(connOld+pos,connOld+posP1);
 +              connNewI->pushBackSilent(connNewI->back()+posP1-pos);
 +            }
 +        }
 +      setConnectivity(connNew,connNewI,false);//false because computeTypes called just behind.
 +    }
 +  computeTypes();
 +}
 +
 +/*!
 + * Converts all cells to either polygons (if \a this is a 2D mesh) or
 + * polyhedrons (if \a this is a 3D mesh).
 + *  \warning As this method is purely for user-friendliness and no optimization is
 + *          done to avoid construction of a useless vector, this method can be costly
 + *          in memory.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is node defined.
 + *  \throw If dimension of \a this mesh is not either 2 or 3.
 + */
 +void MEDCouplingUMesh::convertAllToPoly()
 +{
 +  int nbOfCells=getNumberOfCells();
 +  std::vector<int> cellIds(nbOfCells);
 +  for(int i=0;i<nbOfCells;i++)
 +    cellIds[i]=i;
 +  convertToPolyTypes(&cellIds[0],&cellIds[0]+cellIds.size());
 +}
 +
 +/*!
 + * Fixes nodal connectivity of invalid cells of type NORM_POLYHED. This method
 + * expects that all NORM_POLYHED cells have connectivity similar to that of prismatic
 + * volumes like NORM_HEXA8, NORM_PENTA6 etc., i.e. the first half of nodes describes a
 + * base facet of the volume and the second half of nodes describes an opposite facet
 + * having the same number of nodes as the base one. This method converts such
 + * connectivity to a valid polyhedral format where connectivity of each facet is
 + * explicitly described and connectivity of facets are separated by -1. If \a this mesh
 + * contains a NORM_POLYHED cell with a valid connectivity, or an invalid connectivity is
 + * not as expected, an exception is thrown and the mesh remains unchanged. Care of
 + * a correct orientation of the first facet of a polyhedron, else orientation of a
 + * corrected cell is reverse.<br>
 + * This method is useful to build an extruded unstructured mesh with polyhedrons as
 + * it releases the user from boring description of polyhedra connectivity in the valid
 + * format.
 + *  \throw If \a this->getMeshDimension() != 3.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this mesh contains polyhedrons with the valid connectivity.
 + *  \throw If \a this mesh contains polyhedrons with odd number of nodes.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::convertExtrudedPolyhedra()
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertExtrudedPolyhedra works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newCi=DataArrayInt::New();
 +  newCi->alloc(nbOfCells+1,1);
 +  int *newci=newCi->getPointer();
 +  const int *ci=_nodal_connec_index->getConstPointer();
 +  const int *c=_nodal_connec->getConstPointer();
 +  newci[0]=0;
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[i]];
 +      if(type==INTERP_KERNEL::NORM_POLYHED)
 +        {
 +          if(std::count(c+ci[i]+1,c+ci[i+1],-1)!=0)
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::convertExtrudedPolyhedra : cell # " << i << " is a polhedron BUT it has NOT exactly 1 face !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +          std::size_t n2=std::distance(c+ci[i]+1,c+ci[i+1]);
 +          if(n2%2!=0)
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::convertExtrudedPolyhedra : cell # " << i << " is a polhedron with 1 face but there is a mismatch of number of nodes in face should be even !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +          int n1=(int)(n2/2);
 +          newci[i+1]=7*n1+2+newci[i];//6*n1 (nodal length) + n1+2 (number of faces) - 1 (number of '-1' separator is equal to number of faces -1) + 1 (for cell type)
 +        }
 +      else
 +        newci[i+1]=(ci[i+1]-ci[i])+newci[i];
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newC=DataArrayInt::New();
 +  newC->alloc(newci[nbOfCells],1);
 +  int *newc=newC->getPointer();
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[i]];
 +      if(type==INTERP_KERNEL::NORM_POLYHED)
 +        {
 +          std::size_t n1=std::distance(c+ci[i]+1,c+ci[i+1])/2;
 +          newc=std::copy(c+ci[i],c+ci[i]+n1+1,newc);
 +          *newc++=-1;
 +          for(std::size_t j=0;j<n1;j++)
 +            {
 +              newc[j]=c[ci[i]+1+n1+(n1-j)%n1];
 +              newc[n1+5*j]=-1;
 +              newc[n1+5*j+1]=c[ci[i]+1+j];
 +              newc[n1+5*j+2]=c[ci[i]+1+j+n1];
 +              newc[n1+5*j+3]=c[ci[i]+1+(j+1)%n1+n1];
 +              newc[n1+5*j+4]=c[ci[i]+1+(j+1)%n1];
 +            }
 +          newc+=n1*6;
 +        }
 +      else
 +        newc=std::copy(c+ci[i],c+ci[i+1],newc);
 +    }
 +  _nodal_connec_index->decrRef(); _nodal_connec_index=newCi.retn();
 +  _nodal_connec->decrRef(); _nodal_connec=newC.retn();
 +}
 +
 +
 +/*!
 + * Converts all polygons (if \a this is a 2D mesh) or polyhedrons (if \a this is a 3D
 + * mesh) to cells of classical types. This method is opposite to convertToPolyTypes().
 + * \warning Cells of the result mesh are \b not sorted by geometric type, hence,
 + *          to write this mesh to the MED file, its cells must be sorted using
 + *          sortCellsInMEDFileFrmt().
 + * \return \c true if at least one cell has been converted, \c false else. In the
 + *         last case the nodal connectivity remains unchanged.
 + * \throw If the coordinates array is not set.
 + * \throw If the nodal connectivity of cells is not defined.
 + * \throw If \a this->getMeshDimension() < 0.
 + */
 +bool MEDCouplingUMesh::unPolyze()
 +{
 +  checkFullyDefined();
 +  int mdim=getMeshDimension();
 +  if(mdim<0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::unPolyze works on umeshes with meshdim equals to 0, 1 2 or 3 !");
 +  if(mdim<=1)
 +    return false;
 +  int nbOfCells=getNumberOfCells();
 +  if(nbOfCells<1)
 +    return false;
 +  int initMeshLgth=getMeshLength();
 +  int *conn=_nodal_connec->getPointer();
 +  int *index=_nodal_connec_index->getPointer();
 +  int posOfCurCell=0;
 +  int newPos=0;
 +  int lgthOfCurCell;
 +  bool ret=false;
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      lgthOfCurCell=index[i+1]-posOfCurCell;
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +      INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::NORM_ERROR;
 +      int newLgth;
 +      if(cm.isDynamic())
 +        {
 +          switch(cm.getDimension())
 +          {
 +            case 2:
 +              {
 +                INTERP_KERNEL::AutoPtr<int> tmp=new int[lgthOfCurCell-1];
 +                std::copy(conn+posOfCurCell+1,conn+posOfCurCell+lgthOfCurCell,(int *)tmp);
 +                newType=INTERP_KERNEL::CellSimplify::tryToUnPoly2D(cm.isQuadratic(),tmp,lgthOfCurCell-1,conn+newPos+1,newLgth);
 +                break;
 +              }
 +            case 3:
 +              {
 +                int nbOfFaces,lgthOfPolyhConn;
 +                INTERP_KERNEL::AutoPtr<int> zipFullReprOfPolyh=INTERP_KERNEL::CellSimplify::getFullPolyh3DCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,nbOfFaces,lgthOfPolyhConn);
 +                newType=INTERP_KERNEL::CellSimplify::tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,conn+newPos+1,newLgth);
 +                break;
 +              }
 +            case 1:
 +              {
 +                newType=(lgthOfCurCell==3)?INTERP_KERNEL::NORM_SEG2:INTERP_KERNEL::NORM_POLYL;
 +                break;
 +              }
 +          }
 +          ret=ret || (newType!=type);
 +          conn[newPos]=newType;
 +          newPos+=newLgth+1;
 +          posOfCurCell=index[i+1];
 +          index[i+1]=newPos;
 +        }
 +      else
 +        {
 +          std::copy(conn+posOfCurCell,conn+posOfCurCell+lgthOfCurCell,conn+newPos);
 +          newPos+=lgthOfCurCell;
 +          posOfCurCell+=lgthOfCurCell;
 +          index[i+1]=newPos;
 +        }
 +    }
 +  if(newPos!=initMeshLgth)
 +    _nodal_connec->reAlloc(newPos);
 +  if(ret)
 +    computeTypes();
 +  return ret;
 +}
 +
 +/*!
 + * This method expects that spaceDimension is equal to 3 and meshDimension equal to 3.
 + * This method performs operation only on polyhedrons in \b this. If no polyhedrons exists in \b this, \b this remains unchanged.
 + * This method allows to merge if any coplanar 3DSurf cells that may appear in some polyhedrons cells. 
 + *
 + * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. This epsilon is used to recenter around origin to have maximal 
 + *             precision.
 + */
 +void MEDCouplingUMesh::simplifyPolyhedra(double eps)
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplifyPolyhedra : works on meshdimension 3 and spaceDimension 3 !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=getCoords()->deepCpy();
 +  coords->recenterForMaxPrecision(eps);
 +  //
 +  int nbOfCells=getNumberOfCells();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *index=_nodal_connec_index->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connINew=DataArrayInt::New();
 +  connINew->alloc(nbOfCells+1,1);
 +  int *connINewPtr=connINew->getPointer(); *connINewPtr++=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew=DataArrayInt::New(); connNew->alloc(0,1);
 +  bool changed=false;
 +  for(int i=0;i<nbOfCells;i++,connINewPtr++)
 +    {
 +      if(conn[index[i]]==(int)INTERP_KERNEL::NORM_POLYHED)
 +        {
 +          SimplifyPolyhedronCell(eps,coords,conn+index[i],conn+index[i+1],connNew);
 +          changed=true;
 +        }
 +      else
 +        connNew->insertAtTheEnd(conn+index[i],conn+index[i+1]);
 +      *connINewPtr=connNew->getNumberOfTuples();
 +    }
 +  if(changed)
 +    setConnectivity(connNew,connINew,false);
 +}
 +
 +/*!
 + * This method returns all node ids used in the connectivity of \b this. The data array returned has to be dealt by the caller.
 + * The returned node ids are sorted ascendingly. This method is close to MEDCouplingUMesh::getNodeIdsInUse except
 + * the format of the returned DataArrayInt instance.
 + * 
 + * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
 + * \sa MEDCouplingUMesh::getNodeIdsInUse, areAllNodesFetched
 + */
 +DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const
 +{
 +  checkConnectivityFullyDefined();
 +  int nbOfCells=getNumberOfCells();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *maxEltPt=std::max_element(_nodal_connec->begin(),_nodal_connec->end());
 +  int maxElt=maxEltPt==_nodal_connec->end()?0:std::abs(*maxEltPt)+1;
 +  std::vector<bool> retS(maxElt,false);
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
 +      if(conn[j]>=0)
 +        retS[conn[j]]=true;
 +  int sz=0;
 +  for(int i=0;i<maxElt;i++)
 +    if(retS[i])
 +      sz++;
 +  DataArrayInt *ret=DataArrayInt::New();
 +  ret->alloc(sz,1);
 +  int *retPtr=ret->getPointer();
 +  for(int i=0;i<maxElt;i++)
 +    if(retS[i])
 +      *retPtr++=i;
 +  return ret;
 +}
 +
 +/*!
 + * \param [in,out] nodeIdsInUse an array of size typically equal to nbOfNodes.
 + * \sa MEDCouplingUMesh::getNodeIdsInUse, areAllNodesFetched
 + */
 +void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
 +{
 +  int nbOfNodes((int)nodeIdsInUse.size()),nbOfCells(getNumberOfCells());
 +  const int *connIndex(_nodal_connec_index->getConstPointer()),*conn(_nodal_connec->getConstPointer());
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
 +      if(conn[j]>=0)
 +        {
 +          if(conn[j]<nbOfNodes)
 +            nodeIdsInUse[conn[j]]=true;
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::computeNodeIdsAlg : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +}
 +
 +/*!
 + * Finds nodes not used in any cell and returns an array giving a new id to every node
 + * by excluding the unused nodes, for which the array holds -1. The result array is
 + * a mapping in "Old to New" mode. 
 + *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
 + *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
 + *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
 + *          if the node is unused or a new id else. The caller is to delete this
 + *          array using decrRef() as it is no more needed.  
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If the nodal connectivity includes an invalid id.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getNodeIdsInUse "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getNodeIdsInUse "Here is a Python example".
 + *  \endif
 + * \sa computeFetchedNodeIds, computeNodeIdsAlg()
 + */
 +DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
 +{
 +  nbrOfNodesInUse=-1;
 +  int nbOfNodes(getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  ret->alloc(nbOfNodes,1);
 +  int *traducer=ret->getPointer();
 +  std::fill(traducer,traducer+nbOfNodes,-1);
 +  int nbOfCells=getNumberOfCells();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
 +      if(conn[j]>=0)
 +        {
 +          if(conn[j]<nbOfNodes)
 +            traducer[conn[j]]=1;
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +  nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
 +  std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
 + * For each cell in \b this the number of nodes constituting cell is computed.
 + * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
 + * So for pohyhedrons some nodes can be counted several times in the returned result.
 + * 
 + * \return a newly allocated array
 + * \sa MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell
 + */
 +DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const
 +{
 +  checkConnectivityFullyDefined();
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  ret->alloc(nbOfCells,1);
 +  int *retPtr=ret->getPointer();
 +  const int *conn=getNodalConnectivity()->getConstPointer();
 +  const int *connI=getNodalConnectivityIndex()->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,retPtr++)
 +    {
 +      if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED)
 +        *retPtr=connI[i+1]-connI[i]-1;
 +      else
 +        *retPtr=connI[i+1]-connI[i]-1-std::count(conn+connI[i]+1,conn+connI[i+1],-1);
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
 + * will be counted only once here whereas it will be counted several times in MEDCouplingUMesh::computeNbOfNodesPerCell method.
 + *
 + * \return DataArrayInt * - new object to be deallocated by the caller.
 + * \sa MEDCouplingUMesh::computeNbOfNodesPerCell
 + */
 +DataArrayInt *MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell() const
 +{
 +  checkConnectivityFullyDefined();
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  ret->alloc(nbOfCells,1);
 +  int *retPtr=ret->getPointer();
 +  const int *conn=getNodalConnectivity()->getConstPointer();
 +  const int *connI=getNodalConnectivityIndex()->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,retPtr++)
 +    {
 +      std::set<int> s(conn+connI[i]+1,conn+connI[i+1]);
 +      if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED)
 +        *retPtr=(int)s.size();
 +      else
 +        {
 +          s.erase(-1);
 +          *retPtr=(int)s.size();
 +        }
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
 + * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
 + * 
 + * \return a newly allocated array
 + */
 +DataArrayInt *MEDCouplingUMesh::computeNbOfFacesPerCell() const
 +{
 +  checkConnectivityFullyDefined();
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  ret->alloc(nbOfCells,1);
 +  int *retPtr=ret->getPointer();
 +  const int *conn=getNodalConnectivity()->getConstPointer();
 +  const int *connI=getNodalConnectivityIndex()->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,retPtr++,connI++)
 +    {
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI]);
 +      *retPtr=cm.getNumberOfSons2(conn+connI[0]+1,connI[1]-connI[0]-1);
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * Removes unused nodes (the node coordinates array is shorten) and returns an array
 + * mapping between new and old node ids in "Old to New" mode. -1 values in the returned
 + * array mean that the corresponding old node is no more used. 
 + *  \return DataArrayInt * - a new instance of DataArrayInt of length \a
 + *           this->getNumberOfNodes() before call of this method. The caller is to
 + *           delete this array using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If the nodal connectivity includes an invalid id.
 + *  \sa areAllNodesFetched
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_zipCoordsTraducer "Here is a Python example".
 + *  \endif
 + */
 +DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer()
 +{
 +  return MEDCouplingPointSet::zipCoordsTraducer();
 +}
 +
 +/*!
 + * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy.
 + * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method.
 + */
 +int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType)
 +{
 +  switch(compType)
 +  {
 +    case 0:
 +      return AreCellsEqual0(conn,connI,cell1,cell2);
 +    case 1:
 +      return AreCellsEqual1(conn,connI,cell1,cell2);
 +    case 2:
 +      return AreCellsEqual2(conn,connI,cell1,cell2);
 +    case 3:
 +      return AreCellsEqual3(conn,connI,cell1,cell2);
 +    case 7:
 +      return AreCellsEqual7(conn,connI,cell1,cell2);
 +  }
 +  throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1,2,3 or 7.");
 +}
 +
 +/*!
 + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 0.
 + */
 +int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2)
 +{
 +  if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
 +    return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;
 +  return 0;
 +}
 +
 +/*!
 + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 1.
 + */
 +int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2)
 +{
 +  int sz=connI[cell1+1]-connI[cell1];
 +  if(sz==connI[cell2+1]-connI[cell2])
 +    {
 +      if(conn[connI[cell1]]==conn[connI[cell2]])
 +        {
 +          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]);
 +          unsigned dim=cm.getDimension();
 +          if(dim!=3)
 +            {
 +              if(dim!=1)
 +                {
 +                  int sz1=2*(sz-1);
 +                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz1];
 +                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp);
 +                  std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work);
 +                  work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
 +                  return work!=tmp+sz1?1:0;
 +                }
 +              else
 +                return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;//case of SEG2 and SEG3
 +            }
 +          else
 +            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual1 : not implemented yet for meshdim == 3 !");
 +        }
 +    }
 +  return 0;
 +}
 +
 +/*!
 + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 2.
 + */
 +int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2)
 +{
 +  if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
 +    {
 +      if(conn[connI[cell1]]==conn[connI[cell2]])
 +        {
 +          std::set<int> s1(conn+connI[cell1]+1,conn+connI[cell1+1]);
 +          std::set<int> s2(conn+connI[cell2]+1,conn+connI[cell2+1]);
 +          return s1==s2?1:0;
 +        }
 +    }
 +  return 0;
 +}
 +
 +/*!
 + * This method is less restrictive than AreCellsEqual2. Here the geometric type is absolutely not taken into account !
 + */
 +int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2)
 +{
 +  if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
 +    {
 +      std::set<int> s1(conn+connI[cell1]+1,conn+connI[cell1+1]);
 +      std::set<int> s2(conn+connI[cell2]+1,conn+connI[cell2+1]);
 +      return s1==s2?1:0;
 +    }
 +  return 0;
 +}
 +
 +/*!
 + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 7.
 + */
 +int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2)
 +{
 +  int sz=connI[cell1+1]-connI[cell1];
 +  if(sz==connI[cell2+1]-connI[cell2])
 +    {
 +      if(conn[connI[cell1]]==conn[connI[cell2]])
 +        {
 +          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]);
 +          unsigned dim=cm.getDimension();
 +          if(dim!=3)
 +            {
 +              if(dim!=1)
 +                {
 +                  int sz1=2*(sz-1);
 +                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz1];
 +                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp);
 +                  std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work);
 +                  work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
 +                  if(work!=tmp+sz1)
 +                    return 1;
 +                  else
 +                    {
 +                      std::reverse_iterator<int *> it1((int *)tmp+sz1);
 +                      std::reverse_iterator<int *> it2((int *)tmp);
 +                      if(std::search(it1,it2,conn+connI[cell2]+1,conn+connI[cell2+1])!=it2)
 +                        return 2;
 +                      else
 +                        return 0;
 +                    }
 +
 +                  return work!=tmp+sz1?1:0;
 +                }
 +              else
 +                {//case of SEG2 and SEG3
 +                  if(std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1))
 +                    return 1;
 +                  if(!cm.isQuadratic())
 +                    {
 +                      std::reverse_iterator<const int *> it1(conn+connI[cell1+1]);
 +                      std::reverse_iterator<const int *> it2(conn+connI[cell1]+1);
 +                      if(std::equal(it1,it2,conn+connI[cell2]+1))
 +                        return 2;
 +                      return 0;
 +                    }
 +                  else
 +                    {
 +                      if(conn[connI[cell1]+1]==conn[connI[cell2]+2] && conn[connI[cell1]+2]==conn[connI[cell2]+1] && conn[connI[cell1]+3]==conn[connI[cell2]+3])
 +                        return 2;
 +                      return 0;
 +                    }
 +                }
 +            }
 +          else
 +            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual7 : not implemented yet for meshdim == 3 !");
 +        }
 +    }
 +  return 0;
 +}
 +
 +/*!
 + * 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 MEDCouplingPointSet::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, const int *conn, const int *connI, DataArrayInt *result)
 +{
 +  if(candidates.size()<1)
 +    return false;
 +  bool ret=false;
 +  std::vector<int>::const_iterator iter=candidates.begin();
 +  int start=(*iter++);
 +  for(;iter!=candidates.end();iter++)
 +    {
 +      int status=AreCellsEqual(conn,connI,start,*iter,compType);
 +      if(status!=0)
 +        {
 +          if(!ret)
 +            {
 +              result->pushBackSilent(start);
 +              ret=true;
 +            }
 +          if(status==1)
 +            result->pushBackSilent(*iter);
 +          else
 +            result->pushBackSilent(status==2?(*iter+1):-(*iter+1));
 +        }
 +    }
 +  return ret;
 +}
 +
 +/*!
 + * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified
 + * by \a compType.
 + * This method keeps the coordiantes of \a this. This method is time consuming.
 + *
 + * \param [in] compType input specifying the technique used to compare cells each other.
 + *   - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy.
 + *   - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation)
 + * and their type equal. For 1D mesh the policy 1 is equivalent to 0.
 + *   - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy
 + * can be used for users not sensitive to orientation of cell
 + * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned.
 + * \param [out] commonCellsArr common cells ids (\ref numbering-indirect)
 + * \param [out] commonCellsIArr common cells ids (\ref numbering-indirect)
 + * \return the correspondance array old to new in a newly allocated array.
 + * 
 + */
 +void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New();
 +  getReverseNodalConnectivity(revNodal,revNodalI);
 +  FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr);
 +}
 +
 +void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI,
 +                                          DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr)
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCells=DataArrayInt::New(),commonCellsI=DataArrayInt::New(); commonCells->alloc(0,1);
 +  int nbOfCells=nodalI->getNumberOfTuples()-1;
 +  commonCellsI->reserve(1); commonCellsI->pushBackSilent(0);
 +  const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer();
 +  const int *connPtr=nodal->getConstPointer(),*connIPtr=nodalI->getConstPointer();
 +  std::vector<bool> isFetched(nbOfCells,false);
 +  if(startCellId==0)
 +    {
 +      for(int i=0;i<nbOfCells;i++)
 +        {
 +          if(!isFetched[i])
 +            {
 +              const int *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<int>(),-1));
 +              std::vector<int> v,v2;
 +              if(connOfNode!=connPtr+connIPtr[i+1])
 +                {
 +                  const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i);
 +                  v2.insert(v2.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1]);
 +                  connOfNode++;
 +                }
 +              for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++)
 +                if(*connOfNode>=0)
 +                  {
 +                    v=v2;
 +                    const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i);
 +                    std::vector<int>::iterator it=std::set_intersection(v.begin(),v.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin());
 +                    v2.resize(std::distance(v2.begin(),it));
 +                  }
 +              if(v2.size()>1)
 +                {
 +                  if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells))
 +                    {
 +                      int pos=commonCellsI->back();
 +                      commonCellsI->pushBackSilent(commonCells->getNumberOfTuples());
 +                      for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++)
 +                        isFetched[*it]=true;
 +                    }
 +                }
 +            }
 +        }
 +    }
 +  else
 +    {
 +      for(int i=startCellId;i<nbOfCells;i++)
 +        {
 +          if(!isFetched[i])
 +            {
 +              const int *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<int>(),-1));
 +              std::vector<int> v,v2;
 +              if(connOfNode!=connPtr+connIPtr[i+1])
 +                {
 +                  v2.insert(v2.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1]);
 +                  connOfNode++;
 +                }
 +              for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++)
 +                if(*connOfNode>=0)
 +                  {
 +                    v=v2;
 +                    std::vector<int>::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin());
 +                    v2.resize(std::distance(v2.begin(),it));
 +                  }
 +              if(v2.size()>1)
 +                {
 +                  if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells))
 +                    {
 +                      int pos=commonCellsI->back();
 +                      commonCellsI->pushBackSilent(commonCells->getNumberOfTuples());
 +                      for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++)
 +                        isFetched[*it]=true;
 +                    }
 +                }
 +            }
 +        }
 +    }
 +  commonCellsArr=commonCells.retn();
 +  commonCellsIArr=commonCellsI.retn();
 +}
 +
 +/*!
 + * Checks if \a this mesh includes all cells of an \a other mesh, and returns an array
 + * giving for each cell of the \a other an id of a cell in \a this mesh. A value larger
 + * than \a other->getNumberOfCells() in the returned array means that there is no
 + * corresponding cell in \a this mesh.
 + * It is expected that \a this and \a other meshes share the same node coordinates
 + * array, if it is not so an exception is thrown. 
 + *  \param [in] other - the mesh to compare with.
 + *  \param [in] compType - specifies a cell comparison technique. For meaning of its
 + *         valid values [0,1,2], see zipConnectivityTraducer().
 + *  \param [out] arr - a new instance of DataArrayInt returning correspondence
 + *         between cells of the two meshes. It contains \a other->getNumberOfCells()
 + *         values. The caller is to delete this array using
 + *         decrRef() as it is no more needed.
 + *  \return bool - \c true if all cells of \a other mesh are present in the \a this
 + *         mesh.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_areCellsIncludedIn "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_areCellsIncludedIn "Here is a Python example".
 + *  \endif
 + *  \sa checkDeepEquivalOnSameNodesWith()
 + *  \sa checkGeoEquivalWith()
 + */
 +bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
 +  int nbOfCells=getNumberOfCells();
 +  static const int possibleCompType[]={0,1,2};
 +  if(std::find(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),compType)==possibleCompType+sizeof(possibleCompType)/sizeof(int))
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::areCellsIncludedIn : only following policies are possible : ";
 +      std::copy(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),std::ostream_iterator<int>(oss," "));
 +      oss << " !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=mesh->zipConnectivityTraducer(compType,nbOfCells);
 +  arr=o2n->substr(nbOfCells);
 +  arr->setName(other->getName());
 +  int tmp;
 +  if(other->getNumberOfCells()==0)
 +    return true;
 +  return arr->getMaxValue(tmp)<nbOfCells;
 +}
 +
 +/*!
 + * This method makes the assumption that \a this and \a other share the same coords. If not an exception will be thrown !
 + * This method tries to determine if \b other is fully included in \b this.
 + * The main difference is that this method is not expected to throw exception.
 + * This method has two outputs :
 + *
 + * \param other other mesh
 + * \param arr is an output parameter that returns a \b newly created instance. This array is of size 'other->getNumberOfCells()'.
 + * \return If \a other is fully included in 'this 'true is returned. If not false is returned.
 + */
 +bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
 +  DataArrayInt *commonCells=0,*commonCellsI=0;
 +  int thisNbCells=getNumberOfCells();
 +  mesh->findCommonCells(7,thisNbCells,commonCells,commonCellsI);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
 +  const int *commonCellsPtr=commonCells->getConstPointer(),*commonCellsIPtr=commonCellsI->getConstPointer();
 +  int otherNbCells=other->getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=DataArrayInt::New();
 +  arr2->alloc(otherNbCells,1);
 +  arr2->fillWithZero();
 +  int *arr2Ptr=arr2->getPointer();
 +  int nbOfCommon=commonCellsI->getNumberOfTuples()-1;
 +  for(int i=0;i<nbOfCommon;i++)
 +    {
 +      int start=commonCellsPtr[commonCellsIPtr[i]];
 +      if(start<thisNbCells)
 +        {
 +          for(int j=commonCellsIPtr[i]+1;j!=commonCellsIPtr[i+1];j++)
 +            {
 +              int sig=commonCellsPtr[j]>0?1:-1;
 +              int val=std::abs(commonCellsPtr[j])-1;
 +              if(val>=thisNbCells)
 +                arr2Ptr[val-thisNbCells]=sig*(start+1);
 +            }
 +        }
 +    }
 +  arr2->setName(other->getName());
 +  if(arr2->presenceOfValue(0))
 +    return false;
 +  arr=arr2.retn();
 +  return true;
 +}
 +
 +MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
 +{
 +  if(!other)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : input other is null !");
 +  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
 +  if(!otherC)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type unstructured !");
 +  std::vector<const MEDCouplingUMesh *> ms(2);
 +  ms[0]=this;
 +  ms[1]=otherC;
 +  return MergeUMeshesOnSameCoords(ms);
 +}
 +
 +/*!
 + * Build a sub part of \b this lying or not on the same coordinates than \b this (regarding value of \b keepCoords).
 + * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input
 + * cellIds is not given explicitely but by a range python like.
 + * 
 + * \param start
 + * \param end
 + * \param step
 + * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called.
 + * \return a newly allocated
 + * 
 + * \warning This method modifies can generate an unstructured mesh whose cells are not sorted by geometric type order.
 + * In view of the MED file writing, a renumbering of cells of returned unstructured mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
 + */
 +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const
 +{
 +  if(getMeshDimension()!=-1)
 +    return MEDCouplingPointSet::buildPartOfMySelf2(start,end,step,keepCoords);
 +  else
 +    {
 +      int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh ");
 +      if(newNbOfCells!=1)
 +        throw INTERP_KERNEL::Exception("-1D mesh has only one cell !");
 +      if(start!=0)
 +        throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !");
 +      incrRef();
 +      return const_cast<MEDCouplingUMesh *>(this);
 +    }
 +}
 +
 +/*!
 + * Creates a new MEDCouplingUMesh containing specified cells of \a this mesh.
 + * The result mesh shares or not the node coordinates array with \a this mesh depending
 + * on \a keepCoords parameter.
 + *  \warning Cells of the result mesh can be \b not sorted by geometric type, hence,
 + *           to write this mesh to the MED file, its cells must be sorted using
 + *           sortCellsInMEDFileFrmt().
 + *  \param [in] begin - an array of cell ids to include to the new mesh.
 + *  \param [in] end - a pointer to last-plus-one-th element of \a begin.
 + *  \param [in] keepCoords - if \c true, the result mesh shares the node coordinates
 + *         array of \a this mesh, else "free" nodes are removed from the result mesh
 + *         by calling zipCoords().
 + *  \return MEDCouplingPointSet * - a new instance of MEDCouplingUMesh. The caller is
 + *         to delete this mesh using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If any cell id in the array \a begin is not valid.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_buildPartOfMySelf "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_buildPartOfMySelf "Here is a Python example".
 + *  \endif
 + */
 +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const
 +{
 +  if(getMeshDimension()!=-1)
 +    return MEDCouplingPointSet::buildPartOfMySelf(begin,end,keepCoords);
 +  else
 +    {
 +      if(end-begin!=1)
 +        throw INTERP_KERNEL::Exception("-1D mesh has only one cell !");
 +      if(begin[0]!=0)
 +        throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !");
 +      incrRef();
 +      return const_cast<MEDCouplingUMesh *>(this);
 +    }
 +}
 +
 +/*!
 + * This method operates only on nodal connectivity on \b this. Coordinates of \b this is completely ignored here.
 + *
 + * This method allows to partially modify some cells in \b this (whose list is specified by [ \b cellIdsBg, \b cellIdsEnd ) ) with cells coming in \b otherOnSameCoordsThanThis.
 + * Size of [ \b cellIdsBg, \b cellIdsEnd ) ) must be equal to the number of cells of otherOnSameCoordsThanThis.
 + * The number of cells of \b this will remain the same with this method.
 + *
 + * \param [in] cellIdsBg begin of cell ids (included) of cells in this to assign
 + * \param [in] cellIdsEnd end of cell ids (excluded) of cells in this to assign
 + * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd ).
 + *             Coordinate pointer of \b this and those of \b otherOnSameCoordsThanThis must be the same
 + */
 +void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis)
 +{
 +  checkConnectivityFullyDefined();
 +  otherOnSameCoordsThanThis.checkConnectivityFullyDefined();
 +  if(getCoords()!=otherOnSameCoordsThanThis.getCoords())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !");
 +  if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension())
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : Mismatch of meshdimensions ! this is equal to " << getMeshDimension();
 +      oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  int nbOfCellsToModify=(int)std::distance(cellIdsBg,cellIdsEnd);
 +  if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells())
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : cells ids length (" <<  nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  int nbOfCells=getNumberOfCells();
 +  bool easyAssign=true;
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer();
 +  for(const int *it=cellIdsBg;it!=cellIdsEnd && easyAssign;it++,connIOther++)
 +    {
 +      if(*it>=0 && *it<nbOfCells)
 +        {
 +          easyAssign=(connIOther[1]-connIOther[0])==(connI[*it+1]-connI[*it]);
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : On pos #" << std::distance(cellIdsBg,it) << " id is equal to " << *it << " which is not in [0," << nbOfCells << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  if(easyAssign)
 +    {
 +      MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index);
 +      computeTypes();
 +    }
 +  else
 +    {
 +      DataArrayInt *arrOut=0,*arrIOut=0;
 +      MEDCouplingUMesh::SetPartOfIndexedArrays(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index,
 +                                               arrOut,arrIOut);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrOutAuto(arrOut),arrIOutAuto(arrIOut);
 +      setConnectivity(arrOut,arrIOut,true);
 +    }
 +}
 +
 +void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis)
 +{
 +  checkConnectivityFullyDefined();
 +  otherOnSameCoordsThanThis.checkConnectivityFullyDefined();
 +  if(getCoords()!=otherOnSameCoordsThanThis.getCoords())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf2 : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !");
 +  if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension())
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : Mismatch of meshdimensions ! this is equal to " << getMeshDimension();
 +      oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  int nbOfCellsToModify=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::setPartOfMySelf2 : ");
 +  if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells())
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : cells ids length (" <<  nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  int nbOfCells=getNumberOfCells();
 +  bool easyAssign=true;
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer();
 +  int it=start;
 +  for(int i=0;i<nbOfCellsToModify && easyAssign;i++,it+=step,connIOther++)
 +    {
 +      if(it>=0 && it<nbOfCells)
 +        {
 +          easyAssign=(connIOther[1]-connIOther[0])==(connI[it+1]-connI[it]);
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : On pos #" << i << " id is equal to " << it << " which is not in [0," << nbOfCells << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  if(easyAssign)
 +    {
 +      MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index);
 +      computeTypes();
 +    }
 +  else
 +    {
 +      DataArrayInt *arrOut=0,*arrIOut=0;
 +      MEDCouplingUMesh::SetPartOfIndexedArrays2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index,
 +                                                arrOut,arrIOut);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrOutAuto(arrOut),arrIOutAuto(arrIOut);
 +      setConnectivity(arrOut,arrIOut,true);
 +    }
 +}                      
 +
 +/*!
 + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ).
 + * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
 + * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
 + * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept.
 + *
 + * \param [in] begin input start of array of node ids.
 + * \param [in] end input end of array of node ids.
 + * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in.
 + * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
 + */
 +void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
 +  checkConnectivityFullyDefined();
 +  int tmp=-1;
 +  int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1;
 +  std::vector<bool> fastFinder(sz,false);
 +  for(const int *work=begin;work!=end;work++)
 +    if(*work>=0 && *work<sz)
 +      fastFinder[*work]=true;
 +  int nbOfCells=getNumberOfCells();
 +  const int *conn=getNodalConnectivity()->getConstPointer();
 +  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      int ref=0,nbOfHit=0;
 +      for(const int *work2=conn+connIndex[i]+1;work2!=conn+connIndex[i+1];work2++)
 +        if(*work2>=0)
 +          {
 +            ref++;
 +            if(fastFinder[*work2])
 +              nbOfHit++;
 +          }
 +      if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
 +        cellIdsKept->pushBackSilent(i);
 +    }
 +  cellIdsKeptArr=cellIdsKept.retn();
 +}
 +
 +/*!
 + * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a
 + * this->getMeshDimension(), that bound some cells of \a this mesh.
 + * The cells of lower dimension to include to the result mesh are selected basing on
 + * specified node ids and the value of \a fullyIn parameter. If \a fullyIn ==\c true, a
 + * cell is copied if its all nodes are in the array \a begin of node ids. If \a fullyIn
 + * ==\c false, a cell is copied if any its node is in the array of node ids. The
 + * created mesh shares the node coordinates array with \a this mesh. 
 + *  \param [in] begin - the array of node ids.
 + *  \param [in] end - a pointer to the (last+1)-th element of \a begin.
 + *  \param [in] fullyIn - if \c true, then cells whose all nodes are in the
 + *         array \a begin are added, else cells whose any node is in the
 + *         array \a begin are added.
 + *  \return MEDCouplingPointSet * - new instance of MEDCouplingUMesh. The caller is
 + *         to delete this mesh using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If any node id in \a begin is not valid.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_buildFacePartOfMySelfNode "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_buildFacePartOfMySelfNode "Here is a Python example".
 + *  \endif
 + */
 +MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc,descIndx,revDesc,revDescIndx;
 +  desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
 +  desc=0; descIndx=0; revDesc=0; revDescIndx=0;
 +  return subMesh->buildPartOfMySelfNode(begin,end,fullyIn);
 +}
 +
 +/*!
 + * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a
 + * this->getMeshDimension(), which bound only one cell of \a this mesh.
 + *  \param [in] keepCoords - if \c true, the result mesh shares the node coordinates
 + *         array of \a this mesh, else "free" nodes are removed from the result mesh
 + *         by calling zipCoords().
 + *  \return MEDCouplingPointSet * - a new instance of MEDCouplingUMesh. The caller is
 + *         to delete this mesh using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_buildBoundaryMesh "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_buildBoundaryMesh "Here is a Python example".
 + *  \endif
 + */
 +MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const
 +{
 +  DataArrayInt *desc=DataArrayInt::New();
 +  DataArrayInt *descIndx=DataArrayInt::New();
 +  DataArrayInt *revDesc=DataArrayInt::New();
 +  DataArrayInt *revDescIndx=DataArrayInt::New();
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
 +  revDesc->decrRef();
 +  desc->decrRef();
 +  descIndx->decrRef();
 +  int nbOfCells=meshDM1->getNumberOfCells();
 +  const int *revDescIndxC=revDescIndx->getConstPointer();
 +  std::vector<int> boundaryCells;
 +  for(int i=0;i<nbOfCells;i++)
 +    if(revDescIndxC[i+1]-revDescIndxC[i]==1)
 +      boundaryCells.push_back(i);
 +  revDescIndx->decrRef();
 +  MEDCouplingPointSet *ret=meshDM1->buildPartOfMySelf(&boundaryCells[0],&boundaryCells[0]+boundaryCells.size(),keepCoords);
 +  return ret;
 +}
 +
 +/*!
 + * This method returns a newly created DataArrayInt instance containing ids of cells located in boundary.
 + * A cell is detected to be on boundary if it contains one or more than one face having only one father.
 + * This method makes the assumption that \a this is fully defined (coords,connectivity). If not an exception will be thrown. 
 + */
 +DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const
 +{
 +  checkFullyDefined();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New();
 +  //
 +  buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx)->decrRef();
 +  desc=(DataArrayInt*)0; descIndx=(DataArrayInt*)0;
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=revDescIndx->deltaShiftIndex();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faceIds=tmp->getIdsEqual(1); tmp=(DataArrayInt*)0;
 +  const int *revDescPtr=revDesc->getConstPointer();
 +  const int *revDescIndxPtr=revDescIndx->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  std::vector<bool> ret1(nbOfCells,false);
 +  int sz=0;
 +  for(const int *pt=faceIds->begin();pt!=faceIds->end();pt++)
 +    if(!ret1[revDescPtr[revDescIndxPtr[*pt]]])
 +      { ret1[revDescPtr[revDescIndxPtr[*pt]]]=true; sz++; }
 +  //
 +  DataArrayInt *ret2=DataArrayInt::New();
 +  ret2->alloc(sz,1);
 +  int *ret2Ptr=ret2->getPointer();
 +  sz=0;
 +  for(std::vector<bool>::const_iterator it=ret1.begin();it!=ret1.end();it++,sz++)
 +    if(*it)
 +      *ret2Ptr++=sz;
 +  ret2->setName("BoundaryCells");
 +  return ret2;
 +}
 +
 +/*!
 + * This method finds in \b this the cell ids that lie on mesh \b otherDimM1OnSameCoords.
 + * \b this and \b otherDimM1OnSameCoords have to lie on the same coordinate array pointer. The coherency of that coords array with connectivity
 + * of \b this and \b otherDimM1OnSameCoords is not important here because this method works only on connectivity.
 + * this->getMeshDimension() - 1 must be equal to otherDimM1OnSameCoords.getMeshDimension()
 + *
 + * s0 is the cell ids set in \b this lying on at least one node in the fetched nodes in \b otherDimM1OnSameCoords.
 + * This method also returns the cells ids set s1 which contains the cell ids in \b this for which one of the dim-1 constituent
 + * equals a cell in \b otherDimM1OnSameCoords.
 + *
 + * \throw if \b otherDimM1OnSameCoords is not part of constituent of \b this, or if coordinate pointer of \b this and \b otherDimM1OnSameCoords
 + *        are not same, or if this->getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension()
 + *
 + * \param [in] otherDimM1OnSameCoords
 + * \param [out] cellIdsRk0 a newly allocated array containing the cell ids of s0 (which are cell ids of \b this) in the above algorithm.
 + * \param [out] cellIdsRk1 a newly allocated array containing the cell ids of s1 \b indexed into the \b cellIdsRk0 subset. To get the absolute ids of s1, simply invoke
 + *              cellIdsRk1->transformWithIndArr(cellIdsRk0->begin(),cellIdsRk0->end());
 + */
 +void MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const
 +{
 +  if(getCoords()!=otherDimM1OnSameCoords.getCoords())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : coordinates pointer are not the same ! Use tryToShareSameCoords method !");
 +  checkConnectivityFullyDefined();
 +  otherDimM1OnSameCoords.checkConnectivityFullyDefined();
 +  if(getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : invalid mesh dimension of input mesh regarding meshdimesion of this !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fetchedNodeIds1=otherDimM1OnSameCoords.computeFetchedNodeIds();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s0arr=getCellIdsLyingOnNodes(fetchedNodeIds1->begin(),fetchedNodeIds1->end(),false);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisPart=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(s0arr->begin(),s0arr->end(),true));
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descThisPart=DataArrayInt::New(),descIThisPart=DataArrayInt::New(),revDescThisPart=DataArrayInt::New(),revDescIThisPart=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisPartConsti=thisPart->buildDescendingConnectivity(descThisPart,descIThisPart,revDescThisPart,revDescIThisPart);
 +  const int *revDescThisPartPtr=revDescThisPart->getConstPointer(),*revDescIThisPartPtr=revDescIThisPart->getConstPointer();
 +  DataArrayInt *idsOtherInConsti=0;
 +  bool b=thisPartConsti->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsOtherInConsti);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsOtherInConstiAuto(idsOtherInConsti);
 +  if(!b)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : the given mdim-1 mesh in other is not a constituent of this !");
 +  std::set<int> s1;
 +  for(const int *idOther=idsOtherInConsti->begin();idOther!=idsOtherInConsti->end();idOther++)
 +    s1.insert(revDescThisPartPtr+revDescIThisPartPtr[*idOther],revDescThisPartPtr+revDescIThisPartPtr[*idOther+1]);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s1arr_renum1=DataArrayInt::New(); s1arr_renum1->alloc((int)s1.size(),1); std::copy(s1.begin(),s1.end(),s1arr_renum1->getPointer());
 +  s1arr_renum1->sort();
 +  cellIdsRk0=s0arr.retn();
 +  //cellIdsRk1=s_renum1.retn();
 +  cellIdsRk1=s1arr_renum1.retn();
 +}
 +
 +/*!
 + * This method computes the skin of \b this. That is to say the consituting meshdim-1 mesh is built and only the boundary subpart is
 + * returned. This subpart of meshdim-1 mesh is built using meshdim-1 cells in it shared only one cell in \b this.
 + * 
 + * \return a newly allocated mesh lying on the same coordinates than \b this. The caller has to deal with returned mesh.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::computeSkin() const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New();
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
 +  revDesc=0; desc=0; descIndx=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx2=revDescIndx->deltaShiftIndex();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=revDescIndx2->getIdsEqual(1);
 +  return static_cast<MEDCouplingUMesh *>(meshDM1->buildPartOfMySelf(part->begin(),part->end(),true));
 +}
 +
 +/*!
 + * Finds nodes lying on the boundary of \a this mesh.
 + *  \return DataArrayInt * - a new instance of DataArrayInt holding ids of found
 + *          nodes. The caller is to delete this array using decrRef() as it is no
 + *          more needed.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is node defined.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_findBoundaryNodes "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_findBoundaryNodes "Here is a Python example".
 + *  \endif
 + */
 +DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> skin=computeSkin();
 +  return skin->computeFetchedNodeIds();
 +}
 +
 +MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const
 +{
 +  incrRef();
 +  return const_cast<MEDCouplingUMesh *>(this);
 +}
 +
 +/*!
 + * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array.
 + * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1.
 + * This method searches for nodes needed to be duplicated. These nodes are nodes fetched by \b otherDimM1OnSameCoords which are not part of the boundary of \b otherDimM1OnSameCoords.
 + * If a node is in the boundary of \b this \b and in the boundary of \b otherDimM1OnSameCoords this node is considerd as needed to be duplicated.
 + * When the set of node ids \b nodeIdsToDuplicate is computed, cell ids in \b this is searched so that their connectivity includes at least 1 node in \b nodeIdsToDuplicate.
 + *
 + * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input
 + *             parameter is altered during the call.
 + * \param [out] nodeIdsToDuplicate node ids needed to be duplicated following the algorithm explain above.
 + * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed.
 + * \param [out] cellIdsNotModified cell ids int \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum.
 + *
 + * \warning This method modifies param \b otherDimM1OnSameCoords (for speed reasons).
 + */
 +void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate,
 +                                            DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const
 +{
 +  typedef MEDCouplingAutoRefCountObjectPtr<DataArrayInt> DAInt;
 +
 +  checkFullyDefined();
 +  otherDimM1OnSameCoords.checkFullyDefined();
 +  if(getCoords()!=otherDimM1OnSameCoords.getCoords())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : meshes do not share the same coords array !");
 +  if(otherDimM1OnSameCoords.getMeshDimension()!=getMeshDimension()-1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the mesh given in other parameter must have this->getMeshDimension()-1 !");
 +  DataArrayInt *cellIdsRk0=0,*cellIdsRk1=0;
 +  findCellIdsLyingOn(otherDimM1OnSameCoords,cellIdsRk0,cellIdsRk1);
 +  DAInt cellIdsRk0Auto(cellIdsRk0),cellIdsRk1Auto(cellIdsRk1);
 +  DAInt s0=cellIdsRk1->buildComplement(cellIdsRk0->getNumberOfTuples());
 +  s0->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Part=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(s0->begin(),s0->end(),true));
 +  DAInt s1=m0Part->computeFetchedNodeIds();
 +  DAInt s2=otherDimM1OnSameCoords.computeFetchedNodeIds();
 +  DAInt s3=s2->buildSubstraction(s1);
 +  cellIdsRk1->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end());
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Part2=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(cellIdsRk1->begin(),cellIdsRk1->end(),true));
 +  int nCells2 = m0Part2->getNumberOfCells();
 +  DAInt desc00=DataArrayInt::New(),descI00=DataArrayInt::New(),revDesc00=DataArrayInt::New(),revDescI00=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m01=m0Part2->buildDescendingConnectivity(desc00,descI00,revDesc00,revDescI00);
 +  // Neighbor information of the mesh without considering the crack (serves to count how many connex pieces it is made of)
 +  DataArrayInt *tmp00=0,*tmp11=0;
 +  MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00, tmp00, tmp11);
 +  DAInt neighInit00(tmp00);
 +  DAInt neighIInit00(tmp11);
 +  // Neighbor information of the mesh WITH the crack (some neighbors are removed):
 +  DataArrayInt *idsTmp=0;
 +  bool b=m01->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsTmp);
 +  DAInt ids(idsTmp);
 +  if(!b)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the given mdim-1 mesh in other is not a constituent of this !");
 +  // In the neighbor information remove the connection between high dimension cells and its low level constituents which are part
 +  // of the frontier given in parameter (i.e. the cells of low dimension from the group delimiting the crack):
 +  MEDCouplingUMesh::RemoveIdsFromIndexedArrays(ids->begin(),ids->end(),desc00,descI00);
 +  DataArrayInt *tmp0=0,*tmp1=0;
 +  // Compute the neighbor of each cell in m0Part2, taking into account the broken link above. Two
 +  // cells on either side of the crack (defined by the mesh of low dimension) are not neighbor anymore.
 +  ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00,tmp0,tmp1);
 +  DAInt neigh00(tmp0);
 +  DAInt neighI00(tmp1);
 +
 +  // For each initial connex part of the sub-mesh (or said differently for each independent crack):
 +  int seed = 0, nIter = 0;
 +  int nIterMax = nCells2+1; // Safety net for the loop
 +  DAInt hitCells = DataArrayInt::New(); hitCells->alloc(nCells2);
 +  hitCells->fillWithValue(-1);
 +  DAInt cellsToModifyConn0_torenum = DataArrayInt::New();
 +  cellsToModifyConn0_torenum->alloc(0,1);
 +  while (nIter < nIterMax)
 +    {
 +      DAInt t = hitCells->getIdsEqual(-1);
 +      if (!t->getNumberOfTuples())
 +        break;
 +      // Connex zone without the crack (to compute the next seed really)
 +      int dnu;
 +      DAInt connexCheck = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neighInit00,neighIInit00, -1, dnu);
 +      int cnt = 0;
 +      for (int * ptr = connexCheck->getPointer(); cnt < connexCheck->getNumberOfTuples(); ptr++, cnt++)
 +        hitCells->setIJ(*ptr,0,1);
 +      // Connex zone WITH the crack (to identify cells lying on either part of the crack)
 +      DAInt spreadZone = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neigh00,neighI00, -1, dnu);
 +      cellsToModifyConn0_torenum = DataArrayInt::Aggregate(cellsToModifyConn0_torenum, spreadZone, 0);
 +      // Compute next seed, i.e. a cell in another connex part, which was not covered by the previous iterations
 +      DAInt comple = cellsToModifyConn0_torenum->buildComplement(nCells2);
 +      DAInt nonHitCells = hitCells->getIdsEqual(-1);
 +      DAInt intersec = nonHitCells->buildIntersection(comple);
 +      if (intersec->getNumberOfTuples())
 +        { seed = intersec->getIJ(0,0); }
 +      else
 +        { break; }
 +      nIter++;
 +    }
 +  if (nIter >= nIterMax)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate(): internal error - too many iterations.");
 +
 +  DAInt cellsToModifyConn1_torenum=cellsToModifyConn0_torenum->buildComplement(neighI00->getNumberOfTuples()-1);
 +  cellsToModifyConn0_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end());
 +  cellsToModifyConn1_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end());
 +  //
 +  cellIdsNeededToBeRenum=cellsToModifyConn0_torenum.retn();
 +  cellIdsNotModified=cellsToModifyConn1_torenum.retn();
 +  nodeIdsToDuplicate=s3.retn();
 +}
 +
 +/*!
 + * This method operates a modification of the connectivity and coords in \b this.
 + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this 
 + * its ids will be modified to id this->getNumberOfNodes()+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)).
 + * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be
 + * renumbered. The node id nodeIdsToDuplicateBg[0] will have id this->getNumberOfNodes()+0, node id nodeIdsToDuplicateBg[1] will have id this->getNumberOfNodes()+1,
 + * node id nodeIdsToDuplicateBg[2] will have id this->getNumberOfNodes()+2...
 + * 
 + * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method.
 + * 
 + * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only
 + * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only
 + */
 +void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd)
 +{
 +  int nbOfNodes=getNumberOfNodes();
 +  duplicateNodesInCoords(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd);
 +  duplicateNodesInConn(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,nbOfNodes);
 +}
 +
 +/*!
 + * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
 + * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
 + *
 + * \param [in] offset - specifies the offset to be applied on each element of connectivity.
 + *
 + * \sa renumberNodesInConn
 + */
 +void MEDCouplingUMesh::renumberNodesWithOffsetInConn(int offset)
 +{
 +  checkConnectivityFullyDefined();
 +  int *conn(getNodalConnectivity()->getPointer());
 +  const int *connIndex(getNodalConnectivityIndex()->getConstPointer());
 +  int nbOfCells(getNumberOfCells());
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
 +      {
 +        int& node=conn[iconn];
 +        if(node>=0)//avoid polyhedron separator
 +          {
 +            node+=offset;
 +          }
 +      }
 +  _nodal_connec->declareAsNew();
 +  updateTime();
 +}
 +
 +/*!
 + *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
 + *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
 + *  of a big mesh.
 + */
 +void MEDCouplingUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
 +{
 +  checkConnectivityFullyDefined();
 +  int *conn(getNodalConnectivity()->getPointer());
 +  const int *connIndex(getNodalConnectivityIndex()->getConstPointer());
 +  int nbOfCells(getNumberOfCells());
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
 +      {
 +        int& node=conn[iconn];
 +        if(node>=0)//avoid polyhedron separator
 +          {
 +            INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(node));
 +            if(it!=newNodeNumbersO2N.end())
 +              {
 +                node=(*it).second;
 +              }
 +            else
 +              {
 +                std::ostringstream oss; oss << "MEDCouplingUMesh::renumberNodesInConn(map) : presence in connectivity for cell #" << i << " of node #" << node << " : Not in map !";
 +                throw INTERP_KERNEL::Exception(oss.str().c_str());
 +              }
 +          }
 +      }
 +  _nodal_connec->declareAsNew();
 +  updateTime();
 +}
 +
 +/*!
 + * Changes ids of nodes within the nodal connectivity arrays according to a permutation
 + * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
 + * This method is a generalization of shiftNodeNumbersInConn().
 + *  \warning This method performs no check of validity of new ids. **Use it with care !**
 + *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
 + *         this->getNumberOfNodes(), in "Old to New" mode. 
 + *         See \ref numbering for more info on renumbering modes.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_renumberNodesInConn "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_renumberNodesInConn "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
 +{
 +  checkConnectivityFullyDefined();
 +  int *conn=getNodalConnectivity()->getPointer();
 +  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
 +  int nbOfCells(getNumberOfCells());
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
 +      {
 +        int& node=conn[iconn];
 +        if(node>=0)//avoid polyhedron separator
 +          {
 +            node=newNodeNumbersO2N[node];
 +          }
 +      }
 +  _nodal_connec->declareAsNew();
 +  updateTime();
 +}
 +
 +/*!
 + * This method renumbers nodes \b in \b connectivity \b only \b without \b any \b reference \b to \b coords.
 + * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care !
 + * This method is an specialization of \ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn method".
 + * 
 + * \param [in] delta specifies the shift size applied to nodeId in nodal connectivity in \b this.
 + */
 +void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta)
 +{
 +  checkConnectivityFullyDefined();
 +  int *conn=getNodalConnectivity()->getPointer();
 +  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
 +      {
 +        int& node=conn[iconn];
 +        if(node>=0)//avoid polyhedron separator
 +          {
 +            node+=delta;
 +          }
 +      }
 +  _nodal_connec->declareAsNew();
 +  updateTime();
 +}
 +
 +/*!
 + * This method operates a modification of the connectivity in \b this.
 + * Coordinates are \b NOT considered here and will remain unchanged by this method. this->_coords can ever been null for the needs of this method.
 + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this 
 + * its ids will be modified to id offset+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)).
 + * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be
 + * renumbered. The node id nodeIdsToDuplicateBg[0] will have id offset+0, node id nodeIdsToDuplicateBg[1] will have id offset+1,
 + * node id nodeIdsToDuplicateBg[2] will have id offset+2...
 + * 
 + * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method.
 + * As an another consequense after the call of this method \b this can be transiently non cohrent.
 + * 
 + * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only
 + * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only
 + * \param [in] offset the offset applied to all node ids in connectivity that are in [ \a nodeIdsToDuplicateBg, \a nodeIdsToDuplicateEnd ). 
 + */
 +void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset)
 +{
 +  checkConnectivityFullyDefined();
 +  std::map<int,int> m;
 +  int val=offset;
 +  for(const int *work=nodeIdsToDuplicateBg;work!=nodeIdsToDuplicateEnd;work++,val++)
 +    m[*work]=val;
 +  int *conn=getNodalConnectivity()->getPointer();
 +  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  for(int i=0;i<nbOfCells;i++)
 +    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
 +      {
 +        int& node=conn[iconn];
 +        if(node>=0)//avoid polyhedron separator
 +          {
 +            std::map<int,int>::iterator it=m.find(node);
 +            if(it!=m.end())
 +              node=(*it).second;
 +          }
 +      }
 +  updateTime();
 +}
 +
 +/*!
 + * This method renumbers cells of \a 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 [ \a old2NewBg; \a old2NewEnd ) is unique ; if not
 + * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [ \a old2NewBg ; \a old2NewEnd ) is not expected to
 + * be strictly in [0;this->getNumberOfCells()).
 + *
 + * If 'check' equals false the method will not check the content of [ \a old2NewBg ; \a old2NewEnd ).
 + * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [ \a old2NewBg ; \a old2NewEnd ) should be unique and
 + * should be contained in[0;this->getNumberOfCells()).
 + * 
 + * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells()
 + * \param check
 + */
 +void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check)
 +{
 +  checkConnectivityFullyDefined();
 +  int nbCells=getNumberOfCells();
 +  const int *array=old2NewBg;
 +  if(check)
 +    array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells);
 +  //
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New(); o2n->useArray(array,false,C_DEALLOC,nbCells,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
 +  const int *n2oPtr=n2o->begin();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
 +  newConn->alloc(_nodal_connec->getNumberOfTuples(),_nodal_connec->getNumberOfComponents());
 +  newConn->copyStringInfoFrom(*_nodal_connec);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
 +  newConnI->alloc(_nodal_connec_index->getNumberOfTuples(),_nodal_connec_index->getNumberOfComponents());
 +  newConnI->copyStringInfoFrom(*_nodal_connec_index);
 +  //
 +  int *newC=newConn->getPointer();
 +  int *newCI=newConnI->getPointer();
 +  int loc=0;
 +  newCI[0]=loc;
 +  for(int i=0;i<nbCells;i++)
 +    {
 +      int pos=n2oPtr[i];
 +      int nbOfElts=connI[pos+1]-connI[pos];
 +      newC=std::copy(conn+connI[pos],conn+connI[pos+1],newC);
 +      loc+=nbOfElts;
 +      newCI[i+1]=loc;
 +    }
 +  //
 +  setConnectivity(newConn,newConnI);
 +  if(check)
 +    free(const_cast<int *>(array));
 +}
 +
 +/*!
 + * Finds cells whose bounding boxes intersect a given bounding box.
 + *  \param [in] bbox - an array defining the bounding box via coordinates of its
 + *         extremum points in "no interlace" mode, i.e. xMin, xMax, yMin, yMax, zMin,
 + *         zMax (if in 3D). 
 + *  \param [in] eps - a factor used to increase size of the bounding box of cell
 + *         before comparing it with \a bbox. This factor is multiplied by the maximal
 + *         extent of the bounding box of cell to produce an addition to this bounding box.
 + *  \return DataArrayInt * - a new instance of DataArrayInt holding ids for found
 + *         cells. The caller is to delete this array using decrRef() as it is no more
 + *         needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getCellsInBoundingBox "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getCellsInBoundingBox "Here is a Python example".
 + *  \endif
 + */
 +DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1);
 +  if(getMeshDimension()==-1)
 +    {
 +      elems->pushBackSilent(0);
 +      return elems.retn();
 +    }
 +  int dim=getSpaceDimension();
 +  INTERP_KERNEL::AutoPtr<double> elem_bb=new double[2*dim];
 +  const int* conn      = getNodalConnectivity()->getConstPointer();
 +  const int* conn_index= getNodalConnectivityIndex()->getConstPointer();
 +  const double* coords = getCoords()->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  for ( int ielem=0; ielem<nbOfCells;ielem++ )
 +    {
 +      for (int i=0; i<dim; i++)
 +        {
 +          elem_bb[i*2]=std::numeric_limits<double>::max();
 +          elem_bb[i*2+1]=-std::numeric_limits<double>::max();
 +        }
 +
 +      for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type.
 +        {
 +          int node= conn[inode];
 +          if(node>=0)//avoid polyhedron separator
 +            {
 +              for (int idim=0; idim<dim; idim++)
 +                {
 +                  if ( coords[node*dim+idim] < elem_bb[idim*2] )
 +                    {
 +                      elem_bb[idim*2] = coords[node*dim+idim] ;
 +                    }
 +                  if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
 +                    {
 +                      elem_bb[idim*2+1] = coords[node*dim+idim] ;
 +                    }
 +                }
 +            }
 +        }
 +      if (intersectsBoundingBox(elem_bb, bbox, dim, eps))
 +        elems->pushBackSilent(ielem);
 +    }
 +  return elems.retn();
 +}
 +
 +/*!
 + * Given a boundary box 'bbox' returns elements 'elems' contained in this 'bbox' or touching 'bbox' (within 'eps' distance).
 + * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be
 + * added in 'elems' parameter.
 + */
 +DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1);
 +  if(getMeshDimension()==-1)
 +    {
 +      elems->pushBackSilent(0);
 +      return elems.retn();
 +    }
 +  int dim=getSpaceDimension();
 +  INTERP_KERNEL::AutoPtr<double> elem_bb=new double[2*dim];
 +  const int* conn      = getNodalConnectivity()->getConstPointer();
 +  const int* conn_index= getNodalConnectivityIndex()->getConstPointer();
 +  const double* coords = getCoords()->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  for ( int ielem=0; ielem<nbOfCells;ielem++ )
 +    {
 +      for (int i=0; i<dim; i++)
 +        {
 +          elem_bb[i*2]=std::numeric_limits<double>::max();
 +          elem_bb[i*2+1]=-std::numeric_limits<double>::max();
 +        }
 +
 +      for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type.
 +        {
 +          int node= conn[inode];
 +          if(node>=0)//avoid polyhedron separator
 +            {
 +              for (int idim=0; idim<dim; idim++)
 +                {
 +                  if ( coords[node*dim+idim] < elem_bb[idim*2] )
 +                    {
 +                      elem_bb[idim*2] = coords[node*dim+idim] ;
 +                    }
 +                  if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
 +                    {
 +                      elem_bb[idim*2+1] = coords[node*dim+idim] ;
 +                    }
 +                }
 +            }
 +        }
 +      if(intersectsBoundingBox(bbox, elem_bb, dim, eps))
 +        elems->pushBackSilent(ielem);
 +    }
 +  return elems.retn();
 +}
 +
 +/*!
 + * Returns a type of a cell by its id.
 + *  \param [in] cellId - the id of the cell of interest.
 + *  \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
 + *  \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
 + */
 +INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const
 +{
 +  const int *ptI=_nodal_connec_index->getConstPointer();
 +  const int *pt=_nodal_connec->getConstPointer();
 +  if(cellId>=0 && cellId<(int)_nodal_connec_index->getNbOfElems()-1)
 +    return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]];
 +  else
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << _nodal_connec_index->getNbOfElems()-1 << ") !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +}
 +
 +/*!
 + * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
 + * This method does not throw exception if geometric type \a type is not in \a this.
 + * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
 + * The coordinates array is not considered here.
 + *
 + * \param [in] type the geometric type
 + * \return cell ids in this having geometric type \a type.
 + */
 +DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
 +{
 +
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  ret->alloc(0,1);
 +  checkConnectivityFullyDefined();
 +  int nbCells=getNumberOfCells();
 +  int mdim=getMeshDimension();
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
 +  if(mdim!=(int)cm.getDimension())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::giveCellsWithType : Mismatch between mesh dimension and dimension of the cell !");
 +  const int *ptI=_nodal_connec_index->getConstPointer();
 +  const int *pt=_nodal_connec->getConstPointer();
 +  for(int i=0;i<nbCells;i++)
 +    {
 +      if((INTERP_KERNEL::NormalizedCellType)pt[ptI[i]]==type)
 +        ret->pushBackSilent(i);
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a 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;
 +}
 +
 +/*!
 + * Returns the nodal connectivity of a given cell.
 + * The separator of faces within polyhedron connectivity (-1) is not returned, thus
 + * all returned node ids can be used in getCoordinatesOfNode().
 + *  \param [in] cellId - an id of the cell of interest.
 + *  \param [in,out] conn - a vector where the node ids are appended. It is not
 + *         cleared before the appending.
 + *  \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
 + */
 +void MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
 +{
 +  const int *ptI=_nodal_connec_index->getConstPointer();
 +  const int *pt=_nodal_connec->getConstPointer();
 +  for(const int *w=pt+ptI[cellId]+1;w!=pt+ptI[cellId+1];w++)
 +    if(*w>=0)
 +      conn.push_back(*w);
 +}
 +
 +std::string MEDCouplingUMesh::simpleRepr() const
 +{
 +  static const char msg0[]="No coordinates specified !";
 +  std::ostringstream ret;
 +  ret << "Unstructured mesh with name : \"" << getName() << "\"\n";
 +  ret << "Description of mesh : \"" << getDescription() << "\"\n";
 +  int tmpp1,tmpp2;
 +  double tt=getTime(tmpp1,tmpp2);
 +  ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
 +  ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
 +  if(_mesh_dim>=-1)
 +    { ret << "Mesh dimension : " << _mesh_dim << "\nSpace dimension : "; }
 +  else
 +    { ret << " Mesh dimension has not been set or is invalid !"; }
 +  if(_coords!=0)
 +    {
 +      const int spaceDim=getSpaceDimension();
 +      ret << spaceDim << "\nInfo attached on space dimension : ";
 +      for(int i=0;i<spaceDim;i++)
 +        ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
 +      ret << "\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();
 +}
 +
 +/*!
 + * This method returns a C++ code that is a dump of \a this.
 + * This method will throw if this is not fully defined.
 + */
 +std::string MEDCouplingUMesh::cppRepr() const
 +{
 +  static const char coordsName[]="coords";
 +  static const char connName[]="conn";
 +  static const char connIName[]="connI";
 +  checkFullyDefined();
 +  std::ostringstream ret; ret << "// coordinates" << std::endl;
 +  _coords->reprCppStream(coordsName,ret); ret << std::endl << "// connectivity" << std::endl;
 +  _nodal_connec->reprCppStream(connName,ret); ret << std::endl;
 +  _nodal_connec_index->reprCppStream(connIName,ret); ret << std::endl;
 +  ret << "MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(\"" << getName() << "\"," << getMeshDimension() << ");" << std::endl;
 +  ret << "mesh->setCoords(" << coordsName << ");" << std::endl;
 +  ret << "mesh->setConnectivity(" << connName << "," << connIName << ",true);" << std::endl;
 +  ret << coordsName << "->decrRef(); " << connName << "->decrRef(); " << connIName << "->decrRef();" << std::endl;
 +  return ret.str();
 +}
 +
 +std::string MEDCouplingUMesh::reprConnectivityOfThis() const
 +{
 +  std::ostringstream ret;
 +  reprConnectivityOfThisLL(ret);
 +  return ret.str();
 +}
 +
 +/*!
 + * This method builds a newly allocated instance (with the same name than \a this) that the caller has the responsability to deal with.
 + * This method returns an instance with all arrays allocated (connectivity, connectivity index, coordinates)
 + * but with length of these arrays set to 0. It allows to define an "empty" mesh (with nor cells nor nodes but compliant with
 + * some algos).
 + * 
 + * This method expects that \a this has a mesh dimension set and higher or equal to 0. If not an exception will be thrown.
 + * This method analyzes the 3 arrays of \a this. For each the following behaviour is done : if the array is null a newly one is created
 + * with number of tuples set to 0, if not the array is taken as this in the returned instance.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const
 +{
 +  int mdim=getMeshDimension();
 +  if(mdim<0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSetInstanceFromThis : invalid mesh dimension ! Should be >= 0 !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
 +  bool needToCpyCT=true;
 +  if(!_nodal_connec)
 +    {
 +      tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
 +      needToCpyCT=false;
 +    }
 +  else
 +    {
 +      tmp1=_nodal_connec;
 +      tmp1->incrRef();
 +    }
 +  if(!_nodal_connec_index)
 +    {
 +      tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
 +      needToCpyCT=false;
 +    }
 +  else
 +    {
 +      tmp2=_nodal_connec_index;
 +      tmp2->incrRef();
 +    }
 +  ret->setConnectivity(tmp1,tmp2,false);
 +  if(needToCpyCT)
 +    ret->_types=_types;
 +  if(!_coords)
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
 +      ret->setCoords(coords);
 +    }
 +  else
 +    ret->setCoords(_coords);
 +  return ret.retn();
 +}
 +
 +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();
 +  const int *pt=_nodal_connec->getConstPointer();
 +  if(pt[ptI[cellId]]!=INTERP_KERNEL::NORM_POLYHED)
 +    return ptI[cellId+1]-ptI[cellId]-1;
 +  else
 +    return (int)std::count_if(pt+ptI[cellId]+1,pt+ptI[cellId+1],std::bind2nd(std::not_equal_to<int>(),-1));
 +}
 +
 +/*!
 + * Returns types of cells of the specified part of \a this mesh.
 + * This method avoids computing sub-mesh explicitely to get its types.
 + *  \param [in] begin - an array of cell ids of interest.
 + *  \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element.
 + *  \return std::set<INTERP_KERNEL::NormalizedCellType> - a set of enumeration items
 + *         describing the cell types. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \sa getAllGeoTypes()
 + */
 +std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const
 +{
 +  checkFullyDefined();
 +  std::set<INTERP_KERNEL::NormalizedCellType> ret;
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  for(const int *w=begin;w!=end;w++)
 +    ret.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]);
 +  return ret;
 +}
 +
 +/*!
 + * Defines the nodal connectivity using given connectivity arrays in \ref numbering-indirect format.
 + * Optionally updates
 + * a set of types of cells constituting \a this mesh. 
 + * This method is for advanced users having prepared their connectivity before. For
 + * more info on using this method see \ref MEDCouplingUMeshAdvBuild.
 + *  \param [in] conn - the nodal connectivity array. 
 + *  \param [in] connIndex - the nodal connectivity index array.
 + *  \param [in] isComputingTypes - if \c true, the set of types constituting \a this
 + *         mesh is updated.
 + */
 +void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes)
 +{
 +  DataArrayInt::SetArrayIn(conn,_nodal_connec);
 +  DataArrayInt::SetArrayIn(connIndex,_nodal_connec_index);
 +  if(isComputingTypes)
 +    computeTypes();
 +  declareAsNew();
 +}
 +
 +/*!
 + * Copy constructor. If 'deepCpy' is false \a this is a shallow copy of other.
 + * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied.
 + */
 +MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_mesh_dim(other._mesh_dim),
 +    _nodal_connec(0),_nodal_connec_index(0),
 +    _types(other._types)
 +{
 +  if(other._nodal_connec)
 +    _nodal_connec=other._nodal_connec->performCpy(deepCopy);
 +  if(other._nodal_connec_index)
 +    _nodal_connec_index=other._nodal_connec_index->performCpy(deepCopy);
 +}
 +
 +MEDCouplingUMesh::~MEDCouplingUMesh()
 +{
 +  if(_nodal_connec)
 +    _nodal_connec->decrRef();
 +  if(_nodal_connec_index)
 +    _nodal_connec_index->decrRef();
 +}
 +
 +/*!
 + * Recomputes a set of cell types of \a this mesh. For more info see
 + * \ref MEDCouplingUMeshNodalConnectivity.
 + */
 +void MEDCouplingUMesh::computeTypes()
 +{
 +  ComputeAllTypesInternal(_types,_nodal_connec,_nodal_connec_index);
 +}
 +
 +/*!
 + * This method checks that all arrays are set. If yes nothing done if no an exception is thrown.
 + */
 +void MEDCouplingUMesh::checkFullyDefined() const
 +{
 +  if(!_nodal_connec_index || !_nodal_connec || !_coords)
 +    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity and coordinates set in unstructured mesh.");
 +}
 +
 +/*!
 + * This method checks that all connectivity arrays are set. If yes nothing done if no an exception is thrown.
 + */
 +void MEDCouplingUMesh::checkConnectivityFullyDefined() const
 +{
 +  if(!_nodal_connec_index || !_nodal_connec)
 +    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity set in unstructured mesh.");
 +}
 +
 +/*!
 + * Returns a number of cells constituting \a this mesh. 
 + *  \return int - the number of cells in \a this mesh.
 + *  \throw If the nodal connectivity of cells is not defined.
 + */
 +int MEDCouplingUMesh::getNumberOfCells() const
 +{ 
 +  if(_nodal_connec_index)
 +    return _nodal_connec_index->getNumberOfTuples()-1;
 +  else
 +    if(_mesh_dim==-1)
 +      return 1;
 +    else
 +      throw INTERP_KERNEL::Exception("Unable to get number of cells because no connectivity specified !");
 +}
 +
 +/*!
 + * Returns a dimension of \a this mesh, i.e. a dimension of cells constituting \a this
 + * mesh. For more info see \ref meshes.
 + *  \return int - the dimension of \a this mesh.
 + *  \throw If the mesh dimension is not defined using setMeshDimension().
 + */
 +int MEDCouplingUMesh::getMeshDimension() const
 +{
 +  if(_mesh_dim<-1)
 +    throw INTERP_KERNEL::Exception("No mesh dimension specified !");
 +  return _mesh_dim;
 +}
 +
 +/*!
 + * Returns a length of the nodal connectivity array.
 + * This method is for test reason. Normally the integer returned is not useable by
 + * user.  For more info see \ref MEDCouplingUMeshNodalConnectivity.
 + *  \return int - the length of the nodal connectivity array.
 + */
 +int MEDCouplingUMesh::getMeshLength() const
 +{
 +  return _nodal_connec->getNbOfElems();
 +}
 +
 +/*!
 + * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process.
 + */
 +void MEDCouplingUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
 +{
 +  MEDCouplingPointSet::getTinySerializationInformation(tinyInfoD,tinyInfo,littleStrings);
 +  tinyInfo.push_back(getMeshDimension());
 +  tinyInfo.push_back(getNumberOfCells());
 +  if(_nodal_connec)
 +    tinyInfo.push_back(getMeshLength());
 +  else
 +    tinyInfo.push_back(-1);
 +}
 +
 +/*!
 + * First step of unserialization process.
 + */
 +bool MEDCouplingUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
 +{
 +  return tinyInfo[6]<=0;
 +}
 +
 +/*!
 + * Second step of serialization process.
 + * \param tinyInfo must be equal to the result given by getTinySerializationInformation method.
 + * \param a1
 + * \param a2
 + * \param 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)
 +    a1->alloc(tinyInfo[7]+tinyInfo[6]+1,1);
 +}
 +
 +/*!
 + * Third and final step of serialization process.
 + */
 +void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
 +{
 +  MEDCouplingPointSet::serialize(a1,a2);
 +  if(getMeshDimension()>-1)
 +    {
 +      a1=DataArrayInt::New();
 +      a1->alloc(getMeshLength()+getNumberOfCells()+1,1);
 +      int *ptA1=a1->getPointer();
 +      const int *conn=getNodalConnectivity()->getConstPointer();
 +      const int *index=getNodalConnectivityIndex()->getConstPointer();
 +      ptA1=std::copy(index,index+getNumberOfCells()+1,ptA1);
 +      std::copy(conn,conn+getMeshLength(),ptA1);
 +    }
 +  else
 +    a1=0;
 +}
 +
 +/*!
 + * Second and final unserialization process.
 + * \param tinyInfo must be equal to the result given by getTinySerializationInformation method.
 + */
 +void MEDCouplingUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
 +{
 +  MEDCouplingPointSet::unserialization(tinyInfoD,tinyInfo,a1,a2,littleStrings);
 +  setMeshDimension(tinyInfo[5]);
 +  if(tinyInfo[7]!=-1)
 +    {
 +      // Connectivity
 +      const int *recvBuffer=a1->getConstPointer();
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> myConnecIndex=DataArrayInt::New();
 +      myConnecIndex->alloc(tinyInfo[6]+1,1);
 +      std::copy(recvBuffer,recvBuffer+tinyInfo[6]+1,myConnecIndex->getPointer());
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> myConnec=DataArrayInt::New();
 +      myConnec->alloc(tinyInfo[7],1);
 +      std::copy(recvBuffer+tinyInfo[6]+1,recvBuffer+tinyInfo[6]+1+tinyInfo[7],myConnec->getPointer());
 +      setConnectivity(myConnec, myConnecIndex);
 +    }
 +}
 +
 +/*!
 + * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2.
 + * CellIds are given using range specified by a start an end and step.
 + */
 +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
 +{
 +  checkFullyDefined();
 +  int ncell=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
 +  ret->_mesh_dim=_mesh_dim;
 +  ret->setCoords(_coords);
 +  int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : ");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1);
 +  int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0;
 +  int work=start;
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
 +    {
 +      if(work>=0 && work<ncell)
 +        {
 +          newConnIPtr[1]=newConnIPtr[0]+connIndex[work+1]-connIndex[work];
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << work << " should be in [0," << ncell << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1);
 +  int *newConnPtr=newConn->getPointer();
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  work=start;
 +  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
 +    {
 +      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[work]]);
 +      newConnPtr=std::copy(conn+connIndex[work],conn+connIndex[work+1],newConnPtr);
 +    }
 +  ret->setConnectivity(newConn,newConnI,false);
 +  ret->_types=types;
 +  ret->copyTinyInfoFrom(this);
 +  return ret.retn();
 +}
 +
 +/*!
 + * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf.
 + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ).
 + * The return newly allocated mesh will share the same coordinates as \a this.
 + */
 +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
 +{
 +  checkConnectivityFullyDefined();
 +  int ncell=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
 +  ret->_mesh_dim=_mesh_dim;
 +  ret->setCoords(_coords);
 +  std::size_t nbOfElemsRet=std::distance(begin,end);
 +  int *connIndexRet=(int *)malloc((nbOfElemsRet+1)*sizeof(int));
 +  connIndexRet[0]=0;
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  int newNbring=0;
 +  for(const int *work=begin;work!=end;work++,newNbring++)
 +    {
 +      if(*work>=0 && *work<ncell)
 +        connIndexRet[newNbring+1]=connIndexRet[newNbring]+connIndex[*work+1]-connIndex[*work];
 +      else
 +        {
 +          free(connIndexRet);
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  int *connRet=(int *)malloc(connIndexRet[nbOfElemsRet]*sizeof(int));
 +  int *connRetWork=connRet;
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  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);
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRetArr=DataArrayInt::New();
 +  connRetArr->useArray(connRet,true,C_DEALLOC,connIndexRet[nbOfElemsRet],1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connIndexRetArr=DataArrayInt::New();
 +  connIndexRetArr->useArray(connIndexRet,true,C_DEALLOC,(int)nbOfElemsRet+1,1);
 +  ret->setConnectivity(connRetArr,connIndexRetArr,false);
 +  ret->_types=types;
 +  ret->copyTinyInfoFrom(this);
 +  return ret.retn();
 +}
 +
 +/*!
 + * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
 + * mesh.<br>
 + * For 1D cells, the returned field contains lengths.<br>
 + * For 2D cells, the returned field contains areas.<br>
 + * For 3D cells, the returned field contains volumes.
 + *  \param [in] isAbs - if \c true, the computed cell volume does not reflect cell
 + *         orientation, i.e. the volume is always positive.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
 + *         and one time . The caller is to delete this field using decrRef() as it is no
 + *         more needed.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
 +{
 +  std::string name="MeasureOfMesh_";
 +  name+=getName();
 +  int nbelem=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
 +  field->setName(name);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New();
 +  array->alloc(nbelem,1);
 +  double *area_vol=array->getPointer();
 +  field->setArray(array) ; array=0;
 +  field->setMesh(const_cast<MEDCouplingUMesh *>(this));
 +  field->synchronizeTimeWithMesh();
 +  if(getMeshDimension()!=-1)
 +    {
 +      int ipt;
 +      INTERP_KERNEL::NormalizedCellType type;
 +      int dim_space=getSpaceDimension();
 +      const double *coords=getCoords()->getConstPointer();
 +      const int *connec=getNodalConnectivity()->getConstPointer();
 +      const int *connec_index=getNodalConnectivityIndex()->getConstPointer();
 +      for(int iel=0;iel<nbelem;iel++)
 +        {
 +          ipt=connec_index[iel];
 +          type=(INTERP_KERNEL::NormalizedCellType)connec[ipt];
 +          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)
 +        std::transform(area_vol,area_vol+nbelem,area_vol,std::ptr_fun<double,double>(fabs));
 +    }
 +  else
 +    {
 +      area_vol[0]=std::numeric_limits<double>::max();
 +    }
 +  return field.retn();
 +}
 +
 +/*!
 + * Returns a new DataArrayDouble containing volumes of specified cells of \a this
 + * mesh.<br>
 + * For 1D cells, the returned array contains lengths.<br>
 + * For 2D cells, the returned array contains areas.<br>
 + * For 3D cells, the returned array contains volumes.
 + * This method avoids building explicitly a part of \a this mesh to perform the work.
 + *  \param [in] isAbs - if \c true, the computed cell volume does not reflect cell
 + *         orientation, i.e. the volume is always positive.
 + *  \param [in] begin - an array of cell ids of interest.
 + *  \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element.
 + *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
 + *          delete this array using decrRef() as it is no more needed.
 + * 
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getPartMeasureField "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getPartMeasureField "Here is a Python example".
 + *  \endif
 + *  \sa getMeasureField()
 + */
 +DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const
 +{
 +  std::string name="PartMeasureOfMesh_";
 +  name+=getName();
 +  int nbelem=(int)std::distance(begin,end);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New();
 +  array->setName(name);
 +  array->alloc(nbelem,1);
 +  double *area_vol=array->getPointer();
 +  if(getMeshDimension()!=-1)
 +    {
 +      int ipt;
 +      INTERP_KERNEL::NormalizedCellType type;
 +      int dim_space=getSpaceDimension();
 +      const double *coords=getCoords()->getConstPointer();
 +      const int *connec=getNodalConnectivity()->getConstPointer();
 +      const int *connec_index=getNodalConnectivityIndex()->getConstPointer();
 +      for(const int *iel=begin;iel!=end;iel++)
 +        {
 +          ipt=connec_index[*iel];
 +          type=(INTERP_KERNEL::NormalizedCellType)connec[ipt];
 +          *area_vol++=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[*iel+1]-ipt-1,coords,dim_space);
 +        }
 +      if(isAbs)
 +        std::transform(array->getPointer(),area_vol,array->getPointer(),std::ptr_fun<double,double>(fabs));
 +    }
 +  else
 +    {
 +      area_vol[0]=std::numeric_limits<double>::max();
 +    }
 +  return array.retn();
 +}
 +
 +/*!
 + * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh of
 + * \a this one. The returned field contains the dual cell volume for each corresponding
 + * node in \a this mesh. In other words, the field returns the getMeasureField() of
 + *  the dual mesh in P1 sens of \a this.<br>
 + * For 1D cells, the returned field contains lengths.<br>
 + * For 2D cells, the returned field contains areas.<br>
 + * For 3D cells, the returned field contains volumes.
 + * This method is useful to check "P1*" conservative interpolators.
 + *  \param [in] isAbs - if \c true, the computed cell volume does not reflect cell
 + *         orientation, i.e. the volume is always positive.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          nodes and one time. The caller is to delete this array using decrRef() as
 + *          it is no more needed.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> tmp=getMeasureField(isAbs);
 +  std::string name="MeasureOnNodeOfMesh_";
 +  name+=getName();
 +  int nbNodes=getNumberOfNodes();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_NODES);
 +  double cst=1./((double)getMeshDimension()+1.);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New();
 +  array->alloc(nbNodes,1);
 +  double *valsToFill=array->getPointer();
 +  std::fill(valsToFill,valsToFill+nbNodes,0.);
 +  const double *values=tmp->getArray()->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> daInd=DataArrayInt::New();
 +  getReverseNodalConnectivity(da,daInd);
 +  const int *daPtr=da->getConstPointer();
 +  const int *daIPtr=daInd->getConstPointer();
 +  for(int i=0;i<nbNodes;i++)
 +    for(const int *cell=daPtr+daIPtr[i];cell!=daPtr+daIPtr[i+1];cell++)
 +      valsToFill[i]+=cst*values[*cell];
 +  ret->setMesh(this);
 +  ret->setArray(array);
 +  return ret.retn();
 +}
 +
 +/*!
 + * Returns a new MEDCouplingFieldDouble holding normal vectors to cells of \a this
 + * mesh. The returned normal vectors to each cell have a norm2 equal to 1.
 + * The computed vectors have <em> this->getMeshDimension()+1 </em> components
 + * and are normalized.
 + * <br> \a this can be either 
 + * - a  2D mesh in 2D or 3D space or 
 + * - an 1D mesh in 2D space.
 + * 
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          cells and one time. The caller is to delete this field using decrRef() as
 + *          it is no more needed.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the mesh dimension is not set.
 + *  \throw If the mesh and space dimension is not as specified above.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
 +{
 +  if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
 +    throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New();
 +  int nbOfCells=getNumberOfCells();
 +  int nbComp=getMeshDimension()+1;
 +  array->alloc(nbOfCells,nbComp);
 +  double *vals=array->getPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const double *coords=_coords->getConstPointer();
 +  if(getMeshDimension()==2)
 +    {
 +      if(getSpaceDimension()==3)
 +        {
 +          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=getBarycenterAndOwner();
 +          const double *locPtr=loc->getConstPointer();
 +          for(int i=0;i<nbOfCells;i++,vals+=3)
 +            {
 +              int offset=connI[i];
 +              INTERP_KERNEL::crossprod<3>(locPtr+3*i,coords+3*conn[offset+1],coords+3*conn[offset+2],vals);
 +              double n=INTERP_KERNEL::norm<3>(vals);
 +              std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n));
 +            }
 +        }
 +      else
 +        {
 +          MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> isAbs=getMeasureField(false);
 +          const double *isAbsPtr=isAbs->getArray()->begin();
 +          for(int i=0;i<nbOfCells;i++,isAbsPtr++)
 +            { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=*isAbsPtr>0.?1.:-1.; }
 +        }
 +    }
 +  else//meshdimension==1
 +    {
 +      double tmp[2];
 +      for(int i=0;i<nbOfCells;i++)
 +        {
 +          int offset=connI[i];
 +          std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>());
 +          double n=INTERP_KERNEL::norm<2>(tmp);
 +          std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n));
 +          *vals++=-tmp[1];
 +          *vals++=tmp[0];
 +        }
 +    }
 +  ret->setArray(array);
 +  ret->setMesh(this);
 +  ret->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Returns a new MEDCouplingFieldDouble holding normal vectors to specified cells of
 + * \a this mesh. The computed vectors have <em> this->getMeshDimension()+1 </em> components
 + * and are normalized.
 + * <br> \a this can be either 
 + * - a  2D mesh in 2D or 3D space or 
 + * - an 1D mesh in 2D space.
 + * 
 + * This method avoids building explicitly a part of \a this mesh to perform the work.
 + *  \param [in] begin - an array of cell ids of interest.
 + *  \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          cells and one time. The caller is to delete this field using decrRef() as
 + *          it is no more needed.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the mesh dimension is not set.
 + *  \throw If the mesh and space dimension is not as specified above.
 + *  \sa buildOrthogonalField()
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_buildPartOrthogonalField "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_buildPartOrthogonalField "Here is a Python example".
 + *  \endif
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const
 +{
 +  if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
 +    throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New();
 +  std::size_t nbelems=std::distance(begin,end);
 +  int nbComp=getMeshDimension()+1;
 +  array->alloc((int)nbelems,nbComp);
 +  double *vals=array->getPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const double *coords=_coords->getConstPointer();
 +  if(getMeshDimension()==2)
 +    {
 +      if(getSpaceDimension()==3)
 +        {
 +          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=getPartBarycenterAndOwner(begin,end);
 +          const double *locPtr=loc->getConstPointer();
 +          for(const int *i=begin;i!=end;i++,vals+=3,locPtr+=3)
 +            {
 +              int offset=connI[*i];
 +              INTERP_KERNEL::crossprod<3>(locPtr,coords+3*conn[offset+1],coords+3*conn[offset+2],vals);
 +              double n=INTERP_KERNEL::norm<3>(vals);
 +              std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n));
 +            }
 +        }
 +      else
 +        {
 +          for(std::size_t i=0;i<nbelems;i++)
 +            { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
 +        }
 +    }
 +  else//meshdimension==1
 +    {
 +      double tmp[2];
 +      for(const int *i=begin;i!=end;i++)
 +        {
 +          int offset=connI[*i];
 +          std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>());
 +          double n=INTERP_KERNEL::norm<2>(tmp);
 +          std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n));
 +          *vals++=-tmp[1];
 +          *vals++=tmp[0];
 +        }
 +    }
 +  ret->setArray(array);
 +  ret->setMesh(this);
 +  ret->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Returns a new MEDCouplingFieldDouble holding a direction vector for each SEG2 in \a
 + * this 1D mesh. The computed vectors have <em> this->getSpaceDimension() </em> components
 + * and are \b not normalized.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          cells and one time. The caller is to delete this field using decrRef() as
 + *          it is no more needed.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this->getMeshDimension() != 1.
 + *  \throw If \a this mesh includes cells of type other than SEG2.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const
 +{
 +  if(getMeshDimension()!=1)
 +    throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !");
 +  if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2)
 +    throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New();
 +  int nbOfCells=getNumberOfCells();
 +  int spaceDim=getSpaceDimension();
 +  array->alloc(nbOfCells,spaceDim);
 +  double *pt=array->getPointer();
 +  const double *coo=getCoords()->getConstPointer();
 +  std::vector<int> conn;
 +  conn.reserve(2);
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      conn.resize(0);
 +      getNodeIdsOfCell(i,conn);
 +      pt=std::transform(coo+conn[1]*spaceDim,coo+(conn[1]+1)*spaceDim,coo+conn[0]*spaceDim,pt,std::minus<double>());
 +    }
 +  ret->setArray(array);
 +  ret->setMesh(this);
 +  ret->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Creates a 2D mesh by cutting \a this 3D mesh with a plane. In addition to the mesh,
 + * returns a new DataArrayInt, of length equal to the number of 2D cells in the result
 + * mesh, holding, for each cell in the result mesh, an id of a 3D cell it comes
 + * from. If a result face is shared by two 3D cells, then the face in included twice in
 + * the result mesh.
 + *  \param [in] origin - 3 components of a point defining location of the plane.
 + *  \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude
 + *         must be greater than 1e-6.
 + *  \param [in] eps - half-thickness of the plane.
 + *  \param [out] cellIds - a new instance of DataArrayInt holding ids of 3D cells
 + *         producing correspondent 2D cells. The caller is to delete this array
 + *         using decrRef() as it is no more needed.
 + *  \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This mesh does
 + *         not share the node coordinates array with \a this mesh. The caller is to
 + *         delete this mesh using decrRef() as it is no more needed.  
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If \a this->getMeshDimension() != 3 or \a this->getSpaceDimension() != 3.
 + *  \throw If magnitude of \a vec is less than 1e-6.
 + *  \throw If the plane does not intersect any 3D cell of \a this mesh.
 + *  \throw If \a this includes quadratic cells.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=getCellIdsCrossingPlane(origin,vec,eps);
 +  if(candidates->empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !");
 +  std::vector<int> nodes;
 +  DataArrayInt *cellIds1D=0;
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false));
 +  subMesh->findNodesOnPlane(origin,vec,eps,nodes);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New(),desc2=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New(),descIndx2=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New(),revDesc2=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New(),revDescIndx2=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc2=subMesh->buildDescendingConnectivity(desc2,descIndx2,revDesc2,revDescIndx2);//meshDim==2 spaceDim==3
 +  revDesc2=0; revDescIndx2=0;
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=mDesc2->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3
 +  revDesc1=0; revDescIndx1=0;
 +  mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds1DTmp(cellIds1D);
 +  //
 +  std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2);
 +  for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++)
 +    cut3DCurve[*it]=-1;
 +  mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve);
 +  std::vector< std::pair<int,int> > cut3DSurf(mDesc2->getNumberOfCells());
 +  AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,mDesc2->getNodalConnectivity()->getConstPointer(),mDesc2->getNodalConnectivityIndex()->getConstPointer(),
 +                              mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(),
 +                              desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New());
 +  connI->pushBackSilent(0); conn->alloc(0,1); cellIds2->alloc(0,1);
 +  subMesh->assemblyForSplitFrom3DSurf(cut3DSurf,desc2->getConstPointer(),descIndx2->getConstPointer(),conn,connI,cellIds2);
 +  if(cellIds2->empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3D",2);
 +  ret->setCoords(mDesc1->getCoords());
 +  ret->setConnectivity(conn,connI,true);
 +  cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end());
 +  return ret.retn();
 +}
 +
 +/*!
 + * Creates an 1D mesh by cutting \a this 2D mesh in 3D space with a plane. In
 +addition to the mesh, returns a new DataArrayInt, of length equal to the number of 1D cells in the result mesh, holding, for each cell in the result mesh, an id of a 2D cell it comes
 +from. If a result segment is shared by two 2D cells, then the segment in included twice in
 +the result mesh.
 + *  \param [in] origin - 3 components of a point defining location of the plane.
 + *  \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude
 + *         must be greater than 1e-6.
 + *  \param [in] eps - half-thickness of the plane.
 + *  \param [out] cellIds - a new instance of DataArrayInt holding ids of faces
 + *         producing correspondent segments. The caller is to delete this array
 + *         using decrRef() as it is no more needed.
 + *  \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This is an 1D
 + *         mesh in 3D space. This mesh does not share the node coordinates array with
 + *         \a this mesh. The caller is to delete this mesh using decrRef() as it is
 + *         no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If \a this->getMeshDimension() != 2 or \a this->getSpaceDimension() != 3.
 + *  \throw If magnitude of \a vec is less than 1e-6.
 + *  \throw If the plane does not intersect any 2D cell of \a this mesh.
 + *  \throw If \a this includes quadratic cells.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf works on umeshes with meshdim equal to 2 and spaceDim equal to 3 !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=getCellIdsCrossingPlane(origin,vec,eps);
 +  if(candidates->empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3D surf cells in this intercepts the specified plane considering bounding boxes !");
 +  std::vector<int> nodes;
 +  DataArrayInt *cellIds1D=0;
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false));
 +  subMesh->findNodesOnPlane(origin,vec,eps,nodes);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=subMesh->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3
 +  mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds1DTmp(cellIds1D);
 +  //
 +  std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2);
 +  for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++)
 +    cut3DCurve[*it]=-1;
 +  mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve);
 +  int ncellsSub=subMesh->getNumberOfCells();
 +  std::vector< std::pair<int,int> > cut3DSurf(ncellsSub);
 +  AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,subMesh->getNodalConnectivity()->getConstPointer(),subMesh->getNodalConnectivityIndex()->getConstPointer(),
 +                              mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(),
 +                              desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); connI->pushBackSilent(0);
 +  conn->alloc(0,1);
 +  const int *nodal=subMesh->getNodalConnectivity()->getConstPointer();
 +  const int *nodalI=subMesh->getNodalConnectivityIndex()->getConstPointer();
 +  for(int i=0;i<ncellsSub;i++)
 +    {
 +      if(cut3DSurf[i].first!=-1 && cut3DSurf[i].second!=-1)
 +        {
 +          if(cut3DSurf[i].first!=-2)
 +            {
 +              conn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(cut3DSurf[i].first); conn->pushBackSilent(cut3DSurf[i].second);
 +              connI->pushBackSilent(conn->getNumberOfTuples());
 +              cellIds2->pushBackSilent(i);
 +            }
 +          else
 +            {
 +              int cellId3DSurf=cut3DSurf[i].second;
 +              int offset=nodalI[cellId3DSurf]+1;
 +              int nbOfEdges=nodalI[cellId3DSurf+1]-offset;
 +              for(int j=0;j<nbOfEdges;j++)
 +                {
 +                  conn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(nodal[offset+j]); conn->pushBackSilent(nodal[offset+(j+1)%nbOfEdges]);
 +                  connI->pushBackSilent(conn->getNumberOfTuples());
 +                  cellIds2->pushBackSilent(cellId3DSurf);
 +                }
 +            }
 +        }
 +    }
 +  if(cellIds2->empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3DSurf cells in this intercepts the specified plane !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3DSurf",1);
 +  ret->setCoords(mDesc1->getCoords());
 +  ret->setConnectivity(conn,connI,true);
 +  cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end());
 +  return ret.retn();
 +}
 +
 +/*!
 + * Finds cells whose bounding boxes intersect a given plane.
 + *  \param [in] origin - 3 components of a point defining location of the plane.
 + *  \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude
 + *         must be greater than 1e-6.
 + *  \param [in] eps - half-thickness of the plane.
 + *  \return DataArrayInt * - a new instance of DataArrayInt holding ids of the found
 + *         cells. The caller is to delete this array using decrRef() as it is no more
 + *         needed.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *  \throw If magnitude of \a vec is less than 1e-6.
 + *  \sa buildSlice3D()
 + */
 +DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const
 +{
 +  checkFullyDefined();
 +  if(getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with spaceDim equal to 3 !");
 +  double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
 +  if(normm<1e-6)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellIdsCrossingPlane : parameter 'vec' should have a norm2 greater than 1e-6 !");
 +  double vec2[3];
 +  vec2[0]=vec[1]; vec2[1]=-vec[0]; vec2[2]=0.;//vec2 is the result of cross product of vec with (0,0,1)
 +  double angle=acos(vec[2]/normm);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds;
 +  double bbox[6];
 +  if(angle>eps)
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->deepCpy();
 +      double normm2(sqrt(vec2[0]*vec2[0]+vec2[1]*vec2[1]+vec2[2]*vec2[2]));
 +      if(normm2/normm>1e-6)
 +        MEDCouplingPointSet::Rotate3DAlg(origin,vec2,angle,coo->getNumberOfTuples(),coo->getPointer());
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mw=clone(false);//false -> shallow copy
 +      mw->setCoords(coo);
 +      mw->getBoundingBox(bbox);
 +      bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps;
 +      cellIds=mw->getCellsInBoundingBox(bbox,eps);
 +    }
 +  else
 +    {
 +      getBoundingBox(bbox);
 +      bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps;
 +      cellIds=getCellsInBoundingBox(bbox,eps);
 +    }
 +  return cellIds.retn();
 +}
 +
 +/*!
 + * This method checks that \a this is a contiguous mesh. The user is expected to call this method on a mesh with meshdim==1.
 + * If not an exception will thrown. If this is an empty mesh with no cell an exception will be thrown too.
 + * No consideration of coordinate is done by this method.
 + * A 1D mesh is said contiguous if : a cell i with nodal connectivity (k,p) the cell i+1 the nodal connectivity should be (p,m)
 + * If not false is returned. In case that false is returned a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes could be usefull.
 + */
 +bool MEDCouplingUMesh::isContiguous1D() const
 +{
 +  if(getMeshDimension()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense only for 1D mesh !");
 +  int nbCells=getNumberOfCells();
 +  if(nbCells<1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense for non empty mesh !");
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  int ref=conn[connI[0]+2];
 +  for(int i=1;i<nbCells;i++)
 +    {
 +      if(conn[connI[i]+1]!=ref)
 +        return false;
 +      ref=conn[connI[i]+2];
 +    }
 +  return true;
 +}
 +
 +/*!
 + * This method is only callable on mesh with meshdim == 1 containing only SEG2 and spaceDim==3.
 + * This method projects this on the 3D line defined by (pt,v). This methods first checks that all SEG2 are along v vector.
 + * \param pt reference point of the line
 + * \param v normalized director vector of the line
 + * \param eps max precision before throwing an exception
 + * \param res output of size this->getNumberOfCells
 + */
 +void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const
 +{
 +  if(getMeshDimension()!=1)
 +    throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for project1D !");
 +  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 project1D !");
 +  if(getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("Expected a umesh with spaceDim==3 for project1D !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f=buildDirectionVectorField();
 +  const double *fPtr=f->getArray()->getConstPointer();
 +  double tmp[3];
 +  for(int i=0;i<getNumberOfCells();i++)
 +    {
 +      const double *tmp1=fPtr+3*i;
 +      tmp[0]=tmp1[1]*v[2]-tmp1[2]*v[1];
 +      tmp[1]=tmp1[2]*v[0]-tmp1[0]*v[2];
 +      tmp[2]=tmp1[0]*v[1]-tmp1[1]*v[0];
 +      double n1=INTERP_KERNEL::norm<3>(tmp);
 +      n1/=INTERP_KERNEL::norm<3>(tmp1);
 +      if(n1>eps)
 +        throw INTERP_KERNEL::Exception("UMesh::Projection 1D failed !");
 +    }
 +  const double *coo=getCoords()->getConstPointer();
 +  for(int i=0;i<getNumberOfNodes();i++)
 +    {
 +      std::transform(coo+i*3,coo+i*3+3,pt,tmp,std::minus<double>());
 +      std::transform(tmp,tmp+3,v,tmp,std::multiplies<double>());
 +      res[i]=std::accumulate(tmp,tmp+3,0.);
 +    }
 +}
 +
 +/*!
 + * This method computes the distance from a point \a pt to \a this and the first \a cellId in \a this corresponding to the returned distance. 
 + * \a this is expected to be a mesh so that its space dimension is equal to its
 + * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment.
 + * Distance from \a ptBg to \a ptEnd is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates).
 + *
 + * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken
 + * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance).
 + * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this.
 + *
 + * So this method is more accurate (so, more costly) than simply searching for the closest point in \a this.
 + * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this.
 + *
 + * \param [in] ptBg the start pointer (included) of the coordinates of the point
 + * \param [in] ptEnd the end pointer (not included) of the coordinates of the point
 + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
 + * \return the positive value of the distance.
 + * \throw if distance from \a ptBg to \a ptEnd is not equal to the space dimension. An exception is also thrown if mesh dimension of \a this is not equal to space
 + * dimension - 1.
 + * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoints
 + */
 +double MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId) const
 +{
 +  int meshDim=getMeshDimension(),spaceDim=getSpaceDimension();
 +  if(meshDim!=spaceDim-1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint works only for spaceDim=meshDim+1 !");
 +  if(meshDim!=2 && meshDim!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !");
 +  checkFullyDefined();
 +  if((int)std::distance(ptBg,ptEnd)!=spaceDim)
 +    { std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoint : input point has to have dimension equal to the space dimension of this (" << spaceDim << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
 +  DataArrayInt *ret1=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=DataArrayDouble::New(); pts->useArray(ptBg,false,C_DEALLOC,1,spaceDim);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=distanceToPoints(pts,ret1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1Safe(ret1);
 +  cellId=*ret1Safe->begin();
 +  return *ret0->begin();
 +}
 +
 +/*!
 + * This method computes the distance from each point of points serie \a pts (stored in a DataArrayDouble in which each tuple represents a point)
 + *  to \a this  and the first \a cellId in \a this corresponding to the returned distance. 
 + * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken
 + * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance).
 + * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this.
 + * 
 + * \a this is expected to be a mesh so that its space dimension is equal to its
 + * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment.
 + * Number of components of \a pts is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates).
 + *
 + * So this method is more accurate (so, more costly) than simply searching for each point in \a pts the closest point in \a this.
 + * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this.
 + *
 + * \param [in] pts the list of points in which each tuple represents a point
 + * \param [out] cellIds a newly allocated object that tells for each point in \a pts the first cell id in \a this that minimizes the distance.
 + * \return a newly allocated object to be dealed by the caller that tells for each point in \a pts the distance to \a this.
 + * \throw if number of components of \a pts is not equal to the space dimension.
 + * \throw if mesh dimension of \a this is not equal to space dimension - 1.
 + * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoint
 + */
 +DataArrayDouble *MEDCouplingUMesh::distanceToPoints(const DataArrayDouble *pts, DataArrayInt *& cellIds) const
 +{
 +  if(!pts)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : input points pointer is NULL !");
 +  pts->checkAllocated();
 +  int meshDim=getMeshDimension(),spaceDim=getSpaceDimension();
 +  if(meshDim!=spaceDim-1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints works only for spaceDim=meshDim+1 !");
 +  if(meshDim!=2 && meshDim!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only mesh dimension 2 and 1 are implemented !");
 +  if(pts->getNumberOfComponents()!=spaceDim)
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoints : input pts DataArrayDouble has " << pts->getNumberOfComponents() << " components whereas it should be equal to " << spaceDim << " (mesh spaceDimension) !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  checkFullyDefined();
 +  int nbCells=getNumberOfCells();
 +  if(nbCells==0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : no cells in this !");
 +  int nbOfPts=pts->getNumberOfTuples();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New(); ret0->alloc(nbOfPts,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(nbOfPts,1);
 +  const int *nc=_nodal_connec->begin(),*ncI=_nodal_connec_index->begin(); const double *coords=_coords->begin();
 +  double *ret0Ptr=ret0->getPointer(); int *ret1Ptr=ret1->getPointer(); const double *ptsPtr=pts->begin();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(getBoundingBoxForBBTree());
 +  const double *bbox(bboxArr->begin());
 +  switch(spaceDim)
 +  {
 +    case 3:
 +      {
 +        BBTreeDst<3> myTree(bbox,0,0,nbCells);
 +        for(int i=0;i<nbOfPts;i++,ret0Ptr++,ret1Ptr++,ptsPtr+=3)
 +          {
 +            double x=std::numeric_limits<double>::max();
 +            std::vector<int> elems;
 +            myTree.getMinDistanceOfMax(ptsPtr,x);
 +            myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems);
 +            DistanceToPoint3DSurfAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr);
 +          }
 +        break;
 +      }
 +    case 2:
 +      {
 +        BBTreeDst<2> myTree(bbox,0,0,nbCells);
 +        for(int i=0;i<nbOfPts;i++,ret0Ptr++,ret1Ptr++,ptsPtr+=2)
 +          {
 +            double x=std::numeric_limits<double>::max();
 +            std::vector<int> elems;
 +            myTree.getMinDistanceOfMax(ptsPtr,x);
 +            myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems);
 +            DistanceToPoint2DCurveAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr);
 +          }
 +        break;
 +      }
 +    default:
 +      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only spacedim 2 and 3 supported !");
 +  }
 +  cellIds=ret1.retn();
 +  return ret0.retn();
 +}
 +
++/// @cond INTERNAL
++
 +/*!
 + * \param [in] pt the start pointer (included) of the coordinates of the point
 + * \param [in] cellIdsBg the start pointer (included) of cellIds
 + * \param [in] cellIdsEnd the end pointer (excluded) of cellIds
 + * \param [in] nc nodal connectivity
 + * \param [in] ncI nodal connectivity index
 + * \param [in,out] ret0 the min distance between \a this and the external input point
 + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
 + * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints
 + */
 +void MEDCouplingUMesh::DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId)
 +{
 +  cellId=-1;
 +  ret0=std::numeric_limits<double>::max();
 +  for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++)
 +    {
 +      switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]])
 +      {
 +        case INTERP_KERNEL::NORM_TRI3:
 +          {
 +            double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*nc[ncI[*zeCell]+1],coords+3*nc[ncI[*zeCell]+2],coords+3*nc[ncI[*zeCell]+3]);
 +            if(tmp<ret0)
 +              { ret0=tmp; cellId=*zeCell; }
 +            break;
 +          }
 +        case INTERP_KERNEL::NORM_QUAD4:
 +        case INTERP_KERNEL::NORM_POLYGON:
 +          {
 +            double tmp=INTERP_KERNEL::DistanceFromPtToPolygonInSpaceDim3(pt,nc+ncI[*zeCell]+1,nc+ncI[*zeCell+1],coords);
 +            if(tmp<ret0)
 +              { ret0=tmp; cellId=*zeCell; }
 +            break;
 +          }
 +        default:
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint3DSurfAlg : not managed cell type ! Supporting TRI3, QUAD4 and POLYGON !");
 +      }
 +    }
 +}
 +
 +/*!
 + * \param [in] pt the start pointer (included) of the coordinates of the point
 + * \param [in] cellIdsBg the start pointer (included) of cellIds
 + * \param [in] cellIdsEnd the end pointer (excluded) of cellIds
 + * \param [in] nc nodal connectivity
 + * \param [in] ncI nodal connectivity index
 + * \param [in,out] ret0 the min distance between \a this and the external input point
 + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
 + * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints
 + */
 +void MEDCouplingUMesh::DistanceToPoint2DCurveAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId)
 +{
 +  cellId=-1;
 +  ret0=std::numeric_limits<double>::max();
 +  for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++)
 +    {
 +      switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]])
 +      {
 +        case INTERP_KERNEL::NORM_SEG2:
 +          {
 +            std::size_t uselessEntry=0;
 +            double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*nc[ncI[*zeCell]+1],coords+2*nc[ncI[*zeCell]+2],uselessEntry);
 +            tmp=sqrt(tmp);
 +            if(tmp<ret0)
 +              { ret0=tmp; cellId=*zeCell; }
 +            break;
 +          }
 +        default:
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint2DCurveAlg : not managed cell type ! Supporting SEG2 !");
 +      }
 +    }
 +}
++/// @endcond
 +
 +/*!
 + * Finds cells in contact with a ball (i.e. a point with precision). 
 + * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT.
 + * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method.
 + *
 + * \warning This method is suitable if the caller intends to evaluate only one
 + *          point, for more points getCellsContainingPoints() is recommended as it is
 + *          faster. 
 + *  \param [in] pos - array of coordinates of the ball central point.
 + *  \param [in] eps - ball radius.
 + *  \return int - a smallest id of cells being in contact with the ball, -1 in case
 + *         if there are no such cells.
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this->getMeshDimension() != \a this->getSpaceDimension().
 + */
 +int MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const
 +{
 +  std::vector<int> elts;
 +  getCellsContainingPoint(pos,eps,elts);
 +  if(elts.empty())
 +    return -1;
 +  return elts.front();
 +}
 +
 +/*!
 + * Finds cells in contact with a ball (i.e. a point with precision).
 + * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT.
 + * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method.
 + * \warning This method is suitable if the caller intends to evaluate only one
 + *          point, for more points getCellsContainingPoints() is recommended as it is
 + *          faster. 
 + *  \param [in] pos - array of coordinates of the ball central point.
 + *  \param [in] eps - ball radius.
 + *  \param [out] elts - vector returning ids of the found cells. It is cleared
 + *         before inserting ids.
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this->getMeshDimension() != \a this->getSpaceDimension().
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getCellsContainingPoint "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsUg,eltsIndexUg;
 +  getCellsContainingPoints(pos,1,eps,eltsUg,eltsIndexUg);
 +  elts.clear(); elts.insert(elts.end(),eltsUg->begin(),eltsUg->end());
 +}
 +
 +/// @cond INTERNAL
 +
 +namespace ParaMEDMEM
 +{
 +  template<const int SPACEDIMM>
 +  class DummyClsMCUG
 +  {
 +  public:
 +    static const int MY_SPACEDIM=SPACEDIMM;
 +    static const int MY_MESHDIM=8;
 +    typedef int MyConnType;
 +    static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE;
 +    // begin
 +    // useless, but for windows compilation ...
 +    const double* getCoordinatesPtr() const { return 0; }
 +    const int* getConnectivityPtr() const { return 0; }
 +    const int* getConnectivityIndexPtr() const { return 0; }
 +    INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
 +    // end
 +  };
 +
 +  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>& m)
 +  {
 +    INTERP_KERNEL::Edge *ret(0);
 +    MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> n0(new INTERP_KERNEL::Node(coords2D[2*bg[0]],coords2D[2*bg[0]+1])),n1(new INTERP_KERNEL::Node(coords2D[2*bg[1]],coords2D[2*bg[1]+1]));
 +    m[n0]=bg[0]; m[n1]=bg[1];
 +    switch(typ)
 +    {
 +      case INTERP_KERNEL::NORM_SEG2:
 +        {
 +          ret=new INTERP_KERNEL::EdgeLin(n0,n1);
 +          break;
 +        }
 +      case INTERP_KERNEL::NORM_SEG3:
 +        {
 +          INTERP_KERNEL::Node *n2(new INTERP_KERNEL::Node(coords2D[2*bg[2]],coords2D[2*bg[2]+1])); m[n2]=bg[2];
 +          INTERP_KERNEL::EdgeLin *e1(new INTERP_KERNEL::EdgeLin(n0,n2)),*e2(new INTERP_KERNEL::EdgeLin(n2,n1));
 +          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
 +          // is the SEG3 degenerated, and thus can be reduced to a SEG2?
 +          bool colinearity(inters.areColinears());
 +          delete e1; delete e2;
 +          if(colinearity)
 +            { ret=new INTERP_KERNEL::EdgeLin(n0,n1); }
 +          else
 +            { ret=new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1); }
 +          break;
 +        }
 +      default:
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge2 : Expecting a mesh with spaceDim==2 and meshDim==1 !");
 +    }
 +    return ret;
 +  }
 +
 +  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >& mapp2, const int *bg)
 +  {
 +    INTERP_KERNEL::Edge *ret=0;
 +    switch(typ)
 +    {
 +      case INTERP_KERNEL::NORM_SEG2:
 +        {
 +          ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
 +          break;
 +        }
 +      case INTERP_KERNEL::NORM_SEG3:
 +        {
 +          INTERP_KERNEL::EdgeLin *e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[2]].first);
 +          INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]].first,mapp2[bg[1]].first);
 +          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
 +          // is the SEG3 degenerated, and thus can be reduced to a SEG2?
 +          bool colinearity=inters.areColinears();
 +          delete e1; delete e2;
 +          if(colinearity)
 +            ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
 +          else
 +            ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]].first,mapp2[bg[2]].first,mapp2[bg[1]].first);
 +          mapp2[bg[2]].second=false;
 +          break;
 +        }
 +      default:
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !");
 +    }
 +    return ret;
 +  }
 +
 +  /*!
 +   * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed by the sub set of cells in 'candidates' taken from
 +   * the global mesh 'mDesc'.
 +   * The input mesh 'mDesc' must be so that mDim==1 and spaceDim==2.
 +   * 'mapp' returns a mapping between local numbering in submesh (represented by a Node*) and the global node numbering in 'mDesc'.
 +   */
 +  INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector<int>& candidates,
 +                                                                   std::map<INTERP_KERNEL::Node *,int>& mapp)
 +  {
 +    mapp.clear();
 +    std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;//bool is for a flag specifying if node is boundary (true) or only a middle for SEG3.
 +    const double *coo=mDesc->getCoords()->getConstPointer();
 +    const int *c=mDesc->getNodalConnectivity()->getConstPointer();
 +    const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer();
 +    std::set<int> s;
 +    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
 +      s.insert(c+cI[*it]+1,c+cI[(*it)+1]);
 +    for(std::set<int>::const_iterator it2=s.begin();it2!=s.end();it2++)
 +      {
 +        INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]);
 +        mapp2[*it2]=std::pair<INTERP_KERNEL::Node *,bool>(n,true);
 +      }
 +    INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon;
 +    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
 +      {
 +        INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]];
 +        ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1));
 +      }
 +    for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it2=mapp2.begin();it2!=mapp2.end();it2++)
 +      {
 +        if((*it2).second.second)
 +          mapp[(*it2).second.first]=(*it2).first;
 +        ((*it2).second.first)->decrRef();
 +      }
 +    return ret;
 +  }
 +
 +  INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo)
 +  {
 +    if(nodeId>=offset2)
 +      {
 +        int locId=nodeId-offset2;
 +        return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]);
 +      }
 +    if(nodeId>=offset1)
 +      {
 +        int locId=nodeId-offset1;
 +        return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]);
 +      }
 +    return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]);
 +  }
 +
 +  /**
 +   * Construct a mapping between set of Nodes and the standart MEDCoupling connectivity format (c, cI).
 +   */
 +  void MEDCouplingUMeshBuildQPFromMesh3(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo,
 +                                        const int *desc1Bg, const int *desc1End, const std::vector<std::vector<int> >& intesctEdges1,
 +                                        /*output*/std::map<INTERP_KERNEL::Node *,int>& mapp, std::map<int,INTERP_KERNEL::Node *>& mappRev)
 +  {
 +    for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++)
 +      {
 +        int eltId1=abs(*desc1)-1;
 +        for(std::vector<int>::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++)
 +          {
 +            std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.find(*it1);
 +            if(it==mappRev.end())
 +              {
 +                INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo);
 +                mapp[node]=*it1;
 +                mappRev[*it1]=node;
 +              }
 +          }
 +      }
 +  }
 +}
 +
 +/// @endcond
 +
 +template<int SPACEDIM>
 +void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
 +                                                   double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const
 +{
 +  elts=DataArrayInt::New(); eltsIndex=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1);
 +  int *eltsIndexPtr(eltsIndex->getPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(getBoundingBoxForBBTree(eps));
 +  const double *bbox(bboxArr->begin());
 +  int nbOfCells=getNumberOfCells();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  double bb[2*SPACEDIM];
 +  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps);
 +  for(int i=0;i<nbOfPoints;i++)
 +    {
 +      eltsIndexPtr[i+1]=eltsIndexPtr[i];
 +      for(int j=0;j<SPACEDIM;j++)
 +        {
 +          bb[2*j]=pos[SPACEDIM*i+j];
 +          bb[2*j+1]=pos[SPACEDIM*i+j];
 +        }
 +      std::vector<int> candidates;
 +      myTree.getIntersectingElems(bb,candidates);
 +      for(std::vector<int>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
 +        {
 +          int sz(connI[(*iter)+1]-connI[*iter]-1);
 +          INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]]);
 +          bool status(false);
 +          if(ct!=INTERP_KERNEL::NORM_POLYGON && ct!=INTERP_KERNEL::NORM_QPOLYG)
 +            status=INTERP_KERNEL::PointLocatorAlgos<DummyClsMCUG<SPACEDIM> >::isElementContainsPoint(pos+i*SPACEDIM,ct,coords,conn+connI[*iter]+1,sz,eps);
 +          else
 +            {
 +              if(SPACEDIM!=2)
 +                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPointsAlg : not implemented yet for POLYGON and QPOLYGON in spaceDim 3 !");
 +              INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
 +              INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
 +              std::vector<INTERP_KERNEL::Node *> nodes(sz);
 +              INTERP_KERNEL::QuadraticPolygon *pol(0);
 +              for(int j=0;j<sz;j++)
 +                {
 +                  int nodeId(conn[connI[*iter]+1+j]);
 +                  nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*SPACEDIM],coords[nodeId*SPACEDIM+1]);
 +                }
 +              if(!INTERP_KERNEL::CellModel::GetCellModel(ct).isQuadratic())
 +                pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes);
 +              else
 +                pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes);
 +              INTERP_KERNEL::Node *n(new INTERP_KERNEL::Node(pos[i*SPACEDIM],pos[i*SPACEDIM+1]));
 +              double a(0.),b(0.),c(0.);
 +              a=pol->normalizeMe(b,c); n->applySimilarity(b,c,a);
 +              status=pol->isInOrOut2(n);
 +              delete pol; n->decrRef();
 +            }
 +          if(status)
 +            {
 +              eltsIndexPtr[i+1]++;
 +              elts->pushBackSilent(*iter);
 +            }
 +        }
 +    }
 +}
 +/*!
 + * Finds cells in contact with several balls (i.e. points with precision).
 + * This method is an extension of getCellContainingPoint() and
 + * getCellsContainingPoint() for the case of multiple points.
 + * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT.
 + * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method.
 + *  \param [in] pos - an array of coordinates of points in full interlace mode :
 + *         X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a
 + *         this->getSpaceDimension() * \a nbOfPoints 
 + *  \param [in] nbOfPoints - number of points to locate within \a this mesh.
 + *  \param [in] eps - radius of balls (i.e. the precision).
 + *  \param [out] elts - vector returning ids of found cells.
 + *  \param [out] eltsIndex - an array, of length \a nbOfPoints + 1,
 + *         dividing cell ids in \a elts into groups each referring to one
 + *         point. Its every element (except the last one) is an index pointing to the
 + *         first id of a group of cells. For example cells in contact with the *i*-th
 + *         point are described by following range of indices:
 + *         [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are
 + *         \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ...
 + *         Number of cells in contact with the *i*-th point is
 + *         \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ].
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this->getMeshDimension() != \a this->getSpaceDimension().
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getCellsContainingPoints "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps,
 +                                                MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const
 +{
 +  int spaceDim=getSpaceDimension();
 +  int mDim=getMeshDimension();
 +  if(spaceDim==3)
 +    {
 +      if(mDim==3)
 +        {
 +          const double *coords=_coords->getConstPointer();
 +          getCellsContainingPointsAlg<3>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
 +        }
 +      /*else if(mDim==2)
 +        {
 +
 +        }*/
 +      else
 +        throw INTERP_KERNEL::Exception("For spaceDim==3 only meshDim==3 implemented for getelementscontainingpoints !");
 +    }
 +  else if(spaceDim==2)
 +    {
 +      if(mDim==2)
 +        {
 +          const double *coords=_coords->getConstPointer();
 +          getCellsContainingPointsAlg<2>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("For spaceDim==2 only meshDim==2 implemented for getelementscontainingpoints !");
 +    }
 +  else if(spaceDim==1)
 +    {
 +      if(mDim==1)
 +        {
 +          const double *coords=_coords->getConstPointer();
 +          getCellsContainingPointsAlg<1>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("For spaceDim==1 only meshDim==1 implemented for getelementscontainingpoints !");
 +    }
 +  else
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPoints : not managed for mdim not in [1,2,3] !");
 +}
 +
 +/*!
 + * Finds butterfly cells in \a this mesh. A 2D cell is considered to be butterfly if at
 + * least two its edges intersect each other anywhere except their extremities. An
 + * INTERP_KERNEL::NORM_NORI3 cell can \b not be butterfly.
 + *  \param [in,out] cells - a vector returning ids of the found cells. It is not
 + *         cleared before filling in.
 + *  \param [in] eps - precision.
 + *  \throw If \a this->getMeshDimension() != 2.
 + *  \throw If \a this->getSpaceDimension() != 2 && \a this->getSpaceDimension() != 3.
 + */
 +void MEDCouplingUMesh::checkButterflyCells(std::vector<int>& cells, double eps) const
 +{
 +  const char msg[]="Butterfly detection work only for 2D cells with spaceDim==2 or 3!";
 +  if(getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception(msg);
 +  int spaceDim=getSpaceDimension();
 +  if(spaceDim!=2 && spaceDim!=3)
 +    throw INTERP_KERNEL::Exception(msg);
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  std::vector<double> cell2DinS2;
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      int offset=connI[i];
 +      int nbOfNodesForCell=connI[i+1]-offset-1;
 +      if(nbOfNodesForCell<=3)
 +        continue;
 +      bool isQuad=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[offset]).isQuadratic();
 +      project2DCellOnXY(conn+offset+1,conn+connI[i+1],cell2DinS2);
 +      if(isButterfly2DCell(cell2DinS2,isQuad,eps))
 +        cells.push_back(i);
 +      cell2DinS2.clear();
 +    }
 +}
 +
 +/*!
 + * This method is typically requested to unbutterfly 2D linear cells in \b this.
 + *
 + * This method expects that space dimension is equal to 2 and mesh dimension is equal to 2 too. If it is not the case an INTERP_KERNEL::Exception will be thrown.
 + * This method works only for linear 2D cells. If there is any of non linear cells (INTERP_KERNEL::NORM_QUAD8 for example) an INTERP_KERNEL::Exception will be thrown too.
 + * 
 + * For each 2D linear cell in \b this, this method builds the convex envelop (or the convex hull) of the current cell.
 + * This convex envelop is computed using Jarvis march algorithm.
 + * The coordinates and the number of cells of \b this remain unchanged on invocation of this method.
 + * Only connectivity of some cells could be modified if those cells were not representing a convex envelop. If a cell already equals its convex envelop (regardless orientation)
 + * its connectivity will remain unchanged. If the computation leads to a modification of nodal connectivity of a cell its geometric type will be modified to INTERP_KERNEL::NORM_POLYGON.
 + *
 + * \return a newly allocated array containing cellIds that have been modified if any. If no cells have been impacted by this method NULL is returned.
 + * \sa MEDCouplingUMesh::colinearize2D
 + */
 +DataArrayInt *MEDCouplingUMesh::convexEnvelop2D()
 +{
 +  if(getMeshDimension()!=2 || getSpaceDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convexEnvelop2D  works only for meshDim=2 and spaceDim=2 !");
 +  checkFullyDefined();
 +  const double *coords=getCoords()->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecIndexOut=DataArrayInt::New();
 +  nodalConnecIndexOut->alloc(nbOfCells+1,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecOut(DataArrayInt::New());
 +  int *workIndexOut=nodalConnecIndexOut->getPointer();
 +  *workIndexOut=0;
 +  const int *nodalConnecIn=_nodal_connec->getConstPointer();
 +  const int *nodalConnecIndexIn=_nodal_connec_index->getConstPointer();
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> isChanged(DataArrayInt::New());
 +  isChanged->alloc(0,1);
 +  for(int i=0;i<nbOfCells;i++,workIndexOut++)
 +    {
 +      int pos=nodalConnecOut->getNumberOfTuples();
 +      if(BuildConvexEnvelopOf2DCellJarvis(coords,nodalConnecIn+nodalConnecIndexIn[i],nodalConnecIn+nodalConnecIndexIn[i+1],nodalConnecOut))
 +        isChanged->pushBackSilent(i);
 +      types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut->getIJ(pos,0));
 +      workIndexOut[1]=nodalConnecOut->getNumberOfTuples();
 +    }
 +  if(isChanged->empty())
 +    return 0;
 +  setConnectivity(nodalConnecOut,nodalConnecIndexOut,false);
 +  _types=types;
 +  return isChanged.retn();
 +}
 +
 +/*!
 + * This method is \b NOT const because it can modify \a this.
 + * \a 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 \a this.  
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy)
 +{
 +  checkFullyDefined();
 +  mesh1D->checkFullyDefined();
 +  if(!mesh1D->isContiguous1D())
 +    throw INTERP_KERNEL::Exception("buildExtrudedMesh : 1D mesh passed in parameter is not contiguous !");
 +  if(getSpaceDimension()!=mesh1D->getSpaceDimension())
 +    throw INTERP_KERNEL::Exception("Invalid call to buildExtrudedMesh this and mesh1D must have same space dimension !");
 +  if((getMeshDimension()!=2 || getSpaceDimension()!=3) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
 +    throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMesh method : must be (meshDim==2 and spaceDim==3) or (meshDim==1 and spaceDim==2) !");
 +  if(mesh1D->getMeshDimension()!=1)
 +    throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMesh method : must be meshDim==1 !");
 +  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 !");
 +    }
 +  int oldNbOfNodes(getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords;
 +  switch(policy)
 +  {
 +    case 0:
 +      {
 +        newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad);
 +        break;
 +      }
 +    case 1:
 +      {
 +        newCoords=fillExtCoordsUsingTranslAndAutoRotation(mesh1D,isQuad);
 +        break;
 +      }
 +    default:
 +      throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !");
 +  }
 +  setCoords(newCoords);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad));
 +  updateTime();
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3).
 + * If it is not the case an exception will be thrown.
 + * This method is non const because the coordinate of \a this can be appended with some new points issued from
 + * intersection of plane defined by ('origin','vec').
 + * This method has one in/out parameter : 'cut3DCurve'.
 + * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()')
 + * if cut3DCurve[i]==-2, it means that for cell #i in \a this nothing has been detected previously.
 + * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec').
 + * This method will throw an exception if \a this contains a non linear segment.
 + */
 +void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve)
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=1 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane works on umeshes with meshdim equal to 1 and spaceDim equal to 3 !");
 +  int ncells=getNumberOfCells();
 +  int nnodes=getNumberOfNodes();
 +  double vec2[3],vec3[3],vec4[3];
 +  double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
 +  if(normm<1e-6)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : parameter 'vec' should have a norm2 greater than 1e-6 !");
 +  vec2[0]=vec[0]/normm; vec2[1]=vec[1]/normm; vec2[2]=vec[2]/normm;
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const double *coo=_coords->getConstPointer();
 +  std::vector<double> addCoo;
 +  for(int i=0;i<ncells;i++)
 +    {
 +      if(conn[connI[i]]==(int)INTERP_KERNEL::NORM_SEG2)
 +        {
 +          if(cut3DCurve[i]==-2)
 +            {
 +              int st=conn[connI[i]+1],endd=conn[connI[i]+2];
 +              vec3[0]=coo[3*endd]-coo[3*st]; vec3[1]=coo[3*endd+1]-coo[3*st+1]; vec3[2]=coo[3*endd+2]-coo[3*st+2];
 +              double normm2=sqrt(vec3[0]*vec3[0]+vec3[1]*vec3[1]+vec3[2]*vec3[2]);
 +              double colin=std::abs((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])/normm2);
 +              if(colin>eps)//if colin<=eps -> current SEG2 is colinear to the input plane
 +                {
 +                  const double *st2=coo+3*st;
 +                  vec4[0]=st2[0]-origin[0]; vec4[1]=st2[1]-origin[1]; vec4[2]=st2[2]-origin[2];
 +                  double pos=-(vec4[0]*vec2[0]+vec4[1]*vec2[1]+vec4[2]*vec2[2])/((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2]));
 +                  if(pos>eps && pos<1-eps)
 +                    {
 +                      int nNode=((int)addCoo.size())/3;
 +                      vec4[0]=st2[0]+pos*vec3[0]; vec4[1]=st2[1]+pos*vec3[1]; vec4[2]=st2[2]+pos*vec3[2];
 +                      addCoo.insert(addCoo.end(),vec4,vec4+3);
 +                      cut3DCurve[i]=nnodes+nNode;
 +                    }
 +                }
 +            }
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : this method is only available for linear cell (NORM_SEG2) !");
 +    }
 +  if(!addCoo.empty())
 +    {
 +      int newNbOfNodes=nnodes+((int)addCoo.size())/3;
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo2=DataArrayDouble::New();
 +      coo2->alloc(newNbOfNodes,3);
 +      double *tmp=coo2->getPointer();
 +      tmp=std::copy(_coords->begin(),_coords->end(),tmp);
 +      std::copy(addCoo.begin(),addCoo.end(),tmp);
 +      DataArrayDouble::SetArrayIn(coo2,_coords);
 +    }
 +}
 +
 +/*!
 + * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh 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();
 +  int spaceDim=getSpaceDimension();
 +  DataArrayDouble *ret=DataArrayDouble::New();
 +  std::vector<bool> isQuads;
 +  int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1;
 +  ret->alloc(oldNbOfNodes*nbOfLevsInVec,spaceDim);
 +  double *retPtr=ret->getPointer();
 +  const double *coords=getCoords()->getConstPointer();
 +  double *work=std::copy(coords,coords+spaceDim*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()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
 +      for(int j=0;j<oldNbOfNodes;j++)
 +        work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(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()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
 +          for(int j=0;j<oldNbOfNodes;j++)
 +            work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>());
 +        }
 +    }
 +  ret->copyStringInfoFrom(*getCoords());
 +  return ret;
 +}
 +
 +/*!
 + * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
 + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
 + * \return newCoords new coords filled by this method. 
 + */
 +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const
 +{
 +  if(mesh1D->getSpaceDimension()==2)
 +    return fillExtCoordsUsingTranslAndAutoRotation2D(mesh1D,isQuad);
 +  if(mesh1D->getSpaceDimension()==3)
 +    return fillExtCoordsUsingTranslAndAutoRotation3D(mesh1D,isQuad);
 +  throw INTERP_KERNEL::Exception("Not implemented rotation and translation alg. for spacedim other than 2 and 3 !");
 +}
 +
 +/*!
 + * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
 + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
 + * \return newCoords new coords filled by this method. 
 + */
 +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const
 +{
 +  if(isQuad)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : not implemented for quadratic cells !");
 +  int oldNbOfNodes=getNumberOfNodes();
 +  int nbOf1DCells=mesh1D->getNumberOfCells();
 +  if(nbOf1DCells<2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
 +  int nbOfLevsInVec=nbOf1DCells+1;
 +  ret->alloc(oldNbOfNodes*nbOfLevsInVec,2);
 +  double *retPtr=ret->getPointer();
 +  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=getCoords()->deepCpy();
 +  tmp->setCoords(tmp2);
 +  const double *coo1D=mesh1D->getCoords()->getConstPointer();
 +  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
 +  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
 +  for(int i=1;i<nbOfLevsInVec;i++)
 +    {
 +      const double *begin=coo1D+2*conn1D[connI1D[i-1]+1];
 +      const double *end=coo1D+2*conn1D[connI1D[i-1]+2];
 +      const double *third=i+1<nbOfLevsInVec?coo1D+2*conn1D[connI1D[i]+2]:coo1D+2*conn1D[connI1D[i-2]+1];
 +      const double vec[2]={end[0]-begin[0],end[1]-begin[1]};
 +      tmp->translate(vec);
 +      double tmp3[2],radius,alpha,alpha0;
 +      const double *p0=i+1<nbOfLevsInVec?begin:third;
 +      const double *p1=i+1<nbOfLevsInVec?end:begin;
 +      const double *p2=i+1<nbOfLevsInVec?third:end;
 +      INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0,p1,p2,tmp3,radius,alpha,alpha0);
 +      double cosangle=i+1<nbOfLevsInVec?(p0[0]-tmp3[0])*(p1[0]-tmp3[0])+(p0[1]-tmp3[1])*(p1[1]-tmp3[1]):(p2[0]-tmp3[0])*(p1[0]-tmp3[0])+(p2[1]-tmp3[1])*(p1[1]-tmp3[1]);
 +      double angle=acos(cosangle/(radius*radius));
 +      tmp->rotate(end,0,angle);
 +      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
 + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
 + * \return newCoords new coords filled by this method. 
 + */
 +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const
 +{
 +  if(isQuad)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : not implemented for quadratic cells !");
 +  int oldNbOfNodes=getNumberOfNodes();
 +  int nbOf1DCells=mesh1D->getNumberOfCells();
 +  if(nbOf1DCells<2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
 +  int nbOfLevsInVec=nbOf1DCells+1;
 +  ret->alloc(oldNbOfNodes*nbOfLevsInVec,3);
 +  double *retPtr=ret->getPointer();
 +  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=getCoords()->deepCpy();
 +  tmp->setCoords(tmp2);
 +  const double *coo1D=mesh1D->getCoords()->getConstPointer();
 +  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
 +  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
 +  for(int i=1;i<nbOfLevsInVec;i++)
 +    {
 +      const double *begin=coo1D+3*conn1D[connI1D[i-1]+1];
 +      const double *end=coo1D+3*conn1D[connI1D[i-1]+2];
 +      const double *third=i+1<nbOfLevsInVec?coo1D+3*conn1D[connI1D[i]+2]:coo1D+3*conn1D[connI1D[i-2]+1];
 +      const double vec[3]={end[0]-begin[0],end[1]-begin[1],end[2]-begin[2]};
 +      tmp->translate(vec);
 +      double tmp3[2],radius,alpha,alpha0;
 +      const double *p0=i+1<nbOfLevsInVec?begin:third;
 +      const double *p1=i+1<nbOfLevsInVec?end:begin;
 +      const double *p2=i+1<nbOfLevsInVec?third:end;
 +      double vecPlane[3]={
 +        (p1[1]-p0[1])*(p2[2]-p1[2])-(p1[2]-p0[2])*(p2[1]-p1[1]),
 +        (p1[2]-p0[2])*(p2[0]-p1[0])-(p1[0]-p0[0])*(p2[2]-p1[2]),
 +        (p1[0]-p0[0])*(p2[1]-p1[1])-(p1[1]-p0[1])*(p2[0]-p1[0]),
 +      };
 +      double norm=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]+vecPlane[2]*vecPlane[2]);
 +      if(norm>1.e-7)
 +        {
 +          vecPlane[0]/=norm; vecPlane[1]/=norm; vecPlane[2]/=norm;
 +          double norm2=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]);
 +          double vec2[2]={vecPlane[1]/norm2,-vecPlane[0]/norm2};
 +          double s2=norm2;
 +          double c2=cos(asin(s2));
 +          double m[3][3]={
 +            {vec2[0]*vec2[0]*(1-c2)+c2, vec2[0]*vec2[1]*(1-c2), vec2[1]*s2},
 +            {vec2[0]*vec2[1]*(1-c2), vec2[1]*vec2[1]*(1-c2)+c2, -vec2[0]*s2},
 +            {-vec2[1]*s2, vec2[0]*s2, c2}
 +          };
 +          double p0r[3]={m[0][0]*p0[0]+m[0][1]*p0[1]+m[0][2]*p0[2], m[1][0]*p0[0]+m[1][1]*p0[1]+m[1][2]*p0[2], m[2][0]*p0[0]+m[2][1]*p0[1]+m[2][2]*p0[2]};
 +          double p1r[3]={m[0][0]*p1[0]+m[0][1]*p1[1]+m[0][2]*p1[2], m[1][0]*p1[0]+m[1][1]*p1[1]+m[1][2]*p1[2], m[2][0]*p1[0]+m[2][1]*p1[1]+m[2][2]*p1[2]};
 +          double p2r[3]={m[0][0]*p2[0]+m[0][1]*p2[1]+m[0][2]*p2[2], m[1][0]*p2[0]+m[1][1]*p2[1]+m[1][2]*p2[2], m[2][0]*p2[0]+m[2][1]*p2[1]+m[2][2]*p2[2]};
 +          INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0r,p1r,p2r,tmp3,radius,alpha,alpha0);
 +          double cosangle=i+1<nbOfLevsInVec?(p0r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p0r[1]-tmp3[1])*(p1r[1]-tmp3[1]):(p2r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p2r[1]-tmp3[1])*(p1r[1]-tmp3[1]);
 +          double angle=acos(cosangle/(radius*radius));
 +          tmp->rotate(end,vecPlane,angle);
 +        }
 +      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method is private because not easy to use for end user. This method is const contrary to
 + * MEDCouplingUMesh::buildExtrudedMesh 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",getMeshDimension()+1));
 +  const int *conn(_nodal_connec->begin()),*connI(_nodal_connec_index->begin());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn(DataArrayInt::New()),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++=(int)newc.size();
 +    }
 +  newConn->alloc((int)(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]));
 +      const int *posOfTypeOfCell(newConnIPtr);
 +      for(std::vector<int>::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++)
 +        {
 +          int icell((int)(iter-newc.begin()));//std::distance unfortunately cannot been called here in C++98
 +          if(icell!=*posOfTypeOfCell)
 +            {
 +              if(*iter!=-1)
 +                *newConnPtr=(*iter)+iz*deltaPerLev;
 +              else
 +                *newConnPtr=-1;
 +            }
 +          else
 +            {
 +              *newConnPtr=*iter;
 +              posOfTypeOfCell++;
 +            }
 +        }
 +    }
 +  ret->setConnectivity(newConn,newConnI,true);
 +  ret->setCoords(getCoords());
 +  return ret;
 +}
 +
 +/*!
 + * Checks if \a this mesh is constituted by only quadratic cells.
 + *  \return bool - \c true if there are only quadratic cells in \a this mesh.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + */
 +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;
 +}
 +
 +/*!
 + * Checks if \a this mesh includes any quadratic cell.
 + *  \return bool - \c true if there is at least one quadratic cells in \a this mesh.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + */
 +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;
 +}
 +
 +/*!
 + * Converts all quadratic cells to linear ones. If there are no quadratic cells in \a
 + * this mesh, it remains unchanged.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + */
 +void MEDCouplingUMesh::convertQuadraticCellsToLinear()
 +{
 +  checkFullyDefined();
 +  int nbOfCells=getNumberOfCells();
 +  int delta=0;
 +  const int *iciptr=_nodal_connec_index->getConstPointer();
 +  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);
 +          if(!cml.isDynamic())
 +            delta+=cm.getNumberOfNodes()-cml.getNumberOfNodes();
 +          else
 +            delta+=(iciptr[i+1]-iciptr[i]-1)/2;
 +        }
 +    }
 +  if(delta==0)
 +    return ;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
 +  const int *icptr=_nodal_connec->getConstPointer();
 +  newConn->alloc(getMeshLength()-delta,1);
 +  newConnI->alloc(nbOfCells+1,1);
 +  int *ocptr=newConn->getPointer();
 +  int *ociptr=newConnI->getPointer();
 +  *ociptr=0;
 +  _types.clear();
 +  for(int i=0;i<nbOfCells;i++,ociptr++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)icptr[iciptr[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();
 +          if(cml.isDynamic())
 +            newNbOfNodes=(iciptr[i+1]-iciptr[i]-1)/2;
 +          *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 converts all linear cell in \a this to quadratic one.
 + * Contrary to MEDCouplingUMesh::convertQuadraticCellsToLinear method, here it is needed to specify the target
 + * type of cells expected. For example INTERP_KERNEL::NORM_TRI3 can be converted to INTERP_KERNEL::NORM_TRI6 if \a conversionType is equal to 0 (the default)
 + * or to INTERP_KERNEL::NORM_TRI7 if \a conversionType is equal to 1. All non linear cells and polyhedron in \a this are let untouched.
 + * Contrary to MEDCouplingUMesh::convertQuadraticCellsToLinear method, the coordinates in \a this can be become bigger. All created nodes will be put at the
 + * end of the existing coordinates.
 + * 
 + * \param [in] conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple
 + *             corresponding quadratic cells. 1 is those creating the 'most' complex.
 + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
 + * 
 + * \throw if \a this is not fully defined. It throws too if \a conversionType is not in [0,1].
 + *
 + * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
 + */
 +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic(int conversionType)
 +{
 +  DataArrayInt *conn=0,*connI=0;
 +  DataArrayDouble *coords=0;
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  checkFullyDefined();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret,connSafe,connISafe;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsSafe;
 +  int meshDim=getMeshDimension();
 +  switch(conversionType)
 +  {
 +    case 0:
 +      switch(meshDim)
 +      {
 +        case 1:
 +          ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types);
 +          connSafe=conn; connISafe=connI; coordsSafe=coords;
 +          break;
 +        case 2:
 +          ret=convertLinearCellsToQuadratic2D0(conn,connI,coords,types);
 +          connSafe=conn; connISafe=connI; coordsSafe=coords;
 +          break;
 +        case 3:
 +          ret=convertLinearCellsToQuadratic3D0(conn,connI,coords,types);
 +          connSafe=conn; connISafe=connI; coordsSafe=coords;
 +          break;
 +        default:
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 0 mesh dimensions available are [1,2,3] !");
 +      }
 +      break;
 +        case 1:
 +          {
 +            switch(meshDim)
 +            {
 +              case 1:
 +                ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types);//it is not a bug. In 1D policy 0 and 1 are equals
 +                connSafe=conn; connISafe=connI; coordsSafe=coords;
 +                break;
 +              case 2:
 +                ret=convertLinearCellsToQuadratic2D1(conn,connI,coords,types);
 +                connSafe=conn; connISafe=connI; coordsSafe=coords;
 +                break;
 +              case 3:
 +                ret=convertLinearCellsToQuadratic3D1(conn,connI,coords,types);
 +                connSafe=conn; connISafe=connI; coordsSafe=coords;
 +                break;
 +              default:
 +                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 1 mesh dimensions available are [1,2,3] !");
 +            }
 +            break;
 +          }
 +        default:
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion type available are 0 (default, the simplest) and 1 (the most complex) !");
 +  }
 +  setConnectivity(connSafe,connISafe,false);
 +  _types=types;
 +  setCoords(coordsSafe);
 +  return ret.retn();
 +}
 +
 +#if 0
 +/*!
 + * This method only works if \a this has spaceDimension equal to 2 and meshDimension also equal to 2.
 + * This method allows to modify connectivity of cells in \a this that shares some edges in \a edgeIdsToBeSplit.
 + * The nodes to be added in those 2D cells are defined by the pair of \a  nodeIdsToAdd and \a nodeIdsIndexToAdd.
 + * Length of \a nodeIdsIndexToAdd is expected to equal to length of \a edgeIdsToBeSplit + 1.
 + * The node ids in \a nodeIdsToAdd should be valid. Those nodes have to be sorted exactly following exactly the direction of the edge.
 + * This method can be seen as the opposite method of colinearize2D.
 + * This method can be lead to create some new nodes if quadratic polygon cells have to be split. In this case the added nodes will be put at the end
 + * to avoid to modify the numbering of existing nodes.
 + *
 + * \param [in] nodeIdsToAdd - the list of node ids to be added (\a nodeIdsIndexToAdd array allows to walk on this array)
 + * \param [in] nodeIdsIndexToAdd - the entry point of \a nodeIdsToAdd to point to the corresponding nodes to be added.
 + * \param [in] mesh1Desc - 1st output of buildDescendingConnectivity2 on \a this.
 + * \param [in] desc - 2nd output of buildDescendingConnectivity2 on \a this.
 + * \param [in] descI - 3rd output of buildDescendingConnectivity2 on \a this.
 + * \param [in] revDesc - 4th output of buildDescendingConnectivity2 on \a this.
 + * \param [in] revDescI - 5th output of buildDescendingConnectivity2 on \a this.
 + *
 + * \sa buildDescendingConnectivity2
 + */
 +void MEDCouplingUMesh::splitSomeEdgesOf2DMesh(const DataArrayInt *nodeIdsToAdd, const DataArrayInt *nodeIdsIndexToAdd, const DataArrayInt *edgeIdsToBeSplit,
 +                                              const MEDCouplingUMesh *mesh1Desc, const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI)
 +{
 +  if(!nodeIdsToAdd || !nodeIdsIndexToAdd || !edgeIdsToBeSplit || !mesh1Desc || !desc || !descI || !revDesc || !revDescI)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : input pointers must be not NULL !");
 +  nodeIdsToAdd->checkAllocated(); nodeIdsIndexToAdd->checkAllocated(); edgeIdsToBeSplit->checkAllocated(); desc->checkAllocated(); descI->checkAllocated(); revDesc->checkAllocated(); revDescI->checkAllocated();
 +  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : this must have spacedim=meshdim=2 !");
 +  if(mesh1Desc->getSpaceDimension()!=2 || mesh1Desc->getMeshDimension()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : mesh1Desc must be the explosion of this with spaceDim=2 and meshDim = 1 !");
 +  //DataArrayInt *out0(0),*outi0(0);
 +  //MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0);
 +  //MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out0s(out0),outi0s(outi0);
 +  //out0s=out0s->buildUnique(); out0s->sort(true);
 +}
 +#endif
 +
 +/*!
 + * Implementes \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
 + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
 + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
 + */
 +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
 +  int nbOfCells=getNumberOfCells();
 +  int nbOfNodes=getNumberOfNodes();
 +  const int *cPtr=_nodal_connec->getConstPointer();
 +  const int *icPtr=_nodal_connec_index->getConstPointer();
 +  int lastVal=0,offset=nbOfNodes;
 +  for(int i=0;i<nbOfCells;i++,icPtr++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
 +      if(type==INTERP_KERNEL::NORM_SEG2)
 +        {
 +          types.insert(INTERP_KERNEL::NORM_SEG3);
 +          newConn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG3);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3);
 +          newConn->pushBackSilent(offset++);
 +          lastVal+=4;
 +          newConnI->pushBackSilent(lastVal);
 +          ret->pushBackSilent(i);
 +        }
 +      else
 +        {
 +          types.insert(type);
 +          lastVal+=(icPtr[1]-icPtr[0]);
 +          newConnI->pushBackSilent(lastVal);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
 +        }
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
 +  coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn();
 +  return ret.retn();
 +}
 +
 +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
 +  //
 +  const int *descPtr(desc->begin()),*descIPtr(descI->begin());
 +  DataArrayInt *conn1D=0,*conn1DI=0;
 +  std::set<INTERP_KERNEL::NormalizedCellType> types1D;
 +  DataArrayDouble *coordsTmp=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
 +  const int *c1DPtr=conn1D->begin();
 +  const int *c1DIPtr=conn1DI->begin();
 +  int nbOfCells=getNumberOfCells();
 +  const int *cPtr=_nodal_connec->getConstPointer();
 +  const int *icPtr=_nodal_connec_index->getConstPointer();
 +  int lastVal=0;
 +  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
 +      if(!cm.isQuadratic())
 +        {
 +          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType();
 +          types.insert(typ2); newConn->pushBackSilent(typ2);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
 +          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
 +            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
 +          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]);
 +          newConnI->pushBackSilent(lastVal);
 +          ret->pushBackSilent(i);
 +        }
 +      else
 +        {
 +          types.insert(typ);
 +          lastVal+=(icPtr[1]-icPtr[0]);
 +          newConnI->pushBackSilent(lastVal);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
 +        }
 +    }
 +  conn=newConn.retn(); connI=newConnI.retn(); coords=coordsTmpSafe.retn();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
 + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
 + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
 + */
 +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
 +  return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
 +}
 +
 +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner();
 +  const int *descPtr(desc->begin()),*descIPtr(descI->begin());
 +  DataArrayInt *conn1D=0,*conn1DI=0;
 +  std::set<INTERP_KERNEL::NormalizedCellType> types1D;
 +  DataArrayDouble *coordsTmp=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
 +  const int *c1DPtr=conn1D->begin();
 +  const int *c1DIPtr=conn1DI->begin();
 +  int nbOfCells=getNumberOfCells();
 +  const int *cPtr=_nodal_connec->getConstPointer();
 +  const int *icPtr=_nodal_connec_index->getConstPointer();
 +  int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
 +  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
 +      if(!cm.isQuadratic())
 +        {
 +          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
 +          types.insert(typ2); newConn->pushBackSilent(typ2);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
 +          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
 +            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
 +          newConn->pushBackSilent(offset+ret->getNumberOfTuples());
 +          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1;
 +          newConnI->pushBackSilent(lastVal);
 +          ret->pushBackSilent(i);
 +        }
 +      else
 +        {
 +          types.insert(typ);
 +          lastVal+=(icPtr[1]-icPtr[0]);
 +          newConnI->pushBackSilent(lastVal);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
 +        }
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
 +  coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
 + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
 + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
 + */
 +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
 +  return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
 +}
 +
 +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m2D=buildDescendingConnectivityGen<MinusOneSonsGeneratorBiQuadratic>(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0;
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1);
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner();
 +  const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin());
 +  DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0;
 +  std::set<INTERP_KERNEL::NormalizedCellType> types1D,types2D;
 +  DataArrayDouble *coordsTmp=0,*coordsTmp2=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmp2Safe(coordsTmp2);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn2DSafe(conn2D),conn2DISafe(conn2DI);
 +  const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin();
 +  int nbOfCells=getNumberOfCells();
 +  const int *cPtr=_nodal_connec->getConstPointer();
 +  const int *icPtr=_nodal_connec_index->getConstPointer();
 +  int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
 +  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++,desc2IPtr++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
 +      if(!cm.isQuadratic())
 +        {
 +          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
 +          if(typ2==INTERP_KERNEL::NORM_ERROR)
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::convertLinearCellsToQuadratic3D1 : On cell #" << i << " the linear cell type does not support advanced quadratization !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +          types.insert(typ2); newConn->pushBackSilent(typ2);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
 +          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
 +            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
 +          for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++)
 +            {
 +              int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1];
 +              int tmpPos=newConn->getNumberOfTuples();
 +              newConn->pushBackSilent(nodeId2);
 +              ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos);
 +            }
 +          newConn->pushBackSilent(offset+ret->getNumberOfTuples());
 +          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1;
 +          newConnI->pushBackSilent(lastVal);
 +          ret->pushBackSilent(i);
 +        }
 +      else
 +        {
 +          types.insert(typ);
 +          lastVal+=(icPtr[1]-icPtr[0]);
 +          newConnI->pushBackSilent(lastVal);
 +          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
 +        }
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffRet2D=ret2D->getDifferentValues();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples());
 +  coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
 +  std::vector<const DataArrayDouble *> v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp;
 +  int *c=newConn->getPointer();
 +  const int *cI(newConnI->begin());
 +  for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++)
 +    c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset;
 +  offset=coordsTmp2Safe->getNumberOfTuples();
 +  for(const int *elt=ret->begin();elt!=ret->end();elt++)
 +    c[cI[(*elt)+1]-1]+=offset;
 +  coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces,
 + * so that the number of cells remains the same. Quadratic faces are converted to
 + * polygons. This method works only for 2D meshes in
 + * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8,
 + * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged.
 + * \warning This method can lead to a huge amount of nodes if \a eps is very low.
 + *  \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of
 + *         a polylinized edge constituting the input polygon.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If \a this->getMeshDimension() != 2.
 + *  \throw If \a this->getSpaceDimension() != 2.
 + */
 +void MEDCouplingUMesh::tessellate2D(double eps)
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=2 || getSpaceDimension()!=2)  
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!");
 +  double epsa=fabs(eps);
 +  if(epsa<std::numeric_limits<double>::min())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc=buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
 +  revDesc1=0; revDescIndx1=0;
 +  mDesc->tessellate2DCurve(eps);
 +  subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer());
 +  setCoords(mDesc->getCoords());
 +}
 +
 +/*!
 + * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges.
 + * \warning This method can lead to a huge amount of nodes if \a eps is very low.
 + *  \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of
 + *         a sub-divided edge.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If \a this->getMeshDimension() != 1.
 + *  \throw If \a this->getSpaceDimension() != 2.
 + */
 +void MEDCouplingUMesh::tessellate2DCurve(double eps)
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=1 || getSpaceDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!");
 +  double epsa=fabs(eps);
 +  if(epsa<std::numeric_limits<double>::min())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10;
 +  int nbCells=getNumberOfCells();
 +  int nbNodes=getNumberOfNodes();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const double *coords=_coords->getConstPointer();
 +  std::vector<double> addCoo;
 +  std::vector<int> newConn;//no direct DataArrayInt because interface with Geometric2D
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI(DataArrayInt::New());
 +  newConnI->alloc(nbCells+1,1);
 +  int *newConnIPtr=newConnI->getPointer();
 +  *newConnIPtr=0;
 +  int tmp1[3];
 +  INTERP_KERNEL::Node *tmp2[3];
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  for(int i=0;i<nbCells;i++,newConnIPtr++)
 +    {
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
 +      if(cm.isQuadratic())
 +        {//assert(connI[i+1]-connI[i]-1==3)
 +          tmp1[0]=conn[connI[i]+1+0]; tmp1[1]=conn[connI[i]+1+1]; tmp1[2]=conn[connI[i]+1+2];
 +          tmp2[0]=new INTERP_KERNEL::Node(coords[2*tmp1[0]],coords[2*tmp1[0]+1]);
 +          tmp2[1]=new INTERP_KERNEL::Node(coords[2*tmp1[1]],coords[2*tmp1[1]+1]);
 +          tmp2[2]=new INTERP_KERNEL::Node(coords[2*tmp1[2]],coords[2*tmp1[2]+1]);
 +          INTERP_KERNEL::EdgeArcCircle *eac=INTERP_KERNEL::EdgeArcCircle::BuildFromNodes(tmp2[0],tmp2[2],tmp2[1]);
 +          if(eac)
 +            {
 +              eac->tesselate(tmp1,nbNodes,epsa,newConn,addCoo);
 +              types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]);
 +              delete eac;
 +              newConnIPtr[1]=(int)newConn.size();
 +            }
 +          else
 +            {
 +              types.insert(INTERP_KERNEL::NORM_SEG2);
 +              newConn.push_back(INTERP_KERNEL::NORM_SEG2);
 +              newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3);
 +              newConnIPtr[1]=newConnIPtr[0]+3;
 +            }
 +        }
 +      else
 +        {
 +          types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
 +          newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]);
 +          newConnIPtr[1]=newConnIPtr[0]+3;
 +        }
 +    }
 +  if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed
 +    return ;
 +  _types=types;
 +  DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnArr=DataArrayInt::New();
 +  newConnArr->alloc((int)newConn.size(),1);
 +  std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer());
 +  DataArrayInt::SetArrayIn(newConnArr,_nodal_connec);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=DataArrayDouble::New();
 +  newCoords->alloc(nbNodes+((int)addCoo.size())/2,2);
 +  double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer());
 +  std::copy(addCoo.begin(),addCoo.end(),work);
 +  DataArrayDouble::SetArrayIn(newCoords,_coords);
 +  updateTime();
 +}
 +
 +/*!
 + * Divides every cell of \a this mesh into simplices (triangles in 2D and tetrahedra in 3D).
 + * In addition, returns an array mapping new cells to old ones. <br>
 + * This method typically increases the number of cells in \a this mesh
 + * but the number of nodes remains \b unchanged.
 + * That's why the 3D splitting policies
 + * INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here.
 + *  \param [in] policy - specifies a pattern used for splitting.
 + * The semantic of \a policy is:
 + * - 0 - to split QUAD4 by cutting it along 0-2 diagonal (for 2D mesh only).
 + * - 1 - to split QUAD4 by cutting it along 1-3 diagonal (for 2D mesh only).
 + * - INTERP_KERNEL::PLANAR_FACE_5 - to split HEXA8  into 5 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image).
 + * - INTERP_KERNEL::PLANAR_FACE_6 - to split HEXA8  into 6 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image).
 + *
 + *
 + *  \return DataArrayInt * - a new instance of DataArrayInt holding, for each new cell,
 + *          an id of old cell producing it. The caller is to delete this array using
 + *         decrRef() as it is no more needed.
 + *
 + *  \throw If \a policy is 0 or 1 and \a this->getMeshDimension() != 2.
 + *  \throw If \a policy is INTERP_KERNEL::PLANAR_FACE_5 or INTERP_KERNEL::PLANAR_FACE_6
 + *          and \a this->getMeshDimension() != 3. 
 + *  \throw If \a policy is not one of the four discussed above.
 + *  \throw If the nodal connectivity of cells is not defined.
 + * \sa MEDCouplingUMesh::tetrahedrize, MEDCoupling1SGTUMesh::sortHexa8EachOther
 + */
 +DataArrayInt *MEDCouplingUMesh::simplexize(int policy)
 +{
 +  switch(policy)
 +  {
 +    case 0:
 +      return simplexizePol0();
 +    case 1:
 +      return simplexizePol1();
 +    case (int) INTERP_KERNEL::PLANAR_FACE_5:
 +        return simplexizePlanarFace5();
 +    case (int) INTERP_KERNEL::PLANAR_FACE_6:
 +        return simplexizePlanarFace6();
 +    default:
 +      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n  - 0 or 1 (only available for meshdim=2) \n  - PLANAR_FACE_5, PLANAR_FACE_6  (only for meshdim=3)");
 +  }
 +}
 +
 +/*!
 + * Checks if \a this mesh is constituted by simplex cells only. Simplex cells are:
 + * - 1D: INTERP_KERNEL::NORM_SEG2
 + * - 2D: INTERP_KERNEL::NORM_TRI3
 + * - 3D: INTERP_KERNEL::NORM_TETRA4.
 + *
 + * This method is useful for users that need to use P1 field services as
 + * MEDCouplingFieldDouble::getValueOn(), MEDCouplingField::buildMeasureField() etc.
 + * All these methods need mesh support containing only simplex cells.
 + *  \return bool - \c true if there are only simplex cells in \a this mesh.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If \a this->getMeshDimension() < 1.
 + */
 +bool MEDCouplingUMesh::areOnlySimplexCells() const
 +{
 +  checkFullyDefined();
 +  int mdim=getMeshDimension();
 +  if(mdim<1 || mdim>3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areOnlySimplexCells : only available with meshes having a meshdim 1, 2 or 3 !");
 +  int nbCells=getNumberOfCells();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  for(int i=0;i<nbCells;i++)
 +    {
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
 +      if(!cm.isSimplex())
 +        return false;
 +    }
 +  return true;
 +}
 +
 +/*!
 + * This method implements policy 0 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
 + */
 +DataArrayInt *MEDCouplingUMesh::simplexizePol0()
 +{
 +  checkConnectivityFullyDefined();
 +  if(getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
 +  ret->alloc(nbOfCells+nbOfCutCells,1);
 +  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
 +  int *retPt=ret->getPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
 +  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
 +  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
 +  int *pt=newConn->getPointer();
 +  int *ptI=newConnI->getPointer();
 +  ptI[0]=0;
 +  const int *oldc=_nodal_connec->getConstPointer();
 +  const int *ci=_nodal_connec_index->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,ci++)
 +    {
 +      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
 +        {
 +          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+3],
 +            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+3],oldc[ci[0]+4]};
 +          pt=std::copy(tmp,tmp+8,pt);
 +          ptI[1]=ptI[0]+4;
 +          ptI[2]=ptI[0]+8;
 +          *retPt++=i;
 +          *retPt++=i;
 +          ptI+=2;
 +        }
 +      else
 +        {
 +          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
 +          ptI[1]=ptI[0]+ci[1]-ci[0];
 +          ptI++;
 +          *retPt++=i;
 +        }
 +    }
 +  _nodal_connec->decrRef();
 +  _nodal_connec=newConn.retn();
 +  _nodal_connec_index->decrRef();
 +  _nodal_connec_index=newConnI.retn();
 +  computeTypes();
 +  updateTime();
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
 + */
 +DataArrayInt *MEDCouplingUMesh::simplexizePol1()
 +{
 +  checkConnectivityFullyDefined();
 +  if(getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
 +  ret->alloc(nbOfCells+nbOfCutCells,1);
 +  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
 +  int *retPt=ret->getPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
 +  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
 +  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
 +  int *pt=newConn->getPointer();
 +  int *ptI=newConnI->getPointer();
 +  ptI[0]=0;
 +  const int *oldc=_nodal_connec->getConstPointer();
 +  const int *ci=_nodal_connec_index->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,ci++)
 +    {
 +      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
 +        {
 +          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+4],
 +            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+2],oldc[ci[0]+3],oldc[ci[0]+4]};
 +          pt=std::copy(tmp,tmp+8,pt);
 +          ptI[1]=ptI[0]+4;
 +          ptI[2]=ptI[0]+8;
 +          *retPt++=i;
 +          *retPt++=i;
 +          ptI+=2;
 +        }
 +      else
 +        {
 +          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
 +          ptI[1]=ptI[0]+ci[1]-ci[0];
 +          ptI++;
 +          *retPt++=i;
 +        }
 +    }
 +  _nodal_connec->decrRef();
 +  _nodal_connec=newConn.retn();
 +  _nodal_connec_index->decrRef();
 +  _nodal_connec_index=newConnI.retn();
 +  computeTypes();
 +  updateTime();
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
 + */
 +DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5()
 +{
 +  checkConnectivityFullyDefined();
 +  if(getMeshDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !");
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
 +  ret->alloc(nbOfCells+4*nbOfCutCells,1);
 +  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
 +  int *retPt=ret->getPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
 +  newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1);
 +  newConn->alloc(getMeshLength()+16*nbOfCutCells,1);//21
 +  int *pt=newConn->getPointer();
 +  int *ptI=newConnI->getPointer();
 +  ptI[0]=0;
 +  const int *oldc=_nodal_connec->getConstPointer();
 +  const int *ci=_nodal_connec_index->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,ci++)
 +    {
 +      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
 +        {
 +          for(int j=0;j<5;j++,pt+=5,ptI++)
 +            {
 +              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
 +              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+3]+1];
 +              *retPt++=i;
 +              ptI[1]=ptI[0]+5;
 +            }
 +        }
 +      else
 +        {
 +          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
 +          ptI[1]=ptI[0]+ci[1]-ci[0];
 +          ptI++;
 +          *retPt++=i;
 +        }
 +    }
 +  _nodal_connec->decrRef();
 +  _nodal_connec=newConn.retn();
 +  _nodal_connec_index->decrRef();
 +  _nodal_connec_index=newConnI.retn();
 +  computeTypes();
 +  updateTime();
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
 + */
 +DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6()
 +{
 +  checkConnectivityFullyDefined();
 +  if(getMeshDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !");
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
 +  ret->alloc(nbOfCells+5*nbOfCutCells,1);
 +  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
 +  int *retPt=ret->getPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
 +  newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1);
 +  newConn->alloc(getMeshLength()+21*nbOfCutCells,1);
 +  int *pt=newConn->getPointer();
 +  int *ptI=newConnI->getPointer();
 +  ptI[0]=0;
 +  const int *oldc=_nodal_connec->getConstPointer();
 +  const int *ci=_nodal_connec_index->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,ci++)
 +    {
 +      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
 +        {
 +          for(int j=0;j<6;j++,pt+=5,ptI++)
 +            {
 +              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
 +              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+3]+1];
 +              *retPt++=i;
 +              ptI[1]=ptI[0]+5;
 +            }
 +        }
 +      else
 +        {
 +          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
 +          ptI[1]=ptI[0]+ci[1]-ci[0];
 +          ptI++;
 +          *retPt++=i;
 +        }
 +    }
 +  _nodal_connec->decrRef();
 +  _nodal_connec=newConn.retn();
 +  _nodal_connec_index->decrRef();
 +  _nodal_connec_index=newConnI.retn();
 +  computeTypes();
 +  updateTime();
 +  return ret.retn();
 +}
 +
 +/*!
 + * This private method is used to subdivide edges of a mesh with meshdim==2. If \a this has no a meshdim equal to 2 an exception will be thrown.
 + * This method completly ignore coordinates.
 + * \param nodeSubdived is the nodal connectivity of subdivision of edges
 + * \param nodeIndxSubdived is the nodal connectivity index of subdivision of edges
 + * \param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
 + * \param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
 + */
 +void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex)
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : works only on umesh with meshdim==2 !");
 +  int nbOfCells=getNumberOfCells();
 +  int *connI=_nodal_connec_index->getPointer();
 +  int newConnLgth=0;
 +  for(int i=0;i<nbOfCells;i++,connI++)
 +    {
 +      int offset=descIndex[i];
 +      int nbOfEdges=descIndex[i+1]-offset;
 +      //
 +      bool ddirect=desc[offset+nbOfEdges-1]>0;
 +      int eedgeId=std::abs(desc[offset+nbOfEdges-1])-1;
 +      int ref=ddirect?nodeSubdived[nodeIndxSubdived[eedgeId+1]-1]:nodeSubdived[nodeIndxSubdived[eedgeId]+1];
 +      for(int j=0;j<nbOfEdges;j++)
 +        {
 +          bool direct=desc[offset+j]>0;
 +          int edgeId=std::abs(desc[offset+j])-1;
 +          if(!INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodeSubdived[nodeIndxSubdived[edgeId]]).isQuadratic())
 +            {
 +              int id1=nodeSubdived[nodeIndxSubdived[edgeId]+1];
 +              int id2=nodeSubdived[nodeIndxSubdived[edgeId+1]-1];
 +              int ref2=direct?id1:id2;
 +              if(ref==ref2)
 +                {
 +                  int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
 +                  newConnLgth+=nbOfSubNodes-1;
 +                  ref=direct?id2:id1;
 +                }
 +              else
 +                {
 +                  std::ostringstream oss; oss << "MEDCouplingUMesh::subDivide2DMesh : On polygon #" << i << " edgeid #" << j << " subedges mismatch : end subedge k!=start subedge k+1 !";
 +                  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +                }
 +            }
 +          else
 +            {
 +              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : this method only subdivides into linear edges !");
 +            }
 +        }
 +      newConnLgth++;//+1 is for cell type
 +      connI[1]=newConnLgth;
 +    }
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
 +  newConn->alloc(newConnLgth,1);
 +  int *work=newConn->getPointer();
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      *work++=INTERP_KERNEL::NORM_POLYGON;
 +      int offset=descIndex[i];
 +      int nbOfEdges=descIndex[i+1]-offset;
 +      for(int j=0;j<nbOfEdges;j++)
 +        {
 +          bool direct=desc[offset+j]>0;
 +          int edgeId=std::abs(desc[offset+j])-1;
 +          if(direct)
 +            work=std::copy(nodeSubdived+nodeIndxSubdived[edgeId]+1,nodeSubdived+nodeIndxSubdived[edgeId+1]-1,work);
 +          else
 +            {
 +              int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
 +              std::reverse_iterator<const int *> it(nodeSubdived+nodeIndxSubdived[edgeId+1]);
 +              work=std::copy(it,it+nbOfSubNodes-1,work);
 +            }
 +        }
 +    }
 +  DataArrayInt::SetArrayIn(newConn,_nodal_connec);
 +  _types.clear();
 +  if(nbOfCells>0)
 +    _types.insert(INTERP_KERNEL::NORM_POLYGON);
 +}
 +
 +/*!
 + * Converts degenerated 2D or 3D linear cells of \a this mesh into cells of simpler
 + * type. For example an INTERP_KERNEL::NORM_QUAD4 cell having only three unique nodes in
 + * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell. This method
 + * does \b not perform geometrical checks and checks only nodal connectivity of cells,
 + * so it can be useful to call mergeNodes() before calling this method.
 + *  \throw If \a this->getMeshDimension() <= 1.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + */
 +void MEDCouplingUMesh::convertDegeneratedCells()
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()<=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !");
 +  int nbOfCells=getNumberOfCells();
 +  if(nbOfCells<1)
 +    return ;
 +  int initMeshLgth=getMeshLength();
 +  int *conn=_nodal_connec->getPointer();
 +  int *index=_nodal_connec_index->getPointer();
 +  int posOfCurCell=0;
 +  int newPos=0;
 +  int lgthOfCurCell;
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      lgthOfCurCell=index[i+1]-posOfCurCell;
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
 +      int newLgth;
 +      INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,
 +                                                                                                     conn+newPos+1,newLgth);
 +      conn[newPos]=newType;
 +      newPos+=newLgth+1;
 +      posOfCurCell=index[i+1];
 +      index[i+1]=newPos;
 +    }
 +  if(newPos!=initMeshLgth)
 +    _nodal_connec->reAlloc(newPos);
 +  computeTypes();
 +}
 +
 +/*!
 + * Finds incorrectly oriented cells of this 2D mesh in 3D space.
 + * A cell is considered to be oriented correctly if an angle between its
 + * normal vector and a given vector is less than \c PI / \c 2.
 + *  \param [in] vec - 3 components of the vector specifying the correct orientation of
 + *         cells. 
 + *  \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are
 + *         checked.
 + *  \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It
 + *         is not cleared before filling in.
 + *  \throw If \a this->getMeshDimension() != 2.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const
 +{
 +  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 || type==INTERP_KERNEL::NORM_QPOLYG))
 +        {
 +          bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic();
 +          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
 +            cells.push_back(i);
 +        }
 +    }
 +}
 +
 +/*!
 + * Reverse connectivity of 2D cells whose orientation is not correct. A cell is
 + * considered to be oriented correctly if an angle between its normal vector and a
 + * given vector is less than \c PI / \c 2. 
 + *  \param [in] vec - 3 components of the vector specifying the correct orientation of
 + *         cells. 
 + *  \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are
 + *         checked.
 + *  \throw If \a this->getMeshDimension() != 2.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example".
 + *  \endif
 + *
 + *  \sa changeOrientationOfCells
 + */
 +void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly)
 +{
 +  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()),*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 || type==INTERP_KERNEL::NORM_QPOLYG))
 +        {
 +          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
 +          bool isQuadratic(cm.isQuadratic());
 +          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
 +            {
 +              isModified=true;
 +              cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
 +            }
 +        }
 +    }
 +  if(isModified)
 +    _nodal_connec->declareAsNew();
 +  updateTime();
 +}
 +
 +/*!
 + * This method change the orientation of cells in \a this without any consideration of coordinates. Only connectivity is impacted.
 + *
 + * \sa orientCorrectly2DCells
 + */
 +void MEDCouplingUMesh::changeOrientationOfCells()
 +{
 +  int mdim(getMeshDimension());
 +  if(mdim!=2 && mdim!=1)
 +    throw INTERP_KERNEL::Exception("Invalid mesh to apply changeOrientationOfCells on it : must be meshDim==2 or meshDim==1 !");
 +  int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer());
 +  const int *connI(_nodal_connec_index->getConstPointer());
 +  if(mdim==2)
 +    {//2D
 +      for(int i=0;i<nbOfCells;i++)
 +        {
 +          INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
 +          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
 +          cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
 +        }
 +    }
 +  else
 +    {//1D
 +      for(int i=0;i<nbOfCells;i++)
 +        {
 +          INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
 +          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
 +          cm.changeOrientationOf1D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
 +        }
 +    }
 +}
 +
 +/*!
 + * Finds incorrectly oriented polyhedral cells, i.e. polyhedrons having correctly
 + * oriented facets. The normal vector of the facet should point out of the cell.
 + *  \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It
 + *         is not cleared before filling in.
 + *  \throw If \a this->getMeshDimension() != 3.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example".
 + *  \endif
 + */
 +void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const
 +{
 +  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);
 +        }
 +    }
 +}
 +
 +/*!
 + * Tries to fix connectivity of polyhedra, so that normal vector of all facets to point
 + * out of the cell. 
 + *  \throw If \a this->getMeshDimension() != 3.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \throw If the reparation fails.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example".
 + *  \endif
 + * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells
 + */
 +void MEDCouplingUMesh::orientCorrectlyPolyhedrons()
 +{
 +  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();
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
 +      if(type==INTERP_KERNEL::NORM_POLYHED)
 +        {
 +          try
 +          {
 +              if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
 +                TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
 +          }
 +          catch(INTERP_KERNEL::Exception& e)
 +          {
 +              std::ostringstream oss; oss << "Something wrong in polyhedron #" << i << " : " << e.what();
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +          }
 +        }
 +    }
 +  updateTime();
 +}
 +
 +/*!
 + * Finds and fixes incorrectly oriented linear extruded volumes (INTERP_KERNEL::NORM_HEXA8,
 + * INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXGP12 etc) to respect the MED convention
 + * according to which the first facet of the cell should be oriented to have the normal vector
 + * pointing out of cell.
 + *  \return DataArrayInt * - a new instance of DataArrayInt holding ids of fixed
 + *         cells. The caller is to delete this array using decrRef() as it is no more
 + *         needed. 
 + *  \throw If \a this->getMeshDimension() != 3.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a Python example".
 + *  \endif
 + * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells
 + */
 +DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells()
 +{
 +  const char msg[]="check3DCellsWellOriented detection works only for 3D cells !";
 +  if(getMeshDimension()!=3)
 +    throw INTERP_KERNEL::Exception(msg);
 +  int spaceDim=getSpaceDimension();
 +  if(spaceDim!=3)
 +    throw INTERP_KERNEL::Exception(msg);
 +  //
 +  int nbOfCells=getNumberOfCells();
 +  int *conn=_nodal_connec->getPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const double *coo=getCoords()->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cells(DataArrayInt::New()); cells->alloc(0,1);
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
 +      if(cm.isExtruded() && !cm.isDynamic() && !cm.isQuadratic())
 +        {
 +          if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coo))
 +            {
 +              CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]);
 +              cells->pushBackSilent(i);
 +            }
 +        }
 +    }
 +  return cells.retn();
 +}
 +
 +/*!
 + * This method is a faster method to correct orientation of all 3D cells in \a this.
 + * This method works only if \a this is a 3D mesh, that is to say a mesh with mesh dimension 3 and a space dimension 3.
 + * This method makes the hypothesis that \a this a coherent that is to say MEDCouplingUMesh::checkCoherency2 should throw no exception.
 + * 
 + * \return a newly allocated int array with one components containing cell ids renumbered to fit the convention of MED (MED file and MEDCoupling)
 + * \sa MEDCouplingUMesh::orientCorrectlyPolyhedrons, 
 + */
 +DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DCells()
 +{
 +  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("Invalid mesh to apply findAndCorrectBadOriented3DCells on it : must be meshDim==3 and spaceDim==3 !");
 +  int nbOfCells=getNumberOfCells();
 +  int *conn=_nodal_connec->getPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const double *coordsPtr=_coords->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
 +      switch(type)
 +      {
 +        case INTERP_KERNEL::NORM_TETRA4:
 +          {
 +            if(!IsTetra4WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
 +              {
 +                std::swap(*(conn+connI[i]+2),*(conn+connI[i]+3));
 +                ret->pushBackSilent(i);
 +              }
 +            break;
 +          }
 +        case INTERP_KERNEL::NORM_PYRA5:
 +          {
 +            if(!IsPyra5WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
 +              {
 +                std::swap(*(conn+connI[i]+2),*(conn+connI[i]+4));
 +                ret->pushBackSilent(i);
 +              }
 +            break;
 +          }
 +        case INTERP_KERNEL::NORM_PENTA6:
 +        case INTERP_KERNEL::NORM_HEXA8:
 +        case INTERP_KERNEL::NORM_HEXGP12:
 +          {
 +            if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
 +              {
 +                CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]);
 +                ret->pushBackSilent(i);
 +              }
 +            break;
 +          }
 +        case INTERP_KERNEL::NORM_POLYHED:
 +          {
 +            if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
 +              {
 +                TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
 +                ret->pushBackSilent(i);
 +              }
 +            break;
 +          }
 +        default:
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orientCorrectly3DCells : Your mesh contains type of cell not supported yet ! send mail to anthony.geay@cea.fr to add it !");
 +      }
 +    }
 +  updateTime();
 +  return ret.retn();
 +}
 +
 +/*!
 + * 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 \a 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
 +{
 +  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);
 +}
 +
 +/*!
 + * Creates a new MEDCouplingFieldDouble holding Edge Ratio values of all
 + * cells. Currently cells of the following types are treated:
 + * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4.
 + * For a cell of other type an exception is thrown.
 + * Space dimension of a 2D mesh can be either 2 or 3.
 + * The Edge Ratio of a cell \f$t\f$ is: 
 + *  \f$\frac{|t|_\infty}{|t|_0}\f$,
 + *  where \f$|t|_\infty\f$ and \f$|t|_0\f$ respectively denote the greatest and
 + *  the smallest edge lengths of \f$t\f$.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          cells and one time, lying on \a this mesh. The caller is to delete this
 + *          field using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this mesh contains elements of dimension different from the mesh dimension.
 + *  \throw If the connectivity data array has more than one component.
 + *  \throw If the connectivity data array has a named component.
 + *  \throw If the connectivity index data array has more than one component.
 + *  \throw If the connectivity index data array has a named component.
 + *  \throw If \a this->getMeshDimension() is neither 2 nor 3.
 + *  \throw If \a this->getSpaceDimension() is neither 2 nor 3.
 + *  \throw If \a this mesh includes cells of type different from the ones enumerated above.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const
 +{
 +  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,ONE_TIME);
 +  ret->setMesh(this);
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<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.
 +  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->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Creates a new MEDCouplingFieldDouble holding Aspect Ratio values of all
 + * cells. Currently cells of the following types are treated:
 + * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4.
 + * For a cell of other type an exception is thrown.
 + * Space dimension of a 2D mesh can be either 2 or 3.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          cells and one time, lying on \a this mesh. The caller is to delete this
 + *          field using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this mesh contains elements of dimension different from the mesh dimension.
 + *  \throw If the connectivity data array has more than one component.
 + *  \throw If the connectivity data array has a named component.
 + *  \throw If the connectivity index data array has more than one component.
 + *  \throw If the connectivity index data array has a named component.
 + *  \throw If \a this->getMeshDimension() is neither 2 nor 3.
 + *  \throw If \a this->getSpaceDimension() is neither 2 nor 3.
 + *  \throw If \a this mesh includes cells of type different from the ones enumerated above.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const
 +{
 +  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,ONE_TIME);
 +  ret->setMesh(this);
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<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.
 +  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->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Creates a new MEDCouplingFieldDouble holding Warping factor values of all
 + * cells of \a this 2D mesh in 3D space. Currently cells of the following types are
 + * treated: INTERP_KERNEL::NORM_QUAD4.
 + * For a cell of other type an exception is thrown.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          cells and one time, lying on \a this mesh. The caller is to delete this
 + *          field using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this mesh contains elements of dimension different from the mesh dimension.
 + *  \throw If the connectivity data array has more than one component.
 + *  \throw If the connectivity data array has a named component.
 + *  \throw If the connectivity index data array has more than one component.
 + *  \throw If the connectivity index data array has a named component.
 + *  \throw If \a this->getMeshDimension() != 2.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *  \throw If \a this mesh includes cells of type different from the ones enumerated above.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const
 +{
 +  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,ONE_TIME);
 +  ret->setMesh(this);
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<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.
 +  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->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +
 +/*!
 + * Creates a new MEDCouplingFieldDouble holding Skew factor values of all
 + * cells of \a this 2D mesh in 3D space. Currently cells of the following types are
 + * treated: INTERP_KERNEL::NORM_QUAD4.
 + * For a cell of other type an exception is thrown.
 + *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on
 + *          cells and one time, lying on \a this mesh. The caller is to delete this
 + *          field using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If \a this mesh contains elements of dimension different from the mesh dimension.
 + *  \throw If the connectivity data array has more than one component.
 + *  \throw If the connectivity data array has a named component.
 + *  \throw If the connectivity index data array has more than one component.
 + *  \throw If the connectivity index data array has a named component.
 + *  \throw If \a this->getMeshDimension() != 2.
 + *  \throw If \a this->getSpaceDimension() != 3.
 + *  \throw If \a this mesh includes cells of type different from the ones enumerated above.
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const
 +{
 +  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,ONE_TIME);
 +  ret->setMesh(this);
 +  int nbOfCells=getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<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.
 +  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->synchronizeTimeWithSupport();
 +  return ret.retn();
 +}
 +
 +/*!
 + * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell.
 + *
 + * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
 + *
 + * \sa getSkewField, getWarpField, getAspectRatioField, getEdgeRatioField
 + */
 +MEDCouplingFieldDouble *MEDCouplingUMesh::computeDiameterField() const
 +{
 +  checkCoherency();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
 +  ret->setMesh(this);
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  ComputeAllTypesInternal(types,_nodal_connec,_nodal_connec_index);
 +  int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New());
 +  arr->alloc(nbCells,1);
 +  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++)
 +    {
 +      INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(INTERP_KERNEL::CellModel::GetCellModel(*it).buildInstanceOfDiameterCalulator(spaceDim));
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds(giveCellsWithType(*it));
 +      dc->computeForListOfCellIdsUMeshFrmt(cellIds->begin(),cellIds->end(),_nodal_connec_index->begin(),_nodal_connec->begin(),getCoords()->begin(),arr->getPointer());
 +    }
 +  ret->setArray(arr);
 +  ret->setName("Diameter");
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method aggregate the bbox of each cell and put it into bbox parameter.
 + * 
 + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
 + *                         For all other cases this input parameter is ignored.
 + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
 + * 
 + * \throw If \a this is not fully set (coordinates and connectivity).
 + * \throw If a cell in \a this has no valid nodeId.
 + * \sa MEDCouplingUMesh::getBoundingBoxForBBTreeFast, MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic
 + */
 +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) const
 +{
 +  int mDim(getMeshDimension()),sDim(getSpaceDimension());
 +  if((mDim==3 && sDim==3) || (mDim==2 && sDim==3) || (mDim==1 && sDim==1) || ( mDim==1 && sDim==3))  // Compute refined boundary box for quadratic elements only in 2D.
 +    return getBoundingBoxForBBTreeFast();
 +  if((mDim==2 && sDim==2) || (mDim==1 && sDim==2))
 +    {
 +      bool presenceOfQuadratic(false);
 +      for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=_types.begin();it!=_types.end();it++)
 +        {
 +          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
 +          if(cm.isQuadratic())
 +            presenceOfQuadratic=true;
 +        }
 +      if(!presenceOfQuadratic)
 +        return getBoundingBoxForBBTreeFast();
 +      if(mDim==2 && sDim==2)
 +        return getBoundingBoxForBBTree2DQuadratic(arcDetEps);
 +      else
 +        return getBoundingBoxForBBTree1DQuadratic(arcDetEps);
 +    }
 +  throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree : Managed dimensions are (mDim=1,sDim=1), (mDim=1,sDim=2), (mDim=1,sDim=3), (mDim=2,sDim=2), (mDim=2,sDim=3) and (mDim=3,sDim=3) !");
 +}
 +
 +/*!
 + * This method aggregate the bbox of each cell only considering the nodes constituting each cell and put it into bbox parameter.
 + * So meshes having quadratic cells the computed bounding boxes can be invalid !
 + * 
 + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
 + * 
 + * \throw If \a this is not fully set (coordinates and connectivity).
 + * \throw If a cell in \a this has no valid nodeId.
 + */
 +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTreeFast() const
 +{
 +  checkFullyDefined();
 +  int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
 +  double *bbox(ret->getPointer());
 +  for(int i=0;i<nbOfCells*spaceDim;i++)
 +    {
 +      bbox[2*i]=std::numeric_limits<double>::max();
 +      bbox[2*i+1]=-std::numeric_limits<double>::max();
 +    }
 +  const double *coordsPtr(_coords->getConstPointer());
 +  const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer());
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      int offset=connI[i]+1;
 +      int nbOfNodesForCell(connI[i+1]-offset),kk(0);
 +      for(int j=0;j<nbOfNodesForCell;j++)
 +        {
 +          int nodeId=conn[offset+j];
 +          if(nodeId>=0 && nodeId<nbOfNodes)
 +            {
 +              for(int k=0;k<spaceDim;k++)
 +                {
 +                  bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
 +                  bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
 +                }
 +              kk++;
 +            }
 +        }
 +      if(kk==0)
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method aggregates the bbox of each 2D cell in \a this considering the whole shape. This method is particularly
 + * useful for 2D meshes having quadratic cells
 + * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers
 + * the two extremities of the arc of circle).
 + * 
 + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
 + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
 + * \throw If \a this is not fully defined.
 + * \throw If \a this is not a mesh with meshDimension equal to 2.
 + * \throw If \a this is not a mesh with spaceDimension equal to 2.
 + * \sa MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic
 + */
 +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arcDetEps) const
 +{
 +  checkFullyDefined();
 +  int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells());
 +  if(spaceDim!=2 || mDim!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic : This method should be applied on mesh with mesh dimension equal to 2 and space dimension also equal to 2!");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
 +  double *bbox(ret->getPointer());
 +  const double *coords(_coords->getConstPointer());
 +  const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer());
 +  for(int i=0;i<nbOfCells;i++,bbox+=4,connI++)
 +    {
 +      const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI]));
 +      int sz(connI[1]-connI[0]-1);
 +      INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=arcDetEps;
 +      std::vector<INTERP_KERNEL::Node *> nodes(sz);
 +      INTERP_KERNEL::QuadraticPolygon *pol(0);
 +      for(int j=0;j<sz;j++)
 +        {
 +          int nodeId(conn[*connI+1+j]);
 +          nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*2],coords[nodeId*2+1]);
 +        }
 +      if(!cm.isQuadratic())
 +        pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes);
 +      else
 +        pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes);
 +      INTERP_KERNEL::Bounds b; b.prepareForAggregation(); pol->fillBounds(b); delete pol;
 +      bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); 
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method aggregates the bbox of each 1D cell in \a this considering the whole shape. This method is particularly
 + * useful for 2D meshes having quadratic cells
 + * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers
 + * the two extremities of the arc of circle).
 + * 
 + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
 + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
 + * \throw If \a this is not fully defined.
 + * \throw If \a this is not a mesh with meshDimension equal to 1.
 + * \throw If \a this is not a mesh with spaceDimension equal to 2.
 + * \sa MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic
 + */
 +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic(double arcDetEps) const
 +{
 +  checkFullyDefined();
 +  int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells());
 +  if(spaceDim!=2 || mDim!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic : This method should be applied on mesh with mesh dimension equal to 1 and space dimension also equal to 2!");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
 +  double *bbox(ret->getPointer());
 +  const double *coords(_coords->getConstPointer());
 +  const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer());
 +  for(int i=0;i<nbOfCells;i++,bbox+=4,connI++)
 +    {
 +      const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI]));
 +      int sz(connI[1]-connI[0]-1);
 +      INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=arcDetEps;
 +      std::vector<INTERP_KERNEL::Node *> nodes(sz);
 +      INTERP_KERNEL::Edge *edge(0);
 +      for(int j=0;j<sz;j++)
 +        {
 +          int nodeId(conn[*connI+1+j]);
 +          nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*2],coords[nodeId*2+1]);
 +        }
 +      if(!cm.isQuadratic())
 +        edge=INTERP_KERNEL::QuadraticPolygon::BuildLinearEdge(nodes);
 +      else
 +        edge=INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(nodes);
 +      const INTERP_KERNEL::Bounds& b(edge->getBounds());
 +      bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); edge->decrRef();
 +    }
 +  return ret.retn();
 +}
 +
 +/// @cond INTERNAL
 +
 +namespace ParaMEDMEMImpl
 +{
 +  class ConnReader
 +  {
 +  public:
 +    ConnReader(const int *c, int val):_conn(c),_val(val) { }
 +    bool operator() (const int& pos) { return _conn[pos]!=_val; }
 +  private:
 +    const int *_conn;
 +    int _val;
 +  };
 +
 +  class ConnReader2
 +  {
 +  public:
 +    ConnReader2(const int *c, int val):_conn(c),_val(val) { }
 +    bool operator() (const int& pos) { return _conn[pos]==_val; }
 +  private:
 +    const int *_conn;
 +    int _val;
 +  };
 +}
 +
 +/// @endcond
 +
 +/*!
 + * This method expects that \a this is sorted by types. If not an exception will be thrown.
 + * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
 + * \a this is composed in cell types.
 + * The returned array is of size 3*n where n is the number of different types present in \a this. 
 + * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. 
 + * This parameter is kept only for compatibility with other methode listed above.
 + */
 +std::vector<int> MEDCouplingUMesh::getDistributionOfTypes() const
 +{
 +  checkConnectivityFullyDefined();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const int *work=connI;
 +  int nbOfCells=getNumberOfCells();
 +  std::size_t n=getAllGeoTypes().size();
 +  std::vector<int> ret(3*n,-1); //ret[3*k+2]==-1 because it has no sense here
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  for(std::size_t i=0;work!=connI+nbOfCells;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn[*work];
 +      if(types.find(typ)!=types.end())
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::getDistributionOfTypes : Type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr();
 +          oss << " is not contiguous !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +      types.insert(typ);
 +      ret[3*i]=typ;
 +      const int *work2=std::find_if(work+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,typ));
 +      ret[3*i+1]=(int)std::distance(work,work2);
 +      work=work2;
 +    }
 +  return ret;
 +}
 +
 +/*!
 + * This method is used to check that this has contiguous cell type in same order than described in \a code.
 + * only for types cell, type node is not managed.
 + * Format of \a code is the following. \a code should be of size 3*n and non empty. If not an exception is thrown.
 + * foreach k in [0,n) on 3*k pos represent the geometric type and 3*k+1 number of elements of type 3*k.
 + * 3*k+2 refers if different from -1 the pos in 'idsPerType' to get the corresponding array.
 + * If 2 or more same geometric type is in \a code and exception is thrown too.
 + *
 + * This method firstly checks
 + * If it exists k so that 3*k geometric type is not in geometric types of this an exception will be thrown.
 + * If it exists k so that 3*k geometric type exists but the number of consecutive cell types does not match,
 + * an exception is thrown too.
 + * 
 + * If all geometric types in \a code are exactly those in \a this null pointer is returned.
 + * If it exists a geometric type in \a this \b not in \a code \b no exception is thrown 
 + * and a DataArrayInt instance is returned that the user has the responsability to deallocate.
 + */
 +DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
 +{
 +  if(code.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code is empty, should not !");
 +  std::size_t sz=code.size();
 +  std::size_t n=sz/3;
 +  if(sz%3!=0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT %3 !");
 +  std::vector<INTERP_KERNEL::NormalizedCellType> types;
 +  int nb=0;
 +  bool isNoPflUsed=true;
 +  for(std::size_t i=0;i<n;i++)
 +    if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)code[3*i])==types.end())
 +      {
 +        types.push_back((INTERP_KERNEL::NormalizedCellType)code[3*i]);
 +        nb+=code[3*i+1];
 +        if(_types.find((INTERP_KERNEL::NormalizedCellType)code[3*i])==_types.end())
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : expected geo types not in this !");
 +        isNoPflUsed=isNoPflUsed && (code[3*i+2]==-1);
 +      }
 +  if(types.size()!=n)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code contains duplication of types in unstructured mesh !");
 +  if(isNoPflUsed)
 +    {
 +      if(!checkConsecutiveCellTypesAndOrder(&types[0],&types[0]+types.size()))
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : non contiguous type !");
 +      if(types.size()==_types.size())
 +        return 0;
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  ret->alloc(nb,1);
 +  int *retPtr=ret->getPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  const int *i=connI;
 +  int kk=0;
 +  for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++,kk++)
 +    {
 +      i=std::find_if(i,connI+nbOfCells,ParaMEDMEMImpl::ConnReader2(conn,(int)(*it)));
 +      int offset=(int)std::distance(connI,i);
 +      const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it)));
 +      int nbOfCellsOfCurType=(int)std::distance(i,j);
 +      if(code[3*kk+2]==-1)
 +        for(int k=0;k<nbOfCellsOfCurType;k++)
 +          *retPtr++=k+offset;
 +      else
 +        {
 +          int idInIdsPerType=code[3*kk+2];
 +          if(idInIdsPerType>=0 && idInIdsPerType<(int)idsPerType.size())
 +            {
 +              const DataArrayInt *zePfl=idsPerType[idInIdsPerType];
 +              if(zePfl)
 +                {
 +                  zePfl->checkAllocated();
 +                  if(zePfl->getNumberOfComponents()==1)
 +                    {
 +                      for(const int *k=zePfl->begin();k!=zePfl->end();k++,retPtr++)
 +                        {
 +                          if(*k>=0 && *k<nbOfCellsOfCurType)
 +                            *retPtr=(*k)+offset;
 +                          else
 +                            {
 +                              std::ostringstream oss; oss << "MEDCouplingUMesh::checkTypeConsistencyAndContig : the section " << kk << " points to the profile #" << idInIdsPerType;
 +                              oss << ", and this profile contains a value " << *k << " should be in [0," << nbOfCellsOfCurType << ") !";
 +                              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +                            }
 +                        }
 +                    }
 +                  else
 +                    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : presence of a profile with nb of compo != 1 !");
 +                }
 +              else
 +                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : presence of null profile !");
 +            }
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::checkTypeConsistencyAndContig : at section " << kk << " of code it points to the array #" << idInIdsPerType;
 +              oss << " should be in [0," << idsPerType.size() << ") !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +      i=j;
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method makes the hypothesis that \a this is sorted by type. If not an exception will be thrown.
 + * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
 + * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
 + * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
 + * 
 + * \param [in] profile
 + * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
 + * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
 + *              \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
 + * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
 + *              This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
 + * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
 + */
 +void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
 +{
 +  if(!profile)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile is NULL !");
 +  if(profile->getNumberOfComponents()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile should have exactly one component !");
 +  checkConnectivityFullyDefined();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  std::vector<INTERP_KERNEL::NormalizedCellType> types;
 +  std::vector<int> typeRangeVals(1);
 +  for(const int *i=connI;i!=connI+nbOfCells;)
 +    {
 +      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
 +      if(std::find(types.begin(),types.end(),curType)!=types.end())
 +        {
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : current mesh is not sorted by type !");
 +        }
 +      types.push_back(curType);
 +      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
 +      typeRangeVals.push_back((int)std::distance(connI,i));
 +    }
 +  //
 +  DataArrayInt *castArr=0,*rankInsideCast=0,*castsPresent=0;
 +  profile->splitByValueRange(&typeRangeVals[0],&typeRangeVals[0]+typeRangeVals.size(),castArr,rankInsideCast,castsPresent);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp0=castArr;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1=rankInsideCast;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2=castsPresent;
 +  //
 +  int nbOfCastsFinal=castsPresent->getNumberOfTuples();
 +  code.resize(3*nbOfCastsFinal);
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsInPflPerType2;
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerType2;
 +  for(int i=0;i<nbOfCastsFinal;i++)
 +    {
 +      int castId=castsPresent->getIJ(i,0);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp3=castArr->getIdsEqual(castId);
 +      idsInPflPerType2.push_back(tmp3);
 +      code[3*i]=(int)types[castId];
 +      code[3*i+1]=tmp3->getNumberOfTuples();
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp4=rankInsideCast->selectByTupleId(tmp3->getConstPointer(),tmp3->getConstPointer()+tmp3->getNumberOfTuples());
 +      if(tmp4->getNumberOfTuples()!=typeRangeVals[castId+1]-typeRangeVals[castId] || !tmp4->isIdentity())
 +        {
 +          tmp4->copyStringInfoFrom(*profile);
 +          idsPerType2.push_back(tmp4);
 +          code[3*i+2]=(int)idsPerType2.size()-1;
 +        }
 +      else
 +        {
 +          code[3*i+2]=-1;
 +        }
 +    }
 +  std::size_t sz2=idsInPflPerType2.size();
 +  idsInPflPerType.resize(sz2);
 +  for(std::size_t i=0;i<sz2;i++)
 +    {
 +      DataArrayInt *locDa=idsInPflPerType2[i];
 +      locDa->incrRef();
 +      idsInPflPerType[i]=locDa;
 +    }
 +  std::size_t sz=idsPerType2.size();
 +  idsPerType.resize(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      DataArrayInt *locDa=idsPerType2[i];
 +      locDa->incrRef();
 +      idsPerType[i]=locDa;
 +    }
 +}
 +
 +/*!
 + * This method is here too emulate the MEDMEM behaviour on BDC (buildDescendingConnectivity). Hoping this method becomes deprecated very soon.
 + * This method make the assumption that \a this and 'nM1LevMesh' mesh lyies on same coords (same pointer) as MED and MEDMEM does.
 + * The following equality should be verified 'nM1LevMesh->getMeshDimension()==this->getMeshDimension()-1'
 + * This method returns 5+2 elements. 'desc', 'descIndx', 'revDesc', 'revDescIndx' and 'meshnM1' behaves exactly as ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity except the content as described after. The returned array specifies the n-1 mesh reordered by type as MEDMEM does. 'nM1LevMeshIds' contains the ids in returned 'meshnM1'. Finally 'meshnM1Old2New' contains numbering old2new that is to say the cell #k in coarse 'nM1LevMesh' will have the number ret[k] in returned mesh 'nM1LevMesh' MEDMEM reordered.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const
 +{
 +  checkFullyDefined();
 +  nM1LevMesh->checkFullyDefined();
 +  if(getMeshDimension()-1!=nM1LevMesh->getMeshDimension())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : The mesh passed as first argument should have a meshDim equal to this->getMeshDimension()-1 !" );
 +  if(_coords!=nM1LevMesh->getCoords())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : 'this' and mesh in first argument should share the same coords : Use tryToShareSameCoords method !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp0=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1=buildDescendingConnectivity(desc,descIndx,tmp0,tmp1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=ret1->sortCellsInMEDFileFrmt();
 +  desc->transformWithIndArr(ret0->getConstPointer(),ret0->getConstPointer()+ret0->getNbOfElems());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
 +  tmp->setConnectivity(tmp0,tmp1);
 +  tmp->renumberCells(ret0->getConstPointer(),false);
 +  revDesc=tmp->getNodalConnectivity();
 +  revDescIndx=tmp->getNodalConnectivityIndex();
 +  DataArrayInt *ret=0;
 +  if(!ret1->areCellsIncludedIn(nM1LevMesh,2,ret))
 +    {
 +      int tmp2;
 +      ret->getMaxValue(tmp2);
 +      ret->decrRef();
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::emulateMEDMEMBDC : input N-1 mesh present a cell not in descending mesh ... Id of cell is " << tmp2 << " !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  nM1LevMeshIds=ret;
 +  //
 +  revDesc->incrRef();
 +  revDescIndx->incrRef();
 +  ret1->incrRef();
 +  ret0->incrRef();
 +  meshnM1Old2New=ret0;
 +  return ret1;
 +}
 +
 +/*!
 + * Permutes the nodal connectivity arrays so that the cells are sorted by type, which is
 + * necessary for writing the mesh to MED file. Additionally returns a permutation array
 + * in "Old to New" mode.
 + *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete
 + *          this array using decrRef() as it is no more needed.
 + *  \throw If the nodal connectivity of cells is not defined.
 + */
 +DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt()
 +{
 +  checkConnectivityFullyDefined();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=getRenumArrForMEDFileFrmt();
 +  renumberCells(ret->getConstPointer(),false);
 +  return ret.retn();
 +}
 +
 +/*!
 + * 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();
 +  std::set<INTERP_KERNEL::NormalizedCellType> types;
 +  for(const int *i=connI;i!=connI+nbOfCells;)
 +    {
 +      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
 +      if(types.find(curType)!=types.end())
 +        return false;
 +      types.insert(curType);
 +      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
 +    }
 +  return true;
 +}
 +
 +/*!
 + * This method is a specialization of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method that is called here.
 + * The geometric type order is specified by MED file.
 + * 
 + * \sa  MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder
 + */
 +bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const
 +{
 +  return checkConsecutiveCellTypesAndOrder(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER);
 +}
 +
 +/*!
 + * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check
 + * that the order is specified in array defined by [ \a orderBg , \a orderEnd ).
 + * If there is some geo types in \a this \b NOT in [ \a orderBg, \a orderEnd ) it is OK (return true) if contiguous.
 + * If there is some geo types in [ \a orderBg, \a orderEnd ) \b NOT in \a this it is OK too (return true) if contiguous.
 + */
 +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();
 +  if(nbOfCells==0)
 +    return true;
 +  int lastPos=-1;
 +  std::set<INTERP_KERNEL::NormalizedCellType> sg;
 +  for(const int *i=connI;i!=connI+nbOfCells;)
 +    {
 +      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
 +      const INTERP_KERNEL::NormalizedCellType *isTypeExists=std::find(orderBg,orderEnd,curType);
 +      if(isTypeExists!=orderEnd)
 +        {
 +          int pos=(int)std::distance(orderBg,isTypeExists);
 +          if(pos<=lastPos)
 +            return false;
 +          lastPos=pos;
 +          i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
 +        }
 +      else
 +        {
 +          if(sg.find(curType)==sg.end())
 +            {
 +              i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
 +              sg.insert(curType);
 +            }
 +          else
 +            return false;
 +        }
 +    }
 +  return true;
 +}
 +
 +/*!
 + * This method returns 2 newly allocated DataArrayInt instances. The first is an array of size 'this->getNumberOfCells()' with one component,
 + * that tells for each cell the pos of its type in the array on type given in input parameter. The 2nd output parameter is an array with the same
 + * number of tuples than input type array and with one component. This 2nd output array gives type by type the number of occurence of type in 'this'.
 + */
 +DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const
 +{
 +  checkConnectivityFullyDefined();
 +  int nbOfCells=getNumberOfCells();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpa=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpb=DataArrayInt::New();
 +  tmpa->alloc(nbOfCells,1);
 +  tmpb->alloc((int)std::distance(orderBg,orderEnd),1);
 +  tmpb->fillWithZero();
 +  int *tmp=tmpa->getPointer();
 +  int *tmp2=tmpb->getPointer();
 +  for(const int *i=connI;i!=connI+nbOfCells;i++)
 +    {
 +      const INTERP_KERNEL::NormalizedCellType *where=std::find(orderBg,orderEnd,(INTERP_KERNEL::NormalizedCellType)conn[*i]);
 +      if(where!=orderEnd)
 +        {
 +          int pos=(int)std::distance(orderBg,where);
 +          tmp2[pos]++;
 +          tmp[std::distance(connI,i)]=pos;
 +        }
 +      else
 +        {
 +          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*i]);
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::getLevArrPerCellTypes : Cell #" << std::distance(connI,i);
 +          oss << " has a type " << cm.getRepr() << " not in input array of type !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  nbPerType=tmpb.retn();
 +  return tmpa.retn();
 +}
 +
 +/*!
 + * This method behaves exactly as MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec but the order is those defined in MED file spec.
 + *
 + * \return a new object containing the old to new correspondance.
 + *
 + * \sa MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec, MEDCouplingUMesh::sortCellsInMEDFileFrmt.
 + */
 +DataArrayInt *MEDCouplingUMesh::getRenumArrForMEDFileFrmt() const
 +{
 +  return getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER);
 +}
 +
 +/*!
 + * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a 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 to MEDCouplingMesh::renumberCells 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
 +{
 +  DataArrayInt *nbPerType=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpa=getLevArrPerCellTypes(orderBg,orderEnd,nbPerType);
 +  nbPerType->decrRef();
 +  return tmpa->buildPermArrPerLevel();
 +}
 +
 +/*!
 + * This method reorganize the cells of \a this so that the cells with same geometric types are put together.
 + * The number of cells remains unchanged after the call of this method.
 + * This method tries to minimizes the number of needed permutations. So, this method behaves not exactly as
 + * MEDCouplingUMesh::sortCellsInMEDFileFrmt.
 + *
 + * \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 method splits \a 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
 +{
 +  checkConnectivityFullyDefined();
 +  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=(int)std::distance(connI,i);
 +      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
 +      int endCellId=(int)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 performs the opposite operation than those in MEDCoupling1SGTUMesh::buildUnstructured.
 + * If \a this is a single geometric type unstructured mesh, it will be converted into a more compact data structure,
 + * MEDCoupling1GTUMesh instance. The returned instance will aggregate the same DataArrayDouble instance of coordinates than \a this.
 + *
 + * \return a newly allocated instance, that the caller must manage.
 + * \throw If \a this contains more than one geometric type.
 + * \throw If the nodal connectivity of \a this is not fully defined.
 + * \throw If the internal data is not coherent.
 + */
 +MEDCoupling1GTUMesh *MEDCouplingUMesh::convertIntoSingleGeoTypeMesh() const
 +{
 +  checkConnectivityFullyDefined();
 +  if(_types.size()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : current mesh does not contain exactly one geometric type !");
 +  INTERP_KERNEL::NormalizedCellType typ=*_types.begin();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> ret=MEDCoupling1GTUMesh::New(getName(),typ);
 +  ret->setCoords(getCoords());
 +  MEDCoupling1SGTUMesh *retC=dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh*)ret);
 +  if(retC)
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=convertNodalConnectivityToStaticGeoTypeMesh();
 +      retC->setNodalConnectivity(c);
 +    }
 +  else
 +    {
 +      MEDCoupling1DGTUMesh *retD=dynamic_cast<MEDCoupling1DGTUMesh *>((MEDCoupling1GTUMesh*)ret);
 +      if(!retD)
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : Internal error !");
 +      DataArrayInt *c=0,*ci=0;
 +      convertNodalConnectivityToDynamicGeoTypeMesh(c,ci);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cs(c),cis(ci);
 +      retD->setNodalConnectivity(cs,cis);
 +    }
 +  return ret.retn();
 +}
 +
 +DataArrayInt *MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh() const
 +{
 +  checkConnectivityFullyDefined();
 +  if(_types.size()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : current mesh does not contain exactly one geometric type !");
 +  INTERP_KERNEL::NormalizedCellType typ=*_types.begin();
 +  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
 +  if(cm.isDynamic())
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : this contains a single geo type (" << cm.getRepr() << ") but ";
 +      oss << "this type is dynamic ! Only static geometric type is possible for that type ! call convertNodalConnectivityToDynamicGeoTypeMesh instead !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  int nbCells=getNumberOfCells();
 +  int typi=(int)typ;
 +  int nbNodesPerCell=(int)cm.getNumberOfNodes();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connOut=DataArrayInt::New(); connOut->alloc(nbCells*nbNodesPerCell,1);
 +  int *outPtr=connOut->getPointer();
 +  const int *conn=_nodal_connec->begin();
 +  const int *connI=_nodal_connec_index->begin();
 +  nbNodesPerCell++;
 +  for(int i=0;i<nbCells;i++,connI++)
 +    {
 +      if(conn[connI[0]]==typi && connI[1]-connI[0]==nbNodesPerCell)
 +        outPtr=std::copy(conn+connI[0]+1,conn+connI[1],outPtr);
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : there something wrong in cell #" << i << " ! The type of cell is not those expected, or the length of nodal connectivity is not those expected (" << nbNodesPerCell-1 << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  return connOut.retn();
 +}
 +
 +/*!
 + * Convert the nodal connectivity of the mesh so that all the cells are of dynamic types (polygon or quadratic
 + * polygon). This returns the corresponding new nodal connectivity in \ref numbering-indirect format.
 + * \param nodalConn
 + * \param nodalConnI
 + */
 +void MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndex) const
 +{
 +  static const char msg0[]="MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh : nodal connectivity in this are invalid ! Call checkCoherency2 !";
 +  checkConnectivityFullyDefined();
 +  if(_types.size()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh : current mesh does not contain exactly one geometric type !");
 +  int nbCells=getNumberOfCells(),lgth=_nodal_connec->getNumberOfTuples();
 +  if(lgth<nbCells)
 +    throw INTERP_KERNEL::Exception(msg0);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),ci(DataArrayInt::New());
 +  c->alloc(lgth-nbCells,1); ci->alloc(nbCells+1,1);
 +  int *cp(c->getPointer()),*cip(ci->getPointer());
 +  const int *incp(_nodal_connec->begin()),*incip(_nodal_connec_index->begin());
 +  cip[0]=0;
 +  for(int i=0;i<nbCells;i++,cip++,incip++)
 +    {
 +      int strt(incip[0]+1),stop(incip[1]);//+1 to skip geo type
 +      int delta(stop-strt);
 +      if(delta>=1)
 +        {
 +          if((strt>=0 && strt<lgth) && (stop>=0 && stop<=lgth))
 +            cp=std::copy(incp+strt,incp+stop,cp);
 +          else
 +            throw INTERP_KERNEL::Exception(msg0);
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception(msg0);
 +      cip[1]=cip[0]+delta;
 +    }
 +  nodalConn=c.retn(); nodalConnIndex=ci.retn();
 +}
 +
 +/*!
 + * This method takes in input a vector of MEDCouplingUMesh instances lying on the same coordinates with same mesh dimensions.
 + * Each mesh in \b ms must be sorted by type with the same order (typically using MEDCouplingUMesh::sortCellsInMEDFileFrmt).
 + * This method is particulary useful for MED file interaction. It allows to aggregate several meshes and keeping the type sorting
 + * and the track of the permutation by chunk of same geotype cells to retrieve it. The traditional formats old2new and new2old
 + * are not used here to avoid the build of big permutation array.
 + *
 + * \param [in] ms meshes with same mesh dimension lying on the same coords and sorted by type following de the same geometric type order than
 + *                those specified in MEDCouplingUMesh::sortCellsInMEDFileFrmt method.
 + * \param [out] szOfCellGrpOfSameType is a newly allocated DataArrayInt instance whose number of tuples is equal to the number of chunks of same geotype
 + *              in all meshes in \b ms. The accumulation of all values of this array is equal to the number of cells of returned mesh.
 + * \param [out] idInMsOfCellGrpOfSameType is a newly allocated DataArrayInt instance having the same size than \b szOfCellGrpOfSameType. This
 + *              output array gives for each chunck of same type the corresponding mesh id in \b ms.
 + * \return A newly allocated unstructured mesh that is the result of the aggregation on same coords of all meshes in \b ms. This returned mesh
 + *         is sorted by type following the geo cell types order of MEDCouplingUMesh::sortCellsInMEDFileFrmt method.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& ms,
 +                                                                            DataArrayInt *&szOfCellGrpOfSameType,
 +                                                                            DataArrayInt *&idInMsOfCellGrpOfSameType)
 +{
 +  std::vector<const MEDCouplingUMesh *> ms2;
 +  for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
 +    if(*it)
 +      {
 +        (*it)->checkConnectivityFullyDefined();
 +        ms2.push_back(*it);
 +      }
 +  if(ms2.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : input vector is empty !");
 +  const DataArrayDouble *refCoo=ms2[0]->getCoords();
 +  int meshDim=ms2[0]->getMeshDimension();
 +  std::vector<const MEDCouplingUMesh *> m1ssm;
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > m1ssmAuto;
 +  //
 +  std::vector<const MEDCouplingUMesh *> m1ssmSingle;
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > m1ssmSingleAuto;
 +  int fake=0,rk=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1(DataArrayInt::New()),ret2(DataArrayInt::New());
 +  ret1->alloc(0,1); ret2->alloc(0,1);
 +  for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++)
 +    {
 +      if(meshDim!=(*it)->getMeshDimension())
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshdims mismatch !");
 +      if(refCoo!=(*it)->getCoords())
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshes are not shared by a single coordinates coords !");
 +      std::vector<MEDCouplingUMesh *> sp=(*it)->splitByType();
 +      std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector<const MEDCouplingUMesh *> >(m1ssm));
 +      std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector<MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > >(m1ssmAuto));
 +      for(std::vector<MEDCouplingUMesh *>::const_iterator it2=sp.begin();it2!=sp.end();it2++)
 +        {
 +          MEDCouplingUMesh *singleCell=static_cast<MEDCouplingUMesh *>((*it2)->buildPartOfMySelf(&fake,&fake+1,true));
 +          m1ssmSingleAuto.push_back(singleCell);
 +          m1ssmSingle.push_back(singleCell);
 +          ret1->pushBackSilent((*it2)->getNumberOfCells()); ret2->pushBackSilent(rk);
 +        }
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum=m1ssmSingle2->sortCellsInMEDFileFrmt();
 +  std::vector<const MEDCouplingUMesh *> m1ssmfinal(m1ssm.size());
 +  for(std::size_t i=0;i<m1ssm.size();i++)
 +    m1ssmfinal[renum->getIJ(i,0)]=m1ssm[i];
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal);
 +  szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer());
 +  idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer());
 +  return ret0.retn();
 +}
 +
 +/*!
 + * This method returns a newly created DataArrayInt instance.
 + * This method retrieves cell ids in [ \a begin, \a end ) that have the type \a type.
 + */
 +DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const
 +{
 +  checkFullyDefined();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connIndex=_nodal_connec_index->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
 +  for(const int *w=begin;w!=end;w++)
 +    if((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]==type)
 +      ret->pushBackSilent(*w);
 +  return ret.retn();
 +}
 +
 +/*!
 + * 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
 +{
 +  checkFullyDefined();
 +  const int *conn=_nodal_connec->getConstPointer();
 +  const int *connI=_nodal_connec_index->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  std::set<INTERP_KERNEL::NormalizedCellType> types(getAllGeoTypes());
 +  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'
 + * This method \b works \b for mesh sorted by type.
 + * cells whose ids is in 'idsPerGeoType' array.
 + * This method conserves coords and name of mesh.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const
 +{
 +  std::vector<int> code=getDistributionOfTypes();
 +  std::size_t nOfTypesInThis=code.size()/3;
 +  int sz=0,szOfType=0;
 +  for(std::size_t i=0;i<nOfTypesInThis;i++)
 +    {
 +      if(code[3*i]!=type)
 +        sz+=code[3*i+1];
 +      else
 +        szOfType=code[3*i+1];
 +    }
 +  for(const int *work=idsPerGeoTypeBg;work!=idsPerGeoTypeEnd;work++)
 +    if(*work<0 || *work>=szOfType)
 +      {
 +        std::ostringstream oss; oss << "MEDCouplingUMesh::keepSpecifiedCells : Request on type " << type << " at place #" << std::distance(idsPerGeoTypeBg,work) << " value " << *work;
 +        oss << ". It should be in [0," << szOfType << ") !";
 +        throw INTERP_KERNEL::Exception(oss.str().c_str());
 +      }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsTokeep=DataArrayInt::New(); idsTokeep->alloc(sz+(int)std::distance(idsPerGeoTypeBg,idsPerGeoTypeEnd),1);
 +  int *idsPtr=idsTokeep->getPointer();
 +  int offset=0;
 +  for(std::size_t i=0;i<nOfTypesInThis;i++)
 +    {
 +      if(code[3*i]!=type)
 +        for(int j=0;j<code[3*i+1];j++)
 +          *idsPtr++=offset+j;
 +      else
 +        idsPtr=std::transform(idsPerGeoTypeBg,idsPerGeoTypeEnd,idsPtr,std::bind2nd(std::plus<int>(),offset));
 +      offset+=code[3*i+1];
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true));
 +  ret->copyTinyInfoFrom(this);
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method returns a vector of size 'this->getNumberOfCells()'.
 + * This method retrieves for each cell in \a this if it is linear (false) or quadratic(true).
 + */
 +std::vector<bool> MEDCouplingUMesh::getQuadraticStatus() const
 +{
 +  int ncell=getNumberOfCells();
 +  std::vector<bool> ret(ncell);
 +  const int *cI=getNodalConnectivityIndex()->getConstPointer();
 +  const int *c=getNodalConnectivity()->getConstPointer();
 +  for(int i=0;i<ncell;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[i]];
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
 +      ret[i]=cm.isQuadratic();
 +    }
 +  return ret;
 +}
 +
 +/*!
 + * Returns a newly created mesh (with ref count ==1) that contains merge of \a this and \a other.
 + */
 +MEDCouplingMesh *MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
 +{
 +  if(other->getType()!=UNSTRUCTURED)
 +    throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh each other !");
 +  const MEDCouplingUMesh *otherC=static_cast<const MEDCouplingUMesh *>(other);
 +  return MergeUMeshes(this,otherC);
 +}
 +
 +/*!
 + * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
 + * computed by averaging coordinates of cell nodes, so this method is not a right
 + * choice for degnerated meshes (not well oriented, cells with measure close to zero).
 + *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
 + *          this->getNumberOfCells() tuples per \a this->getSpaceDimension()
 + *          components. The caller is to delete this array using decrRef() as it is
 + *          no more needed.
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *  \sa MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell
 + */
 +DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
 +  int spaceDim=getSpaceDimension();
 +  int nbOfCells=getNumberOfCells();
 +  ret->alloc(nbOfCells,spaceDim);
 +  ret->copyStringInfoFrom(*getCoords());
 +  double *ptToFill=ret->getPointer();
 +  const int *nodal=_nodal_connec->getConstPointer();
 +  const int *nodalI=_nodal_connec_index->getConstPointer();
 +  const double *coor=_coords->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      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;
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method computes for each cell in \a this, the location of the iso barycenter of nodes constituting
 + * the cell. Contrary to badly named MEDCouplingUMesh::getBarycenterAndOwner method that returns the center of inertia of the 
 + * 
 + * \return a newly allocated DataArrayDouble instance that the caller has to deal with. The returned 
 + *          DataArrayDouble instance will have \c this->getNumberOfCells() tuples and \c this->getSpaceDimension() components.
 + * 
 + * \sa MEDCouplingUMesh::getBarycenterAndOwner
 + * \throw If \a this is not fully defined (coordinates and connectivity)
 + * \throw If there is presence in nodal connectivity in \a this of node ids not in [0, \c this->getNumberOfNodes() )
 + */
 +DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const
 +{
 +  checkFullyDefined();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
 +  int spaceDim=getSpaceDimension();
 +  int nbOfCells=getNumberOfCells();
 +  int nbOfNodes=getNumberOfNodes();
 +  ret->alloc(nbOfCells,spaceDim);
 +  double *ptToFill=ret->getPointer();
 +  const int *nodal=_nodal_connec->getConstPointer();
 +  const int *nodalI=_nodal_connec_index->getConstPointer();
 +  const double *coor=_coords->getConstPointer();
 +  for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[i]];
 +      std::fill(ptToFill,ptToFill+spaceDim,0.);
 +      if(type!=INTERP_KERNEL::NORM_POLYHED)
 +        {
 +          for(const int *conn=nodal+nodalI[i]+1;conn!=nodal+nodalI[i+1];conn++)
 +            {
 +              if(*conn>=0 && *conn<nbOfNodes)
 +                std::transform(coor+spaceDim*conn[0],coor+spaceDim*(conn[0]+1),ptToFill,ptToFill,std::plus<double>());
 +              else
 +                {
 +                  std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *conn << " should be in [0," <<   nbOfNodes << ") !";
 +                  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +                }
 +            }
 +          int nbOfNodesInCell=nodalI[i+1]-nodalI[i]-1;
 +          if(nbOfNodesInCell>0)
 +            std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)nbOfNodesInCell));
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of cell with no nodes !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +      else
 +        {
 +          std::set<int> s(nodal+nodalI[i]+1,nodal+nodalI[i+1]);
 +          s.erase(-1);
 +          for(std::set<int>::const_iterator it=s.begin();it!=s.end();it++)
 +            {
 +              if(*it>=0 && *it<nbOfNodes)
 +                std::transform(coor+spaceDim*(*it),coor+spaceDim*((*it)+1),ptToFill,ptToFill,std::plus<double>());
 +              else
 +                {
 +                  std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell polyhedron cell #" << i << " presence of nodeId #" << *it << " should be in [0," <<   nbOfNodes << ") !";
 +                  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +                }
 +            }
 +          if(!s.empty())
 +            std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)s.size()));
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on polyhedron cell #" << i << " there are no nodes !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * Returns a new DataArrayDouble holding barycenters of specified cells. The
 + * barycenter is computed by averaging coordinates of cell nodes. The cells to treat
 + * are specified via an array of cell ids. 
 + *  \warning Validity of the specified cell ids is not checked! 
 + *           Valid range is [ 0, \a this->getNumberOfCells() ).
 + *  \param [in] begin - an array of cell ids of interest.
 + *  \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element.
 + *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size ( \a
 + *          end - \a begin ) tuples per \a this->getSpaceDimension() components. The
 + *          caller is to delete this array using decrRef() as it is no more needed. 
 + *  \throw If the coordinates array is not set.
 + *  \throw If the nodal connectivity of cells is not defined.
 + *
 + *  \if ENABLE_EXAMPLES
 + *  \ref cpp_mcumesh_getPartBarycenterAndOwner "Here is a C++ example".<br>
 + *  \ref  py_mcumesh_getPartBarycenterAndOwner "Here is a Python example".
 + *  \endif
 + */
 +DataArrayDouble *MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const
 +{
 +  DataArrayDouble *ret=DataArrayDouble::New();
 +  int spaceDim=getSpaceDimension();
 +  int nbOfTuple=(int)std::distance(begin,end);
 +  ret->alloc(nbOfTuple,spaceDim);
 +  double *ptToFill=ret->getPointer();
 +  double *tmp=new double[spaceDim];
 +  const int *nodal=_nodal_connec->getConstPointer();
 +  const int *nodalI=_nodal_connec_index->getConstPointer();
 +  const double *coor=_coords->getConstPointer();
 +  for(const int *w=begin;w!=end;w++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[*w]];
 +      INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(type,nodal+nodalI[*w]+1,nodalI[*w+1]-nodalI[*w]-1,coor,spaceDim,ptToFill);
 +      ptToFill+=spaceDim;
 +    }
 +  delete [] tmp;
 +  return ret;
 +}
 +
 +/*!
 + * Returns a DataArrayDouble instance giving for each cell in \a this the equation of plane given by "a*X+b*Y+c*Z+d=0".
 + * So the returned instance will have 4 components and \c this->getNumberOfCells() tuples.
 + * So this method expects that \a this has a spaceDimension equal to 3 and meshDimension equal to 2.
 + * The computation of the plane equation is done using each time the 3 first nodes of 2D cells.
 + * This method is useful to detect 2D cells in 3D space that are not coplanar.
 + * 
 + * \return DataArrayDouble * - a new instance of DataArrayDouble having 4 components and a number of tuples equal to number of cells in \a this.
 + * \throw If spaceDim!=3 or meshDim!=2.
 + * \throw If connectivity of \a this is invalid.
 + * \throw If connectivity of a cell in \a this points to an invalid node.
 + */
 +DataArrayDouble *MEDCouplingUMesh::computePlaneEquationOf3DFaces() const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
 +  int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
 +  if(getSpaceDimension()!=3 || getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computePlaneEquationOf3DFaces : This method must be applied on a mesh having meshDimension equal 2 and a spaceDimension equal to 3 !");
 +  ret->alloc(nbOfCells,4);
 +  double *retPtr(ret->getPointer());
 +  const int *nodal(_nodal_connec->begin()),*nodalI(_nodal_connec_index->begin());
 +  const double *coor(_coords->begin());
 +  for(int i=0;i<nbOfCells;i++,nodalI++,retPtr+=4)
 +    {
 +      double matrix[16]={0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0},matrix2[16];
 +      if(nodalI[1]-nodalI[0]>=3)
 +        {
 +          for(int j=0;j<3;j++)
 +            {
 +              int nodeId(nodal[nodalI[0]+1+j]);
 +              if(nodeId>=0 && nodeId<nbOfNodes)
 +                std::copy(coor+nodeId*3,coor+(nodeId+1)*3,matrix+4*j);
 +              else
 +                {
 +                  std::ostringstream oss; oss << "MEDCouplingUMesh::computePlaneEquationOf3DFaces : invalid 2D cell #" << i << " ! This cell points to an invalid nodeId : " << nodeId << " !";
 +                  throw INTERP_KERNEL::Exception(oss.str().c_str());
 +                }
 +            }
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::computePlaneEquationOf3DFaces : invalid 2D cell #" << i << " ! Must be constitued by more than 3 nodes !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +      INTERP_KERNEL::inverseMatrix(matrix,4,matrix2);
 +      retPtr[0]=matrix2[3]; retPtr[1]=matrix2[7]; retPtr[2]=matrix2[11]; retPtr[3]=matrix2[15];
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method expects as input a DataArrayDouble non nul instance 'da' that should be allocated. If not an exception is thrown.
 + * 
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da)
 +{
 +  if(!da)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Build0DMeshFromCoords : instance of DataArrayDouble must be not null !");
 +  da->checkAllocated();
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(da->getName(),0);
 +  ret->setCoords(da);
 +  int nbOfTuples=da->getNumberOfTuples();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New();
 +  c->alloc(2*nbOfTuples,1);
 +  cI->alloc(nbOfTuples+1,1);
 +  int *cp=c->getPointer();
 +  int *cip=cI->getPointer();
 +  *cip++=0;
 +  for(int i=0;i<nbOfTuples;i++)
 +    {
 +      *cp++=INTERP_KERNEL::NORM_POINT1;
 +      *cp++=i;
 +      *cip++=2*(i+1);
 +    }
 +  ret->setConnectivity(c,cI,true);
 +  return ret.retn();
 +}
 +/*!
 + * Creates a new MEDCouplingUMesh by concatenating two given meshes of the same dimension.
 + * Cells and nodes of
 + * the first mesh precede cells and nodes of the second mesh within the result mesh.
 + *  \param [in] mesh1 - the first mesh.
 + *  \param [in] mesh2 - the second mesh.
 + *  \return MEDCouplingUMesh * - the result mesh. It is a new instance of
 + *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
 + *          is no more needed.
 + *  \throw If \a mesh1 == NULL or \a mesh2 == NULL.
 + *  \throw If the coordinates array is not set in none of the meshes.
 + *  \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0.
 + *  \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension().
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2)
 +{
 +  std::vector<const MEDCouplingUMesh *> tmp(2);
 +  tmp[0]=const_cast<MEDCouplingUMesh *>(mesh1); tmp[1]=const_cast<MEDCouplingUMesh *>(mesh2);
 +  return MergeUMeshes(tmp);
 +}
 +
 +/*!
 + * Creates a new MEDCouplingUMesh by concatenating all given meshes of the same dimension.
 + * Cells and nodes of
 + * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh.
 + *  \param [in] a - a vector of meshes (MEDCouplingUMesh) to concatenate.
 + *  \return MEDCouplingUMesh * - the result mesh. It is a new instance of
 + *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
 + *          is no more needed.
 + *  \throw If \a a.size() == 0.
 + *  \throw If \a a[ *i* ] == NULL.
 + *  \throw If the coordinates array is not set in none of the meshes.
 + *  \throw If \a a[ *i* ]->getMeshDimension() < 0.
 + *  \throw If the meshes in \a a are of different dimension (getMeshDimension()).
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector<const MEDCouplingUMesh *>& a)
 +{
 +  std::size_t sz=a.size();
 +  if(sz==0)
 +    return MergeUMeshesLL(a);
 +  for(std::size_t ii=0;ii<sz;ii++)
 +    if(!a[ii])
 +      {
 +        std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
 +        throw INTERP_KERNEL::Exception(oss.str().c_str());
 +      }
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > bb(sz);
 +  std::vector< const MEDCouplingUMesh * > aa(sz);
 +  int spaceDim=-3;
 +  for(std::size_t i=0;i<sz && spaceDim==-3;i++)
 +    {
 +      const MEDCouplingUMesh *cur=a[i];
 +      const DataArrayDouble *coo=cur->getCoords();
 +      if(coo)
 +        spaceDim=coo->getNumberOfComponents();
 +    }
 +  if(spaceDim==-3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : no spaceDim specified ! unable to perform merge !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
 +      aa[i]=bb[i];
 +    }
 +  return MergeUMeshesLL(aa);
 +}
 +
 +/// @cond INTERNAL
 +
 +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a)
 +{
 +  if(a.empty())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !");
 +  std::vector<const MEDCouplingUMesh *>::const_iterator it=a.begin();
 +  int meshDim=(*it)->getMeshDimension();
 +  int nbOfCells=(*it)->getNumberOfCells();
 +  int meshLgth=(*it++)->getMeshLength();
 +  for(;it!=a.end();it++)
 +    {
 +      if(meshDim!=(*it)->getMeshDimension())
 +        throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, MergeUMeshes impossible !");
 +      nbOfCells+=(*it)->getNumberOfCells();
 +      meshLgth+=(*it)->getMeshLength();
 +    }
 +  std::vector<const MEDCouplingPointSet *> aps(a.size());
 +  std::copy(a.begin(),a.end(),aps.begin());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("merge",meshDim);
 +  ret->setCoords(pts);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
 +  c->alloc(meshLgth,1);
 +  int *cPtr=c->getPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New();
 +  cI->alloc(nbOfCells+1,1);
 +  int *cIPtr=cI->getPointer();
 +  *cIPtr++=0;
 +  int offset=0;
 +  int offset2=0;
 +  for(it=a.begin();it!=a.end();it++)
 +    {
 +      int curNbOfCell=(*it)->getNumberOfCells();
 +      const int *curCI=(*it)->_nodal_connec_index->getConstPointer();
 +      const int *curC=(*it)->_nodal_connec->getConstPointer();
 +      cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus<int>(),offset));
 +      for(int j=0;j<curNbOfCell;j++)
 +        {
 +          const int *src=curC+curCI[j];
 +          *cPtr++=*src++;
 +          for(;src!=curC+curCI[j+1];src++,cPtr++)
 +            {
 +              if(*src!=-1)
 +                *cPtr=*src+offset2;
 +              else
 +                *cPtr=-1;
 +            }
 +        }
 +      offset+=curCI[curNbOfCell];
 +      offset2+=(*it)->getNumberOfNodes();
 +    }
 +  //
 +  ret->setConnectivity(c,cI,true);
 +  return ret.retn();
 +}
 +
 +/// @endcond
 +
 +/*!
 + * Creates a new MEDCouplingUMesh by concatenating cells of two given meshes of same
 + * dimension and sharing the node coordinates array.
 + * All cells of the first mesh precede all cells of the second mesh
 + * within the result mesh. 
 + *  \param [in] mesh1 - the first mesh.
 + *  \param [in] mesh2 - the second mesh.
 + *  \return MEDCouplingUMesh * - the result mesh. It is a new instance of
 + *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
 + *          is no more needed.
 + *  \throw If \a mesh1 == NULL or \a mesh2 == NULL.
 + *  \throw If the meshes do not share the node coordinates array.
 + *  \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0.
 + *  \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension().
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2)
 +{
 +  std::vector<const MEDCouplingUMesh *> tmp(2);
 +  tmp[0]=mesh1; tmp[1]=mesh2;
 +  return MergeUMeshesOnSameCoords(tmp);
 +}
 +
 +/*!
 + * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same
 + * dimension and sharing the node coordinates array.
 + * All cells of the *i*-th mesh precede all cells of the
 + * (*i*+1)-th mesh within the result mesh.
 + *  \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate.
 + *  \return MEDCouplingUMesh * - the result mesh. It is a new instance of
 + *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
 + *          is no more needed.
 + *  \throw If \a a.size() == 0.
 + *  \throw If \a a[ *i* ] == NULL.
 + *  \throw If the meshes do not share the node coordinates array.
 + *  \throw If \a a[ *i* ]->getMeshDimension() < 0.
 + *  \throw If the meshes in \a a are of different dimension (getMeshDimension()).
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes)
 +{
 +  if(meshes.empty())
 +    throw INTERP_KERNEL::Exception("meshes input parameter is expected to be non empty.");
 +  for(std::size_t ii=0;ii<meshes.size();ii++)
 +    if(!meshes[ii])
 +      {
 +        std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshesOnSameCoords : item #" << ii << " in input array of size "<< meshes.size() << " is empty !";
 +        throw INTERP_KERNEL::Exception(oss.str().c_str());
 +      }
 +  const DataArrayDouble *coords=meshes.front()->getCoords();
 +  int meshDim=meshes.front()->getMeshDimension();
 +  std::vector<const 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();
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodal=DataArrayInt::New();
 +  nodal->alloc(meshLgth,1);
 +  int *nodalPtr=nodal->getPointer();
 +  MEDCouplingAutoRefCountObjectPtr<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 meshLgth2=(*iter)->getMeshLength();
 +      nodalPtr=std::copy(nod,nod+meshLgth2,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+=meshLgth2;
 +    }
 +  MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
 +  ret->setName("merge");
 +  ret->setMeshDimension(meshDim);
 +  ret->setConnectivity(nodal,nodalIndex,true);
 +  ret->setCoords(coords);
 +  return ret;
 +}
 +
 +/*!
 + * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same
 + * dimension and sharing the node coordinates array. Cells of the *i*-th mesh precede
 + * cells of the (*i*+1)-th mesh within the result mesh. Duplicates of cells are
 + * removed from \a this mesh and arrays mapping between new and old cell ids in "Old to
 + * New" mode are returned for each input mesh.
 + *  \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate.
 + *  \param [in] compType - specifies a cell comparison technique. For meaning of its
 + *          valid values [0,1,2], see zipConnectivityTraducer().
 + *  \param [in,out] corr - an array of DataArrayInt, of the same size as \a
 + *          meshes. The *i*-th array describes cell ids mapping for \a meshes[ *i* ]
 + *          mesh. The caller is to delete each of the arrays using decrRef() as it is
 + *          no more needed.
 + *  \return MEDCouplingUMesh * - the result mesh. It is a new instance of
 + *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
 + *          is no more needed.
 + *  \throw If \a meshes.size() == 0.
 + *  \throw If \a meshes[ *i* ] == NULL.
 + *  \throw If the meshes do not share the node coordinates array.
 + *  \throw If \a meshes[ *i* ]->getMeshDimension() < 0.
 + *  \throw If the \a meshes are of different dimension (getMeshDimension()).
 + *  \throw If the nodal connectivity of cells of any of \a meshes is not defined.
 + *  \throw If the nodal connectivity any of \a meshes includes an invalid id.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr)
 +{
 +  //All checks are delegated to MergeUMeshesOnSameCoords
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MergeUMeshesOnSameCoords(meshes);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=ret->zipConnectivityTraducer(compType);
 +  corr.resize(meshes.size());
 +  std::size_t nbOfMeshes=meshes.size();
 +  int offset=0;
 +  const int *o2nPtr=o2n->getConstPointer();
 +  for(std::size_t 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;
 +      tmp->setName(meshes[i]->getName());
 +      corr[i]=tmp;
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * Makes all given meshes share the nodal connectivity array. The common connectivity
 + * array is created by concatenating the connectivity arrays of all given meshes. All
 + * the given meshes must be of the same space dimension but dimension of cells **can
 + * differ**. This method is particulary useful in MEDLoader context to build a \ref
 + * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying
 + * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array.
 + *  \param [in,out] meshes - a vector of meshes to update.
 + *  \throw If any of \a meshes is NULL.
 + *  \throw If the coordinates array is not set in any of \a meshes.
 + *  \throw If the nodal connectivity of cells is not defined in any of \a meshes.
 + *  \throw If \a meshes are of different space dimension.
 + */
 +void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCouplingUMesh *>& meshes)
 +{
 +  std::size_t sz=meshes.size();
 +  if(sz==0 || sz==1)
 +    return;
 +  std::vector< const DataArrayDouble * > coords(meshes.size());
 +  std::vector< const DataArrayDouble * >::iterator it2=coords.begin();
 +  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,it2++)
 +    {
 +      if((*it))
 +        {
 +          (*it)->checkConnectivityFullyDefined();
 +          const DataArrayDouble *coo=(*it)->getCoords();
 +          if(coo)
 +            *it2=coo;
 +          else
 +            {
 +              std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size();
 +              oss << " has no coordinate array defined !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size();
 +          oss << " is null !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> res=DataArrayDouble::Aggregate(coords);
 +  std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();
 +  int offset=(*it)->getNumberOfNodes();
 +  (*it++)->setCoords(res);
 +  for(;it!=meshes.end();it++)
 +    {
 +      int oldNumberOfNodes=(*it)->getNumberOfNodes();
 +      (*it)->setCoords(res);
 +      (*it)->shiftNodeNumbersInConn(offset);
 +      offset+=oldNumberOfNodes;
 +    }
 +}
 +
 +/*!
 + * Merges nodes coincident with a given precision within all given meshes that share
 + * the nodal connectivity array. The given meshes **can be of different** mesh
 + * dimension. This method is particulary useful in MEDLoader context to build a \ref
 + * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying
 + * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array. 
 + *  \param [in,out] meshes - a vector of meshes to update.
 + *  \param [in] eps - the precision used to detect coincident nodes (infinite norm).
 + *  \throw If any of \a meshes is NULL.
 + *  \throw If the \a meshes do not share the same node coordinates array.
 + *  \throw If the nodal connectivity of cells is not defined in any of \a meshes.
 + */
 +void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps)
 +{
 +  if(meshes.empty())
 +    return ;
 +  std::set<const DataArrayDouble *> s;
 +  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
 +    {
 +      if(*it)
 +        s.insert((*it)->getCoords());
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << " the element #" << std::distance(meshes.begin(),it) << " is null !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  if(s.size()!=1)
 +    {
 +      std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << ", it appears that they do not share the same instance of DataArrayDouble for coordiantes ! tryToShareSameCoordsPermute method can help to reach that !";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  const DataArrayDouble *coo=*(s.begin());
 +  if(!coo)
 +    return;
 +  //
 +  DataArrayInt *comm,*commI;
 +  coo->findCommonTuples(eps,-1,comm,commI);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1(comm),tmp2(commI);
 +  int oldNbOfNodes=coo->getNumberOfTuples();
 +  int newNbOfNodes;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm->begin(),commI->begin(),commI->end(),newNbOfNodes);
 +  if(oldNbOfNodes==newNbOfNodes)
 +    return ;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes);
 +  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
 +    {
 +      (*it)->renumberNodesInConn(o2n->getConstPointer());
 +      (*it)->setCoords(newCoords);
 +    } 
 +}
 +
 +/*!
 + * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [ \a connBg , \a 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_POINT1:
 +      {
 +        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));
 +        std::size_t nbOfRadFaces=std::distance(connBg+1,connEnd);
 +        for(std::size_t 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 [ \a begin , \a end ).
 + */
 +bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords)
 +{
 +  std::size_t i, ip1;
 +  double v[3]={0.,0.,0.};
 +  std::size_t sz=std::distance(begin,end);
 +  if(isQuadratic)
 +    sz/=2;
 +  for(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]];
 +    }
 +  double ret = vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2];
 +
 +  // Try using quadratic points if standard points are degenerated (for example a QPOLYG with two
 +  // SEG3 forming a circle):
 +  if (fabs(ret) < INTERP_KERNEL::DEFAULT_ABS_TOL && isQuadratic)
 +    {
 +      v[0] = 0.0; v[1] = 0.0; v[2] = 0.0;
 +      for(std::size_t j=0;j<sz;j++)
 +        {
 +          if (j%2)  // current point i is quadratic, next point i+1 is standard
 +            {
 +              i = sz+j;
 +              ip1 = (j+1)%sz; // ip1 = "i+1"
 +            }
 +          else      // current point i is standard, next point i+1 is quadratic
 +            {
 +              i = j;
 +              ip1 = j+sz;
 +            }
 +          v[0]+=coords[3*begin[i]+1]*coords[3*begin[ip1]+2]-coords[3*begin[i]+2]*coords[3*begin[ip1]+1];
 +          v[1]+=coords[3*begin[i]+2]*coords[3*begin[ip1]]-coords[3*begin[i]]*coords[3*begin[ip1]+2];
 +          v[2]+=coords[3*begin[i]]*coords[3*begin[ip1]+1]-coords[3*begin[i]+1]*coords[3*begin[ip1]];
 +        }
 +      ret = vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2];
 +    }
 +  return (ret>0.);
 +}
 +
 +/*!
 + * The polyhedron is specfied by its connectivity nodes in [ \a begin , \a end ).
 + */
 +bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords)
 +{
 +  std::vector<std::pair<int,int> > edges;
 +  std::size_t nbOfFaces=std::count(begin,end,-1)+1;
 +  const int *bgFace=begin;
 +  for(std::size_t i=0;i<nbOfFaces;i++)
 +    {
 +      const int *endFace=std::find(bgFace+1,end,-1);
 +      std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
 +      for(std::size_t 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,(int)std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION;
 +}
 +
 +/*!
 + * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [ \a begin , \a end ).
 + */
 +bool MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords)
 +{
 +  double vec0[3],vec1[3];
 +  std::size_t sz=std::distance(begin,end);
 +  if(sz%2!=0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented : the length of nodal connectivity of extruded cell is not even !");
 +  int nbOfNodes=(int)sz/2;
 +  INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(begin,nbOfNodes,coords,vec0);
 +  const double *pt0=coords+3*begin[0];
 +  const double *pt1=coords+3*begin[nbOfNodes];
 +  vec1[0]=pt1[0]-pt0[0]; vec1[1]=pt1[1]-pt0[1]; vec1[2]=pt1[2]-pt0[2];
 +  return (vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2])<0.;
 +}
 +
 +void MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end)
 +{
 +  std::size_t sz=std::distance(begin,end);
 +  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz];
 +  std::size_t nbOfNodes(sz/2);
 +  std::copy(begin,end,(int *)tmp);
 +  for(std::size_t j=1;j<nbOfNodes;j++)
 +    {
 +      begin[j]=tmp[nbOfNodes-j];
 +      begin[j+nbOfNodes]=tmp[nbOfNodes+nbOfNodes-j];
 +    }
 +}
 +
 +bool MEDCouplingUMesh::IsTetra4WellOriented(const int *begin, const int *end, const double *coords)
 +{
 +  std::size_t sz=std::distance(begin,end);
 +  if(sz!=4)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::IsTetra4WellOriented : Tetra4 cell with not 4 nodes ! Call checkCoherency2 !");
 +  double vec0[3],vec1[3];
 +  const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[1],*pt2=coords+3*begin[2],*pt3=coords+3*begin[3];
 +  vec0[0]=pt1[0]-pt0[0]; vec0[1]=pt1[1]-pt0[1]; vec0[2]=pt1[2]-pt0[2]; vec1[0]=pt2[0]-pt0[0]; vec1[1]=pt2[1]-pt0[1]; vec1[2]=pt2[2]-pt0[2]; 
 +  return ((vec0[1]*vec1[2]-vec0[2]*vec1[1])*(pt3[0]-pt0[0])+(vec0[2]*vec1[0]-vec0[0]*vec1[2])*(pt3[1]-pt0[1])+(vec0[0]*vec1[1]-vec0[1]*vec1[0])*(pt3[2]-pt0[2]))<0;
 +}
 +
 +bool MEDCouplingUMesh::IsPyra5WellOriented(const int *begin, const int *end, const double *coords)
 +{
 +  std::size_t sz=std::distance(begin,end);
 +  if(sz!=5)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::IsPyra5WellOriented : Pyra5 cell with not 5 nodes ! Call checkCoherency2 !");
 +  double vec0[3];
 +  INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(begin,4,coords,vec0);
 +  const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[4];
 +  return (vec0[0]*(pt1[0]-pt0[0])+vec0[1]*(pt1[1]-pt0[1])+vec0[2]*(pt1[2]-pt0[2]))<0.;
 +}
 +
 +/*!
 + * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [ \b begin , \b end ) 
 + * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to
 + * a 2D space.
 + *
 + * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not.
 + * \param [in] coords the coordinates with nb of components exactly equal to 3
 + * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell
 + * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded)
 + * \param [out] res the result is put at the end of the vector without any alteration of the data.
 + */
 +void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res)
 +{
 +  int nbFaces=std::count(begin+1,end,-1)+1;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> v=DataArrayDouble::New(); v->alloc(nbFaces,3);
 +  double *vPtr=v->getPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> p=DataArrayDouble::New(); p->alloc(nbFaces,1);
 +  double *pPtr=p->getPointer();
 +  const int *stFaceConn=begin+1;
 +  for(int i=0;i<nbFaces;i++,vPtr+=3,pPtr++)
 +    {
 +      const int *endFaceConn=std::find(stFaceConn,end,-1);
 +      ComputeVecAndPtOfFace(eps,coords->getConstPointer(),stFaceConn,endFaceConn,vPtr,pPtr);
 +      stFaceConn=endFaceConn+1;
 +    }
 +  pPtr=p->getPointer(); vPtr=v->getPointer();
 +  DataArrayInt *comm1=0,*commI1=0;
 +  v->findCommonTuples(eps,-1,comm1,commI1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> comm1Auto(comm1),commI1Auto(commI1);
 +  const int *comm1Ptr=comm1->getConstPointer();
 +  const int *commI1Ptr=commI1->getConstPointer();
 +  int nbOfGrps1=commI1Auto->getNumberOfTuples()-1;
 +  res->pushBackSilent((int)INTERP_KERNEL::NORM_POLYHED);
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm=MEDCouplingUMesh::New("",3);
 +  mm->setCoords(const_cast<DataArrayDouble *>(coords)); mm->allocateCells(1); mm->insertNextCell(INTERP_KERNEL::NORM_POLYHED,(int)std::distance(begin+1,end),begin+1);
 +  mm->finishInsertingCells();
 +  //
 +  for(int i=0;i<nbOfGrps1;i++)
 +    {
 +      int vecId=comm1Ptr[commI1Ptr[i]];
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmpgrp2=p->selectByTupleId(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]);
 +      DataArrayInt *comm2=0,*commI2=0;
 +      tmpgrp2->findCommonTuples(eps,-1,comm2,commI2);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> comm2Auto(comm2),commI2Auto(commI2);
 +      const int *comm2Ptr=comm2->getConstPointer();
 +      const int *commI2Ptr=commI2->getConstPointer();
 +      int nbOfGrps2=commI2Auto->getNumberOfTuples()-1;
 +      for(int j=0;j<nbOfGrps2;j++)
 +        {
 +          if(commI2Ptr[j+1]-commI2Ptr[j]<=1)
 +            {
 +              res->insertAtTheEnd(begin,end);
 +              res->pushBackSilent(-1);
 +            }
 +          else
 +            {
 +              int pointId=comm1Ptr[commI1Ptr[i]+comm2Ptr[commI2Ptr[j]]];
 +              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=comm2->selectByTupleId2(commI2Ptr[j],commI2Ptr[j+1],1);
 +              ids2->transformWithIndArr(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]);
 +              DataArrayInt *tmp0=DataArrayInt::New(),*tmp1=DataArrayInt::New(),*tmp2=DataArrayInt::New(),*tmp3=DataArrayInt::New();
 +              MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm2=mm->buildDescendingConnectivity(tmp0,tmp1,tmp2,tmp3); tmp0->decrRef(); tmp1->decrRef(); tmp2->decrRef(); tmp3->decrRef();
 +              MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm3=static_cast<MEDCouplingUMesh *>(mm2->buildPartOfMySelf(ids2->begin(),ids2->end(),true));
 +              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNodeTmp=mm3->zipCoordsTraducer();
 +              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNode=idsNodeTmp->invertArrayO2N2N2O(mm3->getNumberOfNodes());
 +              const int *idsNodePtr=idsNode->getConstPointer();
 +              double center[3]; center[0]=pPtr[pointId]*vPtr[3*vecId]; center[1]=pPtr[pointId]*vPtr[3*vecId+1]; center[2]=pPtr[pointId]*vPtr[3*vecId+2];
 +              double vec[3]; vec[0]=vPtr[3*vecId+1]; vec[1]=-vPtr[3*vecId]; vec[2]=0.;
 +              double norm=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2];
 +              if(std::abs(norm)>eps)
 +                {
 +                  double angle=INTERP_KERNEL::EdgeArcCircle::SafeAsin(norm);
 +                  mm3->rotate(center,vec,angle);
 +                }
 +              mm3->changeSpaceDimension(2);
 +              MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm4=mm3->buildSpreadZonesWithPoly();
 +              const int *conn4=mm4->getNodalConnectivity()->getConstPointer();
 +              const int *connI4=mm4->getNodalConnectivityIndex()->getConstPointer();
 +              int nbOfCells=mm4->getNumberOfCells();
 +              for(int k=0;k<nbOfCells;k++)
 +                {
 +                  int l=0;
 +                  for(const int *work=conn4+connI4[k]+1;work!=conn4+connI4[k+1];work++,l++)
 +                    res->pushBackSilent(idsNodePtr[*work]);
 +                  res->pushBackSilent(-1);
 +                }
 +            }
 +        }
 +    }
 +  res->popBackSilent();
 +}
 +
 +/*!
 + * This method computes the normalized vector of the plane and the pos of the point belonging to the plane and the line defined by the vector going
 + * through origin. The plane is defined by its nodal connectivity [ \b begin, \b end ).
 + * 
 + * \param [in] eps below that value the dot product of 2 vectors is considered as colinears
 + * \param [in] coords coordinates expected to have 3 components.
 + * \param [in] begin start of the nodal connectivity of the face.
 + * \param [in] end end of the nodal connectivity (excluded) of the face.
 + * \param [out] v the normalized vector of size 3
 + * \param [out] p the pos of plane
 + */
 +void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p)
 +{
 +  std::size_t nbPoints=std::distance(begin,end);
 +  if(nbPoints<3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeVecAndPtOfFace : < of 3 points in face ! not able to find a plane on that face !");
 +  double vec[3]={0.,0.,0.};
 +  std::size_t j=0;
 +  bool refFound=false;
 +  for(;j<nbPoints-1 && !refFound;j++)
 +    {
 +      vec[0]=coords[3*begin[j+1]]-coords[3*begin[j]];
 +      vec[1]=coords[3*begin[j+1]+1]-coords[3*begin[j]+1];
 +      vec[2]=coords[3*begin[j+1]+2]-coords[3*begin[j]+2];
 +      double norm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
 +      if(norm>eps)
 +        {
 +          refFound=true;
 +          vec[0]/=norm; vec[1]/=norm; vec[2]/=norm;
 +        }
 +    }
 +  for(std::size_t i=j;i<nbPoints-1;i++)
 +    {
 +      double curVec[3];
 +      curVec[0]=coords[3*begin[i+1]]-coords[3*begin[i]];
 +      curVec[1]=coords[3*begin[i+1]+1]-coords[3*begin[i]+1];
 +      curVec[2]=coords[3*begin[i+1]+2]-coords[3*begin[i]+2];
 +      double norm=sqrt(curVec[0]*curVec[0]+curVec[1]*curVec[1]+curVec[2]*curVec[2]);
 +      if(norm<eps)
 +        continue;
 +      curVec[0]/=norm; curVec[1]/=norm; curVec[2]/=norm;
 +      v[0]=vec[1]*curVec[2]-vec[2]*curVec[1]; v[1]=vec[2]*curVec[0]-vec[0]*curVec[2]; v[2]=vec[0]*curVec[1]-vec[1]*curVec[0];
 +      norm=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
 +      if(norm>eps)
 +        {
 +          v[0]/=norm; v[1]/=norm; v[2]/=norm;
 +          *p=v[0]*coords[3*begin[i]]+v[1]*coords[3*begin[i]+1]+v[2]*coords[3*begin[i]+2];
 +          return ;
 +        }
 +    }
 +  throw INTERP_KERNEL::Exception("Not able to find a normal vector of that 3D face !");
 +}
 +
 +/*!
 + * 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)
 +{
 +  std::list< std::pair<int,int> > edgesOK,edgesFinished;
 +  std::size_t nbOfFaces=std::count(begin,end,-1)+1;
 +  std::vector<bool> isPerm(nbOfFaces,false);//field on faces False: I don't know, True : oriented
 +  isPerm[0]=true;
 +  int *bgFace=begin,*endFace=std::find(begin+1,end,-1);
 +  std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
 +  for(std::size_t l=0;l<nbOfEdgesInFace;l++) { std::pair<int,int> p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); edgesOK.push_back(p1); }
 +  //
 +  while(std::find(isPerm.begin(),isPerm.end(),false)!=isPerm.end())
 +    {
 +      bgFace=begin;
 +      std::size_t smthChanged=0;
 +      for(std::size_t i=0;i<nbOfFaces;i++)
 +        {
 +          endFace=std::find(bgFace+1,end,-1);
 +          nbOfEdgesInFace=std::distance(bgFace,endFace);
 +          if(!isPerm[i])
 +            {
 +              bool b;
 +              for(std::size_t j=0;j<nbOfEdgesInFace;j++)
 +                {
 +                  std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
 +                  std::pair<int,int> p2(p1.second,p1.first);
 +                  bool b1=std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end();
 +                  bool b2=std::find(edgesOK.begin(),edgesOK.end(),p2)!=edgesOK.end();
 +                  if(b1 || b2) { b=b2; isPerm[i]=true; smthChanged++; break; }
 +                }
 +              if(isPerm[i])
 +                { 
 +                  if(!b)
 +                    std::reverse(bgFace+1,endFace);
 +                  for(std::size_t j=0;j<nbOfEdgesInFace;j++)
 +                    {
 +                      std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
 +                      std::pair<int,int> p2(p1.second,p1.first);
 +                      if(std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end())
 +                        { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
 +                      if(std::find(edgesFinished.begin(),edgesFinished.end(),p1)!=edgesFinished.end() || std::find(edgesFinished.begin(),edgesFinished.end(),p2)!=edgesFinished.end())
 +                        { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
 +                      std::list< std::pair<int,int> >::iterator it=std::find(edgesOK.begin(),edgesOK.end(),p2);
 +                      if(it!=edgesOK.end())
 +                        {
 +                          edgesOK.erase(it);
 +                          edgesFinished.push_back(p1);
 +                        }
 +                      else
 +                        edgesOK.push_back(p1);
 +                    }
 +                }
 +            }
 +          bgFace=endFace+1;
 +        }
 +      if(smthChanged==0)
 +        { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired !"); }
 +    }
 +  if(!edgesOK.empty())
 +    { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired : Some edges are shared only once !"); }
 +  if(INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION)
 +    {//not lucky ! The first face was not correctly oriented : reorient all faces...
 +      bgFace=begin;
 +      for(std::size_t i=0;i<nbOfFaces;i++)
 +        {
 +          endFace=std::find(bgFace+1,end,-1);
 +          std::reverse(bgFace+1,endFace);
 +          bgFace=endFace+1;
 +        }
 +    }
 +}
 +
 +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const
 +{
 +  int nbOfNodesExpected(skin->getNumberOfNodes());
 +  const int *n2oPtr(n2o->getConstPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
 +  skin->getReverseNodalConnectivity(revNodal,revNodalI);
 +  const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer());
 +  const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer());
 +  const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1);
 +  int *work(ret->getPointer());  *work++=INTERP_KERNEL::NORM_POLYGON;
 +  if(nbOfNodesExpected<1)
 +    return ret.retn();
 +  int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]);
 +  *work++=n2oPtr[prevNode];
 +  for(int i=1;i<nbOfNodesExpected;i++)
 +    {
 +      if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==3)
 +        {
 +          std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3);
 +          conn.erase(prevNode);
 +          if(conn.size()==1)
 +            {
 +              int curNode(*(conn.begin()));
 +              *work++=n2oPtr[curNode];
 +              std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
 +              shar.erase(prevCell);
 +              if(shar.size()==1)
 +                {
 +                  prevCell=*(shar.begin());
 +                  prevNode=curNode;
 +                }
 +              else
 +                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !");
 +            }
 +          else
 +            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !");
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !");
 +    }
 +  return ret.retn();
 +}
 +
 +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const
 +{
 +  int nbOfNodesExpected(skin->getNumberOfNodes());
 +  int nbOfTurn(nbOfNodesExpected/2);
 +  const int *n2oPtr(n2o->getConstPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
 +  skin->getReverseNodalConnectivity(revNodal,revNodalI);
 +  const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer());
 +  const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer());
 +  const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1);
 +  int *work(ret->getPointer());  *work++=INTERP_KERNEL::NORM_QPOLYG;
 +  if(nbOfNodesExpected<1)
 +    return ret.retn();
 +  int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]);
 +  *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++;
 +  for(int i=1;i<nbOfTurn;i++)
 +    {
 +      if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==4)
 +        {
 +          std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3);
 +          conn.erase(prevNode);
 +          if(conn.size()==1)
 +            {
 +              int curNode(*(conn.begin()));
 +              *work=n2oPtr[curNode];
 +              std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
 +              shar.erase(prevCell);
 +              if(shar.size()==1)
 +                {
 +                  int curCell(*(shar.begin()));
 +                  work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]];
 +                  prevCell=curCell;
 +                  prevNode=curNode;
 +                  work++;
 +                }
 +              else
 +                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !");
 +            }
 +          else
 +            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !");
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !");
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method makes the assumption spacedimension == meshdimension == 2.
 + * This method works only for linear cells.
 + * 
 + * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0)
 + */
 +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const
 +{
 +  if(getMeshDimension()!=2 || getSpaceDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> skin(computeSkin());
 +  int oldNbOfNodes(skin->getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(skin->zipCoordsTraducer());
 +  int nbOfNodesExpected(skin->getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(oldNbOfNodes));
 +  int nbCells(skin->getNumberOfCells());
 +  if(nbCells==nbOfNodesExpected)
 +    return buildUnionOf2DMeshLinear(skin,n2o);
 +  else if(2*nbCells==nbOfNodesExpected)
 +    return buildUnionOf2DMeshQuadratic(skin,n2o);
 +  else
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part of a 2D mesh !");
 +}
 +
 +/*!
 + * This method makes the assumption spacedimension == meshdimension == 3.
 + * This method works only for linear cells.
 + * 
 + * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYHED in pos#0)
 + */
 +DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const
 +{
 +  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf3DMesh : meshdimension, spacedimension must be equal to 2 !");
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=computeSkin();
 +  const int *conn=m->getNodalConnectivity()->getConstPointer();
 +  const int *connI=m->getNodalConnectivityIndex()->getConstPointer();
 +  int nbOfCells=m->getNumberOfCells();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(m->getNodalConnectivity()->getNumberOfTuples(),1);
 +  int *work=ret->getPointer();  *work++=INTERP_KERNEL::NORM_POLYHED;
 +  if(nbOfCells<1)
 +    return ret.retn();
 +  work=std::copy(conn+connI[0]+1,conn+connI[1],work);
 +  for(int i=1;i<nbOfCells;i++)
 +    {
 +      *work++=-1;
 +      work=std::copy(conn+connI[i]+1,conn+connI[i+1],work);
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * \brief Creates a graph of cell neighbors
 + *  \return MEDCouplingSkyLineArray * - an sky line array the user should delete.
 + *  In the sky line array, graph arcs are stored in terms of (index,value) notation.
 + *  For example
 + *  - index:  0 3 5 6 6
 + *  - value:  1 2 3 2 3 3
 + *  means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3)
 + *  Arcs are not doubled but reflexive (1,1) arcs are present for each cell
 + */
 +MEDCouplingSkyLineArray *MEDCouplingUMesh::generateGraph() const
 +{
 +  checkConnectivityFullyDefined();
 +
 +  int meshDim = this->getMeshDimension();
 +  ParaMEDMEM::DataArrayInt* indexr=ParaMEDMEM::DataArrayInt::New();
 +  ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New();
 +  this->getReverseNodalConnectivity(revConn,indexr);
 +  const int* indexr_ptr=indexr->getConstPointer();
 +  const int* revConn_ptr=revConn->getConstPointer();
 +
 +  const ParaMEDMEM::DataArrayInt* index;
 +  const ParaMEDMEM::DataArrayInt* conn;
 +  conn=this->getNodalConnectivity(); // it includes a type as the 1st element!!!
 +  index=this->getNodalConnectivityIndex();
 +  int nbCells=this->getNumberOfCells();
 +  const int* index_ptr=index->getConstPointer();
 +  const int* conn_ptr=conn->getConstPointer();
 +
 +  //creating graph arcs (cell to cell relations)
 +  //arcs are stored in terms of (index,value) notation
 +  // 0 3 5 6 6
 +  // 1 2 3 2 3 3
 +  // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3)
 +  // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell
 +
 +  //warning here one node have less than or equal effective number of cell with it
 +  //but cell could have more than effective nodes
 +  //because other equals nodes in other domain (with other global inode)
 +  std::vector <int> cell2cell_index(nbCells+1,0);
 +  std::vector <int> cell2cell;
 +  cell2cell.reserve(3*nbCells);
 +
 +  for (int icell=0; icell<nbCells;icell++)
 +    {
 +      std::map<int,int > counter;
 +      for (int iconn=index_ptr[icell]+1; iconn<index_ptr[icell+1];iconn++)
 +        {
 +          int inode=conn_ptr[iconn];
 +          for (int iconnr=indexr_ptr[inode]; iconnr<indexr_ptr[inode+1];iconnr++)
 +            {
 +              int icell2=revConn_ptr[iconnr];
 +              std::map<int,int>::iterator iter=counter.find(icell2);
 +              if (iter!=counter.end()) (iter->second)++;
 +              else counter.insert(std::make_pair(icell2,1));
 +            }
 +        }
 +      for (std::map<int,int>::const_iterator iter=counter.begin();
 +           iter!=counter.end(); iter++)
 +        if (iter->second >= meshDim)
 +          {
 +            cell2cell_index[icell+1]++;
 +            cell2cell.push_back(iter->first);
 +          }
 +    }
 +  indexr->decrRef();
 +  revConn->decrRef();
 +  cell2cell_index[0]=0;
 +  for (int icell=0; icell<nbCells;icell++)
 +    cell2cell_index[icell+1]=cell2cell_index[icell]+cell2cell_index[icell+1];
 +
 +  //filling up index and value to create skylinearray structure
 +  MEDCouplingSkyLineArray* array=new MEDCouplingSkyLineArray(cell2cell_index,cell2cell);
 +  return array;
 +}
 +
 +/*!
 + * 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)
 +{
 +  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 !");
 +}
 +
 +void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
 +{
 +  int nbOfCells=getNumberOfCells();
 +  if(nbOfCells<=0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::writeVTK : the unstructured mesh has no cells !");
 +  static const int PARAMEDMEM2VTKTYPETRADUCER[INTERP_KERNEL::NORM_MAXTYPE+1]={1,3,21,5,9,7,22,34,23,28,-1,-1,-1,-1,10,14,13,-1,12,-1,24,-1,16,27,-1,26,-1,29,-1,-1,25,42,36,4};
 +  ofs << "  <" << getVTKDataSetType() << ">\n";
 +  ofs << "    <Piece NumberOfPoints=\"" << getNumberOfNodes() << "\" NumberOfCells=\"" << nbOfCells << "\">\n";
 +  ofs << "      <PointData>\n" << pointData << std::endl;
 +  ofs << "      </PointData>\n";
 +  ofs << "      <CellData>\n" << cellData << std::endl;
 +  ofs << "      </CellData>\n";
 +  ofs << "      <Points>\n";
 +  if(getSpaceDimension()==3)
 +    _coords->writeVTK(ofs,8,"Points",byteData);
 +  else
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->changeNbOfComponents(3,0.);
 +      coo->writeVTK(ofs,8,"Points",byteData);
 +    }
 +  ofs << "      </Points>\n";
 +  ofs << "      <Cells>\n";
 +  const int *cPtr=_nodal_connec->getConstPointer();
 +  const int *cIPtr=_nodal_connec_index->getConstPointer();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faceoffsets=DataArrayInt::New(); faceoffsets->alloc(nbOfCells,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> types=DataArrayInt::New(); types->alloc(nbOfCells,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> offsets=DataArrayInt::New(); offsets->alloc(nbOfCells,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connectivity=DataArrayInt::New(); connectivity->alloc(_nodal_connec->getNumberOfTuples()-nbOfCells,1);
 +  int *w1=faceoffsets->getPointer(),*w2=types->getPointer(),*w3=offsets->getPointer(),*w4=connectivity->getPointer();
 +  int szFaceOffsets=0,szConn=0;
 +  for(int i=0;i<nbOfCells;i++,w1++,w2++,w3++)
 +    {
 +      *w2=cPtr[cIPtr[i]];
 +      if((INTERP_KERNEL::NormalizedCellType)cPtr[cIPtr[i]]!=INTERP_KERNEL::NORM_POLYHED)
 +        {
 +          *w1=-1;
 +          *w3=szConn+cIPtr[i+1]-cIPtr[i]-1; szConn+=cIPtr[i+1]-cIPtr[i]-1;
 +          w4=std::copy(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1],w4);
 +        }
 +      else
 +        {
 +          int deltaFaceOffset=cIPtr[i+1]-cIPtr[i]+1;
 +          *w1=szFaceOffsets+deltaFaceOffset; szFaceOffsets+=deltaFaceOffset;
 +          std::set<int> c(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1]); c.erase(-1);
 +          *w3=szConn+(int)c.size(); szConn+=(int)c.size();
 +          w4=std::copy(c.begin(),c.end(),w4);
 +        }
 +    }
 +  types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE+1);
 +  types->writeVTK(ofs,8,"UInt8","types",byteData);
 +  offsets->writeVTK(ofs,8,"Int32","offsets",byteData);
 +  if(szFaceOffsets!=0)
 +    {//presence of Polyhedra
 +      connectivity->reAlloc(szConn);
 +      faceoffsets->writeVTK(ofs,8,"Int32","faceoffsets",byteData);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faces=DataArrayInt::New(); faces->alloc(szFaceOffsets,1);
 +      w1=faces->getPointer();
 +      for(int i=0;i<nbOfCells;i++)
 +        if((INTERP_KERNEL::NormalizedCellType)cPtr[cIPtr[i]]==INTERP_KERNEL::NORM_POLYHED)
 +          {
 +            int nbFaces=std::count(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1],-1)+1;
 +            *w1++=nbFaces;
 +            const int *w6=cPtr+cIPtr[i]+1,*w5=0;
 +            for(int j=0;j<nbFaces;j++)
 +              {
 +                w5=std::find(w6,cPtr+cIPtr[i+1],-1);
 +                *w1++=(int)std::distance(w6,w5);
 +                w1=std::copy(w6,w5,w1);
 +                w6=w5+1;
 +              }
 +          }
 +      faces->writeVTK(ofs,8,"Int32","faces",byteData);
 +    }
 +  connectivity->writeVTK(ofs,8,"Int32","connectivity",byteData);
 +  ofs << "      </Cells>\n";
 +  ofs << "    </Piece>\n";
 +  ofs << "  </" << getVTKDataSetType() << ">\n";
 +}
 +
 +void MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const
 +{
 +  stream << "MEDCouplingUMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
 +  if(_mesh_dim==-2)
 +    { stream << " Not set !"; return ; }
 +  stream << " Mesh dimension : " << _mesh_dim << ".";
 +  if(_mesh_dim==-1)
 +    return ;
 +  if(!_coords)
 +    { stream << " No coordinates set !"; return ; }
 +  if(!_coords->isAllocated())
 +    { stream << " Coordinates set but not allocated !"; return ; }
 +  stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
 +  stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
 +  if(!_nodal_connec_index)
 +    { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
 +  if(!_nodal_connec_index->isAllocated())
 +    { stream << std::endl << "Nodal connectivity set but not allocated !"; return ; }
 +  int lgth=_nodal_connec_index->getNumberOfTuples();
 +  int cpt=_nodal_connec_index->getNumberOfComponents();
 +  if(cpt!=1 || lgth<1)
 +    return ;
 +  stream << std::endl << "Number of cells : " << lgth-1 << ".";
 +}
 +
 +std::string MEDCouplingUMesh::getVTKDataSetType() const
 +{
 +  return std::string("UnstructuredGrid");
 +}
 +
 +std::string MEDCouplingUMesh::getVTKFileExtension() const
 +{
 +  return std::string("vtu");
 +}
 +
 +/*!
 + * Partitions the first given 2D mesh using the second given 2D mesh as a tool, and
 + * returns a result mesh constituted by polygons.
 + * Thus the final result contains all nodes from m1 plus new nodes. However it doesn't necessarily contains
 + * all nodes from m2.
 + * The meshes should be in 2D space. In
 + * addition, returns two arrays mapping cells of the result mesh to cells of the input
 + * meshes.
 + *  \param [in] m1 - the first input mesh which is a partitioned object. The mesh must be so that each point in the space covered by \a m1
 + *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
 + *  \param [in] m2 - the second input mesh which is a partition tool. The mesh must be so that each point in the space covered by \a m2
 + *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
 + *  \param [in] eps - precision used to detect coincident mesh entities.
 + *  \param [out] cellNb1 - a new instance of DataArrayInt holding for each result
 + *         cell an id of the cell of \a m1 it comes from. The caller is to delete
 + *         this array using decrRef() as it is no more needed.
 + *  \param [out] cellNb2 - a new instance of DataArrayInt holding for each result
 + *         cell an id of the cell of \a m2 it comes from. -1 value means that a
 + *         result cell comes from a cell (or part of cell) of \a m1 not overlapped by
 + *         any cell of \a m2. The caller is to delete this array using decrRef() as
 + *         it is no more needed.  
 + *  \return MEDCouplingUMesh * - the result 2D mesh which is a new instance of
 + *         MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
 + *         is no more needed.  
 + *  \throw If the coordinates array is not set in any of the meshes.
 + *  \throw If the nodal connectivity of cells is not defined in any of the meshes.
 + *  \throw If any of the meshes is not a 2D mesh in 2D space.
 + *
 + *  \sa conformize2D, mergeNodes
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2,
 +                                                      double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2)
 +{
 +  if(!m1 || !m2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes : input meshes must be not NULL !");
 +  m1->checkFullyDefined();
 +  m2->checkFullyDefined();
 +  if(m1->getMeshDimension()!=2 || m1->getSpaceDimension()!=2 || m2->getMeshDimension()!=2 || m2->getSpaceDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes works on umeshes m1 AND m2  with meshdim equal to 2 and spaceDim equal to 2 too!");
 +
 +  // Step 1: compute all edge intersections (new nodes)
 +  std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2;
 +  MEDCouplingUMesh *m1Desc=0,*m2Desc=0; // descending connec. meshes
 +  DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0;
 +  std::vector<double> addCoo,addCoordsQuadratic;  // coordinates of newly created nodes
 +  IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,colinear2, subDiv2,
 +                              m1Desc,desc1,descIndx1,revDesc1,revDescIndx1,
 +                              addCoo, m2Desc,desc2,descIndx2,revDesc2,revDescIndx2);
 +  revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(desc2),dd4(descIndx2);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd5(m1Desc),dd6(m2Desc);
 +
 +  // Step 2: re-order newly created nodes according to the ordering found in m2
 +  std::vector< std::vector<int> > intersectEdge2;
 +  BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2);
 +  subDiv2.clear(); dd5=0; dd6=0;
 +
 +  // Step 3:
 +  std::vector<int> cr,crI; //no DataArrayInt because interface with Geometric2D
 +  std::vector<int> cNb1,cNb2; //no DataArrayInt because interface with Geometric2D
 +  BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo,
 +                                    /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2);
 +
 +  // Step 4: Prepare final result:
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCooDa(DataArrayDouble::New());
 +  addCooDa->alloc((int)(addCoo.size())/2,2);
 +  std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCoordsQuadraticDa(DataArrayDouble::New());
 +  addCoordsQuadraticDa->alloc((int)(addCoordsQuadratic.size())/2,2);
 +  std::copy(addCoordsQuadratic.begin(),addCoordsQuadratic.end(),addCoordsQuadraticDa->getPointer());
 +  std::vector<const DataArrayDouble *> coordss(4);
 +  coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa; coordss[3]=addCoordsQuadraticDa;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::Aggregate(coordss));
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("Intersect2D",2));
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connI(DataArrayInt::New()); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c1(DataArrayInt::New()); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c2(DataArrayInt::New()); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer());
 +  ret->setConnectivity(conn,connI,true);
 +  ret->setCoords(coo);
 +  cellNb1=c1.retn(); cellNb2=c2.retn();
 +  return ret.retn();
 +}
 +
 +/// @cond INTERNAL
 +
 +bool IsColinearOfACellOf(const std::vector< std::vector<int> >& intersectEdge1, const std::vector<int>& candidates, int start, int stop, int& retVal)
 +{
 +  if(candidates.empty())
 +    return false;
 +  for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
 +    {
 +      const std::vector<int>& pool(intersectEdge1[*it]);
 +      int tmp[2]; tmp[0]=start; tmp[1]=stop;
 +      if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end())
 +        {
 +          retVal=*it+1;
 +          return true;
 +        }
 +      tmp[0]=stop; tmp[1]=start;
 +      if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end())
 +        {
 +          retVal=-*it-1;
 +          return true;
 +        }
 +    }
 +  return false;
 +}
 +
 +MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector<int> >& intersectEdge2, const DataArrayDouble *coords1, const std::vector<double>& addCoo, const std::map<int,int>& mergedNodes, const std::vector< std::vector<int> >& colinear2, const std::vector< std::vector<int> >& intersectEdge1,
 +                                     MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsInRetColinear, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsInMesh1DForIdsInRetColinear)
 +{
 +  idsInRetColinear=DataArrayInt::New(); idsInRetColinear->alloc(0,1);
 +  idsInMesh1DForIdsInRetColinear=DataArrayInt::New(); idsInMesh1DForIdsInRetColinear->alloc(0,1);
 +  int nCells(mesh1D->getNumberOfCells());
 +  if(nCells!=(int)intersectEdge2.size())
 +    throw INTERP_KERNEL::Exception("BuildMesh1DCutFrom : internal error # 1 !");
 +  const DataArrayDouble *coo2(mesh1D->getCoords());
 +  const int *c(mesh1D->getNodalConnectivity()->begin()),*ci(mesh1D->getNodalConnectivityIndex()->begin());
 +  const double *coo2Ptr(coo2->begin());
 +  int offset1(coords1->getNumberOfTuples());
 +  int offset2(offset1+coo2->getNumberOfTuples());
 +  int offset3(offset2+addCoo.size()/2);
 +  std::vector<double> addCooQuad;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cOut(DataArrayInt::New()),ciOut(DataArrayInt::New()); cOut->alloc(0,1); ciOut->alloc(1,1); ciOut->setIJ(0,0,0);
 +  int tmp[4],cicnt(0),kk(0);
 +  for(int i=0;i<nCells;i++)
 +    {
 +      std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m;
 +      INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coo2Ptr,m));
 +      const std::vector<int>& subEdges(intersectEdge2[i]);
 +      int nbSubEdge(subEdges.size()/2);
 +      for(int j=0;j<nbSubEdge;j++,kk++)
 +        {
 +          MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)),n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo));
 +          MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> e2(e->buildEdgeLyingOnMe(n1,n2));
 +          INTERP_KERNEL::Edge *e2Ptr(e2);
 +          std::map<int,int>::const_iterator itm;
 +          if(dynamic_cast<INTERP_KERNEL::EdgeArcCircle *>(e2Ptr))
 +            {
 +              tmp[0]=INTERP_KERNEL::NORM_SEG3;
 +              itm=mergedNodes.find(subEdges[2*j]);
 +              tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j];
 +              itm=mergedNodes.find(subEdges[2*j+1]);
 +              tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1];
 +              tmp[3]=offset3+(int)addCooQuad.size()/2;
 +              double tmp2[2];
 +              e2->getBarycenter(tmp2); addCooQuad.insert(addCooQuad.end(),tmp2,tmp2+2);
 +              cicnt+=4;
 +              cOut->insertAtTheEnd(tmp,tmp+4);
 +              ciOut->pushBackSilent(cicnt);
 +            }
 +          else
 +            {
 +              tmp[0]=INTERP_KERNEL::NORM_SEG2;
 +              itm=mergedNodes.find(subEdges[2*j]);
 +              tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j];
 +              itm=mergedNodes.find(subEdges[2*j+1]);
 +              tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1];
 +              cicnt+=3;
 +              cOut->insertAtTheEnd(tmp,tmp+3);
 +              ciOut->pushBackSilent(cicnt);
 +            }
 +          int tmp00;
 +          if(IsColinearOfACellOf(intersectEdge1,colinear2[i],tmp[1],tmp[2],tmp00))
 +            {
 +              idsInRetColinear->pushBackSilent(kk);
 +              idsInMesh1DForIdsInRetColinear->pushBackSilent(tmp00);
 +            }
 +        }
 +      e->decrRef();
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(mesh1D->getName(),1));
 +  ret->setConnectivity(cOut,ciOut,true);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr3(DataArrayDouble::New());
 +  arr3->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr4(DataArrayDouble::New()); arr4->useArray(&addCooQuad[0],false,C_DEALLOC,(int)addCooQuad.size()/2,2);
 +  std::vector<const DataArrayDouble *> coordss(4);
 +  coordss[0]=coords1; coordss[1]=mesh1D->getCoords(); coordss[2]=arr3; coordss[3]=arr4;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::Aggregate(coordss));
 +  ret->setCoords(arr);
 +  return ret.retn();
 +}
 +
 +MEDCouplingUMesh *BuildRefined2DCellLinear(const DataArrayDouble *coords, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
 +{
 +  std::vector<int> allEdges;
 +  for(const int *it2(descBg);it2!=descEnd;it2++)
 +    {
 +      const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]);
 +      if(*it2>0)
 +        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
 +      else
 +        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
 +    }
 +  std::size_t nb(allEdges.size());
 +  if(nb%2!=0)
 +    throw INTERP_KERNEL::Exception("BuildRefined2DCellLinear : internal error 1 !");
 +  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2));
 +  ret->setCoords(coords);
 +  ret->allocateCells(1);
 +  std::vector<int> connOut(nbOfEdgesOf2DCellSplit);
 +  for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
 +    connOut[kk]=allEdges[2*kk];
 +  ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,connOut.size(),&connOut[0]);
 +  return ret.retn();
 +}
 +
 +MEDCouplingUMesh *BuildRefined2DCellQuadratic(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
 +{
 +  const int *c(mesh2D->getNodalConnectivity()->begin()),*ci(mesh2D->getNodalConnectivityIndex()->begin());
 +  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[cellIdInMesh2D]]));
 +  std::size_t ii(0);
 +  unsigned sz(cm.getNumberOfSons2(c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1));
 +  if(sz!=std::distance(descBg,descEnd))
 +    throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 1 !");
 +  INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]]);
 +  std::vector<int> allEdges,centers;
 +  const double *coordsPtr(coords->begin());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1);
 +  int offset(coords->getNumberOfTuples());
 +  for(const int *it2(descBg);it2!=descEnd;it2++,ii++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType typeOfSon;
 +      cm.fillSonCellNodalConnectivity2(ii,c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1,tmpPtr,typeOfSon);
 +      const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]);
 +      if(*it2>0)
 +        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
 +      else
 +        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
 +      if(edge1.size()==2)
 +        centers.push_back(tmpPtr[2]);//special case where no subsplit of edge -> reuse the original center.
 +      else
 +        {//the current edge has been subsplit -> create corresponding centers.
 +          std::size_t nbOfCentersToAppend(edge1.size()/2);
 +          std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m;
 +          MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpPtr,coordsPtr,m));
 +          std::vector<int>::const_iterator it3(allEdges.end()-edge1.size());
 +          for(std::size_t k=0;k<nbOfCentersToAppend;k++)
 +            {
 +              double tmpp[2];
 +              const double *aa(coordsPtr+2*(*it3++));
 +              const double *bb(coordsPtr+2*(*it3++));
 +              ee->getMiddleOfPoints(aa,bb,tmpp);
 +              addCoo->insertAtTheEnd(tmpp,tmpp+2);
 +              centers.push_back(offset+k);
 +            }
 +        }
 +    }
 +  std::size_t nb(allEdges.size());
 +  if(nb%2!=0)
 +    throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 2 !");
 +  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2));
 +  if(addCoo->empty())
 +    ret->setCoords(coords);
 +  else
 +    {
 +      addCoo->rearrange(2);
 +      addCoo=DataArrayDouble::Aggregate(coords,addCoo);
 +      ret->setCoords(addCoo);
 +    }
 +  ret->allocateCells(1);
 +  std::vector<int> connOut(nbOfEdgesOf2DCellSplit);
 +  for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
 +    connOut[kk]=allEdges[2*kk];
 +  connOut.insert(connOut.end(),centers.begin(),centers.end());
 +  ret->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,connOut.size(),&connOut[0]);
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method creates a refinement of a cell in \a mesh2D. Those cell is defined by descending connectivity and the sorted subdivided nodal connectivity
 + * of those edges.
 + *
 + * \param [in] mesh2D - The origin 2D mesh. \b Warning \b coords are not those of \a mesh2D. But mesh2D->getCoords()==coords[:mesh2D->getNumberOfNodes()]
 + */
 +MEDCouplingUMesh *BuildRefined2DCell(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
 +{
 +  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(mesh2D->getTypeOfCell(cellIdInMesh2D)));
 +  if(!cm.isQuadratic())
 +    return BuildRefined2DCellLinear(coords,descBg,descEnd,intersectEdge1);
 +  else
 +    return BuildRefined2DCellQuadratic(coords,mesh2D,cellIdInMesh2D,descBg,descEnd,intersectEdge1);
 +}
 +
 +void AddCellInMesh2D(MEDCouplingUMesh *mesh2D, const std::vector<int>& conn, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edges)
 +{
 +  bool isQuad(false);
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >::const_iterator it=edges.begin();it!=edges.end();it++)
 +    {
 +      const INTERP_KERNEL::Edge *ee(*it);
 +      if(dynamic_cast<const INTERP_KERNEL::EdgeArcCircle *>(ee))
 +        isQuad=true;
 +    }
 +  if(!isQuad)
 +    mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,conn.size(),&conn[0]);
 +  else
 +    {
 +      const double *coo(mesh2D->getCoords()->begin());
 +      std::size_t sz(conn.size());
 +      std::vector<double> addCoo;
 +      std::vector<int> conn2(conn);
 +      int offset(mesh2D->getNumberOfNodes());
 +      for(std::size_t i=0;i<sz;i++)
 +        {
 +          double tmp[2];
 +          edges[(i+1)%sz]->getMiddleOfPoints(coo+2*conn[i],coo+2*conn[(i+1)%sz],tmp);// tony a chier i+1 -> i
 +          addCoo.insert(addCoo.end(),tmp,tmp+2);
 +          conn2.push_back(offset+(int)i);
 +        }
 +      mesh2D->getCoords()->rearrange(1);
 +      mesh2D->getCoords()->pushBackValsSilent(&addCoo[0],&addCoo[0]+addCoo.size());
 +      mesh2D->getCoords()->rearrange(2);
 +      mesh2D->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,conn2.size(),&conn2[0]);
 +    }
 +}
 +
 +/*!
 + * \b WARNING edges in out1 coming from \a splitMesh1D are \b NOT oriented because only used for equation of curve.
 + *
 + * This method cuts in 2 parts the input 2D cell given using boundaries description (\a edge1Bis and \a edge1BisPtr) using
 + * a set of edges defined in \a splitMesh1D.
 + */
 +void BuildMesh2DCutInternal2(const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& edge1Bis, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edge1BisPtr,
 +                             std::vector< std::vector<int> >& out0, std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > >& out1)
 +{
 +  std::size_t nb(edge1Bis.size()/2);
 +  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
 +  int iEnd(splitMesh1D->getNumberOfCells());
 +  if(iEnd==0)
 +    throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal2 : internal error ! input 1D mesh must have at least one cell !");
 +  std::size_t ii,jj;
 +  const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin());
 +  for(ii=0;ii<nb && edge1Bis[2*ii]!=cSplitPtr[ciSplitPtr[0]+1];ii++);
 +  for(jj=ii;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd-1]+2];jj++);
 +  //
 +  if(jj==nb)
 +    {//the edges splitMesh1D[iStart:iEnd] does not fully cut the current 2D cell -> single output cell
 +      out0.resize(1); out1.resize(1);
 +      std::vector<int>& connOut(out0[0]);
 +      connOut.resize(nbOfEdgesOf2DCellSplit);
 +      std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr(out1[0]);
 +      edgesPtr.resize(nbOfEdgesOf2DCellSplit);
 +      for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
 +        {
 +          connOut[kk]=edge1Bis[2*kk];
 +          edgesPtr[kk]=edge1BisPtr[2*kk];
 +        }
 +    }
 +  else
 +    {
 +      // [i,iEnd[ contains the
 +      out0.resize(2); out1.resize(2);
 +      std::vector<int>& connOutLeft(out0[0]);
 +      std::vector<int>& connOutRight(out0[1]);//connOutLeft should end with edge1Bis[2*ii] and connOutRight should end with edge1Bis[2*jj+1]
 +      std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& eleft(out1[0]);
 +      std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& eright(out1[1]);
 +      for(std::size_t k=ii;k<jj+1;k++)
 +        { connOutLeft.push_back(edge1Bis[2*k+1]); eleft.push_back(edge1BisPtr[2*k+1]); }
 +      std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > ees(iEnd);
 +      for(int ik=0;ik<iEnd;ik++)
 +        {
 +          std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m;
 +          MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cSplitPtr[ciSplitPtr[ik]],cSplitPtr+ciSplitPtr[ik]+1,splitMesh1D->getCoords()->begin(),m));
 +          ees[ik]=ee;
 +        }
 +      for(int ik=iEnd-1;ik>=0;ik--)
 +        connOutLeft.push_back(cSplitPtr[ciSplitPtr[ik]+1]);
 +      for(std::size_t k=jj+1;k<nbOfEdgesOf2DCellSplit+ii;k++)
 +        { connOutRight.push_back(edge1Bis[2*k+1]); eright.push_back(edge1BisPtr[2*k+1]); }
 +      eleft.insert(eleft.end(),ees.rbegin(),ees.rend());
 +      for(int ik=0;ik<iEnd;ik++)
 +        connOutRight.push_back(cSplitPtr[ciSplitPtr[ik]+2]);
 +      eright.insert(eright.end(),ees.begin(),ees.end());
 +    }
 +}
 +
 +/// @endcond
 +
 +/// @cond INTERNAL
 +
 +struct CellInfo
 +{
 +public:
 +  CellInfo() { }
 +  CellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr);
 +public:
 +  std::vector<int> _edges;
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > _edges_ptr;
 +};
 +
 +CellInfo::CellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr)
 +{
 +  std::size_t nbe(edges.size());
 +  std::vector<int> edges2(2*nbe); std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > edgesPtr2(2*nbe);
 +  for(std::size_t i=0;i<nbe;i++)
 +    {
 +      edges2[2*i]=edges[i]; edges2[2*i+1]=edges[(i+1)%nbe];
 +      edgesPtr2[2*i]=edgesPtr[(i+1)%nbe]; edgesPtr2[2*i+1]=edgesPtr[(i+1)%nbe];//tony a chier
 +    }
 +  _edges.resize(4*nbe); _edges_ptr.resize(4*nbe);
 +  std::copy(edges2.begin(),edges2.end(),_edges.begin()); std::copy(edges2.begin(),edges2.end(),_edges.begin()+2*nbe);
 +  std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()); std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()+2*nbe);
 +}
 +
 +class EdgeInfo
 +{
 +public:
 +  EdgeInfo(int istart, int iend, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh):_istart(istart),_iend(iend),_mesh(mesh),_left(-7),_right(-7) { }
 +  EdgeInfo(int istart, int iend, int pos, const MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge>& edge):_istart(istart),_iend(iend),_edge(edge),_left(pos),_right(pos+1) { }
 +  bool isInMyRange(int pos) const { return pos>=_istart && pos<_iend; }
 +  void somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight);
 +  void feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const;
 +private:
 +  int _istart;
 +  int _iend;
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> _mesh;
 +  MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> _edge;
 +  int _left;
 +  int _right;
 +};
 +
 +void EdgeInfo::somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight)
 +{
 +  const MEDCouplingUMesh *mesh(_mesh);
 +  if(mesh)
 +    return ;
 +  if(_right<pos)
 +    return ;
 +  if(_left>pos)
 +    { _left++; _right++; return ; }
 +  if(_right==pos)
 +    {
 +      bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end());
 +      if((isLeft && isRight) || (!isLeft && !isRight))
 +        throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 1 !");
 +      if(isLeft)
 +        return ;
 +      if(isRight)
 +        {
 +          _right++;
 +          return ;
 +        }
 +    }
 +  if(_left==pos)
 +    {
 +      bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end());
 +      if((isLeft && isRight) || (!isLeft && !isRight))
 +        throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 2 !");
 +      if(isLeft)
 +        {
 +          _right++;
 +          return ;
 +        }
 +      if(isRight)
 +        {
 +          _left++;
 +          _right++;
 +          return ;
 +        }
 +    }
 +}
 +
 +void EdgeInfo::feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const
 +{
 +  const MEDCouplingUMesh *mesh(_mesh);
 +  if(!mesh)
 +    {
 +      neighbors[0]=offset+_left; neighbors[1]=offset+_right;
 +    }
 +  else
 +    {// not fully splitting cell case
 +      if(mesh2D->getNumberOfCells()==1)
 +        {//little optimization. 1 cell no need to find in which cell mesh is !
 +          neighbors[0]=offset; neighbors[1]=offset;
 +          return;
 +        }
 +      else
 +        {
 +          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> barys(mesh->getBarycenterAndOwner());
 +          int cellId(mesh2D->getCellContainingPoint(barys->begin(),eps));
 +          if(cellId==-1)
 +            throw INTERP_KERNEL::Exception("EdgeInfo::feedEdgeInfoAt : internal error !");
 +          neighbors[0]=offset+cellId; neighbors[1]=offset+cellId;
 +        }
 +    }
 +}
 +
 +class VectorOfCellInfo
 +{
 +public:
 +  VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr);
 +  std::size_t size() const { return _pool.size(); }
 +  int getPositionOf(double eps, const MEDCouplingUMesh *mesh) const;
 +  void setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > >& edgePtrs);
 +  const std::vector<int>& getConnOf(int pos) const { return get(pos)._edges; }
 +  const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& getEdgePtrOf(int pos) const { return get(pos)._edges_ptr; }
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> getZeMesh() const { return _ze_mesh; }
 +  void feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const;
 +private:
 +  int getZePosOfEdgeGivenItsGlobalId(int pos) const;
 +  void updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight);
 +  const CellInfo& get(int pos) const;
 +  CellInfo& get(int pos);
 +private:
 +  std::vector<CellInfo> _pool;
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> _ze_mesh;
 +  std::vector<EdgeInfo> _edge_info;
 +};
 +
 +VectorOfCellInfo::VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr):_pool(1)
 +{
 +  _pool[0]._edges=edges;
 +  _pool[0]._edges_ptr=edgesPtr;
 +}
 +
 +int VectorOfCellInfo::getPositionOf(double eps, const MEDCouplingUMesh *mesh) const
 +{
 +  if(_pool.empty())
 +    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : empty !");
 +  if(_pool.size()==1)
 +    return 0;
 +  const MEDCouplingUMesh *zeMesh(_ze_mesh);
 +  if(!zeMesh)
 +    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : null aggregated mesh !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> barys(mesh->getBarycenterAndOwner());
 +  return zeMesh->getCellContainingPoint(barys->begin(),eps);
 +}
 +
 +void VectorOfCellInfo::setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > >& edgePtrs)
 +{
 +  get(pos);//to check pos
 +  bool isFast(pos==0 && _pool.size()==1);
 +  std::size_t sz(edges.size());
 +  // dealing with edges
 +  if(sz==1)
 +    _edge_info.push_back(EdgeInfo(istart,iend,mesh1DInCase));
 +  else
 +    _edge_info.push_back(EdgeInfo(istart,iend,pos,edgePtrs[0].back()));
 +  //
 +  std::vector<CellInfo> pool(_pool.size()-1+sz);
 +  for(int i=0;i<pos;i++)
 +    pool[i]=_pool[i];
 +  for(std::size_t j=0;j<sz;j++)
 +    pool[pos+j]=CellInfo(edges[j],edgePtrs[j]);
 +  for(int i=pos+1;i<(int)_pool.size();i++)
 +    pool[i+sz-1]=_pool[i];
 +  _pool=pool;
 +  //
 +  if(sz==2)
 +    updateEdgeInfo(pos,edgePtrs[0],edgePtrs[1]);
 +  //
 +  if(isFast)
 +    {
 +      _ze_mesh=mesh;
 +      return ;
 +    }
 +  //
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms;
 +  if(pos>0)
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelf2(0,pos,true)));
 +      ms.push_back(elt);
 +    }
 +  ms.push_back(mesh);
 +  if(pos<_ze_mesh->getNumberOfCells()-1)
 +  {
 +    MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelf2(pos+1,_ze_mesh->getNumberOfCells(),true)));
 +    ms.push_back(elt);
 +  }
 +  std::vector< const MEDCouplingUMesh *> ms2(ms.size());
 +  for(std::size_t j=0;j<ms2.size();j++)
 +    ms2[j]=ms[j];
 +  _ze_mesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms2);
 +}
 +
 +void VectorOfCellInfo::feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const
 +{
 +  _edge_info[getZePosOfEdgeGivenItsGlobalId(pos)].feedEdgeInfoAt(eps,_ze_mesh,offset,neighbors);
 +}
 +
 +int VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId(int pos) const
 +{
 +  if(pos<0)
 +    throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id ! Must be >=0 !");
 +  int ret(0);
 +  for(std::vector<EdgeInfo>::const_iterator it=_edge_info.begin();it!=_edge_info.end();it++,ret++)
 +    {
 +      if((*it).isInMyRange(pos))
 +        return ret;
 +    }
 +  throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id !");
 +}
 +
 +void VectorOfCellInfo::updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight)
 +{
 +  get(pos);//to check;
 +  if(_edge_info.empty())
 +    return ;
 +  std::size_t sz(_edge_info.size()-1);
 +  for(std::size_t i=0;i<sz;i++)
 +    _edge_info[i].somethingHappendAt(pos,newLeft,newRight);
 +}
 +
 +const CellInfo& VectorOfCellInfo::get(int pos) const
 +{
 +  if(pos<0 || pos>=(int)_pool.size())
 +    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get const : invalid pos !");
 +  return _pool[pos];
 +}
 +
 +CellInfo& VectorOfCellInfo::get(int pos)
 +{
 +  if(pos<0 || pos>=(int)_pool.size())
 +    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get : invalid pos !");
 +  return _pool[pos];
 +}
 +
 +/*!
 + * Given :
 + * - a \b closed set of edges ( \a allEdges and \a allEdgesPtr ) that defines the split descending 2D cell.
 + * - \a splitMesh1D a split 2D curve mesh contained into 2D cell defined above.
 + *
 + * This method returns the 2D mesh and feeds \a idsLeftRight using offset.
 + *
 + * Algorithm : \a splitMesh1D is cut into contiguous parts. Each contiguous parts will build incrementally the output 2D cells.
 + *
 + * \param [in] allEdges a list of pairs (beginNode, endNode). Linked with \a allEdgesPtr to get the equation of edge.
 + */
 +MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& allEdges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& allEdgesPtr, int offset,
 +                                         MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsLeftRight)
 +{
 +  int nbCellsInSplitMesh1D(splitMesh1D->getNumberOfCells());
 +  if(nbCellsInSplitMesh1D==0)
 +    throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal : internal error ! input 1D mesh must have at least one cell !");
 +  const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin());
 +  std::size_t nb(allEdges.size()),jj;
 +  if(nb%2!=0)
 +    throw INTERP_KERNEL::Exception("BuildMesh2DCutFrom : internal error 2 !");
 +  std::vector<int> edge1Bis(nb*2);
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > edge1BisPtr(nb*2);
 +  std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin());
 +  std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()+nb);
 +  std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin());
 +  std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()+nb);
 +  //
 +  idsLeftRight=DataArrayInt::New(); idsLeftRight->alloc(nbCellsInSplitMesh1D*2); idsLeftRight->fillWithValue(-2); idsLeftRight->rearrange(2);
 +  int *idsLeftRightPtr(idsLeftRight->getPointer());
 +  VectorOfCellInfo pool(edge1Bis,edge1BisPtr);
 +  for(int iStart=0;iStart<nbCellsInSplitMesh1D;)
 +    {// split [0:nbCellsInSplitMesh1D) in contiguous parts [iStart:iEnd)
 +      int iEnd(iStart);
 +      for(;iEnd<nbCellsInSplitMesh1D;)
 +        {
 +          for(jj=0;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd]+2];jj++);
 +          if(jj!=nb)
 +            break;
 +          else
 +            iEnd++;
 +        }
 +      if(iEnd<nbCellsInSplitMesh1D)
 +        iEnd++;
 +      //
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> partOfSplitMesh1D(static_cast<MEDCouplingUMesh *>(splitMesh1D->buildPartOfMySelf2(iStart,iEnd,1,true)));
 +      int pos(pool.getPositionOf(eps,partOfSplitMesh1D));
 +      //
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>retTmp(MEDCouplingUMesh::New("",2));
 +      retTmp->setCoords(splitMesh1D->getCoords());
 +      retTmp->allocateCells();
 +
 +      std::vector< std::vector<int> > out0;
 +      std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > > out1;
 +
 +      BuildMesh2DCutInternal2(partOfSplitMesh1D,pool.getConnOf(pos),pool.getEdgePtrOf(pos),out0,out1);
 +      for(std::size_t cnt=0;cnt<out0.size();cnt++)
 +        AddCellInMesh2D(retTmp,out0[cnt],out1[cnt]);
 +      pool.setMeshAt(pos,retTmp,iStart,iEnd,partOfSplitMesh1D,out0,out1);
 +      //
 +      iStart=iEnd;
 +    }
 +  for(int mm=0;mm<nbCellsInSplitMesh1D;mm++)
 +    pool.feedEdgeInfoAt(eps,mm,offset,idsLeftRightPtr+2*mm);
 +  return pool.getZeMesh().retn();
 +}
 +
 +MEDCouplingUMesh *BuildMesh2DCutFrom(double eps, int cellIdInMesh2D, const MEDCouplingUMesh *mesh2DDesc, const MEDCouplingUMesh *splitMesh1D,
 +                                     const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1, int offset,
 +                                     MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsLeftRight)
 +{
 +  const int *cdescPtr(mesh2DDesc->getNodalConnectivity()->begin()),*cidescPtr(mesh2DDesc->getNodalConnectivityIndex()->begin());
 +  //
 +  std::vector<int> allEdges;
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > allEdgesPtr; // for each sub edge in splitMesh2D the uncut Edge object of the original mesh2D
 +  for(const int *it(descBg);it!=descEnd;it++) // for all edges in the descending connectivity of the 2D mesh in relative Fortran mode
 +    {
 +      int edgeId(std::abs(*it)-1);
 +      std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m;
 +      MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cdescPtr[cidescPtr[edgeId]],cdescPtr+cidescPtr[edgeId]+1,mesh2DDesc->getCoords()->begin(),m));
 +      const std::vector<int>& edge1(intersectEdge1[edgeId]);
 +      if(*it>0)
 +        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
 +      else
 +        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
 +      std::size_t sz(edge1.size());
 +      for(std::size_t cnt=0;cnt<sz;cnt++)
 +        allEdgesPtr.push_back(ee);
 +    }
 +  //
 +  return BuildMesh2DCutInternal(eps,splitMesh1D,allEdges,allEdgesPtr,offset,idsLeftRight);
 +}
 +
 +bool AreEdgeEqual(const double *coo2D, const INTERP_KERNEL::CellModel& typ1, const int *conn1, const INTERP_KERNEL::CellModel& typ2, const int *conn2, double eps)
 +{
 +  if(!typ1.isQuadratic() && !typ2.isQuadratic())
 +    {//easy case comparison not
 +      return conn1[0]==conn2[0] && conn1[1]==conn2[1];
 +    }
 +  else if(typ1.isQuadratic() && typ2.isQuadratic())
 +    {
 +      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
 +      if(!status0)
 +        return false;
 +      if(conn1[2]==conn2[2])
 +        return true;
 +      const double *a(coo2D+2*conn1[2]),*b(coo2D+2*conn2[2]);
 +      double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
 +      return dist<eps;
 +    }
 +  else
 +    {//only one is quadratic
 +      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
 +      if(!status0)
 +        return false;
 +      const double *a(0),*bb(0),*be(0);
 +      if(typ1.isQuadratic())
 +        {
 +          a=coo2D+2*conn1[2]; bb=coo2D+2*conn2[0]; be=coo2D+2*conn2[1];
 +        }
 +      else
 +        {
 +          a=coo2D+2*conn2[2]; bb=coo2D+2*conn1[0]; be=coo2D+2*conn1[1];
 +        }
 +      double b[2]; b[0]=(be[0]+bb[0])/2.; b[1]=(be[1]+bb[1])/2.;
 +      double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
 +      return dist<eps;
 +    }
 +}
 +
 +/*!
 + * This method returns among the cellIds [ \a candidatesIn2DBg , \a candidatesIn2DEnd ) in \a mesh2DSplit those exactly sharing \a cellIdInMesh1DSplitRelative in \a mesh1DSplit.
 + * \a mesh2DSplit and \a mesh1DSplit are expected to share the coordinates array.
 + *
 + * \param [in] cellIdInMesh1DSplitRelative is in Fortran mode using sign to specify direction.
 + */
 +int FindRightCandidateAmong(const MEDCouplingUMesh *mesh2DSplit, const int *candidatesIn2DBg, const int *candidatesIn2DEnd, const MEDCouplingUMesh *mesh1DSplit, int cellIdInMesh1DSplitRelative, double eps)
 +{
 +  if(candidatesIn2DEnd==candidatesIn2DBg)
 +    throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 1 !");
 +  const double *coo(mesh2DSplit->getCoords()->begin());
 +  if(std::distance(candidatesIn2DBg,candidatesIn2DEnd)==1)
 +    return *candidatesIn2DBg;
 +  int edgeId(std::abs(cellIdInMesh1DSplitRelative)-1);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cur1D(static_cast<MEDCouplingUMesh *>(mesh1DSplit->buildPartOfMySelf(&edgeId,&edgeId+1,true)));
 +  if(cellIdInMesh1DSplitRelative<0)
 +    cur1D->changeOrientationOfCells();
 +  const int *c1D(cur1D->getNodalConnectivity()->begin());
 +  const INTERP_KERNEL::CellModel& ref1DType(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c1D[0]));
 +  for(const int *it=candidatesIn2DBg;it!=candidatesIn2DEnd;it++)
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cur2D(static_cast<MEDCouplingUMesh *>(mesh2DSplit->buildPartOfMySelf(it,it+1,true)));
 +      const int *c(cur2D->getNodalConnectivity()->begin()),*ci(cur2D->getNodalConnectivityIndex()->begin());
 +      const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[0]]));
 +      unsigned sz(cm.getNumberOfSons2(c+ci[0]+1,ci[1]-ci[0]-1));
 +      INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[1]-ci[0]]);
 +      for(unsigned it2=0;it2<sz;it2++)
 +        {
 +          INTERP_KERNEL::NormalizedCellType typeOfSon;
 +          cm.fillSonCellNodalConnectivity2(it2,c+ci[0]+1,ci[1]-ci[0]-1,tmpPtr,typeOfSon);
 +          const INTERP_KERNEL::CellModel &curCM(INTERP_KERNEL::CellModel::GetCellModel(typeOfSon));
 +          if(AreEdgeEqual(coo,ref1DType,c1D+1,curCM,tmpPtr,eps))
 +            return *it;
 +        }
 +    }
 +  throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 2 ! Unable to find the edge among split cell !");
 +}
 +
 +/// @endcond
 +
 +/*!
 + * Partitions the first given 2D mesh using the second given 1D mesh as a tool.
 + * Thus the final result contains the aggregation of nodes of \a mesh2D, then nodes of \a mesh1D, then new nodes that are the result of the intersection
 + * and finaly, in case of quadratic polygon the centers of edges new nodes.
 + * The meshes should be in 2D space. In addition, returns two arrays mapping cells of the resulting mesh to cells of the input.
 + *
 + * \param [in] mesh2D - the 2D mesh (spacedim=meshdim=2) to be intersected using \a mesh1D tool. The mesh must be so that each point in the space covered by \a mesh2D
 + *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
 + * \param [in] mesh1D - the 1D mesh (spacedim=2 meshdim=1) the is the tool that will be used to intersect \a mesh2D. \a mesh1D must be ordered consecutively. If it is not the case
 + *                      you can invoke orderConsecutiveCells1D on \a mesh1D.
 + * \param [in] eps - precision used to perform intersections and localization operations.
 + * \param [out] splitMesh2D - the result of the split of \a mesh2D mesh.
 + * \param [out] splitMesh1D - the result of the split of \a mesh1D mesh.
 + * \param [out] cellIdInMesh2D - the array that gives for each cell id \a i in \a splitMesh2D the id in \a mesh2D it comes from.
 + *                               So this array has a number of tuples equal to the number of cells of \a splitMesh2D and a number of component equal to 1.
 + * \param [out] cellIdInMesh1D - the array of pair that gives for each cell id \a i in \a splitMesh1D the cell in \a splitMesh2D on the left for the 1st component
 + *                               and the cell in \a splitMesh2D on the right for the 2nt component. -1 means no cell.
 + *                               So this array has a number of tuples equal to the number of cells of \a splitMesh1D and a number of components equal to 2.
 + *
 + * \sa Intersect2DMeshes, orderConsecutiveCells1D, conformize2D, mergeNodes
 + */
 +void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, double eps, MEDCouplingUMesh *&splitMesh2D, MEDCouplingUMesh *&splitMesh1D, DataArrayInt *&cellIdInMesh2D, DataArrayInt *&cellIdInMesh1D)
 +{
 +  if(!mesh2D || !mesh1D)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine : input meshes must be not NULL !");
 +  mesh2D->checkFullyDefined();
 +  mesh1D->checkFullyDefined();
 +  const std::vector<std::string>& compNames(mesh2D->getCoords()->getInfoOnComponents());
 +  if(mesh2D->getMeshDimension()!=2 || mesh2D->getSpaceDimension()!=2 || mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine works with mesh2D with spacedim=meshdim=2 and mesh1D with meshdim=1 spaceDim=2 !");
 +  // Step 1: compute all edge intersections (new nodes)
 +  std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2;
 +  std::vector<double> addCoo,addCoordsQuadratic;  // coordinates of newly created nodes
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
 +  //
 +  // Build desc connectivity
 +  DataArrayInt *desc1(DataArrayInt::New()),*descIndx1(DataArrayInt::New()),*revDesc1(DataArrayInt::New()),*revDescIndx1(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Desc(mesh2D->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1));
 +  std::map<int,int> mergedNodes;
 +  Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo,mergedNodes);
 +  // use mergeNodes to fix intersectEdge1
 +  for(std::vector< std::vector<int> >::iterator it0=intersectEdge1.begin();it0!=intersectEdge1.end();it0++)
 +    {
 +      std::size_t n((*it0).size()/2);
 +      int eltStart((*it0)[0]),eltEnd((*it0)[2*n-1]);
 +      std::map<int,int>::const_iterator it1;
 +      it1=mergedNodes.find(eltStart);
 +      if(it1!=mergedNodes.end())
 +        (*it0)[0]=(*it1).second;
 +      it1=mergedNodes.find(eltEnd);
 +      if(it1!=mergedNodes.end())
 +        (*it0)[2*n-1]=(*it1).second;
 +    }
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCooDa(DataArrayDouble::New());
 +  addCooDa->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2);
 +  // Step 2: re-order newly created nodes according to the ordering found in m2
 +  std::vector< std::vector<int> > intersectEdge2;
 +  BuildIntersectEdges(m1Desc,mesh1D,addCoo,subDiv2,intersectEdge2);
 +  subDiv2.clear();
 +  // Step 3: compute splitMesh1D
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(DataArrayInt::New()); ret2->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes,colinear2,intersectEdge1,
 +      idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear));
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(std::numeric_limits<int>::max()); ret3->rearrange(2);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInRet1NotColinear(idsInRet1Colinear->buildComplement(ret1->getNumberOfCells()));
 +  // deal with cells in mesh2D that are not cut but only some of their edges are
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInDesc2DToBeRefined(idsInDescMesh2DForIdsInRetColinear->deepCpy());
 +  idsInDesc2DToBeRefined->abs(); idsInDesc2DToBeRefined->applyLin(1,-1);
 +  idsInDesc2DToBeRefined=idsInDesc2DToBeRefined->buildUnique();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out0s;//ids in mesh2D that are impacted by the fact that some edges of \a mesh1D are part of the edges of those cells
 +  if(!idsInDesc2DToBeRefined->empty())
 +    {
 +      DataArrayInt *out0(0),*outi0(0);
 +      MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> outi0s(outi0);
 +      out0s=out0;
 +      out0s=out0s->buildUnique();
 +      out0s->sort(true);
 +    }
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1NonCol(static_cast<MEDCouplingUMesh *>(ret1->buildPartOfMySelf(idsInRet1NotColinear->begin(),idsInRet1NotColinear->end())));
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> baryRet1(ret1NonCol->getBarycenterAndOwner());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elts,eltsIndex;
 +  mesh2D->getCellsContainingPoints(baryRet1->begin(),baryRet1->getNumberOfTuples(),eps,elts,eltsIndex);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsIndex2(eltsIndex->deltaShiftIndex());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsIndex3(eltsIndex2->getIdsEqual(1));
 +  if(eltsIndex2->count(0)+eltsIndex3->getNumberOfTuples()!=ret1NonCol->getNumberOfCells())
 +    throw INTERP_KERNEL::Exception("Intersect2DMeshWith1DLine : internal error 1 !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToBeModified(elts->buildUnique());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> untouchedCells(cellsToBeModified->buildComplement(mesh2D->getNumberOfCells()));
 +  if((DataArrayInt *)out0s)
 +    untouchedCells=untouchedCells->buildSubstraction(out0s);//if some edges in ret1 are colinear to descending mesh of mesh2D remove cells from untouched one
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > outMesh2DSplit;
 +  // OK all is ready to insert in ret2 mesh
 +  if(!untouchedCells->empty())
 +    {// the most easy part, cells in mesh2D not impacted at all
 +      outMesh2DSplit.push_back(static_cast<MEDCouplingUMesh *>(mesh2D->buildPartOfMySelf(untouchedCells->begin(),untouchedCells->end())));
 +      outMesh2DSplit.back()->setCoords(ret1->getCoords());
 +      ret2->pushBackValsSilent(untouchedCells->begin(),untouchedCells->end());
 +    }
 +  if((DataArrayInt *)out0s)
 +    {// here dealing with cells in out0s but not in cellsToBeModified
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fewModifiedCells(out0s->buildSubstraction(cellsToBeModified));
 +      const int *rdptr(dd3->begin()),*rdiptr(dd4->begin()),*dptr(dd1->begin()),*diptr(dd2->begin());
 +      for(const int *it=fewModifiedCells->begin();it!=fewModifiedCells->end();it++)
 +        {
 +          outMesh2DSplit.push_back(BuildRefined2DCell(ret1->getCoords(),mesh2D,*it,dptr+diptr[*it],dptr+diptr[*it+1],intersectEdge1));
 +          ret1->setCoords(outMesh2DSplit.back()->getCoords());
 +        }
 +      int offset(ret2->getNumberOfTuples());
 +      ret2->pushBackValsSilent(fewModifiedCells->begin(),fewModifiedCells->end());
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> partOfRet3(DataArrayInt::New()); partOfRet3->alloc(2*idsInRet1Colinear->getNumberOfTuples(),1);
 +      partOfRet3->fillWithValue(std::numeric_limits<int>::max()); partOfRet3->rearrange(2);
 +      int kk(0),*ret3ptr(partOfRet3->getPointer());
 +      for(const int *it=idsInDescMesh2DForIdsInRetColinear->begin();it!=idsInDescMesh2DForIdsInRetColinear->end();it++,kk++)
 +        {
 +          int faceId(std::abs(*it)-1);
 +          for(const int *it2=rdptr+rdiptr[faceId];it2!=rdptr+rdiptr[faceId+1];it2++)
 +            {
 +              int tmp(fewModifiedCells->locateValue(*it2));
 +              if(tmp!=-1)
 +                {
 +                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1])
 +                    ret3ptr[2*kk]=tmp+offset;
 +                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1])
 +                    ret3ptr[2*kk+1]=tmp+offset;
 +                }
 +              else
 +                {//the current edge is shared by a 2D cell that will be split just after
 +                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1])
 +                    ret3ptr[2*kk]=-(*it2+1);
 +                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1])
 +                    ret3ptr[2*kk+1]=-(*it2+1);
 +                }
 +            }
 +        }
 +      m1Desc->setCoords(ret1->getCoords());
 +      ret1NonCol->setCoords(ret1->getCoords());
 +      ret3->setPartOfValues3(partOfRet3,idsInRet1Colinear->begin(),idsInRet1Colinear->end(),0,2,1,true);
 +      if(!outMesh2DSplit.empty())
 +        {
 +          DataArrayDouble *da(outMesh2DSplit.back()->getCoords());
 +          for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator itt=outMesh2DSplit.begin();itt!=outMesh2DSplit.end();itt++)
 +            (*itt)->setCoords(da);
 +        }
 +    }
 +  cellsToBeModified=cellsToBeModified->buildUniqueNotSorted();
 +  for(const int *it=cellsToBeModified->begin();it!=cellsToBeModified->end();it++)
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNonColPerCell(elts->getIdsEqual(*it));
 +      idsNonColPerCell->transformWithIndArr(eltsIndex3->begin(),eltsIndex3->end());
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNonColPerCell2(idsInRet1NotColinear->selectByTupleId(idsNonColPerCell->begin(),idsNonColPerCell->end()));
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> partOfMesh1CuttingCur2DCell(static_cast<MEDCouplingUMesh *>(ret1NonCol->buildPartOfMySelf(idsNonColPerCell->begin(),idsNonColPerCell->end())));
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> partOfRet3;
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> splitOfOneCell(BuildMesh2DCutFrom(eps,*it,m1Desc,partOfMesh1CuttingCur2DCell,dd1->begin()+dd2->getIJ(*it,0),dd1->begin()+dd2->getIJ((*it)+1,0),intersectEdge1,ret2->getNumberOfTuples(),partOfRet3));
 +      ret3->setPartOfValues3(partOfRet3,idsNonColPerCell2->begin(),idsNonColPerCell2->end(),0,2,1,true);
 +      outMesh2DSplit.push_back(splitOfOneCell);
 +      for(int i=0;i<splitOfOneCell->getNumberOfCells();i++)
 +        ret2->pushBackSilent(*it);
 +    }
 +  //
 +  std::size_t nbOfMeshes(outMesh2DSplit.size());
 +  std::vector<const MEDCouplingUMesh *> tmp(nbOfMeshes);
 +  for(std::size_t i=0;i<nbOfMeshes;i++)
 +    tmp[i]=outMesh2DSplit[i];
 +  //
 +  ret1->getCoords()->setInfoOnComponents(compNames);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret2D(MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp));
 +  // To finish - filter ret3 - std::numeric_limits<int>::max() -> -1 - negate values must be resolved.
 +  ret3->rearrange(1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> edgesToDealWith(ret3->getIdsStrictlyNegative());
 +  for(const int *it=edgesToDealWith->begin();it!=edgesToDealWith->end();it++)
 +    {
 +      int old2DCellId(-ret3->getIJ(*it,0)-1);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates(ret2->getIdsEqual(old2DCellId));
 +      ret3->setIJ(*it,0,FindRightCandidateAmong(ret2D,candidates->begin(),candidates->end(),ret1,*it%2==0?-((*it)/2+1):(*it)/2+1,eps));// div by 2 because 2 components natively in ret3
 +    }
 +  ret3->replaceOneValByInThis(std::numeric_limits<int>::max(),-1);
 +  ret3->rearrange(2);
 +  //
 +  splitMesh1D=ret1.retn();
 +  splitMesh2D=ret2D.retn();
 +  cellIdInMesh2D=ret2.retn();
 +  cellIdInMesh1D=ret3.retn();
 +}
 +
 +/**
 + * Private. Third step of the partitioning algorithm (Intersect2DMeshes): reconstruct full 2D cells from the
 + * (newly created) nodes corresponding to the edge intersections.
 + * Output params:
 + * @param[out] cr, crI connectivity of the resulting mesh
 + * @param[out] cNb1, cNb2 correspondance arrays giving for the merged mesh the initial cells IDs in m1 / m2
 + * TODO: describe input parameters
 + */
 +void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1,
 +                                                         const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,
 +                                                         const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,
 +                                                         const std::vector<double>& addCoords,
 +                                                         std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2)
 +{
 +  static const int SPACEDIM=2;
 +  const double *coo1(m1->getCoords()->getConstPointer());
 +  const int *conn1(m1->getNodalConnectivity()->getConstPointer()),*connI1(m1->getNodalConnectivityIndex()->getConstPointer());
 +  int offset1(m1->getNumberOfNodes());
 +  const double *coo2(m2->getCoords()->getConstPointer());
 +  const int *conn2(m2->getNodalConnectivity()->getConstPointer()),*connI2(m2->getNodalConnectivityIndex()->getConstPointer());
 +  int offset2(offset1+m2->getNumberOfNodes());
 +  int offset3(offset2+((int)addCoords.size())/2);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox1Arr(m1->getBoundingBoxForBBTree()),bbox2Arr(m2->getBoundingBoxForBBTree());
 +  const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
 +  // Here a BBTree on 2D-cells, not on segments:
 +  BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2->getNumberOfCells(),eps);
 +  int ncell1(m1->getNumberOfCells());
 +  crI.push_back(0);
 +  for(int i=0;i<ncell1;i++)
 +    {
 +      std::vector<int> candidates2;
 +      myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
 +      std::map<INTERP_KERNEL::Node *,int> mapp;
 +      std::map<int,INTERP_KERNEL::Node *> mappRev;
 +      INTERP_KERNEL::QuadraticPolygon pol1;
 +      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]];
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
 +      // Populate mapp and mappRev with nodes from the current cell (i) from mesh1 - this also builds the Node* objects:
 +      MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev);
 +      // pol1 is the full cell from mesh2, in QP format, with all the additional intersecting nodes.
 +      pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1,
 +          desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1);
 +      //
 +      std::set<INTERP_KERNEL::Edge *> edges1;// store all edges of pol1 that are NOT consumed by intersect cells. If any after iteration over candidates2 -> a part of pol1 should appear in result
 +      std::set<INTERP_KERNEL::Edge *> edgesBoundary2;// store all edges that are on boundary of (pol2 intersect pol1) minus edges on pol1.
 +      INTERP_KERNEL::IteratorOnComposedEdge it1(&pol1);
 +      for(it1.first();!it1.finished();it1.next())
 +        edges1.insert(it1.current()->getPtr());
 +      //
 +      std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> > edgesIn2ForShare; // common edges
 +      std::vector<INTERP_KERNEL::QuadraticPolygon> pol2s(candidates2.size());
 +      int ii=0;
 +      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
 +        {
 +          INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]];
 +          const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2);
 +          // Complete mapping with elements coming from the current cell it2 in mesh2:
 +          MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev);
 +          // pol2 is the new QP in the final merged result.
 +          pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,
 +              pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2, /* output */ edgesIn2ForShare);
 +        }
 +      ii=0;
 +      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
 +        {
 +          INTERP_KERNEL::ComposedEdge::InitLocationsWithOther(pol1,pol2s[ii]);
 +          pol2s[ii].updateLocOfEdgeFromCrudeDataArray2(desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2);
 +          //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2);
 +          pol1.buildPartitionsAbs(pol2s[ii],edges1,edgesBoundary2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2);
 +        }
 +      // Deals with remaining (non-consumed) edges from m1: these are the edges that were never touched
 +      // by m2 but that we still want to keep in the final result.
 +      if(!edges1.empty())
 +        {
 +          try
 +          {
 +              INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2);
 +          }
 +          catch(INTERP_KERNEL::Exception& e)
 +          {
 +              std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what();
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +          }
 +        }
 +      for(std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.begin();it!=mappRev.end();it++)
 +        (*it).second->decrRef();
 +    }
 +}
 +
 +/**
 + * Provides a renumbering of the cells of this (which has to be a piecewise connected 1D line), so that
 + * the segments of the line are indexed in consecutive order (i.e. cells \a i and \a i+1 are neighbors).
 + * This doesn't modify the mesh. This method only works using nodal connectivity consideration. Coordinates of nodes are ignored here.
 + * The caller is to deal with the resulting DataArrayInt.
 + *  \throw If the coordinate array is not set.
 + *  \throw If the nodal connectivity of the cells is not defined.
 + *  \throw If m1 is not a mesh of dimension 2, or m1 is not a mesh of dimension 1
 + *  \throw If m2 is not a (piecewise) line (i.e. if a point has more than 2 adjacent segments)
 + *
 + * \sa DataArrayInt::sortEachPairToMakeALinkedList
 + */
 +DataArrayInt *MEDCouplingUMesh::orderConsecutiveCells1D() const
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D works on unstructured mesh with meshdim = 1 !");
 +
 +  // Check that this is a line (and not a more complex 1D mesh) - each point is used at most by 2 segments:
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _d(DataArrayInt::New()),_dI(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rD(DataArrayInt::New()),_rDI(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m_points(buildDescendingConnectivity(_d, _dI, _rD, _rDI));
 +  const int *d(_d->getConstPointer()), *dI(_dI->getConstPointer());
 +  const int *rD(_rD->getConstPointer()), *rDI(_rDI->getConstPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _dsi(_rDI->deltaShiftIndex());
 +  const int * dsi(_dsi->getConstPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dsii = _dsi->getIdsNotInRange(0,3);
 +  m_points=0;
 +  if (dsii->getNumberOfTuples())
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D only work with a mesh being a (piecewise) connected line!");
 +
 +  int nc(getNumberOfCells());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> result(DataArrayInt::New());
 +  result->alloc(nc,1);
 +
 +  // set of edges not used so far
 +  std::set<int> edgeSet;
 +  for (int i=0; i<nc; edgeSet.insert(i), i++);
 +
 +  int startSeg=0;
 +  int newIdx=0;
 +  // while we have points with only one neighbor segments
 +  do
 +    {
 +      std::list<int> linePiece;
 +      // fills a list of consecutive segment linked to startSeg. This can go forward or backward.
 +      for (int direction=0;direction<2;direction++) // direction=0 --> forward, direction=1 --> backward
 +        {
 +          // Fill the list forward (resp. backward) from the start segment:
 +          int activeSeg = startSeg;
 +          int prevPointId = -20;
 +          int ptId;
 +          while (!edgeSet.empty())
 +            {
 +              if (!(direction == 1 && prevPointId==-20)) // prevent adding twice startSeg
 +                {
 +                  if (direction==0)
 +                    linePiece.push_back(activeSeg);
 +                  else
 +                    linePiece.push_front(activeSeg);
 +                  edgeSet.erase(activeSeg);
 +                }
 +
 +              int ptId1 = d[dI[activeSeg]], ptId2 = d[dI[activeSeg]+1];
 +              ptId = direction ? (ptId1 == prevPointId ? ptId2 : ptId1) : (ptId2 == prevPointId ? ptId1 : ptId2);
 +              if (dsi[ptId] == 1) // hitting the end of the line
 +                break;
 +              prevPointId = ptId;
 +              int seg1 = rD[rDI[ptId]], seg2 = rD[rDI[ptId]+1];
 +              activeSeg = (seg1 == activeSeg) ? seg2 : seg1;
 +            }
 +        }
 +      // Done, save final piece into DA:
 +      std::copy(linePiece.begin(), linePiece.end(), result->getPointer()+newIdx);
 +      newIdx += linePiece.size();
 +
 +      // identify next valid start segment (one which is not consumed)
 +      if(!edgeSet.empty())
 +        startSeg = *(edgeSet.begin());
 +    }
 +  while (!edgeSet.empty());
 +  return result.retn();
 +}
 +
 +/// @cond INTERNAL
 +
 +void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect)
 +{
 +  MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> nTmp(n); nTmp->incrRef();
 +  std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>::const_iterator it(m.find(nTmp));
 +  if(it==m.end())
 +    throw INTERP_KERNEL::Exception("Internal error in remapping !");
 +  int v((*it).second);
 +  if(v==forbVal0 || v==forbVal1)
 +    return ;
 +  if(std::find(isect.begin(),isect.end(),v)==isect.end())
 +    isect.push_back(v);
 +}
 +
 +bool IKGeo2DInternalMapper(const INTERP_KERNEL::ComposedEdge& c, const std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect)
 +{
 +  int sz(c.size());
 +  if(sz<=1)
 +    return false;
 +  bool presenceOfOn(false);
 +  for(int i=0;i<sz;i++)
 +    {
 +      INTERP_KERNEL::ElementaryEdge *e(c[i]);
 +      if(e->getLoc()!=INTERP_KERNEL::FULL_ON_1)
 +        continue ;
 +      IKGeo2DInternalMapper2(e->getStartNode(),m,forbVal0,forbVal1,isect);
 +      IKGeo2DInternalMapper2(e->getEndNode(),m,forbVal0,forbVal1,isect);
 +    }
 +  return presenceOfOn;
 +}
 +
 +/// @endcond
 +
 +/**
 + * This method split some of edges of 2D cells in \a this. The edges to be split are specified in \a subNodesInSeg
 + * and in \a subNodesInSegI using \ref numbering-indirect storage mode.
 + * To do the work this method can optionally needs information about middle of subedges for quadratic cases if
 + * a minimal creation of new nodes is wanted.
 + * So this method try to reduce at most the number of new nodes. The only case that can lead this method to add
 + * nodes if a SEG3 is split without information of middle.
 + * \b WARNING : is returned value is different from 0 a call to MEDCouplingUMesh::mergeNodes is necessary to
 + * avoid to have a non conform mesh.
 + *
 + * \return int - the number of new nodes created (in most of cases 0).
 + * 
 + * \throw If \a this is not coherent.
 + * \throw If \a this has not spaceDim equal to 2.
 + * \throw If \a this has not meshDim equal to 2.
 + * \throw If some subcells needed to be split are orphan.
 + * \sa MEDCouplingUMesh::conformize2D
 + */
 +int MEDCouplingUMesh::split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt, const DataArrayInt *midOptI)
 +{
 +  if(!desc || !descI || !subNodesInSeg || !subNodesInSegI)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : the 4 first arrays must be not null !");
 +  desc->checkAllocated(); descI->checkAllocated(); subNodesInSeg->checkAllocated(); subNodesInSegI->checkAllocated();
 +  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : This method only works for meshes with spaceDim=2 and meshDim=2 !");
 +  if(midOpt==0 && midOptI==0)
 +    {
 +      split2DCellsLinear(desc,descI,subNodesInSeg,subNodesInSegI);
 +      return 0;
 +    }
 +  else if(midOpt!=0 && midOptI!=0)
 +    return split2DCellsQuadratic(desc,descI,subNodesInSeg,subNodesInSegI,midOpt,midOptI);
 +  else
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : middle parameters must be set to null for all or not null for all.");
 +}
 +
 +/*!
 + * \b WARNING this method is \b potentially \b non \b const (if returned array is empty).
 + * \b WARNING this method lead to have a non geometric type sorted mesh (for MED file users) !
 + * This method performs a conformization of \b this. So if a edge in \a this can be split into entire edges in \a this this method
 + * will suppress such edges to use sub edges in \a this. So this method does not add nodes in \a this if merged edges are both linear (INTERP_KERNEL::NORM_SEG2).
 + * In the other cases new nodes can be created. If any are created, they will be appended at the end of the coordinates object before the invokation of this method.
 + * 
 + * Whatever the returned value, this method does not alter the order of cells in \a this neither the orientation of cells.
 + * The modified cells, if any, are systematically declared as NORM_POLYGON or NORM_QPOLYG depending on the initial quadraticness of geometric type.
 + *
 + * This method expects that \b this has a meshDim equal 2 and spaceDim equal to 2 too.
 + * This method expects that all nodes in \a this are not closer than \a eps.
 + * If it is not the case you can invoke MEDCouplingUMesh::mergeNodes before calling this method.
 + * 
 + * \param [in] eps the relative error to detect merged edges.
 + * \return DataArrayInt  * - The list of cellIds in \a this that have been subdivided. If empty, nothing changed in \a this (as if it were a const method). The array is a newly allocated array
 + *                           that the user is expected to deal with.
 + *
 + * \throw If \a this is not coherent.
 + * \throw If \a this has not spaceDim equal to 2.
 + * \throw If \a this has not meshDim equal to 2.
 + * \sa MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::split2DCells
 + */
 +DataArrayInt *MEDCouplingUMesh::conformize2D(double eps)
 +{
 +  static const int SPACEDIM=2;
 +  checkCoherency();
 +  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1));
 +  const int *c(mDesc->getNodalConnectivity()->getConstPointer()),*ci(mDesc->getNodalConnectivityIndex()->getConstPointer()),*rd(revDesc1->getConstPointer()),*rdi(revDescIndx1->getConstPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(mDesc->getBoundingBoxForBBTree());
 +  const double *bbox(bboxArr->begin()),*coords(getCoords()->begin());
 +  int nCell(getNumberOfCells()),nDescCell(mDesc->getNumberOfCells());
 +  std::vector< std::vector<int> > intersectEdge(nDescCell),overlapEdge(nDescCell);
 +  std::vector<double> addCoo;
 +  BBTree<SPACEDIM,int> myTree(bbox,0,0,nDescCell,-eps);
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
 +  for(int i=0;i<nDescCell;i++)
 +    {
 +      std::vector<int> candidates;
 +      myTree.getIntersectingElems(bbox+i*2*SPACEDIM,candidates);
 +      for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
 +        if(*it>i)
 +          {
 +            std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m;
 +            INTERP_KERNEL::Edge *e1(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)),
 +                *e2(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[*it]],c+ci[*it]+1,coords,m));
 +            INTERP_KERNEL::MergePoints merge;
 +            INTERP_KERNEL::QuadraticPolygon c1,c2;
 +            e1->intersectWith(e2,merge,c1,c2);
 +            e1->decrRef(); e2->decrRef();
 +            if(IKGeo2DInternalMapper(c1,m,c[ci[i]+1],c[ci[i]+2],intersectEdge[i]))
 +              overlapEdge[i].push_back(*it);
 +            if(IKGeo2DInternalMapper(c2,m,c[ci[*it]+1],c[ci[*it]+2],intersectEdge[*it]))
 +              overlapEdge[*it].push_back(i);
 +          }
 +    }
 +  // splitting done. sort intersect point in intersectEdge.
 +  std::vector< std::vector<int> > middle(nDescCell);
 +  int nbOf2DCellsToBeSplit(0);
 +  bool middleNeedsToBeUsed(false);
 +  std::vector<bool> cells2DToTreat(nDescCell,false);
 +  for(int i=0;i<nDescCell;i++)
 +    {
 +      std::vector<int>& isect(intersectEdge[i]);
 +      int sz((int)isect.size());
 +      if(sz>1)
 +        {
 +          std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m;
 +          INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m));
 +          e->sortSubNodesAbs(coords,isect);
 +          e->decrRef();
 +        }
 +      if(sz!=0)
 +        {
 +          int idx0(rdi[i]),idx1(rdi[i+1]);
 +          if(idx1-idx0!=1)
 +            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : internal error #0 !");
 +          if(!cells2DToTreat[rd[idx0]])
 +            {
 +              cells2DToTreat[rd[idx0]]=true;
 +              nbOf2DCellsToBeSplit++;
 +            }
 +          // try to reuse at most eventual 'middle' of SEG3
 +          std::vector<int>& mid(middle[i]);
 +          mid.resize(sz+1,-1);
 +          if((INTERP_KERNEL::NormalizedCellType)c[ci[i]]==INTERP_KERNEL::NORM_SEG3)
 +            {
 +              middleNeedsToBeUsed=true;
 +              const std::vector<int>& candidates(overlapEdge[i]);
 +              std::vector<int> trueCandidates;
 +              for(std::vector<int>::const_iterator itc=candidates.begin();itc!=candidates.end();itc++)
 +                if((INTERP_KERNEL::NormalizedCellType)c[ci[*itc]]==INTERP_KERNEL::NORM_SEG3)
 +                  trueCandidates.push_back(*itc);
 +              int stNode(c[ci[i]+1]),endNode(isect[0]);
 +              for(int j=0;j<sz+1;j++)
 +                {
 +                  for(std::vector<int>::const_iterator itc=trueCandidates.begin();itc!=trueCandidates.end();itc++)
 +                    {
 +                      int tmpSt(c[ci[*itc]+1]),tmpEnd(c[ci[*itc]+2]);
 +                      if((tmpSt==stNode && tmpEnd==endNode) || (tmpSt==endNode && tmpEnd==stNode))
 +                        { mid[j]=*itc; break; }
 +                    }
 +                  stNode=endNode;
 +                  endNode=j<sz-1?isect[j+1]:c[ci[i]+2];
 +                }
 +            }
 +        }
 +    }
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()),notRet(DataArrayInt::New()); ret->alloc(nbOf2DCellsToBeSplit,1);
 +  if(nbOf2DCellsToBeSplit==0)
 +    return ret.retn();
 +  //
 +  int *retPtr(ret->getPointer());
 +  for(int i=0;i<nCell;i++)
 +    if(cells2DToTreat[i])
 +      *retPtr++=i;
 +  //
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> mSafe,nSafe,oSafe,pSafe,qSafe,rSafe;
 +  DataArrayInt *m(0),*n(0),*o(0),*p(0),*q(0),*r(0);
 +  MEDCouplingUMesh::ExtractFromIndexedArrays(ret->begin(),ret->end(),desc1,descIndx1,m,n); mSafe=m; nSafe=n;
 +  DataArrayInt::PutIntoToSkylineFrmt(intersectEdge,o,p); oSafe=o; pSafe=p;
 +  if(middleNeedsToBeUsed)
 +    { DataArrayInt::PutIntoToSkylineFrmt(middle,q,r); qSafe=q; rSafe=r; }
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> modif(static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(ret->begin(),ret->end(),true)));
 +  int nbOfNodesCreated(modif->split2DCells(mSafe,nSafe,oSafe,pSafe,qSafe,rSafe));
 +  setCoords(modif->getCoords());//if nbOfNodesCreated==0 modif and this have the same coordinates pointer so this line has no effect. But for quadratic cases this line is important.
 +  setPartOfMySelf(ret->begin(),ret->end(),*modif);
 +  {
 +    bool areNodesMerged; int newNbOfNodes;
 +    if(nbOfNodesCreated!=0)
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(mergeNodes(eps,areNodesMerged,newNbOfNodes));
 +  }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This non const method works on 2D mesh. This method scans every cell in \a this and look if each edge constituting this cell is not mergeable with neighbors edges of that cell.
 + * If yes, the cell is "repaired" to minimize at most its number of edges. So this method do not change the overall shape of cells in \a this (with eps precision).
 + * This method do not take care of shared edges between cells, so this method can lead to a non conform mesh (\a this). If a conform mesh is required you're expected
 + * to invoke MEDCouplingUMesh::mergeNodes and MEDCouplingUMesh::conformize2D right after this call.
 + * This method works on any 2D geometric types of cell (even static one). If a cell is touched its type becomes dynamic automaticaly. For 2D "repaired" quadratic cells
 + * new nodes for center of merged edges is are systematically created and appended at the end of the previously existing nodes.
 + *
 + * If the returned array is empty it means that nothing has changed in \a this (as if it were a const method). If the array is not empty the connectivity of \a this is modified
 + * using new instance, idem for coordinates.
 + *
 + * If \a this is constituted by only linear 2D cells, this method is close to the computation of the convex hull of each cells in \a this.
 + * 
 + * \return DataArrayInt  * - The list of cellIds in \a this that have at least one edge colinearized.
 + *
 + * \throw If \a this is not coherent.
 + * \throw If \a this has not spaceDim equal to 2.
 + * \throw If \a this has not meshDim equal to 2.
 + * 
 + * \sa MEDCouplingUMesh::conformize2D, MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::convexEnvelop2D.
 + */
 +DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps)
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
 +  checkCoherency();
 +  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::colinearize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !");
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
 +  int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
 +  const int *cptr(_nodal_connec->begin()),*ciptr(_nodal_connec_index->begin());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newc(DataArrayInt::New()),newci(DataArrayInt::New()); newci->alloc(nbOfCells+1,1); newc->alloc(0,1); newci->setIJ(0,0,0);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> appendedCoords(DataArrayDouble::New()); appendedCoords->alloc(0,1);//1 not 2 it is not a bug.
 +  const double *coords(_coords->begin());
 +  int *newciptr(newci->getPointer());
 +  for(int i=0;i<nbOfCells;i++,newciptr++,ciptr++)
 +    {
 +      if(Colinearize2DCell(coords,cptr+ciptr[0],cptr+ciptr[1],nbOfNodes,newc,appendedCoords))
 +        ret->pushBackSilent(i);
 +      newciptr[1]=newc->getNumberOfTuples();
 +    }
 +  //
 +  if(ret->empty())
 +    return ret.retn();
 +  if(!appendedCoords->empty())
 +    {
 +      appendedCoords->rearrange(2);
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(DataArrayDouble::Aggregate(getCoords(),appendedCoords));//treat info on components
 +      //non const part
 +      setCoords(newCoords);
 +    }
 +  //non const part
 +  setConnectivity(newc,newci,true);
 +  return ret.retn();
 +}
 +
 +/*!
 + * \param [out] intersectEdge1 - for each cell in \a m1Desc returns the result of the split. The result is given using pair of int given resp start and stop.
 + *                               So for all edge \a i in \a m1Desc \a  intersectEdge1[i] is of length 2*n where n is the number of sub edges.
 + *                               And for each j in [1,n) intersect[i][2*(j-1)+1]==intersect[i][2*j].
 + * \param [out] subDiv2 - for each cell in \a m2Desc returns nodes that split it using convention \a m1Desc first, then \a m2Desc, then addCoo
 + * \param [out] colinear2 - for each cell in \a m2Desc returns the edges in \a m1Desc that are colinear to it.
 + * \param [out] addCoo - nodes to be append at the end
 + * \param [out] mergedNodes - gives all pair of nodes of \a m2Desc that have same location than some nodes in \a m1Desc. key is id in \a m2Desc offseted and value is id in \a m1Desc.
 + */
 +void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps,
 +                                         std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2, std::vector<double>& addCoo, std::map<int,int>& mergedNodes)
 +{
 +  static const int SPACEDIM=2;
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
 +  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
 +  const int *c1(m1Desc->getNodalConnectivity()->getConstPointer()),*ci1(m1Desc->getNodalConnectivityIndex()->getConstPointer());
 +  // Build BB tree of all edges in the tool mesh (second mesh)
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox1Arr(m1Desc->getBoundingBoxForBBTree()),bbox2Arr(m2Desc->getBoundingBoxForBBTree());
 +  const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
 +  int nDescCell1(m1Desc->getNumberOfCells()),nDescCell2(m2Desc->getNumberOfCells());
 +  intersectEdge1.resize(nDescCell1);
 +  colinear2.resize(nDescCell2);
 +  subDiv2.resize(nDescCell2);
 +  BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2Desc->getNumberOfCells(),-eps);
 +
 +  std::vector<int> candidates1(1);
 +  int offset1(m1Desc->getNumberOfNodes());
 +  int offset2(offset1+m2Desc->getNumberOfNodes());
 +  for(int i=0;i<nDescCell1;i++)  // for all edges in the first mesh
 +    {
 +      std::vector<int> candidates2; // edges of mesh2 candidate for intersection
 +      myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
 +      if(!candidates2.empty()) // candidates2 holds edges from the second mesh potentially intersecting current edge i in mesh1
 +        {
 +          std::map<INTERP_KERNEL::Node *,int> map1,map2;
 +          // pol2 is not necessarily a closed polygon: just a set of (quadratic) edges (same as candidates2) in the Geometric DS format
 +          INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2);
 +          candidates1[0]=i;
 +          INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1);
 +          // This following part is to avoid that some removed nodes (for example due to a merge between pol1 and pol2) are replaced by a newly created one
 +          // This trick guarantees that Node * are discriminant (i.e. form a unique identifier)
 +          std::set<INTERP_KERNEL::Node *> nodes;
 +          pol1->getAllNodes(nodes); pol2->getAllNodes(nodes);
 +          std::size_t szz(nodes.size());
 +          std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> > nodesSafe(szz);
 +          std::set<INTERP_KERNEL::Node *>::const_iterator itt(nodes.begin());
 +          for(std::size_t iii=0;iii<szz;iii++,itt++)
 +            { (*itt)->incrRef(); nodesSafe[iii]=*itt; }
 +          // end of protection
 +          // Performs egde cutting:
 +          pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo,mergedNodes);
 +          delete pol2;
 +          delete pol1;
 +        }
 +      else
 +        // Copy the edge (take only the two first points, ie discard quadratic point at this stage)
 +        intersectEdge1[i].insert(intersectEdge1[i].end(),c1+ci1[i]+1,c1+ci1[i]+3);
 +    }
 +}
 +
 +/*!
 + * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2).
 + * It builds the descending connectivity of the two meshes, and then using a binary tree
 + * it computes the edge intersections. This results in new points being created : they're stored in addCoo.
 + * Documentation about parameters  colinear2 and subDiv2 can be found in method QuadraticPolygon::splitAbs().
 + */
 +void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
 +                                                   std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2,
 +                                                   MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,
 +                                                   std::vector<double>& addCoo,
 +                                                   MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2)
 +{
 +  // Build desc connectivity
 +  desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New();
 +  desc2=DataArrayInt::New();
 +  descIndx2=DataArrayInt::New();
 +  revDesc2=DataArrayInt::New();
 +  revDescIndx2=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd5(desc2),dd6(descIndx2),dd7(revDesc2),dd8(revDescIndx2);
 +  m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
 +  m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2);
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd9(m1Desc),dd10(m2Desc);
 +  std::map<int,int> notUsedMap;
 +  Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo,notUsedMap);
 +  m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef();
 +  m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef();
 +}
 +
 +/*!
 + * This method performs the 2nd step of Partition of 2D mesh.
 + * This method has 4 inputs :
 + *  - a mesh 'm1' with meshDim==1 and a SpaceDim==2
 + *  - a mesh 'm2' with meshDim==1 and a SpaceDim==2
 + *  - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids randomly sorted.
 + * The aim of this method is to sort the splitting nodes, if any, and to put them in 'intersectEdge' output parameter based on edges of mesh 'm2'
 + * Nodes end up lying consecutively on a cutted edge.
 + * \param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
 + * (Only present for its coords in case of 'subDiv' shares some nodes of 'm1')
 + * \param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
 + * \param addCoo input parameter with additional nodes linked to intersection of the 2 meshes.
 + * \param[out] intersectEdge the same content as subDiv, but correclty oriented.
 + */
 +void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2,
 +                                           const std::vector<double>& addCoo,
 +                                           const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge)
 +{
 +  int offset1=m1->getNumberOfNodes();
 +  int ncell=m2->getNumberOfCells();
 +  const int *c=m2->getNodalConnectivity()->getConstPointer();
 +  const int *cI=m2->getNodalConnectivityIndex()->getConstPointer();
 +  const double *coo=m2->getCoords()->getConstPointer();
 +  const double *cooBis=m1->getCoords()->getConstPointer();
 +  int offset2=offset1+m2->getNumberOfNodes();
 +  intersectEdge.resize(ncell);
 +  for(int i=0;i<ncell;i++,cI++)
 +    {
 +      const std::vector<int>& divs=subDiv[i];
 +      int nnode=cI[1]-cI[0]-1;
 +      std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;
 +      std::map<INTERP_KERNEL::Node *, int> mapp22;
 +      for(int j=0;j<nnode;j++)
 +        {
 +          INTERP_KERNEL::Node *nn=new INTERP_KERNEL::Node(coo[2*c[(*cI)+j+1]],coo[2*c[(*cI)+j+1]+1]);
 +          int nnid=c[(*cI)+j+1];
 +          mapp2[nnid]=std::pair<INTERP_KERNEL::Node *,bool>(nn,true);
 +          mapp22[nn]=nnid+offset1;
 +        }
 +      INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1);
 +      for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it=mapp2.begin();it!=mapp2.end();it++)
 +        ((*it).second.first)->decrRef();
 +      std::vector<INTERP_KERNEL::Node *> addNodes(divs.size());
 +      std::map<INTERP_KERNEL::Node *,int> mapp3;
 +      for(std::size_t j=0;j<divs.size();j++)
 +        {
 +          int id=divs[j];
 +          INTERP_KERNEL::Node *tmp=0;
 +          if(id<offset1)
 +            tmp=new INTERP_KERNEL::Node(cooBis[2*id],cooBis[2*id+1]);
 +          else if(id<offset2)
 +            tmp=new INTERP_KERNEL::Node(coo[2*(id-offset1)],coo[2*(id-offset1)+1]);//if it happens, bad news mesh 'm2' is non conform.
 +          else
 +            tmp=new INTERP_KERNEL::Node(addCoo[2*(id-offset2)],addCoo[2*(id-offset2)+1]);
 +          addNodes[j]=tmp;
 +          mapp3[tmp]=id;
 +        }
 +      e->sortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]);
 +      for(std::vector<INTERP_KERNEL::Node *>::const_iterator it=addNodes.begin();it!=addNodes.end();it++)
 +        (*it)->decrRef();
 +      e->decrRef();
 +    }
 +}
 +
 +/*!
 + * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
 + * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells
 + * with a plane. The result will be put in 'cut3DSuf' out parameter.
 + * \param [in] cut3DCurve  input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially.
 + * \param [out] nodesOnPlane, returns all the nodes that are on the plane.
 + * \param [in] nodal3DSurf is the nodal connectivity of 3D surf mesh.
 + * \param [in] nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh.
 + * \param [in] nodal3DCurve is the nodal connectivity of 3D curve mesh.
 + * \param [in] nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh.
 + * \param [in] desc is the descending connectivity 3DSurf->3DCurve
 + * \param [in] descIndx is the descending connectivity index 3DSurf->3DCurve
 + * \param [out] cut3DSuf input/output param.
 + */
 +void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,
 +                                                   const int *nodal3DCurve, const int *nodalIndx3DCurve,
 +                                                   const int *desc, const int *descIndx, 
 +                                                   std::vector< std::pair<int,int> >& cut3DSurf)
 +{
 +  std::set<int> nodesOnP(nodesOnPlane.begin(),nodesOnPlane.end());
 +  int nbOf3DSurfCell=(int)cut3DSurf.size();
 +  for(int i=0;i<nbOf3DSurfCell;i++)
 +    {
 +      std::vector<int> res;
 +      int offset=descIndx[i];
 +      int nbOfSeg=descIndx[i+1]-offset;
 +      for(int j=0;j<nbOfSeg;j++)
 +        {
 +          int edgeId=desc[offset+j];
 +          int status=cut3DCurve[edgeId];
 +          if(status!=-2)
 +            {
 +              if(status>-1)
 +                res.push_back(status);
 +              else
 +                {
 +                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+1]);
 +                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+2]);
 +                }
 +            }
 +        }
 +      switch(res.size())
 +      {
 +        case 2:
 +          {
 +            cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
 +            break;
 +          }
 +        case 1:
 +        case 0:
 +          {
 +            std::set<int> s1(nodal3DSurf+nodalIndx3DSurf[i]+1,nodal3DSurf+nodalIndx3DSurf[i+1]);
 +            std::set_intersection(nodesOnP.begin(),nodesOnP.end(),s1.begin(),s1.end(),std::back_insert_iterator< std::vector<int> >(res));
 +            if(res.size()==2)
 +              {
 +                cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
 +              }
 +            else
 +              {
 +                cut3DSurf[i].first=-1; cut3DSurf[i].second=-1;
 +              }
 +            break;
 +          }
 +        default:
 +          {// case when plane is on a multi colinear edge of a polyhedron
 +            if((int)res.size()==2*nbOfSeg)
 +              {
 +                cut3DSurf[i].first=-2; cut3DSurf[i].second=i;
 +              }
 +            else
 +              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AssemblyPointsFrom3DCurve : unexpected situation !");
 +          }
 +      }
 +    }
 +}
 +
 +/*!
 + * \a this is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown.
 + * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
 + * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells
 + * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters.
 + * \param cut3DSurf  input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve).
 + * \param desc is the descending connectivity 3D->3DSurf
 + * \param descIndx is the descending connectivity index 3D->3DSurf
 + */
 +void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,
 +                                                  const int *desc, const int *descIndx,
 +                                                  DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const
 +{
 +  checkFullyDefined();
 +  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::assemblyForSplitFrom3DSurf works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
 +  const int *nodal3D=_nodal_connec->getConstPointer();
 +  const int *nodalIndx3D=_nodal_connec_index->getConstPointer();
 +  int nbOfCells=getNumberOfCells();
 +  for(int i=0;i<nbOfCells;i++)
 +    {
 +      std::map<int, std::set<int> > m;
 +      int offset=descIndx[i];
 +      int nbOfFaces=descIndx[i+1]-offset;
 +      int start=-1;
 +      int end=-1;
 +      for(int j=0;j<nbOfFaces;j++)
 +        {
 +          const std::pair<int,int>& p=cut3DSurf[desc[offset+j]];
 +          if(p.first!=-1 && p.second!=-1)
 +            {
 +              if(p.first!=-2)
 +                {
 +                  start=p.first; end=p.second;
 +                  m[p.first].insert(p.second);
 +                  m[p.second].insert(p.first);
 +                }
 +              else
 +                {
 +                  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]);
 +                  int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1;
 +                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz];
 +                  INTERP_KERNEL::NormalizedCellType cmsId;
 +                  unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId);
 +                  start=tmp[0]; end=tmp[nbOfNodesSon-1];
 +                  for(unsigned k=0;k<nbOfNodesSon;k++)
 +                    {
 +                      m[tmp[k]].insert(tmp[(k+1)%nbOfNodesSon]);
 +                      m[tmp[(k+1)%nbOfNodesSon]].insert(tmp[k]);
 +                    }
 +                }
 +            }
 +        }
 +      if(m.empty())
 +        continue;
 +      std::vector<int> conn(1,(int)INTERP_KERNEL::NORM_POLYGON);
 +      int prev=end;
 +      while(end!=start)
 +        {
 +          std::map<int, std::set<int> >::const_iterator it=m.find(start);
 +          const std::set<int>& s=(*it).second;
 +          std::set<int> s2; s2.insert(prev);
 +          std::set<int> s3;
 +          std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()));
 +          if(s3.size()==1)
 +            {
 +              int val=*s3.begin();
 +              conn.push_back(start);
 +              prev=start;
 +              start=val;
 +            }
 +          else
 +            start=end;
 +        }
 +      conn.push_back(end);
 +      if(conn.size()>3)
 +        {
 +          nodalRes->insertAtTheEnd(conn.begin(),conn.end());
 +          nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples());
 +          cellIds->pushBackSilent(i);
 +        }
 +    }
 +}
 +
 +/*!
 + * This method compute the convex hull of a single 2D cell. This method tries to conserve at maximum the given input connectivity. In particular, if the orientation of cell is not clockwise
 + * as in MED format norm. If definitely the result of Jarvis algorithm is not matchable with the input connectivity, the result will be copied into \b nodalConnecOut parameter and
 + * the geometric cell type set to INTERP_KERNEL::NORM_POLYGON.
 + * This method excepts that \b coords parameter is expected to be in dimension 2. [ \b nodalConnBg , \b nodalConnEnd ) is the nodal connectivity of the input
 + * cell (geometric cell type included at the position 0). If the meshdimension of the input cell is not equal to 2 an INTERP_KERNEL::Exception will be thrown.
 + * 
 + * \return false if the input connectivity represents already the convex hull, true if the input cell needs to be reordered.
 + */
 +bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut)
 +{
 +  std::size_t sz=std::distance(nodalConnBg,nodalConnEnd);
 +  if(sz>=4)
 +    {
 +      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)*nodalConnBg);
 +      if(cm.getDimension()==2)
 +        {
 +          const int *node=nodalConnBg+1;
 +          int startNode=*node++;
 +          double refX=coords[2*startNode];
 +          for(;node!=nodalConnEnd;node++)
 +            {
 +              if(coords[2*(*node)]<refX)
 +                {
 +                  startNode=*node;
 +                  refX=coords[2*startNode];
 +                }
 +            }
 +          std::vector<int> tmpOut; tmpOut.reserve(sz); tmpOut.push_back(startNode);
 +          refX=1e300;
 +          double tmp1;
 +          double tmp2[2];
 +          double angle0=-M_PI/2;
 +          //
 +          int nextNode=-1;
 +          int prevNode=-1;
 +          double resRef;
 +          double angleNext=0.;
 +          while(nextNode!=startNode)
 +            {
 +              nextNode=-1;
 +              resRef=1e300;
 +              for(node=nodalConnBg+1;node!=nodalConnEnd;node++)
 +                {
 +                  if(*node!=tmpOut.back() && *node!=prevNode)
 +                    {
 +                      tmp2[0]=coords[2*(*node)]-coords[2*tmpOut.back()]; tmp2[1]=coords[2*(*node)+1]-coords[2*tmpOut.back()+1];
 +                      double angleM=INTERP_KERNEL::EdgeArcCircle::GetAbsoluteAngle(tmp2,tmp1);
 +                      double res;
 +                      if(angleM<=angle0)
 +                        res=angle0-angleM;
 +                      else
 +                        res=angle0-angleM+2.*M_PI;
 +                      if(res<resRef)
 +                        {
 +                          nextNode=*node;
 +                          resRef=res;
 +                          angleNext=angleM;
 +                        }
 +                    }
 +                }
 +              if(nextNode!=startNode)
 +                {
 +                  angle0=angleNext-M_PI;
 +                  if(angle0<-M_PI)
 +                    angle0+=2*M_PI;
 +                  prevNode=tmpOut.back();
 +                  tmpOut.push_back(nextNode);
 +                }
 +            }
 +          std::vector<int> tmp3(2*(sz-1));
 +          std::vector<int>::iterator it=std::copy(nodalConnBg+1,nodalConnEnd,tmp3.begin());
 +          std::copy(nodalConnBg+1,nodalConnEnd,it);
 +          if(std::search(tmp3.begin(),tmp3.end(),tmpOut.begin(),tmpOut.end())!=tmp3.end())
 +            {
 +              nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd);
 +              return false;
 +            }
 +          if(std::search(tmp3.rbegin(),tmp3.rend(),tmpOut.begin(),tmpOut.end())!=tmp3.rend())
 +            {
 +              nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd);
 +              return false;
 +            }
 +          else
 +            {
 +              nodalConnecOut->pushBackSilent((int)INTERP_KERNEL::NORM_POLYGON);
 +              nodalConnecOut->insertAtTheEnd(tmpOut.begin(),tmpOut.end());
 +              return true;
 +            }
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !");
 +    }
 +  else
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !");
 +}
 +
 +/*!
 + * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx.
 + * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression.
 + * 
 + * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included)
 + * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded)
 + * \param [in,out] arr array in which the remove operation will be done.
 + * \param [in,out] arrIndx array in the remove operation will modify
 + * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1])
 + * \return true if \b arr and \b arrIndx have been modified, false if not.
 + */
 +bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval)
 +{
 +  if(!arrIndx || !arr)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : some input arrays are empty !");
 +  if(offsetForRemoval<0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !");
 +  std::set<int> s(idsToRemoveBg,idsToRemoveEnd);
 +  int nbOfGrps=arrIndx->getNumberOfTuples()-1;
 +  int *arrIPtr=arrIndx->getPointer();
 +  *arrIPtr++=0;
 +  int previousArrI=0;
 +  const int *arrPtr=arr->getConstPointer();
 +  std::vector<int> arrOut;//no utility to switch to DataArrayInt because copy always needed
 +  for(int i=0;i<nbOfGrps;i++,arrIPtr++)
 +    {
 +      if(*arrIPtr-previousArrI>offsetForRemoval)
 +        {
 +          for(const int *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++)
 +            {
 +              if(s.find(*work)==s.end())
 +                arrOut.push_back(*work);
 +            }
 +        }
 +      previousArrI=*arrIPtr;
 +      *arrIPtr=(int)arrOut.size();
 +    }
 +  if(arr->getNumberOfTuples()==(int)arrOut.size())
 +    return false;
 +  arr->alloc((int)arrOut.size(),1);
 +  std::copy(arrOut.begin(),arrOut.end(),arr->getPointer());
 +  return true;
 +}
 +
 +/*!
 + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
 + * (\ref numbering-indirect).
 + * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ).
 + * The selection of extraction is done standardly in new2old format.
 + * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
 + *
 + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
 + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
 + * \param [in] arrIn arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \param [out] arrOut the resulting array
 + * \param [out] arrIndexOut the index array of the resulting array \b arrOut
 + * \sa MEDCouplingUMesh::ExtractFromIndexedArrays2
 + */
 +void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
 +                                                DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
 +{
 +  if(!arrIn || !arrIndxIn)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !");
 +  arrIn->checkAllocated(); arrIndxIn->checkAllocated();
 +  if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input arrays must have exactly one component !");
 +  std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd);
 +  const int *arrInPtr=arrIn->getConstPointer();
 +  const int *arrIndxPtr=arrIndxIn->getConstPointer();
 +  int nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
 +  if(nbOfGrps<0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
 +  int maxSizeOfArr=arrIn->getNumberOfTuples();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
 +  arrIo->alloc((int)(sz+1),1);
 +  const int *idsIt=idsOfSelectBg;
 +  int *work=arrIo->getPointer();
 +  *work++=0;
 +  int lgth=0;
 +  for(std::size_t i=0;i<sz;i++,work++,idsIt++)
 +    {
 +      if(*idsIt>=0 && *idsIt<nbOfGrps)
 +        lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt];
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +      if(lgth>=work[-1])
 +        *work=lgth;
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt;
 +          oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  arro->alloc(lgth,1);
 +  work=arro->getPointer();
 +  idsIt=idsOfSelectBg;
 +  for(std::size_t i=0;i<sz;i++,idsIt++)
 +    {
 +      if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr)
 +        work=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],work);
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx[";
 +          oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  arrOut=arro.retn();
 +  arrIndexOut=arrIo.retn();
 +}
 +
 +/*!
 + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
 + * (\ref numbering-indirect).
 + * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ).
 + * The selection of extraction is done standardly in new2old format.
 + * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
 + *
 + * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included)
 + * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded)
 + * \param [in] idsOfSelectStep
 + * \param [in] arrIn arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \param [out] arrOut the resulting array
 + * \param [out] arrIndexOut the index array of the resulting array \b arrOut
 + * \sa MEDCouplingUMesh::ExtractFromIndexedArrays
 + */
 +void MEDCouplingUMesh::ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
 +                                                 DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
 +{
 +  if(!arrIn || !arrIndxIn)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input pointer is NULL !");
 +  arrIn->checkAllocated(); arrIndxIn->checkAllocated();
 +  if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input arrays must have exactly one component !");
 +  int sz=DataArrayInt::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArrays2 : Input slice ");
 +  const int *arrInPtr=arrIn->getConstPointer();
 +  const int *arrIndxPtr=arrIndxIn->getConstPointer();
 +  int nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
 +  if(nbOfGrps<0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
 +  int maxSizeOfArr=arrIn->getNumberOfTuples();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
 +  arrIo->alloc((int)(sz+1),1);
 +  int idsIt=idsOfSelectStart;
 +  int *work=arrIo->getPointer();
 +  *work++=0;
 +  int lgth=0;
 +  for(int i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep)
 +    {
 +      if(idsIt>=0 && idsIt<nbOfGrps)
 +        lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt];
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +      if(lgth>=work[-1])
 +        *work=lgth;
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt;
 +          oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  arro->alloc(lgth,1);
 +  work=arro->getPointer();
 +  idsIt=idsOfSelectStart;
 +  for(int i=0;i<sz;i++,idsIt+=idsOfSelectStep)
 +    {
 +      if(arrIndxPtr[idsIt]>=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr)
 +        work=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],work);
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx[";
 +          oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  arrOut=arro.retn();
 +  arrIndexOut=arrIo.retn();
 +}
 +
 +/*!
 + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
 + * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for
 + * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
 + * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays.
 + *
 + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
 + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
 + * \param [in] arrIn arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd )
 + * \param [in] srcArrIndex index array of \b srcArr
 + * \param [out] arrOut the resulting array
 + * \param [out] arrIndexOut the index array of the resulting array \b arrOut
 + * 
 + * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx
 + */
 +void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
 +                                              const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
 +                                              DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
 +{
 +  if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : presence of null pointer in input parameter !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
 +  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
 +  std::vector<bool> v(nbOfTuples,true);
 +  int offset=0;
 +  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
 +  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
 +  for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
 +    {
 +      if(*it>=0 && *it<nbOfTuples)
 +        {
 +          v[*it]=false;
 +          offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]);
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  srcArrIndexPtr=srcArrIndex->getConstPointer();
 +  arrIo->alloc(nbOfTuples+1,1);
 +  arro->alloc(arrIn->getNumberOfTuples()+offset,1);
 +  const int *arrInPtr=arrIn->getConstPointer();
 +  const int *srcArrPtr=srcArr->getConstPointer();
 +  int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
 +  int *arroPtr=arro->getPointer();
 +  for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
 +    {
 +      if(v[ii])
 +        {
 +          arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
 +          *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
 +        }
 +      else
 +        {
 +          std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
 +          arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
 +          *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
 +        }
 +    }
 +  arrOut=arro.retn();
 +  arrIndexOut=arrIo.retn();
 +}
 +
 +/*!
 + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
 + * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn.
 + *
 + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
 + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
 + * \param [in,out] arrInOut arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd )
 + * \param [in] srcArrIndex index array of \b srcArr
 + * 
 + * \sa MEDCouplingUMesh::SetPartOfIndexedArrays
 + */
 +void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
 +                                                     const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex)
 +{
 +  if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !");
 +  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
 +  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
 +  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
 +  int *arrInOutPtr=arrInOut->getPointer();
 +  const int *srcArrPtr=srcArr->getConstPointer();
 +  for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
 +    {
 +      if(*it>=0 && *it<nbOfTuples)
 +        {
 +          if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it])
 +            std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +}
 +
 +/*!
 + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn.
 + * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method.
 + * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 looking at arrIn[arrIndxIn[0]:arrIndxIn[0+1]].
 + * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step.
 + * A negative value in \b arrIn means that it is ignored.
 + * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1.
 + * 
 + * \param [in] arrIn arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process.
 + * \sa MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed, MEDCouplingUMesh::partitionBySpreadZone
 + */
 +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn)
 +{
 +  int seed=0,nbOfDepthPeelingPerformed=0;
 +  return ComputeSpreadZoneGraduallyFromSeed(&seed,&seed+1,arrIn,arrIndxIn,-1,nbOfDepthPeelingPerformed);
 +}
 +
 +/*!
 + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn.
 + * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method.
 + * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]].
 + * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step.
 + * A negative value in \b arrIn means that it is ignored.
 + * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1.
 + * \param [in] seedBg the begin pointer (included) of an array containing the seed of the search zone
 + * \param [in] seedEnd the end pointer (not included) of an array containing the seed of the search zone
 + * \param [in] arrIn arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \param [in] nbOfDepthPeeling the max number of peels requested in search. By default -1, that is to say, no limit.
 + * \param [out] nbOfDepthPeelingPerformed the number of peels effectively performed. May be different from \a nbOfDepthPeeling
 + * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process.
 + * \sa MEDCouplingUMesh::partitionBySpreadZone
 + */
 +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed)
 +{
 +  nbOfDepthPeelingPerformed=0;
 +  if(!arrIndxIn)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed : arrIndxIn input pointer is NULL !");
 +  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
 +  if(nbOfTuples<=0)
 +    {
 +      DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1);
 +      return ret;
 +    }
 +  //
 +  std::vector<bool> fetched(nbOfTuples,false);
 +  return ComputeSpreadZoneGraduallyFromSeedAlg(fetched,seedBg,seedEnd,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed);
 +}
 +
 +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed)
 +{
 +  nbOfDepthPeelingPerformed=0;
 +  if(!seedBg || !seedEnd || !arrIn || !arrIndxIn)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !");
 +  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
 +  std::vector<bool> fetched2(nbOfTuples,false);
 +  int i=0;
 +  for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++)
 +    {
 +      if(*seedElt>=0 && *seedElt<nbOfTuples)
 +        { fetched[*seedElt]=true; fetched2[*seedElt]=true; }
 +      else
 +        { std::ostringstream oss; oss << "MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : At pos #" << i << " of seeds value is " << *seedElt << "! Should be in [0," << nbOfTuples << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
 +    }
 +  const int *arrInPtr=arrIn->getConstPointer();
 +  const int *arrIndxPtr=arrIndxIn->getConstPointer();
 +  int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits<int>::max();
 +  std::vector<int> idsToFetch1(seedBg,seedEnd);
 +  std::vector<int> idsToFetch2;
 +  std::vector<int> *idsToFetch=&idsToFetch1;
 +  std::vector<int> *idsToFetchOther=&idsToFetch2;
 +  while(!idsToFetch->empty() && nbOfDepthPeelingPerformed<targetNbOfDepthPeeling)
 +    {
 +      for(std::vector<int>::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++)
 +        for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++)
 +          if(!fetched[*it2])
 +            { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); }
 +      std::swap(idsToFetch,idsToFetchOther);
 +      idsToFetchOther->clear();
 +      nbOfDepthPeelingPerformed++;
 +    }
 +  int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true);
 +  i=0;
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(lgth,1);
 +  int *retPtr=ret->getPointer();
 +  for(std::vector<bool>::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++)
 +    if(*it)
 +      *retPtr++=i;
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
 + * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for
 + * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
 + * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays.
 + *
 + * \param [in] start begin of set of ids of the input extraction (included)
 + * \param [in] end end of set of ids of the input extraction (excluded)
 + * \param [in] step step of the set of ids in range mode.
 + * \param [in] arrIn arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
 + * \param [in] srcArrIndex index array of \b srcArr
 + * \param [out] arrOut the resulting array
 + * \param [out] arrIndexOut the index array of the resulting array \b arrOut
 + * 
 + * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx MEDCouplingUMesh::SetPartOfIndexedArrays
 + */
 +void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
 +                                               const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
 +                                               DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
 +{
 +  if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays2 : presence of null pointer in input parameter !");
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
 +  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
 +  int offset=0;
 +  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
 +  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
 +  int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArrays2 : ");
 +  int it=start;
 +  for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
 +    {
 +      if(it>=0 && it<nbOfTuples)
 +        offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +  srcArrIndexPtr=srcArrIndex->getConstPointer();
 +  arrIo->alloc(nbOfTuples+1,1);
 +  arro->alloc(arrIn->getNumberOfTuples()+offset,1);
 +  const int *arrInPtr=arrIn->getConstPointer();
 +  const int *srcArrPtr=srcArr->getConstPointer();
 +  int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
 +  int *arroPtr=arro->getPointer();
 +  for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
 +    {
 +      int pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
 +      if(pos<0)
 +        {
 +          arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
 +          *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
 +        }
 +      else
 +        {
 +          arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
 +          *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
 +        }
 +    }
 +  arrOut=arro.retn();
 +  arrIndexOut=arrIo.retn();
 +}
 +
 +/*!
 + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
 + * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn.
 + *
 + * \param [in] start begin of set of ids of the input extraction (included)
 + * \param [in] end end of set of ids of the input extraction (excluded)
 + * \param [in] step step of the set of ids in range mode.
 + * \param [in,out] arrInOut arr origin array from which the extraction will be done.
 + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
 + * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
 + * \param [in] srcArrIndex index array of \b srcArr
 + * 
 + * \sa MEDCouplingUMesh::SetPartOfIndexedArrays2 MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx
 + */
 +void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
 +                                                      const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex)
 +{
 +  if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : presence of null pointer in input parameter !");
 +  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
 +  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
 +  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
 +  int *arrInOutPtr=arrInOut->getPointer();
 +  const int *srcArrPtr=srcArr->getConstPointer();
 +  int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : ");
 +  int it=start;
 +  for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
 +    {
 +      if(it>=0 && it<nbOfTuples)
 +        {
 +          if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
 +            std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
 +          else
 +            {
 +              std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
 +              throw INTERP_KERNEL::Exception(oss.str().c_str());
 +            }
 +        }
 +      else
 +        {
 +          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +    }
 +}
 +
 +/*!
 + * \b this is expected to be a mesh fully defined whose spaceDim==meshDim.
 + * It returns a new allocated mesh having the same mesh dimension and lying on same coordinates.
 + * The returned mesh contains as poly cells as number of contiguous zone (regarding connectivity).
 + * A spread contiguous zone is built using poly cells (polyhedra in 3D, polygons in 2D and polyline in 1D).
 + * The sum of measure field of returned mesh is equal to the sum of measure field of this.
 + * 
 + * \return a newly allocated mesh lying on the same coords than \b this with same meshdimension than \b this.
 + */
 +MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const
 +{
 +  checkFullyDefined();
 +  int mdim=getMeshDimension();
 +  int spaceDim=getSpaceDimension();
 +  if(mdim!=spaceDim)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension and spacedimension do not match !");
 +  std::vector<DataArrayInt *> partition=partitionBySpreadZone();
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > partitionAuto; partitionAuto.reserve(partition.size());
 +  std::copy(partition.begin(),partition.end(),std::back_insert_iterator<std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > >(partitionAuto));
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim);
 +  ret->setCoords(getCoords());
 +  ret->allocateCells((int)partition.size());
 +  //
 +  for(std::vector<DataArrayInt *>::const_iterator it=partition.begin();it!=partition.end();it++)
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf((*it)->begin(),(*it)->end(),true));
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cell;
 +      switch(mdim)
 +      {
 +        case 2:
 +          cell=tmp->buildUnionOf2DMesh();
 +          break;
 +        case 3:
 +          cell=tmp->buildUnionOf3DMesh();
 +          break;
 +        default:
 +          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension supported are [2,3] ! Not implemented yet for others !");
 +      }
 +
 +      ret->insertNextCell((INTERP_KERNEL::NormalizedCellType)cell->getIJSafe(0,0),cell->getNumberOfTuples()-1,cell->getConstPointer()+1);
 +    }
 +  //
 +  ret->finishInsertingCells();
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method partitions \b this into contiguous zone.
 + * This method only needs a well defined connectivity. Coordinates are not considered here.
 + * This method returns a vector of \b newly allocated arrays that the caller has to deal with.
 + */
 +std::vector<DataArrayInt *> MEDCouplingUMesh::partitionBySpreadZone() const
 +{
 +  int nbOfCellsCur=getNumberOfCells();
 +  std::vector<DataArrayInt *> ret;
 +  if(nbOfCellsCur<=0)
 +    return ret;
 +  DataArrayInt *neigh=0,*neighI=0;
 +  computeNeighborsOfCells(neigh,neighI);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighAuto(neigh),neighIAuto(neighI);
 +  std::vector<bool> fetchedCells(nbOfCellsCur,false);
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret2;
 +  int seed=0;
 +  while(seed<nbOfCellsCur)
 +    {
 +      int nbOfPeelPerformed=0;
 +      ret2.push_back(ComputeSpreadZoneGraduallyFromSeedAlg(fetchedCells,&seed,&seed+1,neigh,neighI,-1,nbOfPeelPerformed));
 +      seed=(int)std::distance(fetchedCells.begin(),std::find(fetchedCells.begin()+seed,fetchedCells.end(),false));
 +    }
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::iterator it=ret2.begin();it!=ret2.end();it++)
 +    ret.push_back((*it).retn());
 +  return ret;
 +}
 +
 +/*!
 + * This method returns given a distribution of cell type (returned for example by MEDCouplingUMesh::getDistributionOfTypes method and customized after) a
 + * newly allocated DataArrayInt instance with 2 components ready to be interpreted as input of DataArrayInt::findRangeIdForEachTuple method.
 + *
 + * \param [in] code a code with the same format than those returned by MEDCouplingUMesh::getDistributionOfTypes except for the code[3*k+2] that should contain start id of chunck.
 + * \return a newly allocated DataArrayInt to be managed by the caller.
 + * \throw In case of \a code has not the right format (typically of size 3*n)
 + */
 +DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector<int>& code)
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
 +  std::size_t nb=code.size()/3;
 +  if(code.size()%3!=0)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeRangesFromTypeDistribution : invalid input code !");
 +  ret->alloc((int)nb,2);
 +  int *retPtr=ret->getPointer();
 +  for(std::size_t i=0;i<nb;i++,retPtr+=2)
 +    {
 +      retPtr[0]=code[3*i+2];
 +      retPtr[1]=code[3*i+2]+code[3*i+1];
 +    }
 +  return ret.retn();
 +}
 +
 +/*!
 + * This method expects that \a this a 3D mesh (spaceDim=3 and meshDim=3) with all coordinates and connectivities set.
 + * All cells in \a this are expected to be linear 3D cells.
 + * This method will split **all** 3D cells in \a this into INTERP_KERNEL::NORM_TETRA4 cells and put them in the returned mesh.
 + * It leads to an increase to number of cells.
 + * This method contrary to MEDCouplingUMesh::simplexize can append coordinates in \a this to perform its work.
 + * The \a nbOfAdditionalPoints returned value informs about it. If > 0, the coordinates array in returned mesh will have \a nbOfAdditionalPoints 
 + * more tuples (nodes) than in \a this. Anyway, all the nodes in \a this (with the same order) will be in the returned mesh.
 + *
 + * \param [in] policy - the policy of splitting that must be in (PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48). The policy will be used only for INTERP_KERNEL::NORM_HEXA8 cells.
 + *                      For all other cells, the splitting policy will be ignored. See INTERP_KERNEL::SplittingPolicy for the images.
 + * \param [out] nbOfAdditionalPoints - number of nodes added to \c this->_coords. If > 0 a new coordinates object will be constructed result of the aggregation of the old one and the new points added. 
 + * \param [out] n2oCells - A new instance of DataArrayInt holding, for each new cell,
 + *          an id of old cell producing it. The caller is to delete this array using
 + *         decrRef() as it is no more needed.
 + * \return MEDCoupling1SGTUMesh * - the mesh containing only INTERP_KERNEL::NORM_TETRA4 cells.
 + *
 + * \warning This method operates on each cells in this independantly ! So it can leads to non conform mesh in returned value ! If you expect to have a conform mesh in output
 + * the policy PLANAR_FACE_6 should be used on a mesh sorted with MEDCoupling1SGTUMesh::sortHexa8EachOther.
 + * 
 + * \throw If \a this is not a 3D mesh (spaceDim==3 and meshDim==3).
 + * \throw If \a this is not fully constituted with linear 3D cells.
 + * \sa MEDCouplingUMesh::simplexize, MEDCoupling1SGTUMesh::sortHexa8EachOther
 + */
 +MEDCoupling1SGTUMesh *MEDCouplingUMesh::tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const
 +{
 +  INTERP_KERNEL::SplittingPolicy pol((INTERP_KERNEL::SplittingPolicy)policy);
 +  checkConnectivityFullyDefined();
 +  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tetrahedrize : only available for mesh with meshdim == 3 and spacedim == 3 !");
 +  int nbOfCells(getNumberOfCells()),nbNodes(getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret0(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_TETRA4));
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfCells,1);
 +  int *retPt(ret->getPointer());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn(DataArrayInt::New()); newConn->alloc(0,1);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addPts(DataArrayDouble::New()); addPts->alloc(0,1);
 +  const int *oldc(_nodal_connec->begin());
 +  const int *oldci(_nodal_connec_index->begin());
 +  const double *coords(_coords->begin());
 +  for(int i=0;i<nbOfCells;i++,oldci++,retPt++)
 +    {
 +      std::vector<int> a; std::vector<double> b;
 +      INTERP_KERNEL::SplitIntoTetras(pol,(INTERP_KERNEL::NormalizedCellType)oldc[oldci[0]],oldc+oldci[0]+1,oldc+oldci[1],coords,a,b);
 +      std::size_t nbOfTet(a.size()/4); *retPt=(int)nbOfTet;
 +      const int *aa(&a[0]);
 +      if(!b.empty())
 +        {
 +          for(std::vector<int>::iterator it=a.begin();it!=a.end();it++)
 +            if(*it<0)
 +              *it=(-(*(it))-1+nbNodes);
 +          addPts->insertAtTheEnd(b.begin(),b.end());
 +          nbNodes+=(int)b.size()/3;
 +        }
 +      for(std::size_t j=0;j<nbOfTet;j++,aa+=4)
 +        newConn->insertAtTheEnd(aa,aa+4);
 +    }
 +  if(!addPts->empty())
 +    {
 +      addPts->rearrange(3);
 +      nbOfAdditionalPoints=addPts->getNumberOfTuples();
 +      addPts=DataArrayDouble::Aggregate(getCoords(),addPts);
 +      ret0->setCoords(addPts);
 +    }
 +  else
 +    {
 +      nbOfAdditionalPoints=0;
 +      ret0->setCoords(getCoords());
 +    }
 +  ret0->setNodalConnectivity(newConn);
 +  //
 +  ret->computeOffsets2();
 +  n2oCells=ret->buildExplicitArrOfSliceOnScaledArr(0,nbOfCells,1);
 +  return ret0.retn();
 +}
 +
 +/*!
 + * It is the linear part of MEDCouplingUMesh::split2DCells. Here no additionnal nodes will be added in \b this. So coordinates pointer remain unchanged (is not even touch). 
 + *
 + * \sa MEDCouplingUMesh::split2DCells
 + */
 +void MEDCouplingUMesh::split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI)
 +{
 +  checkConnectivityFullyDefined();
 +  int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+subNodesInSeg->getNumberOfTuples());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach);
 +  const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin());
 +  int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer());
 +  int prevPosOfCi(ciPtr[0]);
 +  for(int i=0;i<ncells;i++,ciPtr++,descIPtr++)
 +    {
 +      int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(0);
 +      *cPtr++=(int)INTERP_KERNEL::NORM_POLYGON; *cPtr++=oldConn[prevPosOfCi+1];
 +      for(int j=0;j<sz;j++)
 +        {
 +          int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]);
 +          for(int k=0;k<sz2;k++)
 +            *cPtr++=subPtr[offset2+k];
 +          if(j!=sz-1)
 +            *cPtr++=oldConn[prevPosOfCi+j+2];
 +          deltaSz+=sz2;
 +        }
 +      prevPosOfCi=ciPtr[1];
 +      ciPtr[1]=ciPtr[0]+1+sz+deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons)
 +    }
 +  if(c->end()!=cPtr)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsLinear : Some of edges to be split are orphan !");
 +  _nodal_connec->decrRef();
 +  _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_POLYGON);
 +}
 +
 +int InternalAddPoint(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter)
 +{
 +  if(id!=-1)
 +    return id;
 +  else
 +    {
 +      int ret(nodesCnter++);
 +      double newPt[2];
 +      e->getMiddleOfPoints(coo+2*startId,coo+2*endId,newPt);
 +      addCoo.insertAtTheEnd(newPt,newPt+2);
 +      return ret;
 +    }
 +}
 +
 +int InternalAddPointOriented(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter)
 +{
 +  if(id!=-1)
 +    return id;
 +  else
 +    {
 +      int ret(nodesCnter++);
 +      double newPt[2];
 +      e->getMiddleOfPointsOriented(coo+2*startId,coo+2*endId,newPt);
 +      addCoo.insertAtTheEnd(newPt,newPt+2);
 +      return ret;
 +    }
 +}
 +
 +
 +/// @cond INTERNAL
 +
 +void EnterTheResultOf2DCellFirst(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
 +{
 +  int tmp[3];
 +  int trueStart(start>=0?start:nbOfEdges+start);
 +  tmp[0]=linOrArc?(int)INTERP_KERNEL::NORM_QPOLYG:(int)INTERP_KERNEL::NORM_POLYGON; tmp[1]=connBg[trueStart]; tmp[2]=connBg[stp];
 +  newConnOfCell->insertAtTheEnd(tmp,tmp+3);
 +  if(linOrArc)
 +    {
 +      if(stp-start>1)
 +        {
 +          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
 +          InternalAddPointOriented(e,-1,coords,tmp[1],tmp[2],*appendedCoords,tmp2);
 +          middles.push_back(tmp3+offset);
 +        }
 +      else
 +        middles.push_back(connBg[trueStart+nbOfEdges]);
 +    }
 +}
 +
 +void EnterTheResultOf2DCellMiddle(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
 +{
 +  int tmpSrt(newConnOfCell->back()),tmpEnd(connBg[stp]);
 +  newConnOfCell->pushBackSilent(tmpEnd);
 +  if(linOrArc)
 +    {
 +      if(stp-start>1)
 +        {
 +          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
 +          InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2);
 +          middles.push_back(tmp3+offset);
 +        }
 +      else
 +        middles.push_back(connBg[start+nbOfEdges]);
 +    }
 +}
 +
 +void EnterTheResultOf2DCellEnd(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
 +{
 +  // only the quadratic point to deal with:
 +  if(linOrArc)
 +    {
 +      if(stp-start>1)
 +        {
 +          int tmpSrt(connBg[start]),tmpEnd(connBg[stp]);
 +          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
 +          InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2);
 +          middles.push_back(tmp3+offset);
 +        }
 +      else
 +        middles.push_back(connBg[start+nbOfEdges]);
 +    }
 +}
 +
 +/// @endcond
 +
 +/*!
 + * Returns true if a colinearization has been found in the given cell. If false is returned the content pushed in \a newConnOfCell is equal to [ \a connBg , \a connEnd ) .
 + * \a appendedCoords is a DataArrayDouble instance with number of components equal to one (even if the items are pushed by pair).
 + */
 +bool MEDCouplingUMesh::Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords)
 +{
 +  std::size_t sz(std::distance(connBg,connEnd));
 +  if(sz<3)//3 because 2+1(for the cell type) and 2 is the minimal number of edges of 2D cell.
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Colinearize2DCell : the input cell has invalid format !");
 +  sz--;
 +  INTERP_KERNEL::AutoPtr<int> tmpConn(new int[sz]);
 +  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connBg[0]));
 +  unsigned nbs(cm.getNumberOfSons2(connBg+1,sz));
 +  unsigned nbOfHit(0); // number of fusions operated
 +  int posBaseElt(0),posEndElt(0),nbOfTurn(0);
 +  const unsigned int maxNbOfHit = cm.isQuadratic() ? nbs-2 : nbs-3;  // a quad cell is authorized to end up with only two edges, a linear one has to keep 3 at least
 +  INTERP_KERNEL::NormalizedCellType typeOfSon;
 +  std::vector<int> middles;
 +  bool ret(false);
 +  for(;(nbOfTurn+nbOfHit)<nbs;nbOfTurn++)
 +    {
 +      cm.fillSonCellNodalConnectivity2(posBaseElt,connBg+1,sz,tmpConn,typeOfSon);
 +      std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m;
 +      INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
 +      posEndElt = posBaseElt+1;
 +
 +      // Look backward first: are the final edges of the cells colinear with the first ones?
 +      // This initializes posBaseElt.
 +      if(nbOfTurn==0)
 +        {
 +          for(unsigned i=1;i<nbs && nbOfHit<maxNbOfHit;i++) // 2nd condition is to avoid ending with a cell wih one single edge
 +            {
 +              cm.fillSonCellNodalConnectivity2(nbs-i,connBg+1,sz,tmpConn,typeOfSon);
 +              INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
 +              INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand));
 +              bool isColinear=eint->areColinears();
 +              if(isColinear)
 +                {
 +                  nbOfHit++;
 +                  posBaseElt--;
 +                  ret=true;
 +                }
 +              delete eint;
 +              eCand->decrRef();
 +              if(!isColinear)
 +                break;
 +            }
 +        }
 +      // Now move forward:
 +      const unsigned fwdStart = (nbOfTurn == 0 ? 0 : posBaseElt);  // the first element to be inspected going forward
 +      for(unsigned j=fwdStart+1;j<nbs && nbOfHit<maxNbOfHit;j++)  // 2nd condition is to avoid ending with a cell wih one single edge
 +        {
 +          cm.fillSonCellNodalConnectivity2((int)j,connBg+1,sz,tmpConn,typeOfSon); // get edge #j's connectivity
 +          INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
 +          INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand));
 +          bool isColinear(eint->areColinears());
 +          if(isColinear)
 +            {
 +              nbOfHit++;
 +              posEndElt++;
 +              ret=true;
 +            }
 +          delete eint;
 +          eCand->decrRef();
 +          if(!isColinear)
 +              break;
 +        }
 +      //push [posBaseElt,posEndElt) in newConnOfCell using e
 +      // The if clauses below are (volontary) not mutually exclusive: on a quad cell with 2 edges, the end of the connectivity is also its begining!
 +      if(nbOfTurn==0)
 +        // at the begining of the connectivity (insert type)
 +        EnterTheResultOf2DCellFirst(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
 +      else if((nbOfHit+nbOfTurn) != (nbs-1))
 +        // in the middle
 +        EnterTheResultOf2DCellMiddle(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
 +      if ((nbOfHit+nbOfTurn) == (nbs-1))
 +        // at the end (only quad points to deal with)
 +        EnterTheResultOf2DCellEnd(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
 +      posBaseElt=posEndElt;
 +      e->decrRef();
 +    }
 +  if(!middles.empty())
 +    newConnOfCell->insertAtTheEnd(middles.begin(),middles.end());
 +  return ret;
 +}
 +
 +/*!
 + * It is the quadratic part of MEDCouplingUMesh::split2DCells. Here some additionnal nodes can be added at the end of coordinates array object.
 + *
 + * \return  int - the number of new nodes created.
 + * \sa MEDCouplingUMesh::split2DCells
 + */
 +int MEDCouplingUMesh::split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI)
 +{
 +  checkCoherency();
 +  int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes());
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1);
 +  const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin());
 +  const int *midPtr(mid->begin()),*midIPtr(midI->begin());
 +  const double *oldCoordsPtr(getCoords()->begin());
 +  int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer());
 +  int prevPosOfCi(ciPtr[0]);
 +  for(int i=0;i<ncells;i++,ciPtr++,descIPtr++)
 +    {
 +      int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(sz);
 +      for(int j=0;j<sz;j++)
 +        { int sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]); deltaSz+=sz2; }
 +      *cPtr++=(int)INTERP_KERNEL::NORM_QPOLYG; cPtr[0]=oldConn[prevPosOfCi+1];
 +      for(int j=0;j<sz;j++)//loop over subedges of oldConn
 +        {
 +          int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]),offset3(midIPtr[descPtr[offset+j]]);
 +          if(sz2==0)
 +            {
 +              if(j<sz-1)
 +                cPtr[1]=oldConn[prevPosOfCi+2+j];
 +              cPtr[deltaSz]=oldConn[prevPosOfCi+1+j+sz]; cPtr++;
 +              continue;
 +            }
 +          std::vector<INTERP_KERNEL::Node *> ns(3);
 +          ns[0]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]+1]);
 +          ns[1]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]+1]);
 +          ns[2]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]+1]);
 +          MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> e(INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(ns));
 +          for(int k=0;k<sz2;k++)//loop over subsplit of current subedge
 +            {
 +              cPtr[1]=subPtr[offset2+k];
 +              cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+k],oldCoordsPtr,cPtr[0],cPtr[1],*addCoo,nodesCnt); cPtr++;
 +            }
 +          int tmpEnd(oldConn[prevPosOfCi+1+(j+1)%sz]);
 +          if(j!=sz-1)
 +            { cPtr[1]=tmpEnd; }
 +          cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+sz2],oldCoordsPtr,cPtr[0],tmpEnd,*addCoo,nodesCnt); cPtr++;
 +        }
 +      prevPosOfCi=ciPtr[1]; cPtr+=deltaSz;
 +      ciPtr[1]=ciPtr[0]+1+2*deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons)
 +    }
 +  if(c->end()!=cPtr)
 +    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsQuadratic : Some of edges to be split are orphan !");
 +  _nodal_connec->decrRef();
 +  _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_QPOLYG);
 +  addCoo->rearrange(2);
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate
 +  setCoords(coo);
 +  return addCoo->getNumberOfTuples();
 +}
 +
 +void MEDCouplingUMesh::ComputeAllTypesInternal(std::set<INTERP_KERNEL::NormalizedCellType>& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex)
 +{
 +  if(nodalConnec && nodalConnecIndex)
 +    {
 +      types.clear();
 +      const int *conn(nodalConnec->getConstPointer()),*connIndex(nodalConnecIndex->getConstPointer());
 +      int nbOfElem(nodalConnecIndex->getNbOfElems()-1);
 +      if(nbOfElem>0)
 +        for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++)
 +          types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
 +    }
 +}
 +
 +MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),
 +    _own_cell(true),_cell_id(-1),_nb_cell(0)
 +{
 +  if(mesh)
 +    {
 +      mesh->incrRef();
 +      _nb_cell=mesh->getNumberOfCells();
 +    }
 +}
 +
 +MEDCouplingUMeshCellIterator::~MEDCouplingUMeshCellIterator()
 +{
 +  if(_mesh)
 +    _mesh->decrRef();
 +  if(_own_cell)
 +    delete _cell;
 +}
 +
 +MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_cell(itc),
 +    _own_cell(false),_cell_id(bg-1),
 +    _nb_cell(end)
 +{
 +  if(mesh)
 +    mesh->incrRef();
 +}
 +
 +MEDCouplingUMeshCell *MEDCouplingUMeshCellIterator::nextt()
 +{
 +  _cell_id++;
 +  if(_cell_id<_nb_cell)
 +    {
 +      _cell->next();
 +      return _cell;
 +    }
 +  else
 +    return 0;
 +}
 +
 +MEDCouplingUMeshCellByTypeEntry::MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh):_mesh(mesh)
 +{
 +  if(_mesh)
 +    _mesh->incrRef();
 +}
 +
 +MEDCouplingUMeshCellByTypeIterator *MEDCouplingUMeshCellByTypeEntry::iterator()
 +{
 +  return new MEDCouplingUMeshCellByTypeIterator(_mesh);
 +}
 +
 +MEDCouplingUMeshCellByTypeEntry::~MEDCouplingUMeshCellByTypeEntry()
 +{
 +  if(_mesh)
 +    _mesh->decrRef();
 +}
 +
 +MEDCouplingUMeshCellEntry::MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh,  INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_type(type),
 +    _itc(itc),
 +    _bg(bg),_end(end)
 +{
 +  if(_mesh)
 +    _mesh->incrRef();
 +}
 +
 +MEDCouplingUMeshCellEntry::~MEDCouplingUMeshCellEntry()
 +{
 +  if(_mesh)
 +    _mesh->decrRef();
 +}
 +
 +INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCellEntry::getType() const
 +{
 +  return _type;
 +}
 +
 +int MEDCouplingUMeshCellEntry::getNumberOfElems() const
 +{
 +  return _end-_bg;
 +}
 +
 +MEDCouplingUMeshCellIterator *MEDCouplingUMeshCellEntry::iterator()
 +{
 +  return new MEDCouplingUMeshCellIterator(_mesh,_itc,_bg,_end);
 +}
 +
 +MEDCouplingUMeshCellByTypeIterator::MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),_cell_id(0),_nb_cell(0)
 +{
 +  if(mesh)
 +    {
 +      mesh->incrRef();
 +      _nb_cell=mesh->getNumberOfCells();
 +    }
 +}
 +
 +MEDCouplingUMeshCellByTypeIterator::~MEDCouplingUMeshCellByTypeIterator()
 +{
 +  if(_mesh)
 +    _mesh->decrRef();
 +  delete _cell;
 +}
 +
 +MEDCouplingUMeshCellEntry *MEDCouplingUMeshCellByTypeIterator::nextt()
 +{
 +  const int *c=_mesh->getNodalConnectivity()->getConstPointer();
 +  const int *ci=_mesh->getNodalConnectivityIndex()->getConstPointer();
 +  if(_cell_id<_nb_cell)
 +    {
 +      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[_cell_id]];
 +      int nbOfElems=(int)std::distance(ci+_cell_id,std::find_if(ci+_cell_id,ci+_nb_cell,ParaMEDMEMImpl::ConnReader(c,type)));
 +      int startId=_cell_id;
 +      _cell_id+=nbOfElems;
 +      return new MEDCouplingUMeshCellEntry(_mesh,type,_cell,startId,_cell_id);
 +    }
 +  else
 +    return 0;
 +}
 +
 +MEDCouplingUMeshCell::MEDCouplingUMeshCell(MEDCouplingUMesh *mesh):_conn(0),_conn_indx(0),_conn_lgth(NOTICABLE_FIRST_VAL)
 +{
 +  if(mesh)
 +    {
 +      _conn=mesh->getNodalConnectivity()->getPointer();
 +      _conn_indx=mesh->getNodalConnectivityIndex()->getPointer();
 +    }
 +}
 +
 +void MEDCouplingUMeshCell::next()
 +{
 +  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
 +    {
 +      _conn+=_conn_lgth;
 +      _conn_indx++;
 +    }
 +  _conn_lgth=_conn_indx[1]-_conn_indx[0];
 +}
 +
 +std::string MEDCouplingUMeshCell::repr() const
 +{
 +  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
 +    {
 +      std::ostringstream oss; oss << "Cell Type " << INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)_conn[0]).getRepr();
 +      oss << " : ";
 +      std::copy(_conn+1,_conn+_conn_lgth,std::ostream_iterator<int>(oss," "));
 +      return oss.str();
 +    }
 +  else
 +    return std::string("MEDCouplingUMeshCell::repr : Invalid pos");
 +}
 +
 +INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCell::getType() const
 +{
 +  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
 +    return (INTERP_KERNEL::NormalizedCellType)_conn[0];
 +  else
 +    return INTERP_KERNEL::NORM_ERROR;
 +}
 +
 +const int *MEDCouplingUMeshCell::getAllConn(int& lgth) const
 +{
 +  lgth=_conn_lgth;
 +  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
 +    return _conn;
 +  else
 +    return 0;
 +}
index 3ebd2170d8a645ccb6947be7cbca8e43a7124e49,0000000000000000000000000000000000000000..86ee5d7671f94976aea21a7284c91d03f5b5f7f0
mode 100644,000000..100644
--- /dev/null
@@@ -1,2343 -1,0 +1,2345 @@@
 +#  -*- coding: iso-8859-1 -*-
 +# Copyright (C) 2007-2015  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, or (at your option) any later version.
 +#
 +# 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 MEDCoupling import *
 +import unittest
 +from math import pi, sqrt
 +
 +class MEDCouplingBasicsTest(unittest.TestCase):
 +
 +    def testExample_MEDCouplingFieldDouble_WriteVTK(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1]
 +        # mesh
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr) # mesh becomes a 2D one
 +
 +        # 3 fields (lying on the same mesh!)
 +        field1 = mesh.getMeasureField( True )
 +        field2 = mesh.buildOrthogonalField()
 +        field3 = mesh.fillFromAnalytic( ON_CELLS, 2, "IVec * x + JVec * y" )
 +        field2.setName( "Normal" ) # name is necessary!
 +        field3.setName( "Barycenter" ) # name is necessary!
 +
 +        # WriteVTK
 +        fileName = "testExample_MEDCouplingFieldDouble_WriteVTK"
 +        fs = [ field1, field2, field3 ] # field series
 +        writtenFileName=MEDCouplingFieldDouble.WriteVTK( fileName, fs )
 +        print "The file name with correct extension is : %s"%(writtenFileName)
 +        #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1]
 +        import os
 +        os.remove( writtenFileName )
 +
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_MaxFields(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1]
 +        vals1   = [0.,2., 4.,6.] # for field 1
 +        vals2   = [2.,0., 6.,4.] # for field 2
 +        valsMax = [2.,2., 6.,6.] # expected max field
 +        valsMin = [0.,0., 4.,4.] # expected min field
 +
 +        # field 1
 +        valsArr1=DataArrayDouble(vals1,2,2) # 2 tuples per 2 components
 +        field1 = MEDCouplingFieldDouble( ON_NODES )
 +        field1.setArray( valsArr1 )
 +
 +        # field 2
 +        valsArr2=DataArrayDouble(vals2,2,2) # 2 tuples per 2 components
 +        field2 = MEDCouplingFieldDouble( ON_NODES )
 +        field2.setArray( valsArr2 )
 +
 +        # max field 
 +        fieldMax = MEDCouplingFieldDouble.MaxFields( field1, field2 )
 +        self.assertTrue( fieldMax.getArray().getValues() == valsMax )
 +
 +        # min field 
 +        fieldMin = MEDCouplingFieldDouble.MinFields( field1, field2 )
 +        self.assertTrue( fieldMin.getArray().getValues() == valsMin )
 +        #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1]
 +
 +    def testExample_MEDCouplingFieldDouble_MergeFields(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1]
 +        # mesh 1
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh1=MEDCouplingCMesh()
 +        mesh1.setCoords(coordsArr)
 +        # field 1
 +        field1 = mesh1.fillFromAnalytic( ON_CELLS, 1, "x")
 +
 +        # mesh 2 and field 2
 +        field2 = field1.cloneWithMesh( True )
 +        vec = [5.]
 +        field2.getMesh().translate(vec) # translate mesh2
 +        field2.applyFunc("x + 5") # "translate" field2
 +
 +        # concatenate field1 and field2
 +        field3 = MEDCouplingFieldDouble.MergeFields( field1, field2 )
 +        field4 = MEDCouplingFieldDouble.MergeFields( [ field1, field2] )
 +        #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_substractInPlaceDM(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1]
 +        coords1=[0.,1.,2.,3.]
 +        coords2=[2.,1.,0.,3.] #0 <==> #2
 +        # mesh 1
 +        mesh1=MEDCouplingUMesh()
 +        coordsArr=DataArrayDouble(coords1, 4, 1)
 +        mesh1.setCoords(coordsArr)
 +        mesh1.setMeshDimension(0)
 +        mesh1.allocateCells(0)
 +        mesh1.finishInsertingCells()
 +        # mesh 2
 +        mesh2=mesh1.deepCpy()
 +        mesh2.getCoords().setValues(coords2, 4, 1)
 +        #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2]
 +        field1 = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field1 values == coords1
 +        field2 = mesh2.fillFromAnalytic(ON_NODES,1,"x") # field2 values == coords2
 +        levOfCheck = 10 # nodes can be permuted
 +        field1.substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap
 +        #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2]
 +        #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3]
 +        field2.applyFunc( 1, 0.0 ) # all field2 values == 0.0
 +        self.assertTrue( field1.isEqual( field2, 1e-13, 1e-13 )) # field1 == field2 == 0.0
 +        #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_changeUnderlyingMesh(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1]
 +        coords1=[0.,1.,2.,3.]
 +        coords2=[2.,1.,0.,3.] #0 <==> #2
 +        # mesh 1
 +        mesh1=MEDCouplingUMesh()
 +        coordsArr=DataArrayDouble(coords1, 4, 1)
 +        mesh1.setCoords(coordsArr)
 +        mesh1.setMeshDimension(0)
 +        mesh1.allocateCells(0)
 +        mesh1.finishInsertingCells()
 +        # mesh 2
 +        mesh2=mesh1.deepCpy()
 +        mesh2.getCoords().setValues(coords2, 4, 1)
 +        #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2]
 +        field = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field values == coords1
 +        levOfCheck = 10 # nodes can be permuted
 +        field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap
 +        self.assertTrue( field.getArray().getValues() == coords2 )
 +        #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1]
 +        v = [1.,2., 3.,4.]
 +        array = DataArrayDouble( v, 2, 2 ) # 2 tuples per 2 components
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setArray( array )
 +        func = "IVec * v + JVec * w*w + 10"
 +        field.applyFunc( 2, func )
 +        self.assertTrue( field.getNumberOfComponents() == 2 ) # 2 components remains
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2]
 +        v2 = field.getArray().getValues()
 +        self.assertAlmostEqual( v2[0], 10 + v[0], 13 )      # "10 + IVec * v"
 +        self.assertAlmostEqual( v2[1], 10 + v[1]*v[1], 13 ) # "10 + JVec * v*v"
 +        self.assertAlmostEqual( v2[2], 10 + v[2], 13 )      # "10 + IVec * v"
 +        self.assertAlmostEqual( v2[3], 10 + v[3]*v[3], 13 ) # "10 + JVec * v*v"
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_applyFunc3(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1]
 +        # create a 2D vector field
 +        values = [1.,1., 2.,1.]
 +        array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setArray( array )
 +        # transform the field to a 3D vector field
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        varNames=["a","b"] # names used to refer to X and Y components
 +        field.applyFunc3( 3, varNames, func ) # require 3 components 
 +        self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2]
 +        vec1 = field.getArray().getTuple(1) # vector #1
 +        a,b = values[2], values[3] # initial components of the vector #1
 +        self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_applyFunc2(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1]
 +        # create a 2D vector field
 +        values = [1.,1., 2.,1.]
 +        array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components
 +        array.setInfoOnComponent(0,"a") # name used to refer to X component within a function
 +        array.setInfoOnComponent(1,"b") # name used to refer to Y component within a function
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setArray( array )
 +        # transform the field to a 3D vector field
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        field.applyFunc2( 3, func ) # require 3 components 
 +        self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2]
 +        vec1 = field.getArray().getTuple(1) # vector #1
 +        a,b = values[2], values[3] # initial components of the vector #1
 +        self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_applyFunc(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1]
 +        # create a 2D vector field
 +        values = [1.,1., 2.,1.]
 +        array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setArray( array )
 +        # transform the field to a 3D vector field
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        field.applyFunc( 3, func ) # require 3 components 
 +        self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2]
 +        vec1 = field.getArray().getTuple(1) # vector #1
 +        a,b = values[2], values[3] # initial components of the vector #1
 +        self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_applyFunc_val(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setMesh( mesh )
 +        field.fillFromAnalytic(2,"IVec * x + JVec * y") # 2 components
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2]
 +        newValue = 7.
 +        field.applyFunc( 3, newValue ) # 3 components are required
 +        self.assertTrue( field.getIJ(1,0) == newValue ) # a value is as expected
 +        self.assertTrue( field.getNumberOfComponents() == 3 )
 +        self.assertTrue( field.getNumberOfTuples() == mesh.getNumberOfCells() )
 +        #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_fillFromAnalytic3(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1]
 +        coords = [0.,2.,4.,6.] #  6. is not used
 +        x=DataArrayDouble(coords[:3],3,1)
 +        y=DataArrayDouble(coords[:2],2,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(x,y)
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2]
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setMesh( mesh )
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        varNames=["a","b"] # names used to refer to X and Y coord components
 +        field.fillFromAnalytic3(3,varNames,func)
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2]
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3]
 +        vals1 = field.getArray().getTuple(1) # values of the cell #1
 +        assert len( vals1 ) == 3 # 3 components in the field
 +        #
 +        bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells
 +        bc1 = bc.getTuple(1) # coordinates of the second point
 +        #
 +        dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
 +        self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vals1[2], 10 + dist  , 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_fillFromAnalytic2(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1]
 +        coords = [0.,2.,4.]
 +        x=DataArrayDouble(coords[:3],3,1)
 +        y=DataArrayDouble(coords[:2],2,1)
 +        x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function
 +        y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(x,y)
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2]
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setMesh( mesh )
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        field.fillFromAnalytic2(3,func)
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2]
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3]
 +        vals1 = field.getArray().getTuple(1) # values of the cell #1
 +        assert len( vals1 ) == 3 # 3 components in the field
 +        #
 +        bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells
 +        bc1 = bc.getTuple(1) # coordinates of the second point
 +        #
 +        dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
 +        self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vals1[2], 10 + dist  , 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_fillFromAnalytic(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1]
 +        coords = [0.,2.,4.]
 +        x=DataArrayDouble(coords[:3],3,1)
 +        y=DataArrayDouble(coords[:2],2,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(x,y)
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2]
 +        field = MEDCouplingFieldDouble( ON_CELLS )
 +        field.setMesh( mesh )
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        field.fillFromAnalytic(3,func)
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2]
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3]
 +        vals1 = field.getArray().getTuple(1) # values of the cell #1
 +        assert len( vals1 ) == 3 # 3 components in the field
 +        #
 +        bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells
 +        bc1 = bc.getTuple(1) # coordinates of the second point
 +        #
 +        dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
 +        self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vals1[2], 10 + dist  , 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_getValueOn_time(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2]
 +        field = MEDCouplingFieldDouble( ON_CELLS, LINEAR_TIME )
 +        field.setMesh( mesh )
 +        field.fillFromAnalytic(1,"10") # all values == 10.
 +        field.setEndArray( field.getArray() + field.getArray() ) # all values == 20.
 +        time1, time2 = 1.1, 22.
 +        field.setStartTime( time1, 0, 0 )
 +        field.setEndTime  ( time2, 0, 0 )
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2]
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3]
 +        pos = [ 1., 1. ] # we are in 2D space
 +        value = field.getValueOn( pos, 0.5*( time1 + time2 ))
 +        self.assertTrue( value[0] == 0.5*( 10. + 20.))
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_getValueOnMulti(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y")
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2]
 +        bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters
 +        valArray = field.getValueOnMulti( bc )
 +        self.assertTrue( valArray.isEqual( field.getArray(), 1e-13 ))
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_getValueOn(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y")
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2]
 +        bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters
 +        vals = [] # array to collect values returned by getValueOn()
 +        for i,tupl in enumerate( bc ):
 +            vals.extend( field.getValueOn( tupl ) )
 +        self.assertTrue( vals == field.getArray().getValues() )
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_getValueOnPos(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y")
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2]
 +        val11 = field.getValueOnPos( 1,1,-1)
 +        bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters
 +        self.assertTrue( val11[0] == bc[3,0] + bc[3,1] )
 +        #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_renumberNodes(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        mesh=mesh.buildUnstructured()
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2]
 +        field = mesh.fillFromAnalytic(ON_NODES,2,"IVec*x+JVec*y")
 +        values = field.getArray()
 +        nodeCoords = mesh.getCoords()
 +        self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 ))
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2]
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3]
 +        renumber = [8, 7, 6, 5, 4, 3, 2, 1, 0]
 +        field.renumberNodes(renumber,False)
 +        mesh2 = field.getMesh() # field now refers to another mesh
 +        values = field.getArray()
 +        nodeCoords = mesh2.getCoords()
 +        self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 ))
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3]
 +        return
 +
 +
 +    def testExample_MEDCouplingFieldDouble_renumberCells(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        mesh=mesh.buildUnstructured()
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2]
 +        field = mesh.fillFromAnalytic(ON_CELLS,2,"IVec*x+JVec*y")
 +        values = field.getArray()
 +        bc = mesh.getBarycenterAndOwner()
 +        self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 ))
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2]
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3]
 +        renumber = [ 3, 2, 1, 0 ]
 +        field.renumberCells(renumber,False)
 +        mesh2 = field.getMesh() # field now refers to another mesh
 +        values = field.getArray()
 +        bc = mesh2.getBarycenterAndOwner()
 +        self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 ))
 +        #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3]
 +        return
 +
 +    def testExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis(self):
 +        #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1]
 +        coords = [0.,2.,4.]
 +        coordsArr=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(coordsArr,coordsArr)
 +        field1 = mesh.fillFromAnalytic(ON_NODES,1,"x+y")
 +        self.assertTrue( field1.getTimeDiscretization() == ONE_TIME )
 +        #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1]
 +        #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2]
 +        field2 = field1.buildNewTimeReprFromThis(NO_TIME,False)
 +        self.assertTrue( field2.getTimeDiscretization() == NO_TIME )
 +        #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2]
 +        return
 +
 +    def testExample_MEDCouplingMesh_fillFromAnalytic3(self):
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1]
 +        coords = [0.,2.,4.,6.] #  6. is not used
 +        x=DataArrayDouble(coords[:3],3,1)
 +        y=DataArrayDouble(coords[:2],2,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(x,y)
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1]
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2]
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        varNames=["a","b"] # names used to refer to X and Y coord components
 +        field=mesh.fillFromAnalytic3(ON_CELLS,3,varNames,func)
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2]
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3]
 +        vals1 = field.getArray().getTuple(1) # values of the cell #1
 +        assert len( vals1 ) == 3 # 3 components in the field
 +        #
 +        bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells
 +        bc1 = bc.getTuple(1) # coordinates of the second point
 +        #
 +        dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
 +        self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vals1[2], 10 + dist  , 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3]
 +        return
 +
 +    def testExample_MEDCouplingMesh_fillFromAnalytic2(self):
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1]
 +        coords = [0.,2.,4.,6.] #  6. is not used
 +        x=DataArrayDouble(coords[:3],3,1)
 +        y=DataArrayDouble(coords[:2],2,1)
 +        x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function
 +        y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(x,y)
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1]
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2]
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        field=mesh.fillFromAnalytic2(ON_CELLS,3,func)
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2]
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3]
 +        vals1 = field.getArray().getTuple(1) # values of the cell #1
 +        assert len( vals1 ) == 3 # 3 components in the field
 +        #
 +        bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells
 +        bc1 = bc.getTuple(1) # coordinates of the second point
 +        #
 +        dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
 +        self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vals1[2], 10 + dist  , 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3]
 +        return
 +
 +    def testExample_MEDCouplingMesh_fillFromAnalytic(self):
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1]
 +        coords = [0.,2.,4.,6.] #  6. is not used
 +        x=DataArrayDouble(coords[:3],3,1)
 +        y=DataArrayDouble(coords[:2],2,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoords(x,y)
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1]
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2]
 +        func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
 +        field=mesh.fillFromAnalytic(ON_CELLS,3,func)
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2]
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3]
 +        vals1 = field.getArray().getTuple(1) # values of the cell #1
 +        assert len( vals1 ) == 3 # 3 components in the field
 +        #
 +        bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells
 +        bc1 = bc.getTuple(1) # coordinates of the second point
 +        #
 +        dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
 +        self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
 +        self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
 +        self.assertAlmostEqual( vals1[2], 10 + dist  , 13 ) # "10 + KVec * sqrt( a*a + b*b )"
 +        #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3]
 +        return
 +
 +    def testExample_MEDCouplingCMesh_getCoordsAt(self):
 +        #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1]
 +        coords = [1.,2.,4.]
 +        x=DataArrayDouble(coords,3,1)
 +        mesh=MEDCouplingCMesh()
 +        mesh.setCoordsAt(0,x)
 +        x2=mesh.getCoordsAt(0)
 +        assert coords == x2.getValues()
 +        #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_areCellsIncludedIn(self):
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1]
 +        mesh1=MEDCouplingUMesh()
 +        mesh1.setMeshDimension(2)
 +        mesh1.allocateCells(5)
 +        conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh1.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh1.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh1.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh1.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh1.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh1.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh1.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1]
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2]
 +        cells2 = [ 4,2,0 ]
 +        mesh2 = mesh1.buildPartOfMySelf(cells2, True ) # even cells selected
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2]
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3]
 +        compType = 0 # the strongest policy
 +        isOk, corr2to1 = mesh1.areCellsIncludedIn( mesh2, compType )
 +        assert isOk # a larger mesh1 includes a smaller mesh2
 +        assert corr2to1.getValues() == cells2
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3]
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4]
 +        isOk, corr1to2 = mesh2.areCellsIncludedIn( mesh1, compType )
 +        assert not isOk # the smaller mesh2 does NOT include the larger mesh1
 +        assert corr1to2.getValues() == [2, 3, 1, 4, 0]
 +        #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4]
 +
 +    def testExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells(self):
 +        #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1]
 +        # 2D coordinates of 5 base nodes
 +        coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2]
 +        coordsArr=DataArrayDouble(coords,5,2)
 +        # coordinates of 5 top nodes
 +        coordsArr2 = coordsArr.deepCpy()
 +        # 3D coordinates of base + top nodes
 +        coordsArr  = coordsArr.changeNbOfComponents( 3, 0 )
 +        coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 )
 +        coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2])
 +        # mesh
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        mesh.setMeshDimension(3)
 +        mesh.allocateCells(2)
 +        # connectivity of reversed HEXA8 and PENTA6
 +        conn=[0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9]
 +        mesh.insertNextCell(NORM_HEXA8, 8,conn[0:0+8])
 +        mesh.insertNextCell(NORM_PENTA6,6,conn[8:8+6])
 +        mesh.finishInsertingCells()
 +        #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1]
 +        #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2]
 +        fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells()
 +        assert len( fixedCells ) == 2 # 2 cells fixed
 +        fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells()
 +        assert len( fixedCells ) == 0 # no bad cells
 +        #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented(self):
 +        #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1]
 +        # 2D coordinates of 5 base nodes
 +        coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2]
 +        coordsArr=DataArrayDouble(coords,5,2)
 +        # coordinates of 5 top nodes
 +        coordsArr2 = coordsArr.deepCpy()
 +        # 3D coordinates of base + top nodes
 +        coordsArr  = coordsArr.changeNbOfComponents( 3, 0 )
 +        coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 )
 +        coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2])
 +        # mesh
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        mesh.setMeshDimension(3)
 +        mesh.allocateCells(2)
 +        # connectivity of a HEXA8 + a reversed PENTA6
 +        conn=[0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9]
 +        mesh.insertNextCell(NORM_POLYHED, 8,conn[0:0+8]) # "extruded" polyhedron
 +        mesh.insertNextCell(NORM_POLYHED,6,conn[8:8+6])
 +        mesh.finishInsertingCells()
 +        # fix connectivity of NORM_POLYHED's
 +        mesh.convertExtrudedPolyhedra()
 +        #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1]
 +        #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2]
 +        badCells = mesh.arePolyhedronsNotCorrectlyOriented()
 +        assert len( badCells ) == 1 # one polyhedron is KO
 +        # fix invalid rolyherdons
 +        mesh.orientCorrectlyPolyhedrons()
 +        # re-check the orientation
 +        badCells = mesh.arePolyhedronsNotCorrectlyOriented()
 +        assert len( badCells ) == 0 # connectivity is OK
 +        #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented(self):
 +        #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        mesh.changeSpaceDimension(3)
 +        #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1]
 +        #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2]
 +        vec = [0.,0.,-1.]
 +        badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False )
 +        assert len( badCellIds ) == 1 # one cell is reversed
 +        # fix orientation
 +        mesh.orientCorrectly2DCells( vec, False )
 +        # re-check orientation
 +        badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False )
 +        assert len( badCellIds ) == 0 # the orientation is OK
 +        #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_getCellsContainingPoints(self):
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1]
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2]
 +        pos = [ 10., 10,              # point out of the mesh
 +                0.3, 0.3,             # point located somewhere inside the mesh
 +                coords[2], coords[3]] # point at the node #1
 +        eps = 1e-4 # ball radius
 +        cells,cellsIndex=mesh.getCellsContainingPoints( pos, 3, eps )
 +        assert cells.getValues() == [4, 0, 1]
 +        assert cellsIndex.getValues() == [0, 0, 1, 3]
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2]
 +        return
 +
 +
 +    def testExample_MEDCouplingUMesh_getCellsContainingPoint(self):
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) 
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1]
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2]
 +        pos4 = coords[ 4*2 : ] # coordinates of the node #4
 +        eps = 1e-4 # ball radius
 +        pos = [ pos4[0]+eps, pos4[1]-eps ] # ball center
 +        cellIds=mesh.getCellsContainingPoint( pos, eps )
 +        assert len( cellIds ) == mesh.getNumberOfCells()
 +        #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2]
 +        return
 +
 +
 +    def testExample_MEDCouplingUMesh_buildPartOrthogonalField(self):
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1]
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2]
 +        part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted
 +        vecField=mesh.buildPartOrthogonalField( part )
 +        vecArr = vecField.getArray()
 +        assert len( vecArr ) == len( part )
 +        assert vecArr.getNumberOfComponents() == 3
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_getPartMeasureField(self):
 +        #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1]
 +        #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2]
 +        isAbs = True
 +        part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted
 +        areaArr=mesh.getPartMeasureField( isAbs, part )
 +        assert areaArr[0] > 0 # orientation ignored
 +        areaArr=mesh.getPartMeasureField( not isAbs, part )
 +        assert areaArr[0] < 0 # orientation considered
 +        assert len( areaArr ) == len( part )
 +        #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2]
 +        #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3]
 +        part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted
 +        baryCenters = mesh.getPartBarycenterAndOwner( part )
 +        assert len( baryCenters ) == len( part )
 +        assert baryCenters.getNumberOfComponents() == mesh.getSpaceDimension()
 +        #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_getCellsInBoundingBox(self):
 +        #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        coords=[0.,0., 0.,1., 1.,1]
 +        coordsArr=DataArrayDouble(coords,3,2)
 +        mesh.setCoords(coordsArr)
 +        mesh.allocateCells(1)
 +        conn=[0,1,2]
 +        mesh.insertNextCell(NORM_TRI3,3,conn)
 +        mesh.finishInsertingCells()
 +        #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1]
 +        #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2]
 +        bbox = [1., 1., 1.001,1.001] # xMin, xMax, yMin, yMax
 +        cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.0 )
 +        assert cellsInBox.getValues() == []
 +        cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.1 )
 +        assert cellsInBox.getValues() == [0]
 +        #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2]
 +
 +
 +    def testExample_MEDCouplingUMesh_renumberNodesInConn(self):
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(1)
 +        conn=[4,3,2,1]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
 +        mesh.finishInsertingCells()
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1]
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2]
 +        old2newIds = [-1,3,2,1,0]
 +        mesh.renumberNodesInConn( old2newIds )
 +        nodes0 = mesh.getNodeIdsOfCell( 0 )
 +        assert nodes0 == [0,1,2,3]
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2]
 +        return
 +
 +
 +    def testExample_MEDCouplingUMesh_renumberNodes(self):
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodes_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3]
 +        coordsArr=DataArrayDouble(coords,4,2)
 +        mesh.setCoords(coordsArr)
 +        mesh.allocateCells(0)
 +        mesh.finishInsertingCells()
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodes_1]
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodes_2]
 +        mesh.renumberNodes([ 2,1,0,-1 ], 3)
 +        coordsArr = mesh.getCoords() # get a shorten array
 +        assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,-0.3]
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodes_2]
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodes_3]
 +        coordsArr.setValues(coords,4,2) # restore old nodes
 +        mesh.renumberNodes2([ 2,1,0,2 ], 3)
 +        coordsArr = mesh.getCoords() # get a shorten array
 +        assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,0.0]
 +        #! [PySnippet_MEDCouplingUMesh_renumberNodes_3]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_findBoundaryNodes(self):
 +        #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) 
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1]
 +        #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2]
 +        nodeIdsArr=mesh.findBoundaryNodes()
 +        assert nodeIdsArr.getNumberOfTuples() == mesh.getNumberOfNodes() - 1 
 +        #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_buildBoundaryMesh(self):
 +        #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) 
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1]
 +        #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2]
 +        mesh1=mesh.buildBoundaryMesh(True)
 +        mesh2=mesh.buildBoundaryMesh(False)
 +        assert coordsArr.isEqual( mesh1.getCoords(), 1e-13 )  # same nodes
 +        assert not coordsArr.isEqual( mesh2.getCoords(), 1e-13 ) # different nodes
 +        #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_buildFacePartOfMySelfNode(self):
 +        #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1]
 +        #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2]
 +        nodeIds = mesh.getNodeIdsOfCell( 0 )
 +        allNodes = True
 +        mesh1 = mesh.buildFacePartOfMySelfNode( nodeIds, allNodes )
 +        assert mesh1.getNumberOfCells() == 4 # 4 segments bounding QUAD4 #0 only
 +        mesh2 = mesh.buildFacePartOfMySelfNode( nodeIds, not allNodes )
 +        assert mesh2.getNumberOfCells() >  4 # more segments added
 +        #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2]
 +        return
 +
 +
 +    def testExample_MEDCouplingUMesh_buildPartOfMySelfNode(self):
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1]
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2]
 +        nodeIds = mesh.getNodeIdsOfCell( 0 )
 +        allNodes = True
 +        mesh1 = mesh.buildPartOfMySelfNode( nodeIds, allNodes )
 +        mesh2 = mesh.buildPartOfMySelfNode( nodeIds, not allNodes )
 +        assert mesh1.getNumberOfCells() == 1 # cell #0 is found only
 +        assert mesh2.getNumberOfCells() == mesh.getNumberOfCells() # all cells are found
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2]
 +        return
 +
 +
 +    def testExample_MEDCouplingUMesh_getCellIdsLyingOnNodes(self):
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1]
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2]
 +        nodeIds = mesh.getNodeIdsOfCell( 0 )
 +        allNodes = True
 +        cellIdsArr1 = mesh.getCellIdsLyingOnNodes( nodeIds, allNodes )
 +        cellIdsArr2 = mesh.getCellIdsLyingOnNodes( nodeIds, not allNodes )
 +        assert cellIdsArr1.getNumberOfTuples() == 1 # cell #0 is found only
 +        assert cellIdsArr2.getNumberOfTuples() == mesh.getNumberOfCells() # all cells are found
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2]
 +        return
 +
 +
 +    def testExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds(self):
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) 
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1]
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2]
 +        cellIds = [1,2]
 +        nodeIds =  mesh.getNodeIdsOfCell( cellIds[0] )
 +        nodeIds += mesh.getNodeIdsOfCell( cellIds[1] )
 +        cellIdsArr = mesh.getCellIdsFullyIncludedInNodeIds( nodeIds )
 +        assert cellIdsArr.getValues() == cellIds
 +        #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2]
 +        return
 +
 +
 +    def testExample_MEDCouplingUMesh_buildPartOfMySelf(self):
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1]
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2]
 +        cellIds=[1,2]
 +        mesh2=mesh.buildPartOfMySelf(cellIds, True)
 +        mesh3=mesh.buildPartOfMySelf(cellIds, False)
 +        coordsArr2 = mesh2.getCoords()
 +        assert coordsArr.isEqual( coordsArr2, 1e-13 )  # same nodes
 +        coordsArr3 = mesh3.getCoords()
 +        assert not coordsArr.isEqual( coordsArr3, 1e-13 ) # different nodes
 +        assert mesh2.getNodeIdsOfCell(0) == mesh.getNodeIdsOfCell( cellIds[0]) # cell #1 was copied
 +        assert mesh2.getNodeIdsOfCell(1) == mesh.getNodeIdsOfCell( cellIds[1]) # cell #2 was copied
 +        #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_mergeNodes(self):
 +        #! [PySnippet_MEDCouplingUMesh_mergeNodes_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) 
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) 
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
 +        mesh.finishInsertingCells()
 +        coords=[0.3,-0.301, # 0
 +                0.2,-0.3,   # 1
 +                0.3,-0.302, # 2 ~~ 0
 +                1.1,0.0,    # 3
 +                1.1,0.0,    # 4 == 3
 +                0.3,-0.303]# 5 ~~ 0
 +        coordsArr=DataArrayDouble(coords,6,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_mergeNodes_1]
 +        #! [PySnippet_MEDCouplingUMesh_mergeNodes_2]
 +        arr,areNodesMerged,newNbOfNodes=mesh.mergeNodes(0.004)
 +        assert arr.getValues() == [0, 1, 0, 2, 2, 0]
 +        assert areNodesMerged
 +        assert newNbOfNodes == 3
 +        #! [PySnippet_MEDCouplingUMesh_mergeNodes_2]
 +        #! [PySnippet_MEDCouplingUMesh_mergeNodes_3]
 +        baryCoords2 = coords[2*2:] # initial coordinates of node #2
 +        coordsArr = mesh.getCoords() # retrieve a new shorten coord array
 +        self.assertNotAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 differs from that of baryCoords2
 +        # restore coordinates
 +        coordsArr = DataArrayDouble(coords,6,2)
 +        mesh.setCoords(coordsArr)
 +        # call mergeNodes2()
 +        mesh.mergeNodes2(0.004)
 +        coordsArr = mesh.getCoords() # retrieve a new shorten coord array
 +        self.assertAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 equals to that of baryCoords2
 +        #! [PySnippet_MEDCouplingUMesh_mergeNodes_3]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_zipConnectivityTraducer(self):
 +        #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])           # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])           # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])           # 2 == 1
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])           # 3 == 0
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[2:4]+conn[0:2]) # 4 ~~ 0
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1]
 +        #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2]
 +        oldNbCells = mesh.getNumberOfCells()
 +        arr = mesh.zipConnectivityTraducer(0)
 +        assert mesh.getNumberOfCells() == oldNbCells-2
 +        assert arr.getValues() == [0, 1, 1, 0, 2]
 +        #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_zipCoordsTraducer(self):
 +        #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) 
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1]
 +        #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2]
 +        cellIds=[1,2]
 +        mesh2=mesh.buildPartOfMySelf(cellIds,True)
 +        arr=mesh2.zipCoordsTraducer()
 +        assert mesh2.getNumberOfNodes() == 4 # nb of nodes decreased
 +        assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] # -1 for unused nodes
 +        #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_getNodeIdsInUse(self):
 +        #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])  
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) 
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1]
 +        #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2]
 +        cellIds=[1,2]
 +        mesh2=mesh.buildPartOfMySelf(cellIds,True)
 +        arr,newNbOfNodes=mesh2.getNodeIdsInUse()
 +        assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1]
 +        #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2]
 +        #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3]
 +        arr2=arr.invertArrayO2N2N2O(newNbOfNodes)
 +        assert arr2.getValues() == [1,2,4,5]
 +        #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_convertToPolyTypes(self):
 +        #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1]
 +        #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2]
 +        cells=[1,3]
 +        mesh.convertToPolyTypes(cells)
 +        assert mesh.getTypeOfCell(0) == NORM_QUAD4
 +        assert mesh.getTypeOfCell(1) == NORM_POLYGON, mesh.getTypeOfCell(1)
 +        assert mesh.getTypeOfCell(2) == NORM_TRI3
 +        assert mesh.getTypeOfCell(3) == NORM_POLYGON
 +        #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_buildDescendingConnectivity2(self):
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1]
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2]
 +        mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2()
 +        assert desc.getValues()        == [1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10]
 +        assert descIndx.getValues()    == [0,4,7,10,14,18]
 +        assert revDesc.getValues()     == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]
 +        assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18]
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2]
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3]
 +        assert mesh2.getNodeIdsOfCell( 3-1 ) == [4, 1]  # cell #3 in FORTRAN mode
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_buildDescendingConnectivity(self):
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1]
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2]
 +        mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity()
 +        assert desc.getValues()        == [0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9]
 +        assert descIndx.getValues()    == [0,4,7,10,14,18]
 +        assert revDesc.getValues()     == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]
 +        assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18]
 +        #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_getReverseNodalConnectivity(self):
 +        #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1]
 +        mesh=MEDCouplingUMesh()
 +        mesh.setMeshDimension(2)
 +        mesh.allocateCells(5)
 +        conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])   # 0
 +        mesh.insertNextCell(NORM_TRI3,3, conn[4:7])   # 1
 +        mesh.insertNextCell(NORM_TRI3,3, conn[7:10])  # 2
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
 +        mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
 +        mesh.finishInsertingCells()
 +        coords=[-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 ]
 +        coordsArr=DataArrayDouble(coords,9,2)
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1]
 +        #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2]
 +        revNodal,revNodalIndx=mesh.getReverseNodalConnectivity()
 +        assert revNodal.getValues()     == [0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4]
 +        assert revNodalIndx.getValues() == [0,1,3,5,7,12,14,15,17,18]
 +        #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2]
 +        return
 +
 +    def testExample_MEDCouplingUMesh_checkDeepEquivalWith(self):
 +        #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1]
 +        # mesh 1
 +        mesh1=MEDCouplingUMesh()
 +        mesh1.setMeshDimension(2)
 +        coords=[0.0,0.0, #0
 +                1.0,0.0, #1
 +                1.0,1.0, #2
 +                0.0,1.0] #3
 +        coordsArr=DataArrayDouble(coords,4,2)
 +        mesh1.setCoords(coordsArr)
 +        mesh1.allocateCells(2)
 +        mesh1.insertNextCell(NORM_TRI3,3,[0,1,2]) #0
 +        mesh1.insertNextCell(NORM_TRI3,3,[1,2,3]) #1
 +        mesh1.finishInsertingCells()
 +        # mesh 2
 +        mesh2=MEDCouplingUMesh()
 +        mesh2.setMeshDimension(2)
 +        coords=[0.0,1.0,    #0 = #3
 +                0.0,0.0,    #1 = #0
 +                1.0,0.0,    #2 = #1
 +                1.0,1.001]  #3 ~ #2
 +        coordsArr2=DataArrayDouble(coords,4,2)
 +        mesh2.setCoords(coordsArr2)
 +        mesh2.allocateCells(2)
 +        mesh2.insertNextCell(NORM_TRI3,3,[2,3,0]) #0 = #1
 +        mesh2.insertNextCell(NORM_TRI3,3,[3,1,2]) #1 ~ #0
 +        mesh2.finishInsertingCells()
 +        #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1]
 +        #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2]
 +        cellCompPol = 1 # "permuted same orientation" - policy of medium severity
 +        cOld2New, nOld2New = mesh1.checkDeepEquivalWith( mesh2, cellCompPol, 0.002 )
 +        assert nOld2New.getValues() == [3, 0, 1, 2]
 +        assert cOld2New.getValues() == [1, 0]
 +        #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2]
 +        #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3]
 +        self.assertRaises( InterpKernelException, mesh1.checkDeepEquivalOnSameNodesWith, mesh2, cellCompPol, 0.002)
 +        mesh2.setCoords(coordsArr) # make meshes share the same coordinates array
 +        mesh2.allocateCells(2)
 +        mesh2.insertNextCell(NORM_TRI3,3,[1,2,3]) #0 = #1
 +        mesh2.insertNextCell(NORM_TRI3,3,[1,0,2]) #1 ~ #0
 +        mesh2.finishInsertingCells()
 +        cellCompPol = 2 # the weakest policy
 +        mesh1.checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0 )
 +        #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3]
 +        return
 +
 +    def testExample_MEDCouplingPointSet_scale(self):
 +        #! [PySnippet_MEDCouplingPointSet_scale_1]
 +        coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes
 +        coordsArr=DataArrayDouble(coords,4,2)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        initCoords = coordsArr.deepCpy()
 +        #! [PySnippet_MEDCouplingPointSet_scale_1]
 +        #! [PySnippet_MEDCouplingPointSet_scale_2]
 +        center = [0.,0.]
 +        factor = 2.
 +        mesh.scale(center,factor)
 +        #! [PySnippet_MEDCouplingPointSet_scale_2]
 +        #! [PySnippet_MEDCouplingPointSet_scale_3]
 +        coords2 = mesh.getCoords()
 +        assert coords2.isEqualWithoutConsideringStr( initCoords, 1.0 )
 +        assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 )
 +        #! [PySnippet_MEDCouplingPointSet_scale_3]
 +        return
 +
 +    def testExample_MEDCouplingPointSet_translate(self):
 +        #! [PySnippet_MEDCouplingPointSet_translate_1]
 +        coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes
 +        coordsArr=DataArrayDouble(coords,4,2)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        initCoords = coordsArr.deepCpy()
 +        #! [PySnippet_MEDCouplingPointSet_translate_1]
 +        #! [PySnippet_MEDCouplingPointSet_translate_2]
 +        vector = [1.,1.]
 +        mesh.translate(vector)
 +        #! [PySnippet_MEDCouplingPointSet_translate_2]
 +        #! [PySnippet_MEDCouplingPointSet_translate_3]
 +        coords2 = mesh.getCoords()
 +        assert coords2.isEqualWithoutConsideringStr( initCoords, 1 )
 +        assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 )
 +        #! [PySnippet_MEDCouplingPointSet_translate_3]
 +        return
 +
 +    def testExample_MEDCouplingPointSet_rotate(self):
 +        #! [PySnippet_MEDCouplingPointSet_rotate_1]
 +        coords=[0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1] # 2D coordinates of 4 nodes
 +        coordsArr=DataArrayDouble(coords,4,2)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingPointSet_rotate_1]
 +        #! [PySnippet_MEDCouplingPointSet_rotate_2]
 +        center = [0.,0.]
 +        mesh.rotate(center,-pi/2)
 +        #! [PySnippet_MEDCouplingPointSet_rotate_2]
 +        #! [PySnippet_MEDCouplingPointSet_rotate_3]
 +        mesh.changeSpaceDimension(3)
 +        center = [0.,0.,0.]
 +        vector = [0.,0.,1.]
 +        mesh.rotate(center,vector,pi/2)
 +        #! [PySnippet_MEDCouplingPointSet_rotate_3]
 +        #! [PySnippet_MEDCouplingPointSet_rotate_4]
 +        mesh.changeSpaceDimension(2)
 +        coords2 = mesh.getCoords()
 +        for i,c in enumerate( coords ):
 +            self.assertAlmostEqual( c, coords2.getIJ(0,i), 13 )
 +        #! [PySnippet_MEDCouplingPointSet_rotate_4]
 +        return
 +
 +    def testExample_MEDCouplingPointSet_getBoundingBox(self):
 +        #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1]
 +        cc=[0.0, 0.1, 0.2, # 3D coordinates of 2 nodes
 +            2.0, 2.1, 2.2]
 +        coordsArr=DataArrayDouble(cc,2,3)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1]
 +        #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2]
 +        bbox=mesh.getBoundingBox()
 +        assert bbox == [( cc[0], cc[3] ), # NOTE: list of 3 tuples is retirned!
 +                        ( cc[1], cc[4] ),
 +                        ( cc[2], cc[5] )]
 +        #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2]
 +
 +    def testExample_MEDCouplingPointSet_getNodeIdsNearPoint(self):
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1]
 +        # 2D coordinates of 5 nodes
 +        coords=[0.3,-0.301, # 0
 +                0.2,-0.3,   # 1
 +                0.3,-0.302, # 2
 +                1.1,0.0,    # 3
 +                0.3,-0.30299999999999]# 4
 +        coordsArr=DataArrayDouble(coords,5,2)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1]
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2]
 +        point=[0.3, -0.3]   # point close to nodes #0, #2 and #4
 +        ids=mesh.getNodeIdsNearPoint(point,0.003)
 +        assert ids.getValues() == [0,2,4]
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2]
 +        return
 +
 +    def testExample_MEDCouplingPointSet_getNodeIdsNearPoints(self):
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1]
 +        # 2D coordinates of 7 nodes
 +        coords=[0.3,-0.301, # 0
 +                0.2,-0.3,   # 1
 +                0.3,-0.302, # 2
 +                1.1,0.0,    # 3
 +                1.1,0.0,    # 4
 +                1.1,0.002,  # 5
 +                0.3,-0.303]# 6
 +        coordsArr=DataArrayDouble(coords,7,2)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1]
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2]
 +        points=[0.2,-0.301,   # ~ node #1
 +                0.0, 0.0,
 +                1.1, 0.002]   # ~ nodes #3, #4 and #5
 +        ids,idsIndex=mesh.getNodeIdsNearPoints(points,3,0.003)
 +        assert ids.getValues() == [1, 3, 4, 5]
 +        assert idsIndex.getValues() == [0, 1, 1, 4]
 +        #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2]
 +        return
 +
 +    def testExample_MEDCouplingPointSet_findCommonNodes(self):
 +        #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1]
 +        coords=[0.3,-0.301, # 0
 +                0.2,-0.3,   # 1
 +                0.3,-0.302, # 2
 +                1.1,0.0,    # 3
 +                1.1,0.0,    # 4
 +                0.3,-0.303]# 5
 +        coordsArr=DataArrayDouble(coords,6,2)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +        #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1]
 +        #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2]
 +        comm,commI=mesh.findCommonNodes(1e-13)
 +        assert comm.getValues() == [3,4]
 +        comm,commI=mesh.findCommonNodes(0.004)
 +        assert comm.getValues() == [0,2,5,3,4]
 +        #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2]
 +        return
 +
 +    def testExample_MEDCouplingPointSet_getCoordinatesOfNode(self):
 +        #! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1]
 +        coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3]
 +        coordsArr=DataArrayDouble(coords,3,2)
 +        mesh=MEDCouplingUMesh()
 +        mesh.setCoords(coordsArr)
 +#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1]
 +#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2]
 +        nodeCoords=mesh.getCoordinatesOfNode(1)
 +        self.assertAlmostEqual(0.2, nodeCoords[0],13)
 +        self.assertAlmostEqual(-0.3,nodeCoords[1],13)
 +#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2]
 +        return
 +
 +    def testExample_DataArrayInt_getTuple(self):
 +#! [Snippet_DataArrayInt_getTuple_1]
 +        dv=DataArrayInt()
 +        dv.alloc( 6, 1 )
 +        dv.iota(7)
 +        dv.rearrange( 2 )
 +        assert dv.getTuple( 1 ) == [9,10]
 +#! [Snippet_DataArrayInt_getTuple_1]
 +#! [Snippet_DataArrayInt_getTuple_2]
 +        for tpl in dv:
 +            print tpl
 +#! [Snippet_DataArrayInt_getTuple_2]
 +        return
 +
 +    def testExample_DataArrayInt_buildPermutationArr(self):
 +#! [PySnippet_DataArrayInt_buildPermutationArr_1]
 +        a=DataArrayInt()
 +        a.setValues([4,5,6,7,8],5,1)
 +        b=DataArrayInt()
 +        b.setValues([5,4,8,6,7],5,1)
 +        c=a.buildPermutationArr(b)
 +#! [PySnippet_DataArrayInt_buildPermutationArr_1]
 +        self.assertEqual([1,0,4,2,3],c.getValues())
 +        return
 +
 +    def testExample_DataArrayInt_invertArrayO2N2N2O(self):
 +#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1]
 +        arr1=[2,0,4,1,5,3]
 +        da=DataArrayInt()
 +        da.setValues(arr1,6,1)
 +        da2=da.invertArrayO2N2N2O(6)
 +        expected1=[1,3,0,5,2,4]
 +        for i in xrange(6):
 +            self.assertEqual(expected1[i],da2.getIJ(i,0))
 +            pass
 +#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1]
 +        return
 +
 +    def testExample_DataArrayInt_invertArrayN2O2O2N(self):
 +#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1]
 +        arr1=[2,0,4,1,5,3]
 +        da=DataArrayInt()
 +        da.setValues(arr1,6,1)
 +        da2=da.invertArrayN2O2O2N(7)
 +        expected1=[1,3,0,5,2,4,-1]
 +        for i in xrange(6):
 +            self.assertEqual(expected1[i],da2.getIJ(i,0))
 +            pass
 +#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1]
 +        return
 +
 +
 +    def testExample_DataArrayDouble_getIdsInRange(self):
 +#! [PySnippet_DataArrayDouble_getIdsInRange_1]
 +        da=DataArrayDouble()
 +        da.alloc( 10, 1 )
 +        da[ :, :] = range(10)
 +        da2 = da.getIdsInRange( 2.5, 6 )
 +#! [PySnippet_DataArrayDouble_getIdsInRange_1]
 +        return
 +
 +    def testExample_DataArrayDouble_setPartOfValues2(self):
 +#! [Snippet_DataArrayDouble_setPartOfValues2_1]
 +        da=DataArrayDouble()
 +        da.alloc( 4, 7 )
 +        #
 +        dv=DataArrayDouble()
 +        dv.alloc( 6, 1 )
 +        dv.iota(7)
 +        dv.rearrange( 2 )
 +#! [Snippet_DataArrayDouble_setPartOfValues2_1]
 +#! [Snippet_DataArrayDouble_setPartOfValues2_2]
 +        da.fillWithZero()
 +        da[ [0,1,2], [1,3] ] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValues2_2]
 +#! [Snippet_DataArrayDouble_setPartOfValues2_3]
 +        da.fillWithZero()
 +        dv.rearrange( 6 )
 +        da[ [0,2,3], [0,2,3,4,5,6]] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValues2_3]
 +        return
 +
 +    def testExample_DataArrayInt_setPartOfValues2(self):
 +#! [Snippet_DataArrayInt_setPartOfValues2_1]
 +        da=DataArrayInt()
 +        da.alloc( 4, 7 )
 +        #
 +        dv=DataArrayInt()
 +        dv.alloc( 6, 1 )
 +        dv.iota(7)
 +        dv.rearrange( 2 )
 +#! [Snippet_DataArrayInt_setPartOfValues2_1]
 +#! [Snippet_DataArrayInt_setPartOfValues2_2]
 +        da.fillWithZero()
 +        da[ [0,1,2], [1,3] ] = dv
 +#! [Snippet_DataArrayInt_setPartOfValues2_2]
 +#! [Snippet_DataArrayInt_setPartOfValues2_3]
 +        da.fillWithZero()
 +        dv.rearrange( 6 )
 +        da[ [0,2,3], [0,2,3,4,5,6]] = dv
 +#! [Snippet_DataArrayInt_setPartOfValues2_3]
 +        return
 +
 +    def testExample_DataArrayDouble_setPartOfValues3(self):
 +#! [Snippet_DataArrayDouble_setPartOfValues3_1]
 +        da=DataArrayDouble()
 +        da.alloc( 4, 7 )
 +        #
 +        dv=DataArrayDouble()
 +        dv.alloc( 6, 1 )
 +        dv.iota(7)
 +        dv.rearrange( 2 )
 +#! [Snippet_DataArrayDouble_setPartOfValues3_1]
 +#! [Snippet_DataArrayDouble_setPartOfValues3_2]
 +        da.fillWithZero()
 +        da[ 0:3, [1,3] ] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValues3_2]
 +#! [Snippet_DataArrayDouble_setPartOfValues3_3]
 +        da.fillWithZero()
 +        dv.rearrange( 6 )
 +        da[ 0:4:2, [0,2,3,4,5,6]] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValues3_3]
 +        return
 +
 +    def testExample_DataArrayInt_setPartOfValues3(self):
 +#! [Snippet_DataArrayInt_setPartOfValues3_1]
 +        da=DataArrayInt()
 +        da.alloc( 4, 7 )
 +        #
 +        dv=DataArrayInt()
 +        dv.alloc( 6, 1 )
 +        dv.iota(7)
 +        dv.rearrange( 2 )
 +#! [Snippet_DataArrayInt_setPartOfValues3_1]
 +#! [Snippet_DataArrayInt_setPartOfValues3_2]
 +        da.fillWithZero()
 +        da[ 0:3, [1,3] ] = dv
 +#! [Snippet_DataArrayInt_setPartOfValues3_2]
 +#! [Snippet_DataArrayInt_setPartOfValues3_3]
 +        da.fillWithZero()
 +        dv.rearrange( 6 )
 +        da[ 0:4:2, [0,2,3,4,5,6]] = dv
 +#! [Snippet_DataArrayInt_setPartOfValues3_3]
 +        return
 +
 +    def testExample_DataArrayDouble_setPartOfValues1(self):
 +#! [Snippet_DataArrayDouble_setPartOfValues1_1]
 +        da=DataArrayDouble()
 +        da.alloc( 4, 4 )
 +        da.setInfoOnComponents( ["v1","v2","v3","v4"])
 +        #
 +        dv=DataArrayDouble()
 +        dv.alloc( 4, 1 )
 +        dv.iota(7)
 +        dv.rearrange( 2 )
 +        dv.setInfoOnComponents( ["a1","a2"])
 +#! [Snippet_DataArrayDouble_setPartOfValues1_1]
 +#! [Snippet_DataArrayDouble_setPartOfValues1_2]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 1,3,1, 1,3,1, True )
 +#! [Snippet_DataArrayDouble_setPartOfValues1_2]
 +#! [Snippet_DataArrayDouble_setPartOfValues1_3]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 0,4,1, 1,2,1, False )
 +#! [Snippet_DataArrayDouble_setPartOfValues1_3]
 +#! [Snippet_DataArrayDouble_setPartOfValues1_4]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 1,2,1, 0,4,1, False )
 +#! [Snippet_DataArrayDouble_setPartOfValues1_4]
 +#! [Snippet_DataArrayDouble_setPartOfValues1_5]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 0,3,2, 1,4,2, True )
 +#! [Snippet_DataArrayDouble_setPartOfValues1_5]
 +#! [Snippet_DataArrayDouble_setPartOfValues1_6]
 +        da2 = da.deepCpy()
 +        da2.fillWithZero()
 +        da2[ 0:3:2, 1:4:2 ] = dv
 +        self.assertTrue( da.isEqual( da2, 1e-20 ))
 +#! [Snippet_DataArrayDouble_setPartOfValues1_6]
 +        return
 +
 +    def testExample_DataArrayInt_setPartOfValues1(self):
 +#! [Snippet_DataArrayInt_setPartOfValues1_1]
 +        da=DataArrayInt()
 +        da.alloc( 4, 4 )
 +        da.setInfoOnComponents( ["v1","v2","v3","v4"])
 +        #
 +        dv=DataArrayInt()
 +        dv.alloc( 4, 1 )
 +        dv.iota(7)
 +        dv.rearrange( 2 )
 +        dv.setInfoOnComponents( ["a1","a2"])
 +#! [Snippet_DataArrayInt_setPartOfValues1_1]
 +#! [Snippet_DataArrayInt_setPartOfValues1_2]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 1,3,1, 1,3,1, True )
 +#! [Snippet_DataArrayInt_setPartOfValues1_2]
 +#! [Snippet_DataArrayInt_setPartOfValues1_3]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 0,4,1, 1,2,1, False )
 +#! [Snippet_DataArrayInt_setPartOfValues1_3]
 +#! [Snippet_DataArrayInt_setPartOfValues1_4]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 1,2,1, 0,4,1, False )
 +#! [Snippet_DataArrayInt_setPartOfValues1_4]
 +#! [Snippet_DataArrayInt_setPartOfValues1_5]
 +        da.fillWithZero()
 +        da.setPartOfValues1( dv, 0,3,2, 1,4,2, True )
 +#! [Snippet_DataArrayInt_setPartOfValues1_5]
 +#! [Snippet_DataArrayInt_setPartOfValues1_6]
 +        da2 = da.deepCpy()
 +        da2.fillWithZero()
 +        da2[ 0:3:2, 1:4:2 ] = dv
 +        self.assertTrue( da.isEqual( da2 ))
 +#! [Snippet_DataArrayInt_setPartOfValues1_6]
 +        return
 +
 +    def testExample_DataArrayDouble_setPartOfValuesSimple1(self):
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1]
 +        da=DataArrayDouble()
 +        da.alloc( 4, 4 )
 +        dv = 7
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 )
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 )
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 )
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 )
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6]
 +        da2 = da.deepCpy()
 +        da2.fillWithZero()
 +        da2[ 0:3:2, 1:4:2 ] = dv
 +        self.assertTrue( da.isEqual( da2, 1e-20 ))
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6]
 +        return
 +
 +    def testExample_DataArrayInt_setPartOfValuesSimple1(self):
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1]
 +        da=DataArrayInt()
 +        da.alloc( 4, 4 )
 +        dv = 7
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 )
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 )
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 )
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5]
 +        da.fillWithZero()
 +        da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 )
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6]
 +        da2 = da.deepCpy()
 +        da2.fillWithZero()
 +        da2[ 0:3:2, 1:4:2 ] = dv
 +        self.assertTrue( da.isEqual( da2 ))
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6]
 +        return
 +
 +    def testExample_DataArrayDouble_setPartOfValuesSimple2(self):
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1]
 +        da=DataArrayDouble()
 +        da.alloc( 4, 4 )
 +        dv = 7
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2]
 +        da.fillWithZero()
 +        da[[1,2], [1,2]] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3]
 +        da.fillWithZero()
 +        da[[0,1,2,3], [1]] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4]
 +        da.fillWithZero()
 +        da[[1], [0,1,2,3]] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5]
 +        da.fillWithZero()
 +        da[[0,2], [1,3]] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5]
 +        return
 +
 +    def testExample_DataArrayInt_setPartOfValuesSimple2(self):
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1]
 +        da=DataArrayInt()
 +        da.alloc( 4, 4 )
 +        dv = 7
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2]
 +        da.fillWithZero()
 +        da[[1,2], [1,2]] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3]
 +        da.fillWithZero()
 +        da[[0,1,2,3], [1]] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4]
 +        da.fillWithZero()
 +        da[[1], [0,1,2,3]] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5]
 +        da.fillWithZero()
 +        da[[0,2], [1,3]] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5]
 +        return
 +
 +    def testExample_DataArrayDouble_setPartOfValuesSimple3(self):
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1]
 +        da=DataArrayDouble()
 +        da.alloc( 4, 4 )
 +        dv = 7
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2]
 +        da.fillWithZero()
 +        da[[1,2], 1:3] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3]
 +        da.fillWithZero()
 +        da[[0,1,2,3], 1:2] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4]
 +        da.fillWithZero()
 +        da[[1], 0:4] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4]
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5]
 +        da.fillWithZero()
 +        da[[0,2], 1:4:2] = dv
 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5]
 +        return
 +
 +    def testExample_DataArrayInt_setPartOfValuesSimple3(self):
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1]
 +        da=DataArrayInt()
 +        da.alloc( 4, 4 )
 +        dv = 7
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2]
 +        da.fillWithZero()
 +        da[[1,2], 1:3] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3]
 +        da.fillWithZero()
 +        da[[0,1,2,3], 1:2] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4]
 +        da.fillWithZero()
 +        da[[1], 0:4] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4]
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5]
 +        da.fillWithZero()
 +        da[[0,2], 1:4:2] = dv
 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5]
 +        return
 +
 +    def testExample_DataArrayDouble_setSelectedComponents(self):
 +#! [Snippet_DataArrayDouble_setSelectedComponents1]
 +        array1=[1.,2., 3.,4., 5.,6.]
 +        da=DataArrayDouble(array1,3,2)
 +        da.setInfoOnComponents( ["a1","a2"])
 +#! [Snippet_DataArrayDouble_setSelectedComponents1]
 +#! [Snippet_DataArrayDouble_setSelectedComponents2]
 +        dv=DataArrayDouble()
 +        dv.alloc( 4, 4 )
 +        dv.fillWithZero()
 +        dv.setInfoOnComponents( ["v1","v2","v3","v4"])
 +        dv2 = dv.deepCpy()
 +        dv.setSelectedComponents( da, [1,0] )
 +#! [Snippet_DataArrayDouble_setSelectedComponents2]
 +#! [Snippet_DataArrayDouble_setSelectedComponents3]
 +        dv2[:3,[1,0]] = da
 +        self.assertTrue( dv.isEqualWithoutConsideringStr( dv2, 1e-20 ))
 +#! [Snippet_DataArrayDouble_setSelectedComponents3]
 +        return
 +
 +    def testExample_DataArrayInt_setSelectedComponents(self):
 +#! [Snippet_DataArrayInt_setSelectedComponents1]
 +        da=DataArrayInt()
 +        array1=[1,2, 3,4, 5,6]
 +        da.setValues(array1,3,2)
 +        da.setInfoOnComponents( ["a1","a2"])
 +#! [Snippet_DataArrayInt_setSelectedComponents1]
 +#! [Snippet_DataArrayInt_setSelectedComponents2]
 +        dv=DataArrayInt()
 +        dv.alloc( 4, 4 )
 +        dv.fillWithZero()
 +        dv.setInfoOnComponents( ["v1","v2","v3","v4"])
 +        dv2 = dv.deepCpy()
 +        dv.setSelectedComponents( da, [1,0] )
 +#! [Snippet_DataArrayInt_setSelectedComponents2]
 +#! [Snippet_DataArrayInt_setSelectedComponents3]
 +        dv2[:3,[1,0]] = da
 +        self.assertTrue( dv.isEqualWithoutConsideringStr( dv2 ))
 +#! [Snippet_DataArrayInt_setSelectedComponents3]
 +        return
 +
 +    def testExample_DataArrayDouble_getDifferentValues(self):
 +#! [Snippet_DataArrayDouble_getDifferentValues1]
 +        array1=[2.3,1.2,1.3,2.3,2.301,0.8]
 +        da=DataArrayDouble(array1,6,1)
 +        #
 +        dv=da.getDifferentValues(2e-1)
 +        expected2=[2.301,1.3,0.8]
 +        self.assertEqual(3,dv.getNbOfElems())
 +        for i in xrange(3):
 +            self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14)
 +            pass
 +#! [Snippet_DataArrayDouble_getDifferentValues1]
 +        return
 +
 +    def testExample_DataArrayDouble_findCommonTuples1(self):
 +#! [PySnippet_DataArrayDouble_findCommonTuples1]
 +        array2=[2.3,2.3, 1.2,1.2, 1.3,1.3, 2.3,2.3, 2.301,2.301, 0.8,0.8]
 +        da=DataArrayDouble(array2,6,2)        
 +#! [PySnippet_DataArrayDouble_findCommonTuples1]
 +#! [PySnippet_DataArrayDouble_findCommonTuples2]
 +        c,cI=da.findCommonTuples(1.01e-1)
 +        expected3=[0,3,4,1,2]
 +        expected4=[0,3,5]
 +        self.assertEqual(expected3,c.getValues())
 +        self.assertEqual(expected4,cI.getValues())
 +#! [PySnippet_DataArrayDouble_findCommonTuples2]
 +        return
 +
 +    def testExampleDataArrayDoubleMeldWith(self):
 +#! [PySnippet_DataArrayDouble_Meld1_1]
 +        da1=DataArrayDouble()
 +        da1.alloc(7,2)
 +        da2=DataArrayDouble()
 +        da2.alloc(7,1)
 +        #
 +        da1.fillWithValue(7.)
 +        da2.iota(0.)
 +        da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec")
 +        #
 +        da1.setInfoOnComponent(0,"c0da1")
 +        da1.setInfoOnComponent(1,"c1da1")
 +        da3.setInfoOnComponent(0,"c0da3")
 +        da3.setInfoOnComponent(1,"c1da3")
 +        da3.setInfoOnComponent(2,"c2da3")
 +        #
 +        da1C=da1.deepCpy()
 +        da1.meldWith(da3)
 +#! [PySnippet_DataArrayDouble_Meld1_1]
 +
 +    def testExampleDataArrayIntMeldWith(self):
 +#! [PySnippet_DataArrayInt_Meld1_1]
 +        da1=DataArrayInt()
 +        da1.alloc(7,2)
 +        da2=DataArrayInt()
 +        da2.alloc(7,1)
 +        #
 +        da1.fillWithValue(7)
 +        da2.iota(0)
 +        #
 +        da1.setInfoOnComponent(0,"c0da1")
 +        da1.setInfoOnComponent(1,"c1da1")
 +        da2.setInfoOnComponent(0,"c0da2")
 +        #
 +        da1.meldWith(da2)
 +#! [PySnippet_DataArrayInt_Meld1_1]
 +
 +    def testExampleDataArrayDoubleKeepSelectedComponents1(self):
 +#! [SnippeDataArrayDoubleKeepSelectedComponents1_1]
 +        arr1=[1.,2.,3.,4.,     # tuple 0
 +              11.,12.,13.,14., # tuple 1
 +              21.,22.,23.,24., # ...
 +              31.,32.,33.,34.,
 +              41.,42.,43.,44.]
 +        a1=DataArrayDouble(arr1,5,4)
 +        a1.setInfoOnComponent(0,"a")
 +        a1.setInfoOnComponent(1,"b")
 +        a1.setInfoOnComponent(2,"c")
 +        a1.setInfoOnComponent(3,"d")
 +#! [SnippeDataArrayDoubleKeepSelectedComponents1_1]
 +#! [SnippeDataArrayDoubleKeepSelectedComponents1_2]
 +        arr2V=[1,2,1,2,0,0]
 +        a2=a1.keepSelectedComponents(arr2V)
 +#! [SnippeDataArrayDoubleKeepSelectedComponents1_2]
 +        return
 +
 +    def testExampleDataArrayIntKeepSelectedComponents1(self):
 +#! [SnippeDataArrayIntKeepSelectedComponents1_1]
 +        arr1=[1,2,3,4,     # tuple 0
 +              11,12,13,14, # tuple 1
 +              21,22,23,24, # 
 +              31,32,33,34,
 +              41,42,43,44]
 +        a1=DataArrayInt()
 +        a1.setValues(arr1,5,4)
 +        a1.setInfoOnComponent(0,"a")
 +        a1.setInfoOnComponent(1,"b")
 +        a1.setInfoOnComponent(2,"c")
 +        a1.setInfoOnComponent(3,"d")
 +#! [SnippeDataArrayIntKeepSelectedComponents1_1]
 +#! [SnippeDataArrayIntKeepSelectedComponents1_2]
 +        arr2V=[1,2,1,2,0,0]
 +        a2=a1.keepSelectedComponents(arr2V)
 +#! [SnippeDataArrayIntKeepSelectedComponents1_2]
 +#! [SnippeDataArrayIntKeepSelectedComponents1_3]
 +        a3=a1[:,arr2V ]
 +#! [SnippeDataArrayIntKeepSelectedComponents1_3]
 +        return
 +
 +    def testExampleFieldDoubleBuildSubPart1(self):
 +        from MEDCouplingDataForTest import MEDCouplingDataForTest
 +#! [PySnippetFieldDoubleBuildSubPart1_1]
 +        mesh1=MEDCouplingDataForTest.build2DTargetMesh_1()
 +        f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME)
 +        f1.setTime(2.3,5,6)
 +        f1.setMesh(mesh1)
 +        arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.]
 +        array=DataArrayDouble(arr1,mesh1.getNumberOfCells(),2)
 +        f1.setArray(array)
 +# ! [PySnippetFieldDoubleBuildSubPart1_1]
 +# ! [PySnippetFieldDoubleBuildSubPart1_2]
 +        part1=[2,1,4]
 +        f2=f1.buildSubPart(part1)
 +# ! [PySnippetFieldDoubleBuildSubPart1_2]
 +        f2.zipCoords()
 +        self.assertEqual(3,f2.getNumberOfTuples())
 +        self.assertEqual(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.assertEqual(3,f2.getMesh().getNumberOfCells())
 +        self.assertEqual(6,f2.getMesh().getNumberOfNodes())
 +        self.assertEqual(2,f2.getMesh().getSpaceDimension())
 +        self.assertEqual(2,f2.getMesh().getMeshDimension())
 +        m2C=f2.getMesh()
 +        self.assertEqual(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.assertEqual(expected3,list(m2C.getNodalConnectivity().getValues()))
 +        expected4=[0,4,8,13]
 +        self.assertEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues()))
 +        # Test with field on nodes.
 +# ! [PySnippetFieldDoubleBuildSubPart1_3]
 +        f1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME)
 +        f1.setTime(2.3,5,6)
 +        f1.setMesh(mesh1)
 +        arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.]
 +        array=DataArrayDouble(arr2,mesh1.getNumberOfNodes(),2)
 +        f1.setArray(array)
 +# ! [PySnippetFieldDoubleBuildSubPart1_3]
 +# ! [PySnippetFieldDoubleBuildSubPart1_4]
 +        part2=[1,2]
 +        f2=f1.buildSubPart(part2)
 +# ! [PySnippetFieldDoubleBuildSubPart1_4]
 +        self.assertEqual(4,f2.getNumberOfTuples())
 +        self.assertEqual(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.assertEqual(2,f2.getMesh().getNumberOfCells())
 +        self.assertEqual(4,f2.getMesh().getNumberOfNodes())
 +        self.assertEqual(2,f2.getMesh().getSpaceDimension())
 +        self.assertEqual(2,f2.getMesh().getMeshDimension())
 +        m2C=f2.getMesh()
 +        self.assertEqual(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.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:])
 +        self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4])
 +        self.assertEqual(expected4[:3],[int(i) for i in m2C.getNodalConnectivityIndex()])
 +        #idem previous because nodes of cell#4 are not fully present in part3
 +        part3=[1,2]
 +        arrr=DataArrayInt()
 +        arrr.setValues(part3,2,1)
 +        f2=f1.buildSubPart(arrr)
 +        self.assertEqual(4,f2.getNumberOfTuples())
 +        self.assertEqual(2,f2.getNumberOfComponents())
 +        for i in xrange(8):
 +            self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12)
 +            pass
 +        self.assertEqual(2,f2.getMesh().getNumberOfCells())
 +        self.assertEqual(4,f2.getMesh().getNumberOfNodes())
 +        self.assertEqual(2,f2.getMesh().getSpaceDimension())
 +        self.assertEqual(2,f2.getMesh().getMeshDimension())
 +        m2C=f2.getMesh()
 +        self.assertEqual(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.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:8])
 +        self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4])
 +        self.assertEqual(expected4[:3],m2C.getNodalConnectivityIndex().getValues())
 +        part4=[1,2,4]
 +        f2=f1.buildSubPart(part4)
 +        self.assertEqual(6,f2.getNumberOfTuples())
 +        self.assertEqual(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.assertEqual(3,f2.getMesh().getNumberOfCells())
 +        self.assertEqual(6,f2.getMesh().getNumberOfNodes())
 +        self.assertEqual(2,f2.getMesh().getSpaceDimension())
 +        self.assertEqual(2,f2.getMesh().getMeshDimension())
 +        m2C=f2.getMesh()
 +        self.assertEqual(13,m2C.getMeshLength())
 +        for i in xrange(12):
 +            self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12)
 +            pass
 +        self.assertEqual(expected3[0:4],m2C.getNodalConnectivity().getValues()[4:8])
 +        self.assertEqual(expected3[4:8],m2C.getNodalConnectivity().getValues()[0:4])
 +        self.assertEqual(expected3[8:13],m2C.getNodalConnectivity().getValues()[8:13])
 +        self.assertEqual(expected4,m2C.getNodalConnectivityIndex().getValues())
 +        # previous line equivalent to
 +        self.assertEqual(expected4,[int(i) for i in m2C.getNodalConnectivityIndex()])
 +        return
 +
 +    def testExampleUMeshStdBuild1(self):
 +# ! [PySnippetUMeshStdBuild1_1]
 +        coords=[-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. ]
 +        nodalConnPerCell=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
 +# ! [PySnippetUMeshStdBuild1_1]
 +# ! [PySnippetUMeshStdBuild1_2]
 +        mesh=MEDCouplingUMesh("My2DMesh",2)
 +# ! [PySnippetUMeshStdBuild1_2]
 +# ! [PySnippetUMeshStdBuild1_3]
 +        mesh.allocateCells(5)#You can put more than 5 if you want but not less.
 +        mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[:4])
 +        mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[4:7])
 +        mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[7:10])
 +        mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[10:14])
 +        mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[14:])
 +        mesh.finishInsertingCells()
 +# ! [PySnippetUMeshStdBuild1_3]
 +# ! [PySnippetUMeshStdBuild1_4]
 +        coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. 
 +        mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes.
 +# ! [PySnippetUMeshStdBuild1_4]
 +# ! [PySnippetUMeshStdBuild1_5]
 +# ! [PySnippetUMeshStdBuild1_5]
 +        mesh.checkCoherency()
 +        return
 +
 +    def testExampleCMeshStdBuild1(self):
 +# ! [PySnippetCMeshStdBuild1_1]
 +        XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] # 9 values along X
 +        YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] # 7 values along Y
 +        arrX=DataArrayDouble(XCoords)
 +        arrX.setInfoOnComponent(0,"X [m]")
 +        arrY=DataArrayDouble(YCoords)
 +        arrY.setInfoOnComponent(0,"Y [m]")
 +# ! [PySnippetCMeshStdBuild1_1]
 +# ! [PySnippetCMeshStdBuild1_2]
 +        mesh=MEDCouplingCMesh("My2D_CMesh")
 +        mesh.setCoords(arrX,arrY)
 +# ! [PySnippetCMeshStdBuild1_2]
 +# ! [PySnippetCMeshStdBuild1_3]
 +        self.assertEqual(8*6,mesh.getNumberOfCells())
 +        self.assertEqual(9*7,mesh.getNumberOfNodes())
 +        self.assertEqual(2,mesh.getSpaceDimension())
 +        self.assertEqual(2,mesh.getMeshDimension())
 +# ! [PySnippetCMeshStdBuild1_3]
 +        mesh=MEDCouplingCMesh("My2D_CMesh")
 +# ! [PySnippetCMeshStdBuild1_2bis]
 +        mesh.setCoordsAt(0,arrX)
 +        mesh.setCoordsAt(1,arrY)
 +# ! [PySnippetCMeshStdBuild1_2bis]
 +        self.assertEqual(8*6,mesh.getNumberOfCells())
 +        self.assertEqual(9*7,mesh.getNumberOfNodes())
 +        self.assertEqual(2,mesh.getSpaceDimension())
 +        self.assertEqual(2,mesh.getMeshDimension())
++# ! [PySnippetCMeshStdBuild1_4]
++# ! [PySnippetCMeshStdBuild1_4]
 +        return
 +
 +    def testExampleUMeshAdvBuild1(self):
 +# ! [PySnippetUMeshAdvBuild1_1]
 +        coords=[-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. ]
 +        nodalConnPerCell=[4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4]
 +        nodalConnPerCellIndex=[0,5,9,13,18,23]
 +# ! [PySnippetUMeshAdvBuild1_1]
 +# ! [PySnippetUMeshAdvBuild1_2]
 +        mesh=MEDCouplingUMesh("My2DMesh",2)
 +# ! [PySnippetUMeshAdvBuild1_2]
 +# ! [PySnippetUMeshAdvBuild1_3]
 +        nodalConn=DataArrayInt(nodalConnPerCell,23,1)
 +        nodalConnI=DataArrayInt(nodalConnPerCellIndex,6,1)
 +        mesh.setConnectivity(nodalConn,nodalConnI,True)
 +# ! [PySnippetUMeshAdvBuild1_3]
 +# ! [PySnippetUMeshAdvBuild1_4]
 +        coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3.
 +        mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes.
 +# ! [PySnippetUMeshAdvBuild1_4]
 +# ! [PySnippetUMeshAdvBuild1_5]
 +# ! [PySnippetUMeshAdvBuild1_5]
 +        mesh.checkCoherency()
 +        return
 +
 +    def testExampleDataArrayBuild1(self):
 +# ! [PySnippetDataArrayBuild1_0]
 +        dataDouble=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.]
 +# ! [PySnippetDataArrayBuild1_0]
 +# ! [PySnippetDataArrayBuild1_1]
 +        arrayDouble=DataArrayDouble()
 +        arrayDouble.setValues(dataDouble,5,3)# 5 tuples containing each 3 components
 +# ! [PySnippetDataArrayBuild1_1]
 +# ! [PySnippetDataArrayBuild1_1bis]
 +        arrayDouble=DataArrayDouble(dataDouble,5,3)
 +# ! [PySnippetDataArrayBuild1_1bis]
 +# ! [PySnippetDataArrayBuild1_2]
 +        dataInt=[0, 10, 20, 1, 11, 21, 2, 12, 22, 3, 13, 23, 4, 14, 24]
 +# ! [PySnippetDataArrayBuild1_2]
 +# ! [PySnippetDataArrayBuild1_3]
 +        arrayInt=DataArrayInt()
 +        arrayInt.setValues(dataInt,5,3)# 5 tuples containing each 3 components
 +# ! [PySnippetDataArrayBuild1_3]
 +# ! [PySnippetDataArrayBuild1_3bis]
 +        arrayInt=DataArrayInt(dataInt,5,3)
 +# ! [PySnippetDataArrayBuild1_3bis]
 +        return
 +
 +    def testExampleFieldDoubleBuild1(self):
 +        XCoords=[-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22];  arrX=DataArrayDouble(XCoords)
 +        YCoords=[0.07,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords)
 +        mesh=MEDCouplingCMesh("My2D_CMesh")
 +        mesh.setCoords(arrX,arrY)
 +# ! [PySnippetFieldDoubleBuild1_1]
 +        fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,NO_TIME)
 +        fieldOnCells.setName("MyTensorFieldOnCellNoTime")
 +        fieldOnCells.setMesh(mesh)
 +        array=DataArrayDouble()
 +        array.alloc(fieldOnCells.getMesh().getNumberOfCells(),9) # Implicitely fieldOnCells will be a 9 components field.
 +        array.fillWithValue(7.)
 +        fieldOnCells.setArray(array)
 +        # fieldOnCells is now usable
 +        # ...
 +# ! [PySnippetFieldDoubleBuild1_1]
 +# ! [PySnippetFieldDoubleBuild1_2]
 +        f1=mesh.fillFromAnalytic(ON_CELLS,1,"x*x+y*y*3+2.*x") # f1 is scalar
 +        f2=mesh.fillFromAnalytic(ON_CELLS,1,"cos(x+y/x)") # f2 is scalar too
 +        f2bis=mesh.fillFromAnalytic(ON_CELLS,2,"x*x*IVec+3*y*JVec") # f2bis is a vectors field
 +        f3=f1+f2 # f3 scalar
 +        f4=f3/f2 # f4 scalar
 +        f2bis.applyFunc(1,"sqrt(x*x+y*y)") # f2bis becomes scalar
 +        f5=f2bis*f4 # f5 scalar
 +        pos1=[0.48,0.38]
 +        res=f4.getValueOn(pos1) # f4 is scalar so the returned value is of size 1.
 +        # ...
 +# ! [PySnippetFieldDoubleBuild1_2]
 +# ! [PySnippetFieldDoubleBuild1_3]
 +# ! [PySnippetFieldDoubleBuild1_3]
 +        return
 +
 +    def testExampleFieldDoubleBuild2(self):
 +        XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22];  arrX=DataArrayDouble(XCoords)
 +        YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007];  arrY=DataArrayDouble(YCoords)
 +        mesh=MEDCouplingCMesh("My2D_CMesh")
 +        mesh.setCoords(arrX,arrY)
 +# ! [PySnippetFieldDoubleBuild2_1]
 +        fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,NO_TIME)
 +        fieldOnNodes.setName("MyScalarFieldOnNodeNoTime")
 +        fieldOnNodes.setMesh(mesh)
 +        array=DataArrayDouble()
 +        array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),1) # Implicitely fieldOnNodes will be a 1 component field.
 +        array.fillWithValue(7.)
 +        fieldOnNodes.setArray(array)
 +        # fieldOnNodes is now usable
 +        # ...
 +# ! [PySnippetFieldDoubleBuild2_1]
 +        return
 +
 +    def testExampleFieldDoubleBuild3(self):
 +        XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22];  arrX=DataArrayDouble(XCoords)
 +        YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007];  arrY=DataArrayDouble(YCoords)
 +        mesh=MEDCouplingCMesh("My2D_CMesh")
 +        mesh.setCoords(arrX,arrY)
 +# ! [PySnippetFieldDoubleBuild3_1]
 +        fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME)
 +        fieldOnCells.setName("MyTensorFieldOnCellNoTime")
 +        fieldOnCells.setTimeUnit("ms") # Time unit is ms.
 +        fieldOnCells.setTime(4.22,2,-1) # Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1
 +        fieldOnCells.setMesh(mesh)
 +        array=DataArrayDouble()
 +        array.alloc(fieldOnCells.getMesh().getNumberOfCells(),2) # Implicitely fieldOnCells will be a 2 components field.
 +        array.fillWithValue(7.)
 +        fieldOnCells.setArray(array)
 +        # fieldOnCells is now usable
 +        # ...
 +# ! [PySnippetFieldDoubleBuild3_1]
 +        return
 +
 +    def testExampleFieldDoubleBuild4(self):
 +        XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22];  arrX=DataArrayDouble(XCoords)
 +        YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007];  arrY=DataArrayDouble(YCoords)
 +        mesh=MEDCouplingCMesh("My2D_CMesh")
 +        mesh.setCoords(arrX,arrY)
 +# ! [PySnippetFieldDoubleBuild4_1]
 +        fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,CONST_ON_TIME_INTERVAL)
 +        fieldOnNodes.setName("MyVecFieldOnNodeWithConstTime")
 +        fieldOnNodes.setTimeUnit("ms") # Time unit is ms.
 +        fieldOnNodes.setStartTime(4.22,2,-1)
 +        fieldOnNodes.setEndTime(6.44,4,-1)# fieldOnNodes is defined in interval [4.22 ms,6.44 ms]
 +        fieldOnNodes.setMesh(mesh)
 +        array=DataArrayDouble()
 +        array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),3) # Implicitely fieldOnNodes will be a 3 components field.
 +        array.fillWithValue(7.)
 +        fieldOnNodes.setArray(array)
 +        # fieldOnNodes is now usable
 +        # ...
 +# ! [PySnippetFieldDoubleBuild4_1]
 +        return
 +
 +    def testExampleDataArrayApplyFunc1(self):
 +# ! [PySnippetDataArrayApplyFunc1_1]
 +        d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2)
 +        self.assertRaises(InterpKernelException,d.applyFunc,"x*y")
 +# ! [PySnippetDataArrayApplyFunc1_1]
 +# ! [PySnippetDataArrayApplyFunc1_2]
 +        d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2)
 +        d1=d.applyFunc("smth*smth")
 +        self.assertTrue(d1.isEqual(DataArrayDouble([1.,4.,121.,144.,441.,484.,961.,1681.],4,2),1e-12))
 +# ! [PySnippetDataArrayApplyFunc1_2]
 +# ! [PySnippetDataArrayApplyFunc1_3]
 +        d2=d.applyFunc(2,"smth1*IVec+2*smth2*JVec")
 +        self.assertTrue(d2.isEqual(DataArrayDouble([1.,4.,11.,24.,21.,44.,31.,82.],4,2),1e-12))
 +# ! [PySnippetDataArrayApplyFunc1_3]
 +# ! [PySnippetDataArrayApplyFunc1_4]
 +        dd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3)
 +# ! [PySnippetDataArrayApplyFunc1_4]
 +# ! [PySnippetDataArrayApplyFunc1_5]
 +        dd1=dd.applyFunc(1,"f+sqrt(g)+h")
 +        self.assertTrue(dd1.isEqual(DataArrayDouble([6.,36.,66.,96.],4,1),1e-12))
 +# ! [PySnippetDataArrayApplyFunc1_5]
 +# ! [PySnippetDataArrayApplyFunc1_6]
 +        dd2=dd.applyFunc(1,"a+0.*b+c")
 +        self.assertTrue(dd2.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12))
 +# ! [PySnippetDataArrayApplyFunc1_6]
 +# ! [PySnippetDataArrayApplyFunc1_7]
 +        ddd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3)
 +        ddd.setInfoOnComponents(["Y [m]","AA [m/s]","GG [MW]"])
 +# ! [PySnippetDataArrayApplyFunc1_7]
 +# ! [PySnippetDataArrayApplyFunc1_8]
 +        ddd1=ddd.applyFunc2(1,"Y+GG")
 +        self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12))
 +# ! [PySnippetDataArrayApplyFunc1_8]
 +# ! [PySnippetDataArrayApplyFunc1_9]
 +        ddd1=ddd.applyFunc3(1,["X","Y","Z"],"X+Z")
 +        self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12))
 +# ! [PySnippetDataArrayApplyFunc1_9]
 +        return
 +
 +    pass
 +
 +unittest.main()
index cf6177bebd19549aab5fe0654c51dfa18426def3,0000000000000000000000000000000000000000..8fad6bf6ff89e36f3cc7fe4002686296848277d8
mode 100644,000000..100644
--- /dev/null
@@@ -1,1707 -1,0 +1,1707 @@@
-         throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh : the mode of mesh setting expects to follow the MED file numbering convention ! it is not the case !");
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#include "MEDFileMeshLL.hxx"
 +#include "MEDFileMesh.hxx"
 +#include "MEDLoaderBase.hxx"
 +#include "MEDFileSafeCaller.txx"
 +#include "MEDFileMeshReadSelector.hxx"
 +
 +#include "MEDCouplingUMesh.hxx"
 +
 +#include "InterpKernelAutoPtr.hxx"
 +#include "CellModel.hxx"
 +
 +#include <set>
 +
 +extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
 +extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
 +extern med_geometry_type typmainoeud[1];
 +
 +using namespace ParaMEDMEM;
 +
 +MEDFileMeshL2::MEDFileMeshL2():_name(MED_NAME_SIZE),_description(MED_COMMENT_SIZE),_univ_name(MED_LNAME_SIZE),_dt_unit(MED_LNAME_SIZE)
 +{
 +}
 +
 +std::size_t MEDFileMeshL2::getHeapMemorySizeWithoutChildren() const
 +{
 +  return 0;
 +}
 +
 +std::vector<const BigMemoryObject *> MEDFileMeshL2::getDirectChildrenWithNull() const
 +{
 +  return std::vector<const BigMemoryObject *>();
 +}
 +
 +int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const std::string& mname, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1)
 +{
 +  med_mesh_type type_maillage;
 +  char maillage_description[MED_COMMENT_SIZE+1];
 +  char dtunit[MED_LNAME_SIZE+1];
 +  med_int spaceDim,dim;
 +  char nommaa[MED_NAME_SIZE+1];
 +  med_int n=MEDnMesh(fid);
 +  bool found=false;
 +  int ret=-1;
 +  med_sorting_type stype;
 +  std::vector<std::string> ms;
 +  int nstep;
 +  med_axis_type axistype;
 +  for(int i=0;i<n && !found;i++)
 +    {
 +      int naxis(MEDmeshnAxis(fid,i+1));
 +      INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
 +      INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
 +      MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&spaceDim,&dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit));
 +      dtunit1=MEDLoaderBase::buildStringFromFortran(dtunit,sizeof(dtunit));
 +      std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa));
 +      ms.push_back(cur);
 +      if(cur==mname)
 +        {
 +          found=true;
 +          ret=i+1;
 +        }
 +    }
 +  if(!found)
 +    {
 +      std::ostringstream oss;
 +      oss << "No such meshname (" << mname <<  ") in file ! Must be in : ";
 +      std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss,", "));
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  switch(type_maillage)
 +  {
 +    case MED_UNSTRUCTURED_MESH:
 +      meshType=UNSTRUCTURED;
 +      break;
 +    case MED_STRUCTURED_MESH:
 +      {
 +        med_grid_type gt;
 +        MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mname.c_str(),&gt));
 +        switch(gt)
 +        {
 +          case MED_CARTESIAN_GRID:
 +            meshType=CARTESIAN;
 +            break;
 +          case MED_CURVILINEAR_GRID:
 +            meshType=CURVE_LINEAR;
 +            break;
 +          default:
 +            throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n");
 +        }
 +        break;
 +      }
 +    default:
 +      throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !");
 +  }
 +  med_int numdt,numit;
 +  med_float dtt;
 +  MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mname.c_str(),1,&numdt,&numit,&dtt));
 +  dt=numdt; it=numit;
 +  return ret;
 +}
 +
 +double MEDFileMeshL2::CheckMeshTimeStep(med_idt fid, const std::string& mName, int nstep, int dt, int it)
 +{
 +  bool found=false;
 +  med_int numdt,numit;
 +  med_float dtt;
 +  std::vector< std::pair<int,int> > p(nstep);
 +  for(int i=0;i<nstep;i++)
 +    {
 +      MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mName.c_str(),i+1,&numdt,&numit,&dtt));
 +      p[i]=std::make_pair(numdt,numit);
 +      found=(numdt==dt) && (numit==numit);
 +    }
 +  if(!found)
 +    {
 +      std::ostringstream oss; oss << "No such iteration=" << dt << ",order=" << it << " numbers found for mesh '" << mName << "' ! ";
 +      oss << "Possibilities are : ";
 +      for(int i=0;i<nstep;i++)
 +        oss << "(" << p[i].first << "," << p[i].second << "), ";
 +      throw INTERP_KERNEL::Exception(oss.str().c_str());
 +    }
 +  return dtt;
 +}
 +
 +std::vector<std::string> MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim)
 +{
 +  med_mesh_type type_maillage;
 +  med_int spaceDim;
 +  med_sorting_type stype;
 +  med_axis_type axistype;
 +  int naxis(MEDmeshnAxis(fid,mId));
 +  INTERP_KERNEL::AutoPtr<char> nameTmp=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
 +  INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
 +  INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
 +  INTERP_KERNEL::AutoPtr<char> univTmp=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
 +  if(MEDmeshInfo(fid,mId,nameTmp,&spaceDim,&Mdim,&type_maillage,_description.getPointer(),_dt_unit.getPointer(),
 +      &stype,&nstep,&axistype,axisname,axisunit)!=0)
 +    throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !");
 +  MEDmeshUniversalNameRd(fid,nameTmp,_univ_name.getPointer());// do not protect  MEDFILESAFECALLERRD0 call : Thanks to fra.med.
 +  switch(type_maillage)
 +  {
 +    case MED_UNSTRUCTURED_MESH:
 +      meshType=UNSTRUCTURED;
 +      break;
 +    case MED_STRUCTURED_MESH:
 +      {
 +        med_grid_type gt;
 +        MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gt));
 +        switch(gt)
 +        {
 +          case MED_CARTESIAN_GRID:
 +            meshType=CARTESIAN;
 +            break;
 +          case MED_CURVILINEAR_GRID:
 +            meshType=CURVE_LINEAR;
 +            break;
 +          default:
 +            throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getAxisInfoOnMesh : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n");
 +        }
 +        break;
 +      }
 +    default:
 +      throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !");
 +  }
 +  //
 +  std::vector<std::string> infosOnComp(naxis);
 +  for(int i=0;i<naxis;i++)
 +    {
 +      std::string info=MEDLoaderBase::buildUnionUnit(((char *)axisname)+i*MED_SNAME_SIZE,MED_SNAME_SIZE,((char *)axisunit)+i*MED_SNAME_SIZE,MED_SNAME_SIZE);
 +      infosOnComp[i]=info;
 +    }
 +  return infosOnComp;
 +}
 +
 +void MEDFileMeshL2::ReadFamiliesAndGrps(med_idt fid, const std::string& meshName, std::map<std::string,int>& fams, std::map<std::string, std::vector<std::string> >& grps, MEDFileMeshReadSelector *mrs)
 +{
 +  if(mrs && !(mrs->isCellFamilyFieldReading() || mrs->isNodeFamilyFieldReading()))
 +    return ;
 +  char nomfam[MED_NAME_SIZE+1];
 +  med_int numfam;
 +  int nfam=MEDnFamily(fid,meshName.c_str());
 +  for(int i=0;i<nfam;i++)
 +    {
 +      int ngro=MEDnFamilyGroup(fid,meshName.c_str(),i+1);
 +      med_int natt=MEDnFamily23Attribute(fid,meshName.c_str(),i+1);
 +      INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
 +      INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
 +      INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
 +      INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
 +      MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro);
 +      std::string famName=MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE);
 +      fams[famName]=numfam;
 +      for(int j=0;j<ngro;j++)
 +        {
 +          std::string groupname=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
 +          grps[groupname].push_back(famName);
 +        }
 +    }
 +}
 +
 +void MEDFileMeshL2::WriteFamiliesAndGrps(med_idt fid, const std::string& mname, const std::map<std::string,int>& fams, const std::map<std::string, std::vector<std::string> >& grps, int tooLongStrPol)
 +{
 +  for(std::map<std::string,int>::const_iterator it=fams.begin();it!=fams.end();it++)
 +    {
 +      std::vector<std::string> grpsOfFam;
 +      for(std::map<std::string, std::vector<std::string> >::const_iterator it1=grps.begin();it1!=grps.end();it1++)
 +        {
 +          if(std::find((*it1).second.begin(),(*it1).second.end(),(*it).first)!=(*it1).second.end())
 +            grpsOfFam.push_back((*it1).first);
 +        }
 +      int ngro=grpsOfFam.size();
 +      INTERP_KERNEL::AutoPtr<char> groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro);
 +      int i=0;
 +      for(std::vector<std::string>::const_iterator it2=grpsOfFam.begin();it2!=grpsOfFam.end();it2++,i++)
 +        MEDLoaderBase::safeStrCpy2((*it2).c_str(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,tooLongStrPol);
 +      INTERP_KERNEL::AutoPtr<char> famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
 +      MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_NAME_SIZE,famName,tooLongStrPol);
 +      int ret=MEDfamilyCr(fid,mname.c_str(),famName,(*it).second,ngro,groName);
 +      ret++;
 +    }
 +}
 +
 +MEDFileUMeshL2::MEDFileUMeshL2()
 +{
 +}
 +
 +std::vector<std::string> MEDFileUMeshL2::loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim)
 +{
 +  Mdim=-3;
 +  _name.set(mName.c_str());
 +  int nstep;
 +  ParaMEDMEM::MEDCouplingMeshType meshType;
 +  std::vector<std::string> ret(getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim));
 +  if(nstep==0)
 +    {
 +      Mdim=-4;
 +      return std::vector<std::string>();
 +    }
 +  if(meshType!=UNSTRUCTURED)
 +    throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !");
 +  _time=CheckMeshTimeStep(fid,mName,nstep,dt,it);
 +  _iteration=dt;
 +  _order=it;
 +  return ret;
 +}
 +
 +void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 +{
 +  int Mdim;
 +  std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
 +  if(Mdim==-4)
 +    return ;
 +  loadConnectivity(fid,Mdim,mName,dt,it,mrs);//to improve check (dt,it) coherency
 +  loadCoords(fid,mId,infosOnComp,mName,dt,it);
 +}
 +
 +void MEDFileUMeshL2::loadPart(med_idt fid, int mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 +{
 +  int Mdim;
 +  std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
 +  if(Mdim==-4)
 +    return ;
 +  loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs);
 +  med_bool changement,transformation;
 +  int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
 +  std::vector<bool> fetchedNodeIds(nCoords,false);
 +  for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
 +    for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
 +      (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds);
 +  int nMin(std::distance(fetchedNodeIds.begin(),std::find(fetchedNodeIds.begin(),fetchedNodeIds.end(),true)));
 +  int nMax(std::distance(fetchedNodeIds.rbegin(),std::find(fetchedNodeIds.rbegin(),fetchedNodeIds.rend(),true)));
 +  nMax=nCoords-nMax;
 +  for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
 +    for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
 +      (*it1)->getMesh()->renumberNodesWithOffsetInConn(-nMin);
 +  loadPartCoords(fid,mId,infosOnComp,mName,dt,it,nMin,nMax);
 +}
 +
 +void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 +{
 +  _per_type_mesh.resize(1);
 +  _per_type_mesh[0].clear();
 +  for(int j=0;j<MED_N_CELL_FIXED_GEO;j++)
 +    {
 +      MEDFileUMeshPerType *tmp(MEDFileUMeshPerType::New(fid,mName.c_str(),dt,it,mdim,typmai[j],typmai2[j],mrs));
 +      if(tmp)
 +        _per_type_mesh[0].push_back(tmp);
 +    }
 +  sortTypes();
 +}
 +
 +void MEDFileUMeshL2::loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 +{
 +  std::size_t nbOfTypes(types.size());
 +  if(slicPerTyp.size()!=3*nbOfTypes)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : The size of slicPerTyp array is expected to be equal to 3 times size of array types !");
 +  std::set<INTERP_KERNEL::NormalizedCellType> types2(types.begin(),types.end());
 +  if(types2.size()!=nbOfTypes)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : the geometric types in types array must appear once !");
 +  _per_type_mesh.resize(1);
 +  _per_type_mesh[0].clear();
 +  for(std::size_t ii=0;ii<nbOfTypes;ii++)
 +    {
 +      int strt(slicPerTyp[3*ii+0]),stp(slicPerTyp[3*ii+1]),step(slicPerTyp[3*ii+2]);
 +      MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,types[ii],strt,stp,step,mrs));
 +      _per_type_mesh[0].push_back(tmp);
 +    }
 +  sortTypes();
 +}
 +
 +void MEDFileUMeshL2::loadCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it)
 +{
 +  int spaceDim((int)infosOnComp.size());
 +  med_bool changement,transformation;
 +  int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
 +  _coords=DataArrayDouble::New();
 +  _coords->alloc(nCoords,spaceDim);
 +  double *coordsPtr(_coords->getPointer());
 +  if (nCoords)
 +    MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,coordsPtr));
 +  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
 +    {
 +      _fam_coords=DataArrayInt::New();
 +      _fam_coords->alloc(nCoords,1);
 +      MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_fam_coords->getPointer()));
 +    }
 +  else
 +    _fam_coords=0;
 +  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
 +    {
 +      _num_coords=DataArrayInt::New();
 +      _num_coords->alloc(nCoords,1);
 +      MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_num_coords->getPointer()));
 +    }
 +  else
 +    _num_coords=0;
 +  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0)
 +    {
 +      _name_coords=DataArrayAsciiChar::New();
 +      _name_coords->alloc(nCoords+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
 +      MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_name_coords->getPointer()));
 +      _name_coords->reAlloc(nCoords);//not a bug to avoid the memory corruption due to last \0 at the end
 +    }
 +  else
 +    _name_coords=0;
 +  for(int i=0;i<spaceDim;i++)
 +    _coords->setInfoOnComponent(i,infosOnComp[i]);
 +}
 +
 +void MEDFileUMeshL2::loadPartCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax)
 +{
 +  med_bool changement,transformation;
 +  int spaceDim((int)infosOnComp.size()),nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
 +  _coords=DataArrayDouble::New();
 +  int nbNodesToLoad(nMax-nMin);
 +  _coords->alloc(nbNodesToLoad,spaceDim);
 +  med_filter filter=MED_FILTER_INIT,filter2=MED_FILTER_INIT;
 +  MEDfilterBlockOfEntityCr(fid,/*nentity*/nCoords,/*nvaluesperentity*/1,/*nconstituentpervalue*/spaceDim,
 +                           MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
 +                           /*start*/nMin+1,/*stride*/1,/*count*/1,/*blocksize*/nbNodesToLoad,
 +                           /*lastblocksize=useless because count=1*/0,&filter);
 +  MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateAdvancedRd,(fid,mName.c_str(),dt,it,&filter,_coords->getPointer()));
 +  _part_coords=PartDefinition::New(nMin,nMax,1);
 +  MEDfilterClose(&filter);
 +  MEDfilterBlockOfEntityCr(fid,nCoords,1,1,MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,
 +                           MED_NO_PROFILE,nMin+1,1,1,nbNodesToLoad,0,&filter2);
 +  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
 +    {
 +      _fam_coords=DataArrayInt::New();
 +      _fam_coords->alloc(nbNodesToLoad,1);
 +      MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_FAMILY_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_fam_coords->getPointer()));
 +    }
 +  else
 +    _fam_coords=0;
 +  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
 +    {
 +      _num_coords=DataArrayInt::New();
 +      _num_coords->alloc(nbNodesToLoad,1);
 +      MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_num_coords->getPointer()));
 +    }
 +  else
 +    _num_coords=0;
 +  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0)
 +    {
 +      _name_coords=DataArrayAsciiChar::New();
 +      _name_coords->alloc(nbNodesToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
 +      MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NAME,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_name_coords->getPointer()));
 +      _name_coords->reAlloc(nbNodesToLoad);//not a bug to avoid the memory corruption due to last \0 at the end
 +    }
 +  else
 +    _name_coords=0;
 +  MEDfilterClose(&filter2);
 +  _coords->setInfoOnComponents(infosOnComp);
 +}
 +
 +void MEDFileUMeshL2::sortTypes()
 +{
 +  std::set<int> mdims;
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > tmp(_per_type_mesh[0]);
 +  _per_type_mesh.clear();
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++)
 +    mdims.insert((*it)->getDim());
 +  if(mdims.empty())
 +    return;
 +  int mdim=*mdims.rbegin();
 +  _per_type_mesh.resize(mdim+1);
 +  for(int dim=mdim+1;dim!=0;dim--)
 +    {
 +      std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& elt=_per_type_mesh[mdim+1-dim];
 +      for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++)
 +        if((*it)->getDim()==dim-1)
 +          elt.push_back(*it);
 +    }
 +  // suppression of contiguous empty levels at the end of _per_type_mesh.
 +  int nbOfUselessLev=0;
 +  bool isFirst=true;
 +  for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::reverse_iterator it2=_per_type_mesh.rbegin();it2!=_per_type_mesh.rend();it2++)
 +    {
 +      if((*it2).empty() && isFirst)
 +        {
 +          nbOfUselessLev++;
 +        }
 +      else
 +        isFirst=false;
 +    }
 +  _per_type_mesh.resize(_per_type_mesh.size()-nbOfUselessLev);
 +}
 +
 +void MEDFileUMeshL2::WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords)
 +{
 +  if(!coords)
 +    return ;
 +  MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,mname.c_str(),dt,it,time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->getConstPointer()));
 +  if(famCoords)
 +    MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,famCoords->getNumberOfTuples(),famCoords->getConstPointer()));
 +  if(numCoords)
 +    MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,numCoords->getNumberOfTuples(),numCoords->getConstPointer()));
 +  if(nameCoords)
 +    {
 +      if(nameCoords->getNumberOfComponents()!=MED_SNAME_SIZE)
 +        {
 +          std::ostringstream oss; oss << " MEDFileUMeshL2::WriteCoords : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
 +          oss << " ! The array has " << nameCoords->getNumberOfComponents() << " components !";
 +          throw INTERP_KERNEL::Exception(oss.str().c_str());
 +        }
 +      MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,nameCoords->getNumberOfTuples(),nameCoords->getConstPointer()));
 +    }
 +}
 +
 +bool MEDFileUMeshL2::isFamDefinedOnLev(int levId) const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
 +    if((*it)->getFam()==0)
 +      return false;
 +  return true;
 +}
 +
 +bool MEDFileUMeshL2::isNumDefinedOnLev(int levId) const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
 +    if((*it)->getNum()==0)
 +      return false;
 +  return true;
 +}
 +
 +bool MEDFileUMeshL2::isNamesDefinedOnLev(int levId) const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
 +    if((*it)->getNames()==0)
 +      return false;
 +  return true;
 +}
 +
 +MEDFileCMeshL2::MEDFileCMeshL2()
 +{
 +}
 +
 +void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it)
 +{
 +  _name.set(mName.c_str());
 +  int nstep;
 +  int Mdim;
 +  ParaMEDMEM::MEDCouplingMeshType meshType;
 +  std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim);
 +  if(meshType!=CARTESIAN)
 +    throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !");
 +  _time=CheckMeshTimeStep(fid,mName,nstep,dt,it);
 +  _iteration=dt;
 +  _order=it;
 +  //
 +  med_grid_type gridtype;
 +  MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gridtype));
 +  if(gridtype!=MED_CARTESIAN_GRID)
 +    throw INTERP_KERNEL::Exception("Invalid structured mesh ! Expected cartesian mesh type !");
 +  _cmesh=MEDCouplingCMesh::New();
 +  for(int i=0;i<Mdim;i++)
 +    {
 +      med_data_type dataTypeReq=GetDataTypeCorrespondingToSpaceId(i);
 +      med_bool chgt=MED_FALSE,trsf=MED_FALSE;
 +      int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,dataTypeReq,MED_NO_CMODE,&chgt,&trsf));
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> da=DataArrayDouble::New();
 +      da->alloc(nbOfElt,1);
 +      da->setInfoOnComponent(0,infosOnComp[i]);
 +      MEDFILESAFECALLERRD0(MEDmeshGridIndexCoordinateRd,(fid,mName.c_str(),dt,it,i+1,da->getPointer()));
 +      _cmesh->setCoordsAt(i,da);
 +    }
 +}
 +
 +med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id)
 +{
 +  switch(id)
 +  {
 +    case 0:
 +      return MED_COORDINATE_AXIS1;
 +    case 1:
 +      return MED_COORDINATE_AXIS2;
 +    case 2:
 +      return MED_COORDINATE_AXIS3;
 +    default:
 +      throw INTERP_KERNEL::Exception("Invalid meshdim detected in Cartesian Grid !");
 +  }
 +}
 +
 +MEDFileCLMeshL2::MEDFileCLMeshL2()
 +{
 +}
 +
 +void MEDFileCLMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it)
 +{
 +  _name.set(mName.c_str());
 +  int nstep;
 +  int Mdim;
 +  ParaMEDMEM::MEDCouplingMeshType meshType;
 +  std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim);
 +  if(meshType!=CURVE_LINEAR)
 +    throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !");
 +  _time=CheckMeshTimeStep(fid,mName,nstep,dt,it);
 +  _iteration=dt;
 +  _order=it;
 +  //
 +  _clmesh=MEDCouplingCurveLinearMesh::New();
 +  INTERP_KERNEL::AutoPtr<int> stGrid=new int[Mdim];
 +  MEDFILESAFECALLERRD0(MEDmeshGridStructRd,(fid,mName.c_str(),dt,it,stGrid));
 +  _clmesh->setNodeGridStructure(stGrid,((int *)stGrid)+Mdim);
 +  med_bool chgt=MED_FALSE,trsf=MED_FALSE;
 +  int nbNodes(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&chgt,&trsf));
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> da=DataArrayDouble::New();
 +  da->alloc(nbNodes,infosOnComp.size());
 +  da->setInfoOnComponents(infosOnComp);
 +  MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,da->getPointer()));
 +  _clmesh->setCoords(da);
 +}
 +
 +MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0)
 +{
 +}
 +
 +/*!
 + * Warning it returns an instance to deallocate !!!!
 + */
 +MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const
 +{
 +  _st->_num->updateTime();
 +  if((MEDCouplingUMesh *)_m==0)
 +    {
 +      updateTime();
 +      _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types.getUmesh()->deepCpy());
 +      _m->renumberCells(_st->_num->getConstPointer(),true);
 +      return _m.retn();
 +    }
 +  else
 +    {
 +      if(_mpt_time==_st->_m_by_types.getTimeOfThis() && _num_time==_st->_num->getTimeOfThis())
 +        return _m.retn();
 +      else
 +        {
 +          updateTime();
 +          _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types.getUmesh()->deepCpy());
 +          _m->renumberCells(_st->_num->getConstPointer(),true);
 +          return _m.retn();
 +        }
 +    }
 +}
 +
 +void MEDFileUMeshPermCompute::operator=(MEDCouplingUMesh *m)
 +{
 +  _m=m;
 +}
 +
 +void MEDFileUMeshPermCompute::updateTime() const
 +{
 +  _mpt_time=_st->_m_by_types.getTimeOfThis();
 +  _num_time=_st->_num->getTimeOfThis();
 +}
 +
 +std::vector<const BigMemoryObject *> MEDFileUMeshPermCompute::getDirectChildrenWithNull() const
 +{
 +  std::vector<const BigMemoryObject *> ret;
 +  ret.push_back((const MEDCouplingUMesh *)_m);
 +  return ret;
 +}
 +
 +std::size_t MEDFileUMeshPermCompute::getHeapMemorySizeWithoutChildren() const
 +{
 +  return sizeof(MEDFileUMeshPermCompute);
 +}
 +
 +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other):RefCountObject(other),_m_by_types(other._m_by_types),_fam(other._fam),_num(other._num),_names(other._names),_rev_num(other._rev_num),_m(this)
 +{
 +}
 +
 +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id):_m(this)
 +{
 +  const std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& v=l2.getLev(id);
 +  if(v.empty())
 +    return;
 +  int sz=v.size();
 +  std::vector<const MEDCoupling1GTUMesh *> ms(sz);
 +  std::vector<const DataArrayInt *> fams(sz),nums(sz);
 +  std::vector<const DataArrayChar *> names(sz);
 +  std::vector<const PartDefinition *> pds(sz);
 +  for(int i=0;i<sz;i++)
 +    {
 +      MEDCoupling1GTUMesh *elt(v[i]->getMesh());
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=l2.getCoords();
 +      elt->setCoords(tmp2);
 +      ms[i]=elt;
 +      pds[i]=v[i]->getPartDef();
 +    }
 +  _m_by_types.assignParts(ms);
 +  _m_by_types.assignDefParts(pds);
 +  if(l2.isFamDefinedOnLev(id))
 +    {
 +      for(int i=0;i<sz;i++)
 +        fams[i]=v[i]->getFam();
 +      if(sz!=1)
 +        _fam=DataArrayInt::Aggregate(fams);
 +      else
 +        {
 +          fams[0]->incrRef();
 +          _fam=const_cast<DataArrayInt *>(fams[0]);
 +        }
 +    }
 +  if(l2.isNumDefinedOnLev(id))
 +    {
 +      for(int i=0;i<sz;i++)
 +        nums[i]=v[i]->getNum();
 +      if(sz!=1)
 +        _num=DataArrayInt::Aggregate(nums);
 +      else
 +        {
 +          nums[0]->incrRef();
 +          _num=const_cast<DataArrayInt *>(nums[0]);
 +        }
 +      computeRevNum();
 +    }
 +  if(l2.isNamesDefinedOnLev(id))
 +    {
 +      for(int i=0;i<sz;i++)
 +        names[i]=v[i]->getNames();
 +      _names=dynamic_cast<DataArrayAsciiChar *>(DataArrayChar::Aggregate(names));
 +    }
 +}
 +
 +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m):_m(this)
 +{
 +  std::vector< const MEDCoupling1GTUMesh * > v(1);
 +  v[0]=m;
 +  assignParts(v);
 +}
 +
 +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m):_m(this)
 +{
 +  assignMesh(m,true);
 +}
 +
 +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m(this)
 +{
 +  assignMesh(m,newOrOld);
 +}
 +
 +void MEDFileUMeshSplitL1::setName(const std::string& name)
 +{
 +  _m_by_types.setName(name);
 +}
 +
 +std::size_t MEDFileUMeshSplitL1::getHeapMemorySizeWithoutChildren() const
 +{
 +  return 0;
 +}
 +
 +std::vector<const BigMemoryObject *> MEDFileUMeshSplitL1::getDirectChildrenWithNull() const
 +{
 +  std::vector<const BigMemoryObject *> ret;
 +  ret.push_back(&_m_by_types);
 +  ret.push_back(&_m);
 +  ret.push_back((const DataArrayInt*)_fam);
 +  ret.push_back((const DataArrayInt*)_num);
 +  ret.push_back((const DataArrayInt*)_rev_num);
 +  ret.push_back((const DataArrayAsciiChar*)_names);
 +  return ret;
 +}
 +
 +MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::deepCpy(DataArrayDouble *coords) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> ret=new MEDFileUMeshSplitL1(*this);
 +  ret->_m_by_types=_m_by_types.deepCpy(coords);
 +  if((const DataArrayInt *)_fam)
 +    ret->_fam=_fam->deepCpy();
 +  if((const DataArrayInt *)_num)
 +    ret->_num=_num->deepCpy();
 +  if((const DataArrayInt *)_rev_num)
 +    ret->_rev_num=_rev_num->deepCpy();
 +  if((const DataArrayAsciiChar *)_names)
 +    ret->_names=_names->deepCpy();
 +  return ret.retn();
 +}
 +
 +bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const
 +{
 +  if(!_m_by_types.isEqual(other->_m_by_types,eps,what))
 +    return false;
 +  const DataArrayInt *d1=_fam;
 +  const DataArrayInt *d2=other->_fam;
 +  if((d1==0 && d2!=0) || (d1!=0 && d2==0))
 +    {
 +      what="Presence of family arr in one sublevel and not in other!";
 +      return false;
 +    }
 +  if(d1)
 +    if(!d1->isEqual(*d2))
 +      {
 +        what="family arr at a sublevel are not deeply equal !";
 +        return false;
 +      }
 +  d1=_num;
 +  d2=other->_num;
 +  if((d1==0 && d2!=0) || (d1!=0 && d2==0))
 +    {
 +      what="Presence of cell numbering arr in one sublevel and not in other!";
 +      return false;
 +    }
 +  if(d1)
 +    if(!d1->isEqual(*d2))
 +      {
 +        what="Numbering cell arr at a sublevel are not deeply equal !";
 +        return false;
 +      }
 +  const DataArrayAsciiChar *e1=_names;
 +  const DataArrayAsciiChar *e2=other->_names;
 +  if((e1==0 && e2!=0) || (e1!=0 && e2==0))
 +    {
 +      what="Presence of cell names arr in one sublevel and not in other!";
 +      return false;
 +    }
 +  if(e1)
 +    if(!e1->isEqual(*e2))
 +      {
 +        what="Name cell arr at a sublevel are not deeply equal !";
 +        return false;
 +      }
 +  return true;
 +}
 +
 +void MEDFileUMeshSplitL1::synchronizeTinyInfo(const MEDFileMesh& master) const
 +{
 +  _m_by_types.synchronizeTinyInfo(master);
 +}
 +
 +void MEDFileUMeshSplitL1::clearNonDiscrAttributes() const
 +{
 +  _m_by_types.clearNonDiscrAttributes();
 +}
 +
 +void MEDFileUMeshSplitL1::ClearNonDiscrAttributes(const MEDCouplingMesh *tmp)
 +{
 +  if(!tmp)
 +    return ;
 +  (const_cast<MEDCouplingMesh *>(tmp))->setName("");
 +  (const_cast<MEDCouplingMesh *>(tmp))->setDescription("");
 +  (const_cast<MEDCouplingMesh *>(tmp))->setTime(0.,-1,-1);
 +  (const_cast<MEDCouplingMesh *>(tmp))->setTimeUnit("");
 +}
 +
 +void MEDFileUMeshSplitL1::setCoords(DataArrayDouble *coords)
 +{
 +  _m_by_types.setCoords(coords);
 +}
 +
 +void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld)
 +{
 +  if(newOrOld)
 +    {
 +      m->incrRef();
 +      _m=m;
 +      _m_by_types.assignUMesh(dynamic_cast<MEDCouplingUMesh *>(m->deepCpy()));
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=_m_by_types.getUmesh()->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO);
 +      if(!da->isIdentity())
 +        {
 +          _num=da->invertArrayO2N2N2O(m->getNumberOfCells());
 +          _m.updateTime();
 +          computeRevNum();
 +          _m_by_types.getUmesh()->renumberCells(da->getConstPointer(),false);
 +        }
 +    }
 +  else
 +    {
 +      if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO))
++        throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh(): the mesh does not follow the MED file numbering convention! Invoke sortCellsInMEDFileFrmt() first!");
 +      m->incrRef();
 +      _m_by_types.assignUMesh(m);
 +    }
 +  assignCommonPart();
 +}
 +
 +void MEDFileUMeshSplitL1::forceComputationOfParts() const
 +{
 +  _m_by_types.forceComputationOfPartsFromUMesh();
 +}
 +
 +void MEDFileUMeshSplitL1::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts)
 +{
 +  _m_by_types.assignParts(mParts);
 +  assignCommonPart();
 +}
 +
 +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1():_m(this)
 +{
 +}
 +
 +void MEDFileUMeshSplitL1::assignCommonPart()
 +{
 +  _fam=DataArrayInt::New();
 +  _fam->alloc(_m_by_types.getSize(),1);
 +  _fam->fillWithValue(0);
 +}
 +
 +bool MEDFileUMeshSplitL1::empty() const
 +{
 +  return _m_by_types.empty();
 +}
 +
 +bool MEDFileUMeshSplitL1::presenceOfOneFams(const std::vector<int>& ids) const
 +{
 +  const DataArrayInt *fam=_fam;
 +  if(!fam)
 +    return false;
 +  return fam->presenceOfValue(ids);
 +}
 +
 +int MEDFileUMeshSplitL1::getMeshDimension() const
 +{
 +  return _m_by_types.getMeshDimension();
 +}
 +
 +void MEDFileUMeshSplitL1::simpleRepr(std::ostream& oss) const
 +{
 +  std::vector<int> code=_m_by_types.getDistributionOfTypes();
 +  int nbOfTypes=code.size()/3;
 +  for(int i=0;i<nbOfTypes;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType) code[3*i];
 +      oss << "    - Number of cells with type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr() << " : " << code[3*i+1] << std::endl;
 +    }
 +}
 +
 +int MEDFileUMeshSplitL1::getSize() const
 +{
 +  return _m_by_types.getSize();
 +}
 +
 +MEDCouplingUMesh *MEDFileUMeshSplitL1::getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsToKeep=_fam->getIdsEqualList(idsBg,idsEnd);
 +  MEDCouplingUMesh *m=(MEDCouplingUMesh *)_m_by_types.getUmesh()->buildPartOfMySelf(eltsToKeep->getConstPointer(),eltsToKeep->getConstPointer()+eltsToKeep->getNumberOfTuples(),true);
 +  if(renum)
 +    return renumIfNeeded(m,eltsToKeep->getConstPointer());
 +  return m;
 +}
 +
 +DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=_fam->getIdsEqualList(idsBg,idsEnd);
 +  if(renum)
 +    return renumIfNeededArr(da);
 +  return da.retn();
 +}
 +
 +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshSplitL1::getGeoTypes() const
 +{
 +  return _m_by_types.getGeoTypes();
 +}
 +
 +MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp;
 +  if(renum && ((const DataArrayInt *)_num))
 +    tmp=_m;
 +  else
 +    { tmp=_m_by_types.getUmesh(); if(tmp) tmp->incrRef(); }
 +  return tmp.retn();
 +}
 +
 +int MEDFileUMeshSplitL1::getNumberOfCells() const
 +{
 +  return _m_by_types.getNumberOfCells();
 +}
 +
 +DataArrayInt *MEDFileUMeshSplitL1::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
 +{
 +  const DataArrayInt *fam(_fam);
 +  if(!fam)
 +    return 0;
 +  int start(0),stop(0);
 +  _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop);
 +  return fam->selectByTupleId2(start,stop,1);
 +}
 +
 +DataArrayInt *MEDFileUMeshSplitL1::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
 +{
 +  const DataArrayInt *num(_num);
 +  if(!num)
 +    return 0;
 +  int start(0),stop(0);
 +  _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop);
 +  return num->selectByTupleId2(start,stop,1);
 +}
 +
 +DataArrayInt *MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField()
 +{
 +  if((DataArrayInt *)_fam)
 +    return _fam;
 +  int nbOfTuples=_m_by_types.getSize();
 +  _fam=DataArrayInt::New(); _fam->alloc(nbOfTuples,1); _fam->fillWithZero();
 +  return _fam;
 +}
 +
 +const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const
 +{
 +  return _fam;
 +}
 +
 +const DataArrayInt *MEDFileUMeshSplitL1::getNumberField() const
 +{
 +  return _num;
 +}
 +
 +const DataArrayInt *MEDFileUMeshSplitL1::getRevNumberField() const
 +{
 +  return _rev_num;
 +}
 +
 +const DataArrayAsciiChar *MEDFileUMeshSplitL1::getNameField() const
 +{
 +  return _names;
 +}
 +
 +const PartDefinition *MEDFileUMeshSplitL1::getPartDef(INTERP_KERNEL::NormalizedCellType gt) const
 +{
 +  return _m_by_types.getPartDefOfWithoutComputation(gt);
 +}
 +
 +void MEDFileUMeshSplitL1::eraseFamilyField()
 +{
 +  _fam->fillWithZero();
 +}
 +
 +/*!
 + * This method ignores _m and _m_by_types.
 + */
 +void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vector<const MEDCouplingUMesh *>& ms, std::map<std::string,int>& familyIds,
 +                                               std::map<std::string, std::vector<std::string> >& groups)
 +{
 +  std::vector< DataArrayInt * > corr;
 +  _m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,0,corr);
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corrMSafe(corr.begin(),corr.end());
 +  std::vector< std::vector<int> > fidsOfGroups;
 +  std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end());
 +  _fam=DataArrayInt::MakePartition(corr2,((MEDCouplingUMesh *)_m)->getNumberOfCells(),fidsOfGroups);
 +  int nbOfCells=((MEDCouplingUMesh *)_m)->getNumberOfCells();
 +  std::map<int,std::string> newfams;
 +  std::map<int,int> famIdTrad;
 +  TraduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams);
 +  int *w=_fam->getPointer();
 +  for(int i=0;i<nbOfCells;i++,w++)
 +    *w=famIdTrad[*w];
 +}
 +
 +void MEDFileUMeshSplitL1::write(med_idt fid, const std::string& mName, int mdim) const
 +{
 +  std::vector<MEDCoupling1GTUMesh *> ms(_m_by_types.getParts());
 +  int start=0;
 +  for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
 +    {
 +      int nbCells=(*it)->getNumberOfCells();
 +      int end=start+nbCells;
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam,num;
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> names;
 +      if((const DataArrayInt *)_fam)
 +        fam=_fam->substr(start,end);
 +      if((const DataArrayInt *)_num)
 +        num=_num->substr(start,end);
 +      if((const DataArrayAsciiChar *)_names)
 +        names=static_cast<DataArrayAsciiChar *>(_names->substr(start,end));
 +      MEDFileUMeshPerType::Write(fid,mName,mdim,(*it),fam,num,names);
 +      start=end;
 +    }
 +}
 +
 +void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N)
 +{
 +  _m_by_types.renumberNodesInConnWithoutComputation(newNodeNumbersO2N);
 +}
 +
 +void MEDFileUMeshSplitL1::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const
 +{
 +  bigArraysI.push_back(_fam);
 +  bigArraysI.push_back(_num);
 +  _m_by_types.serialize(tinyInt,bigArraysI);
 +}
 +
 +void MEDFileUMeshSplitL1::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI)
 +{
 +  _fam=bigArraysI.back(); bigArraysI.pop_back();
 +  _num=bigArraysI.back(); bigArraysI.pop_back();
 +  _m_by_types.unserialize(name,coo,tinyInt,bigArraysI);
 +}
 +
 +void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId)
 +{
 +  DataArrayInt *arr=_fam;
 +  if(arr)
 +    arr->changeValue(oldId,newId);
 +}
 +
 +void MEDFileUMeshSplitL1::setFamilyArr(DataArrayInt *famArr)
 +{
 +  if(!famArr)
 +    {
 +      _fam=0;
 +      return ;
 +    }
 +  int sz(_m_by_types.getSize());
 +  famArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setFamilyArr : Problem in size of Family arr ! ");
 +  famArr->incrRef();
 +  _fam=famArr;
 +}
 +
 +DataArrayInt *MEDFileUMeshSplitL1::getFamilyField()
 +{
 +  return _fam;
 +}
 +
 +void MEDFileUMeshSplitL1::setRenumArr(DataArrayInt *renumArr)
 +{
 +  if(!renumArr)
 +    {
 +      _num=0;
 +      _rev_num=0;
 +      return ;
 +    }
 +  int sz(_m_by_types.getSize());
 +  renumArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setRenumArr : Problem in size of numbering arr ! ");
 +  renumArr->incrRef();
 +  _num=renumArr;
 +  computeRevNum();
 +}
 +
 +void MEDFileUMeshSplitL1::setNameArr(DataArrayAsciiChar *nameArr)
 +{
 +  if(!nameArr)
 +    {
 +      _names=0;
 +      return ;
 +    }
 +  int sz(_m_by_types.getSize());
 +  nameArr->checkNbOfTuplesAndComp(sz,MED_SNAME_SIZE,"MEDFileUMeshSplitL1::setNameArr : Problem in size of name arr ! ");
 +  nameArr->incrRef();
 +  _names=nameArr;
 +}
 +
 +MEDCouplingUMesh *MEDFileUMeshSplitL1::Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds)
 +{
 +  if(renum==0)
 +    return m;
 +  if(cellIds==0)
 +    m->renumberCells(renum->getConstPointer(),true);
 +  else
 +    {
 +      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> locnum=renum->selectByTupleId(cellIds,cellIds+m->getNumberOfCells());
 +      m->renumberCells(locnum->getConstPointer(),true);
 +    }
 +  return m;
 +}
 +
 +MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::Unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI)
 +{
 +  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> ret(new MEDFileUMeshSplitL1);
 +  ret->unserialize(name,coo,tinyInt,bigArraysI);
 +  return ret.retn();
 +}
 +
 +MEDCouplingUMesh *MEDFileUMeshSplitL1::renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const
 +{
 +  return Renumber2(_num,m,cellIds);
 +}
 +
 +DataArrayInt *MEDFileUMeshSplitL1::Renumber(const DataArrayInt *renum, const DataArrayInt *da)
 +{
 +  if((const DataArrayInt *)renum==0)
 +    {
 +      da->incrRef();
 +      return const_cast<DataArrayInt *>(da);
 +    }
 +  return renum->selectByTupleId(da->getConstPointer(),da->getConstPointer()+da->getNumberOfTuples());
 +}
 +
 +DataArrayInt *MEDFileUMeshSplitL1::renumIfNeededArr(const DataArrayInt *da) const
 +{
 +  return Renumber(_num,da);
 +}
 +
 +std::vector<int> MEDFileUMeshSplitL1::GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families)
 +{
 +  int id=-1;
 +  for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++)
 +    id=std::max(id,(*it).second);
 +  if(id==-1)
 +    id=0;
 +  std::vector<int> ret(nb);
 +  for(int i=1;i<=nb;i++)
 +    ret[i]=id+i;
 +  return ret;
 +}
 +
 +void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds,
 +                                              std::map<int,int>& famIdTrad, std::map<int,std::string>& newfams)
 +{
 +  std::set<int> allfids;
 +  //tony
 +}
 +
 +void MEDFileUMeshSplitL1::computeRevNum() const
 +{
 +  int pos;
 +  int maxValue=_num->getMaxValue(pos);
 +  _rev_num=_num->invertArrayN2O2O2N(maxValue+1);
 +}
 +
 +//=
 +
 +MEDFileUMeshAggregateCompute::MEDFileUMeshAggregateCompute():_mp_time(0),_m_time(0)
 +{
 +}
 +
 +void MEDFileUMeshAggregateCompute::setName(const std::string& name)
 +{
 +  if(_m_time>=_mp_time)
 +    {
 +      MEDCouplingUMesh *um(_m);
 +      if(um)
 +        um->setName(name);
 +    }
 +  if(_mp_time>=_m_time)
 +    {
 +      for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +        {
 +          MEDCoupling1GTUMesh *tmp(*it);
 +          if(tmp)
 +            tmp->setName(name);
 +        }
 +    }
 +}
 +
 +void MEDFileUMeshAggregateCompute::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts)
 +{
 +  std::size_t sz(mParts.size());
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> > ret(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const MEDCoupling1GTUMesh *elt(mParts[i]);
 +      if(!elt)
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignParts : presence of null pointer !");
 +      ret[i]=const_cast<MEDCoupling1GTUMesh *>(elt); elt->incrRef();
 +    }
 +  _m_parts=ret;
 +  _part_def.clear(); _part_def.resize(sz);
 +  _mp_time=std::max(_mp_time,_m_time)+1;
 +  _m=0;
 +}
 +
 +void MEDFileUMeshAggregateCompute::assignDefParts(const std::vector<const PartDefinition *>& partDefs)
 +{
 +  if(_mp_time<_m_time)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : the parts require a computation !");
 +  std::size_t sz(partDefs.size());
 +  if(_part_def.size()!=partDefs.size() || _part_def.size()!=_m_parts.size())
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : sizes of vectors of part definition mismatch !");
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const PartDefinition *elt(partDefs[i]);
 +      if(elt)
 +        elt->incrRef();
 +      _part_def[i]=const_cast<PartDefinition*>(elt);
 +    }
 +}
 +
 +void MEDFileUMeshAggregateCompute::assignUMesh(MEDCouplingUMesh *m)
 +{
 +  _m=m;
 +  _m_parts.clear();
 +  _m_time=std::max(_mp_time,_m_time)+1;
 +}
 +
 +MEDCouplingUMesh *MEDFileUMeshAggregateCompute::getUmesh() const
 +{
 +  if(_mp_time<=_m_time)
 +    return _m;
 +  std::vector< const MEDCoupling1GTUMesh *> mp(_m_parts.size());
 +  std::copy(_m_parts.begin(),_m_parts.end(),mp.begin());
 +  _m=MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(mp);
 +  _m_parts.clear();//to avoid memory peak !
 +  _m_time=_mp_time+1;//+1 is important ! That is to say that only _m is OK not _m_parts because cleared !
 +  return _m;
 +}
 +
 +int MEDFileUMeshAggregateCompute::getNumberOfCells() const
 +{
 +  if(_mp_time<=_m_time)
 +    return _m->getNumberOfCells();
 +  int ret(0);
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +    ret+=(*it)->getNumberOfCells();
 +  return ret;
 +}
 +
 +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshAggregateCompute::getGeoTypes() const
 +{
 +  if(_mp_time>=_m_time)
 +    {
 +      std::size_t sz(_m_parts.size());
 +      std::vector<INTERP_KERNEL::NormalizedCellType> ret(sz);
 +      for(std::size_t i=0;i<sz;i++)
 +        ret[i]=_m_parts[i]->getCellModelEnum();
 +      return ret;
 +    }
 +  else
 +    return _m->getAllGeoTypesSorted();
 +}
 +
 +std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::retrievePartsWithoutComputation() const
 +{
 +  if(_mp_time<_m_time)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartsWithoutComputation : the parts require a computation !");
 +  //
 +  std::vector<MEDCoupling1GTUMesh *> ret(_m_parts.size());
 +  std::size_t i(0);
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++,i++)
 +    {
 +      const MEDCoupling1GTUMesh *elt(*it);
 +      ret[i]=const_cast<MEDCoupling1GTUMesh *>(elt);
 +    }
 +  return ret;
 +}
 +
 +std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::getParts() const
 +{
 +  if(_mp_time<_m_time)
 +    forceComputationOfPartsFromUMesh();
 +  return retrievePartsWithoutComputation();
 +}
 +
 +MEDCoupling1GTUMesh *MEDFileUMeshAggregateCompute::retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const
 +{
 +  std::vector<MEDCoupling1GTUMesh *> v(retrievePartsWithoutComputation());
 +  std::size_t sz(v.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      if(v[i])
 +        if(v[i]->getCellModelEnum()==gt)
 +          return v[i];
 +    }
 +  throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartWithoutComputation : the geometric type is not existing !");
 +}
 +
 +void MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const
 +{
 +  start=0; stop=0;
 +  std::vector<MEDCoupling1GTUMesh *> v(retrievePartsWithoutComputation());
 +  std::size_t sz(v.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      if(v[i])
 +        {
 +          if(v[i]->getCellModelEnum()==gt)
 +            {
 +              stop=start+v[i]->getNumberOfCells();
 +              return;
 +            }
 +          else
 +            start+=v[i]->getNumberOfCells();
 +        }
 +    }
 +  throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation : the geometric type is not existing !");
 +}
 +
 +void MEDFileUMeshAggregateCompute::renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N)
 +{
 +  if(_mp_time>_m_time)
 +    {
 +      for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +        {
 +          MEDCoupling1GTUMesh *m(*it);
 +          if(m)
 +            m->renumberNodesInConn(newNodeNumbersO2N);
 +        }
 +    }
 +  else
 +    {
 +      MEDCouplingUMesh *m(getUmesh());
 +      if(!m)
 +        return;
 +      m->renumberNodesInConn(newNodeNumbersO2N);
 +    }
 +}
 +
 +void MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh() const
 +{
 +  const MEDCouplingUMesh *m(_m);
 +  if(!m)
 +    {
 +      if(_m_parts.empty())
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh : null UMesh !");
 +      else
 +        return ;// no needs to compte parts they are already here !
 +    }
 +  std::vector<MEDCouplingUMesh *> ms(m->splitByType());
 +  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > msMSafe(ms.begin(),ms.end());
 +  std::size_t sz(msMSafe.size());
 +  _m_parts.resize(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    _m_parts[i]=MEDCoupling1GTUMesh::New(ms[i]);
 +  _part_def.clear();
 +  _part_def.resize(_m_parts.size());
 +  _mp_time=std::max(_mp_time,_m_time);
 +}
 +
 +const PartDefinition *MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const
 +{
 +  if(_mp_time<_m_time)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : the parts require a computation !");
 +  if(_m_parts.size()!=_part_def.size())
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : size of arrays are expected to be the same !");
 +  std::size_t sz(_m_parts.size());
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const MEDCoupling1GTUMesh *mesh(_m_parts[i]);
 +      if(mesh)
 +        if(mesh->getCellModelEnum()==gt)
 +          return _part_def[i];
 +    }
 +  throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : The input geo type is not existing in this !");
 +}
 +
 +void MEDFileUMeshAggregateCompute::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const
 +{
 +  if(_mp_time<_m_time)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : the parts require a computation !");
 +  std::size_t sz(_m_parts.size());
 +  tinyInt.push_back((int)sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const MEDCoupling1GTUMesh *mesh(_m_parts[i]);
 +      if(!mesh)
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : one part is empty !");
 +      tinyInt.push_back(mesh->getCellModelEnum());
 +      const MEDCoupling1SGTUMesh *mesh1(dynamic_cast<const MEDCoupling1SGTUMesh *>(mesh));
 +      const MEDCoupling1DGTUMesh *mesh2(dynamic_cast<const MEDCoupling1DGTUMesh *>(mesh));
 +      if(mesh1)
 +        {
 +          DataArrayInt *elt(mesh1->getNodalConnectivity());
 +          if(elt)
 +            elt->incrRef();
 +          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt1(elt);
 +          bigArraysI.push_back(elt1);
 +        }
 +      else if(mesh2)
 +        {
 +          DataArrayInt *elt1(mesh2->getNodalConnectivity()),*elt2(mesh2->getNodalConnectivityIndex());
 +          if(elt1)
 +            elt1->incrRef();
 +          if(elt2)
 +            elt2->incrRef();
 +          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt11(elt1),elt22(elt2);
 +          bigArraysI.push_back(elt11); bigArraysI.push_back(elt22);
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : unrecognized single geo type mesh !");
 +      const PartDefinition *pd(_part_def[i]);
 +      if(!pd)
 +        tinyInt.push_back(-1);
 +      else
 +        {
 +          std::vector<int> tinyTmp;
 +          pd->serialize(tinyTmp,bigArraysI);
 +          tinyInt.push_back((int)tinyTmp.size());
 +          tinyInt.insert(tinyInt.end(),tinyTmp.begin(),tinyTmp.end());
 +        }
 +    }
 +}
 +
 +void MEDFileUMeshAggregateCompute::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI)
 +{
 +  int nbParts(tinyInt.back()); tinyInt.pop_back();
 +  _part_def.clear(); _part_def.resize(nbParts);
 +  _m_parts.clear(); _m_parts.resize(nbParts);
 +  for(int i=0;i<nbParts;i++)
 +    {
 +      INTERP_KERNEL::NormalizedCellType tp((INTERP_KERNEL::NormalizedCellType) tinyInt.back()); tinyInt.pop_back();
 +      MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> mesh(MEDCoupling1GTUMesh::New(name,tp));
 +      mesh->setCoords(coo);
 +      MEDCoupling1SGTUMesh *mesh1(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *) mesh));
 +      MEDCoupling1DGTUMesh *mesh2(dynamic_cast<MEDCoupling1DGTUMesh *>((MEDCoupling1GTUMesh *) mesh));
 +      if(mesh1)
 +        {
 +          mesh1->setNodalConnectivity(bigArraysI.back()); bigArraysI.pop_back();
 +        }
 +      else if(mesh2)
 +        {
 +          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt0,elt1;
 +          elt0=bigArraysI.back(); bigArraysI.pop_back();
 +          elt1=bigArraysI.back(); bigArraysI.pop_back();
 +          mesh2->setNodalConnectivity(elt0,elt1);
 +        }
 +      else
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::unserialize : unrecognized single geo type mesh !");
 +      _m_parts[i]=mesh;
 +      int pdid(tinyInt.back()); tinyInt.pop_back();
 +      if(pdid!=-1)
 +        _part_def[i]=PartDefinition::Unserialize(tinyInt,bigArraysI);
 +      _mp_time=std::max(_mp_time,_m_time)+1;
 +    }
 +}
 +
 +/*!
 + * This method returns true if \a this is stored split by type false if stored in a merged unstructured mesh.
 + */
 +bool MEDFileUMeshAggregateCompute::isStoredSplitByType() const
 +{
 +  return _mp_time>=_m_time;
 +}
 +
 +std::size_t MEDFileUMeshAggregateCompute::getTimeOfThis() const
 +{
 +  if(_mp_time>_m_time)
 +    return getTimeOfParts();
 +  if(_m_time>_mp_time)
 +    return getTimeOfUMesh();
 +  return std::max(getTimeOfParts(),getTimeOfUMesh());
 +}
 +
 +std::size_t MEDFileUMeshAggregateCompute::getTimeOfParts() const
 +{
 +  std::size_t ret(0);
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +    {
 +      const MEDCoupling1GTUMesh *elt(*it);
 +      if(!elt)
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : null obj in parts !");
 +      ret=std::max(ret,elt->getTimeOfThis());
 +    }
 +  if(ret==0)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : parts is empty !");
 +  return ret;
 +}
 +
 +std::size_t MEDFileUMeshAggregateCompute::getTimeOfUMesh() const
 +{
 +  const MEDCouplingUMesh *m(_m);
 +  if(!m)
 +    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfUMesh : unmesh is null !");
 +  return m->getTimeOfThis();
 +}
 +
 +std::size_t MEDFileUMeshAggregateCompute::getHeapMemorySizeWithoutChildren() const
 +{
 +  std::size_t ret(_m_parts.size()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh>));
 +  return ret;
 +}
 +
 +std::vector<const BigMemoryObject *> MEDFileUMeshAggregateCompute::getDirectChildrenWithNull() const
 +{
 +  std::vector<const BigMemoryObject *> ret;
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +    ret.push_back((const MEDCoupling1GTUMesh *)*it);
 +  ret.push_back((const MEDCouplingUMesh *)_m);
 +  return ret;
 +}
 +
 +MEDFileUMeshAggregateCompute MEDFileUMeshAggregateCompute::deepCpy(DataArrayDouble *coords) const
 +{
 +  MEDFileUMeshAggregateCompute ret;
 +  ret._m_parts.resize(_m_parts.size());
 +  for(std::size_t i=0;i<_m_parts.size();i++)
 +    {
 +      const MEDCoupling1GTUMesh *elt(_m_parts[i]);
 +      if(elt)
 +        {
 +          ret._m_parts[i]=static_cast<ParaMEDMEM::MEDCoupling1GTUMesh*>(elt->deepCpy());
 +          ret._m_parts[i]->setCoords(coords);
 +        }
 +    }
 +  ret._mp_time=_mp_time; ret._m_time=_m_time;
 +  if((const MEDCouplingUMesh *)_m)
 +    {
 +      ret._m=static_cast<ParaMEDMEM::MEDCouplingUMesh*>(_m->deepCpy());
 +      ret._m->setCoords(coords);
 +    }
 +  std::size_t sz(_part_def.size());
 +  ret._part_def.clear(); ret._part_def.resize(sz);
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const PartDefinition *elt(_part_def[i]);
 +      if(elt)
 +        ret._part_def[i]=elt->deepCpy();
 +    }
 +  return ret;
 +}
 +
 +bool MEDFileUMeshAggregateCompute::isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const
 +{
 +  const MEDCouplingUMesh *m1(getUmesh());
 +  const MEDCouplingUMesh *m2(other.getUmesh());
 +  if((m1==0 && m2!=0) || (m1!=0 && m2==0))
 +    {
 +      what="Presence of mesh in one sublevel and not in other!";
 +      return false;
 +    }
 +  if(m1)
 +    {
 +      std::string what2;
 +      if(!m1->isEqualIfNotWhy(m2,eps,what2))
 +        {
 +          what=std::string("meshes at a sublevel are not deeply equal (")+what2+std::string(")!");
 +          return false;
 +        }
 +    }
 +  std::size_t sz(_part_def.size());
 +  if(sz!=other._part_def.size())
 +    {
 +      what=std::string("number of subdivision per geo type for part definition is not the same !");
 +      return false;
 +    }
 +  for(std::size_t i=0;i<sz;i++)
 +    {
 +      const PartDefinition *pd0(_part_def[i]),*pd1(other._part_def[i]);
 +      if(!pd0 && !pd1)
 +        continue;
 +      if((!pd0 && pd1) || (pd0 && !pd1))
 +        {
 +          what=std::string("a cell part def is defined only for one among this or other !");
 +          return false;
 +        }
 +      bool ret(pd0->isEqual(pd1,what));
 +      if(!ret)
 +        return false;
 +    }
 +  return true;
 +}
 +
 +void MEDFileUMeshAggregateCompute::clearNonDiscrAttributes() const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +    MEDFileUMeshSplitL1::ClearNonDiscrAttributes(*it);
 +  MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_m);
 +}
 +
 +void MEDFileUMeshAggregateCompute::synchronizeTinyInfo(const MEDFileMesh& master) const
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +    {
 +      const MEDCoupling1GTUMesh *tmp(*it);
 +      if(tmp)
 +        {
 +          (const_cast<MEDCoupling1GTUMesh *>(tmp))->setName(master.getName().c_str());
 +          (const_cast<MEDCoupling1GTUMesh *>(tmp))->setDescription(master.getDescription().c_str());
 +          (const_cast<MEDCoupling1GTUMesh *>(tmp))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder());
 +          (const_cast<MEDCoupling1GTUMesh *>(tmp))->setTimeUnit(master.getTimeUnit());
 +        }
 +    }
 +  const MEDCouplingUMesh *m(_m);
 +  if(m)
 +    {
 +      (const_cast<MEDCouplingUMesh *>(m))->setName(master.getName().c_str());
 +      (const_cast<MEDCouplingUMesh *>(m))->setDescription(master.getDescription().c_str());
 +      (const_cast<MEDCouplingUMesh *>(m))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder());
 +      (const_cast<MEDCouplingUMesh *>(m))->setTimeUnit(master.getTimeUnit());
 +    }
 +}
 +
 +bool MEDFileUMeshAggregateCompute::empty() const
 +{
 +  if(_mp_time<_m_time)
 +    return ((const MEDCouplingUMesh *)_m)==0;
 +  //else _mp_time>=_m_time)
 +  return _m_parts.empty();
 +}
 +
 +int MEDFileUMeshAggregateCompute::getMeshDimension() const
 +{
 +  if(_mp_time<_m_time)
 +    {
 +      const MEDCouplingUMesh *m(_m);
 +      if(!m)
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : no umesh in this !");
 +      return m->getMeshDimension();
 +    }
 +  else
 +    {
 +      if(_m_parts.empty())
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh is empty !");
 +      const MEDCoupling1GTUMesh *m(_m_parts[0]);
 +      if(!m)
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh contains null instance !");
 +      return m->getMeshDimension();
 +    }
 +}
 +
 +std::vector<int> MEDFileUMeshAggregateCompute::getDistributionOfTypes() const
 +{
 +  if(_mp_time<_m_time)
 +    {
 +      const MEDCouplingUMesh *m(_m);
 +      if(!m)
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : no umesh in this !");
 +      return m->getDistributionOfTypes();
 +    }
 +  else
 +    {
 +      std::vector<int> ret;
 +      for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +        {
 +          const MEDCoupling1GTUMesh *tmp(*it);
 +          if(!tmp)
 +            throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : part mesh contains null instance !");
 +          std::vector<int> ret0(tmp->getDistributionOfTypes());
 +          ret.insert(ret.end(),ret0.begin(),ret0.end());
 +        }
 +      return ret;
 +    }
 +}
 +
 +int MEDFileUMeshAggregateCompute::getSize() const
 +{
 +  if(_mp_time<_m_time)
 +    {
 +      const MEDCouplingUMesh *m(_m);
 +      if(!m)
 +        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : no umesh in this !");
 +      return m->getNumberOfCells();
 +    }
 +  else
 +    {
 +      int ret=0;
 +      for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +        {
 +          const MEDCoupling1GTUMesh *m(*it);
 +          if(!m)
 +            throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : part mesh contains null instance !");
 +          ret+=m->getNumberOfCells();
 +        }
 +      return ret;
 +    }
 +}
 +
 +void MEDFileUMeshAggregateCompute::setCoords(DataArrayDouble *coords)
 +{
 +  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++)
 +    {
 +      MEDCoupling1GTUMesh *tmp(*it);
 +      if(tmp)
 +        (*it)->setCoords(coords);
 +    }
 +  MEDCouplingUMesh *m(_m);
 +  if(m)
 +    m->setCoords(coords);
 +}
index dd2ba8961f036eca1796a3ed1aedc2fd11a80c4c,0000000000000000000000000000000000000000..8972744a409c2bef28d39a28750ff147809f2606
mode 100644,000000..100644
--- /dev/null
@@@ -1,3830 -1,0 +1,3831 @@@
-     bool operator () (const Cell* i1, const Cell* i2)
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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
 +//
 +// File      : SauvMedConvertor.cxx
 +// Created   : Tue Aug 16 14:43:20 2011
 +// Author    : Edward AGAPOV (eap)
 +//
 +
 +#include "SauvMedConvertor.hxx"
 +
 +#include "CellModel.hxx"
 +#include "MEDFileMesh.hxx"
 +#include "MEDFileField.hxx"
 +#include "MEDFileData.hxx"
 +#include "MEDCouplingFieldDouble.hxx"
 +
 +#include <iostream>
 +#include <cassert>
 +#include <cmath>
 +#include <queue>
 +#include <limits>
 +
 +#include <cstdlib>
 +#include <cstring>
 +#include <fcntl.h>
 +
 +#ifdef WIN32
 +#include <io.h>
 +#else
 +#include <unistd.h>
 +#endif
 +
 +#ifdef HAS_XDR
++#include <rpc/types.h>
 +#include <rpc/xdr.h>
 +#endif
 +
 +using namespace SauvUtilities;
 +using namespace ParaMEDMEM;
 +
 +namespace
 +{
 +  // for ASCII file reader
 +  const int GIBI_MaxOutputLen = 150; // max length of a line in the sauve file
 +  const int GIBI_BufferSize   = 16184; // for buffered reading
 +
 +  using namespace INTERP_KERNEL;
 +
 +  const size_t MaxMedCellType = NORM_ERROR;
 +  const size_t NbGibiCellTypes = 47;
 +  const TCellType GibiTypeToMed[NbGibiCellTypes] =
 +    {
 +      /*1 */ NORM_POINT1 ,/*2 */ NORM_SEG2   ,/*3 */ NORM_SEG3   ,/*4 */ NORM_TRI3   ,/*5 */ NORM_ERROR  ,
 +      /*6 */ NORM_TRI6   ,/*7 */ NORM_ERROR  ,/*8 */ NORM_QUAD4  ,/*9 */ NORM_ERROR  ,/*10*/ NORM_QUAD8  ,
 +      /*11*/ NORM_ERROR  ,/*12*/ NORM_ERROR  ,/*13*/ NORM_ERROR  ,/*14*/ NORM_HEXA8  ,/*15*/ NORM_HEXA20 ,
 +      /*16*/ NORM_PENTA6 ,/*17*/ NORM_PENTA15,/*18*/ NORM_ERROR  ,/*19*/ NORM_ERROR  ,/*20*/ NORM_ERROR  ,
 +      /*21*/ NORM_ERROR  ,/*22*/ NORM_ERROR  ,/*23*/ NORM_TETRA4 ,/*24*/ NORM_TETRA10,/*25*/ NORM_PYRA5  ,
 +      /*26*/ NORM_PYRA13 ,/*27*/ NORM_ERROR  ,/*28*/ NORM_ERROR  ,/*29*/ NORM_ERROR  ,/*30*/ NORM_ERROR  ,
 +      /*31*/ NORM_ERROR  ,/*32*/ NORM_ERROR  ,/*33*/ NORM_ERROR  ,/*34*/ NORM_ERROR  ,/*35*/ NORM_ERROR  ,
 +      /*36*/ NORM_ERROR  ,/*37*/ NORM_ERROR  ,/*38*/ NORM_ERROR  ,/*39*/ NORM_ERROR  ,/*40*/ NORM_ERROR  ,
 +      /*41*/ NORM_ERROR  ,/*42*/ NORM_ERROR  ,/*43*/ NORM_ERROR  ,/*44*/ NORM_ERROR  ,/*45*/ NORM_ERROR  ,
 +      /*46*/ NORM_ERROR  ,/*47*/ NORM_ERROR
 +    };
 +
 +  //================================================================================
 +  /*!
 +   * \brief Return dimension of a group
 +   */
 +  //================================================================================
 +
 +  unsigned getDim( const Group* grp )
 +  {
 +    return SauvUtilities::getDimension( grp->_groups.empty() ? grp->_cellType : grp->_groups[0]->_cellType );
 +  }
 +
 +  //================================================================================
 +  /*!
 +   * \brief Converts connectivity of quadratic elements
 +   */
 +  //================================================================================
 +
 +  inline void ConvertQuadratic( const INTERP_KERNEL::NormalizedCellType type,
 +                                const Cell &                            aCell )
 +  {
 +    if ( const int * conn = getGibi2MedQuadraticInterlace( type ))
 +      {
 +        Cell* ma = const_cast<Cell*>(&aCell);
 +        std::vector< Node* > new_nodes( ma->_nodes.size() );
 +        for (std:: size_t i = 0; i < new_nodes.size(); ++i )
 +          new_nodes[ i ] = ma->_nodes[ conn[ i ]];
 +        ma->_nodes.swap( new_nodes );
 +      }
 +  }
 +
 +  //================================================================================
 +  /*!
 +   * \brief Returns a vector of pairs of node indices to inverse a med volume element
 +   */
 +  //================================================================================
 +
 +  void getReverseVector (const INTERP_KERNEL::NormalizedCellType type,
 +                         std::vector<std::pair<int,int> > &                swapVec )
 +  {
 +    swapVec.clear();
 +
 +    switch ( type )
 +      {
 +      case NORM_TETRA4:
 +        swapVec.resize(1);
 +        swapVec[0] = std::make_pair( 1, 2 );
 +        break;
 +      case NORM_PYRA5:
 +        swapVec.resize(1);
 +        swapVec[0] = std::make_pair( 1, 3 );
 +        break;
 +      case NORM_PENTA6:
 +        swapVec.resize(2);
 +        swapVec[0] = std::make_pair( 1, 2 );
 +        swapVec[1] = std::make_pair( 4, 5 );
 +        break;
 +      case NORM_HEXA8:
 +        swapVec.resize(2);
 +        swapVec[0] = std::make_pair( 1, 3 );
 +        swapVec[1] = std::make_pair( 5, 7 );
 +        break;
 +      case NORM_TETRA10:
 +        swapVec.resize(3);
 +        swapVec[0] = std::make_pair( 1, 2 );
 +        swapVec[1] = std::make_pair( 4, 6 );
 +        swapVec[2] = std::make_pair( 8, 9 );
 +        break;
 +      case NORM_PYRA13:
 +        swapVec.resize(4);
 +        swapVec[0] = std::make_pair( 1, 3 );
 +        swapVec[1] = std::make_pair( 5, 8 );
 +        swapVec[2] = std::make_pair( 6, 7 );
 +        swapVec[3] = std::make_pair( 10, 12 );
 +        break;
 +      case NORM_PENTA15:
 +        swapVec.resize(4);
 +        swapVec[0] = std::make_pair( 1, 2 );
 +        swapVec[1] = std::make_pair( 4, 5 );
 +        swapVec[2] = std::make_pair( 6, 8 );
 +        swapVec[3] = std::make_pair( 9, 11 );
 +        break;
 +      case NORM_HEXA20:
 +        swapVec.resize(7);
 +        swapVec[0] = std::make_pair( 1, 3 );
 +        swapVec[1] = std::make_pair( 5, 7 );
 +        swapVec[2] = std::make_pair( 8, 11 );
 +        swapVec[3] = std::make_pair( 9, 10 );
 +        swapVec[4] = std::make_pair( 12, 15 );
 +        swapVec[5] = std::make_pair( 13, 14 );
 +        swapVec[6] = std::make_pair( 17, 19 );
 +        break;
 +        //   case NORM_SEG3: no need to reverse edges
 +        //     swapVec.resize(1);
 +        //     swapVec[0] = std::make_pair( 1, 2 );
 +        //     break;
 +      case NORM_TRI6:
 +        swapVec.resize(2);
 +        swapVec[0] = std::make_pair( 1, 2 );
 +        swapVec[1] = std::make_pair( 3, 5 );
 +        break;
 +      case NORM_QUAD8:
 +        swapVec.resize(3);
 +        swapVec[0] = std::make_pair( 1, 3 );
 +        swapVec[1] = std::make_pair( 4, 7 );
 +        swapVec[2] = std::make_pair( 5, 6 );
 +        break;
 +      default:;
 +      }
 +  }
 +
 +  //================================================================================
 +  /*!
 +   * \brief Inverses element orientation using vector of indices to swap
 +   */
 +  //================================================================================
 +
 +  inline void reverse(const Cell & aCell, const std::vector<std::pair<int,int> > & swapVec )
 +  {
 +    Cell* ma = const_cast<Cell*>(&aCell);
 +    for ( unsigned i = 0; i < swapVec.size(); ++i )
 +      std::swap( ma->_nodes[ swapVec[i].first ],
 +                 ma->_nodes[ swapVec[i].second ]);
 +    if ( swapVec.empty() )
 +      ma->_reverse = true;
 +    else
 +      ma->_reverse = false;
 +  }
 +  //================================================================================
 +  /*!
 +   * \brief Comparator of cells by number used for ordering cells within a med group
 +   */
 +  struct TCellByIDCompare
 +  {
++    bool operator () (const Cell* i1, const Cell* i2) const
 +    {
 +      return i1->_number < i2->_number;
 +    }
 +  };
 +  typedef std::map< const Cell*, unsigned, TCellByIDCompare > TCellToOrderMap;
 +
 +  //================================================================================
 +  /*!
 +   * \brief Fill Group::_relocTable if necessary
 +   */
 +  //================================================================================
 +
 +  void setRelocationTable( Group* grp, TCellToOrderMap& cell2order )
 +  {
 +    if ( !grp->_isProfile ) return;
 +
 +    // check if relocation table is necessary
 +    bool isRelocated = false;
 +    unsigned newOrder = 0;
 +    TCellToOrderMap::iterator c2oIt = cell2order.begin(), c2oEnd = cell2order.end();
 +    for ( ; !isRelocated && c2oIt != c2oEnd; ++c2oIt, ++newOrder )
 +      isRelocated = ( c2oIt->second != newOrder );
 +
 +    if ( isRelocated )
 +    {
 +      grp->_relocTable.resize( cell2order.size() );
 +      for ( newOrder = 0, c2oIt = cell2order.begin(); c2oIt != c2oEnd; ++c2oIt, ++newOrder )
 +        grp->_relocTable[ c2oIt->second ] = newOrder;
 +    }
 +  }
 +}
 +
 +namespace // define default GAUSS points
 +{
 +  typedef std::vector<double> TDoubleVector;
 +  typedef double*             TCoordSlice;
 +  typedef int                 TInt;
 +  //---------------------------------------------------------------
 +  //! Shape function definitions
 +  //---------------------------------------------------------------
 +  struct TShapeFun
 +  {
 +    TInt myDim;
 +    TInt myNbRef;
 +    TDoubleVector myRefCoord;
 +
 +    TShapeFun(TInt theDim = 0, TInt theNbRef = 0)
 +      :myDim(theDim),myNbRef(theNbRef),myRefCoord(theNbRef*theDim) {}
 +
 +    TInt GetNbRef() const { return myNbRef; }
 +
 +    TCoordSlice GetCoord(TInt theRefId) { return &myRefCoord[0] + theRefId * myDim; }
 +  };
 +  //---------------------------------------------------------------
 +  /*!
 +   * \brief Description of family of integration points
 +   */
 +  //---------------------------------------------------------------
 +  struct TGaussDef
 +  {
 +    int           myType;      //!< element geometry (EGeometrieElement or med_geometrie_element)
 +    TDoubleVector myRefCoords; //!< description of reference points
 +    TDoubleVector myCoords;    //!< coordinates of Gauss points
 +    TDoubleVector myWeights;   //!< weights, len(weights)==<nb of gauss points>
 +
 +    /*!
 +     * \brief Creates definition of gauss points family
 +     *  \param geomType - element geometry (EGeometrieElement or med_geometrie_element)
 +     *  \param nbPoints - nb gauss point
 +     *  \param variant - [1-3] to choose the variant of definition
 +     * 
 +     * Throws in case of invalid parameters
 +     * variant == 1 refers to "Fonctions de forme et points d'integration 
 +     *              des elements finis" v7.4 by J. PELLET, X. DESROCHES, 15/09/05
 +     * variant == 2 refers to the same doc v6.4 by J.P. LEFEBVRE, X. DESROCHES, 03/07/03
 +     * variant == 3 refers to the same doc v6.4, second variant for 2D elements
 +     */
 +    TGaussDef(const int geomType, const int nbPoints, const int variant=1);
 +
 +    int dim() const { return SauvUtilities::getDimension( NormalizedCellType( myType )); }
 +    int nbPoints() const { return myWeights.capacity(); }
 +
 +  private:
 +    void add(const double x, const double weight);
 +    void add(const double x, const double y, const double weight);
 +    void add(const double x, const double y, const double z, const double weight);
 +    void setRefCoords(const TShapeFun& aShapeFun) { myRefCoords = aShapeFun.myRefCoord; }
 +  };
 +  struct TSeg2a: TShapeFun {
 +    TSeg2a();
 +  };
 +  struct TSeg3a: TShapeFun {
 +    TSeg3a();
 +  };
 +  struct TTria3a: TShapeFun {
 +    TTria3a();
 +  };
 +  struct TTria6a: TShapeFun {
 +    TTria6a();
 +  };
 +  struct TTria3b: TShapeFun {
 +    TTria3b();
 +  };
 +  struct TTria6b: TShapeFun {
 +    TTria6b();
 +  };
 +  struct TQuad4a: TShapeFun {
 +    TQuad4a();
 +  };
 +  struct TQuad8a: TShapeFun {
 +    TQuad8a();
 +  };
 +  struct TQuad4b: TShapeFun {
 +    TQuad4b();
 +  };
 +  struct TQuad8b: TShapeFun {
 +    TQuad8b();
 +  };
 +  struct TTetra4a: TShapeFun {
 +    TTetra4a();
 +  };
 +  struct TTetra10a: TShapeFun {
 +    TTetra10a();
 +  };
 +  struct TTetra4b: TShapeFun {
 +    TTetra4b();
 +  };
 +  struct TTetra10b: TShapeFun {
 +    TTetra10b();
 +  };
 +  struct THexa8a: TShapeFun {
 +    THexa8a();
 +  };
 +  struct THexa20a: TShapeFun {
 +    THexa20a(TInt theDim = 3, TInt theNbRef = 20);
 +  };
 +  struct THexa27a: THexa20a {
 +    THexa27a();
 +  };
 +  struct THexa8b: TShapeFun {
 +    THexa8b();
 +  };
 +  struct THexa20b: TShapeFun {
 +    THexa20b(TInt theDim = 3, TInt theNbRef = 20);
 +  };
 +  struct TPenta6a: TShapeFun {
 +    TPenta6a();
 +  };
 +  struct TPenta6b: TShapeFun {
 +    TPenta6b();
 +  };
 +  struct TPenta15a: TShapeFun {
 +    TPenta15a();
 +  };
 +  struct TPenta15b: TShapeFun {
 +    TPenta15b();
 +  };
 +  struct TPyra5a: TShapeFun {
 +    TPyra5a();
 +  };
 +  struct TPyra5b: TShapeFun {
 +    TPyra5b();
 +  };
 +  struct TPyra13a: TShapeFun {
 +    TPyra13a();
 +  };
 +  struct TPyra13b: TShapeFun {
 +    TPyra13b();
 +  };
 +
 +  void TGaussDef::add(const double x, const double weight)
 +  {
 +    if ( dim() != 1 )
 +      THROW_IK_EXCEPTION("TGaussDef: dim() != 1");
 +    if ( myWeights.capacity() == myWeights.size() )
 +      THROW_IK_EXCEPTION("TGaussDef: Extra gauss point");
 +    myCoords.push_back( x );
 +    myWeights.push_back( weight );
 +  }
 +  void TGaussDef::add(const double x, const double y, const double weight)
 +  {
 +    if ( dim() != 2 )
 +      THROW_IK_EXCEPTION("TGaussDef: dim() != 2");
 +    if ( myWeights.capacity() == myWeights.size() )
 +      THROW_IK_EXCEPTION("TGaussDef: Extra gauss point");
 +    myCoords.push_back( x );
 +    myCoords.push_back( y );
 +    myWeights.push_back( weight );
 +  }
 +  void TGaussDef::add(const double x, const double y, const double z, const double weight)
 +  {
 +    if ( dim() != 3 )
 +      THROW_IK_EXCEPTION("TGaussDef: dim() != 3");
 +    if ( myWeights.capacity() == myWeights.size() )
 +      THROW_IK_EXCEPTION("TGaussDef: Extra gauss point");
 +    myCoords.push_back( x );
 +    myCoords.push_back( y );
 +    myCoords.push_back( z );
 +    myWeights.push_back( weight );
 +  }
 +
 +  //---------------------------------------------------------------
 +  TSeg2a::TSeg2a():TShapeFun(1,2)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0; break;
 +      case  1: aCoord[0] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TSeg3a::TSeg3a():TShapeFun(1,3)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0; break;
 +      case  1: aCoord[0] =  1.0; break;
 +      case  2: aCoord[0] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTria3a::TTria3a():
 +    TShapeFun(2,3)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] = -1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTria6a::TTria6a():TShapeFun(2,6)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] = -1.0; break;
 +
 +      case  3: aCoord[0] = -1.0;  aCoord[1] =  1.0; break;
 +      case  4: aCoord[0] =  0.0;  aCoord[1] = -1.0; break;
 +      case  5: aCoord[0] =  0.0;  aCoord[1] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTria3b::TTria3b():
 +    TShapeFun(2,3)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  0.0;  aCoord[1] =  0.0; break;
 +      case  1: aCoord[0] =  1.0;  aCoord[1] =  0.0; break;
 +      case  2: aCoord[0] =  0.0;  aCoord[1] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTria6b::TTria6b():
 +    TShapeFun(2,6)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  0.0;  aCoord[1] =  0.0; break;
 +      case  1: aCoord[0] =  1.0;  aCoord[1] =  0.0; break;
 +      case  2: aCoord[0] =  0.0;  aCoord[1] =  1.0; break;
 +
 +      case  3: aCoord[0] =  0.5;  aCoord[1] =  0.0; break;
 +      case  4: aCoord[0] =  0.5;  aCoord[1] =  0.5; break;
 +      case  5: aCoord[0] =  0.0;  aCoord[1] =  0.5; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TQuad4a::TQuad4a():
 +    TShapeFun(2,4)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] = -1.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TQuad8a::TQuad8a():
 +    TShapeFun(2,8)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] = -1.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  1.0; break;
 +
 +      case  4: aCoord[0] = -1.0;  aCoord[1] =  0.0; break;
 +      case  5: aCoord[0] =  0.0;  aCoord[1] = -1.0; break;
 +      case  6: aCoord[0] =  1.0;  aCoord[1] =  0.0; break;
 +      case  7: aCoord[0] =  0.0;  aCoord[1] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TQuad4b::TQuad4b():
 +    TShapeFun(2,4)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] = -1.0; break;
 +      case  1: aCoord[0] =  1.0;  aCoord[1] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] =  1.0; break;
 +      case  3: aCoord[0] = -1.0;  aCoord[1] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TQuad8b::TQuad8b():
 +    TShapeFun(2,8)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] = -1.0; break;
 +      case  1: aCoord[0] =  1.0;  aCoord[1] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] =  1.0; break;
 +      case  3: aCoord[0] = -1.0;  aCoord[1] =  1.0; break;
 +
 +      case  4: aCoord[0] =  0.0;  aCoord[1] = -1.0; break;
 +      case  5: aCoord[0] =  1.0;  aCoord[1] =  0.0; break;
 +      case  6: aCoord[0] =  0.0;  aCoord[1] =  1.0; break;
 +      case  7: aCoord[0] = -1.0;  aCoord[1] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTetra4a::TTetra4a():
 +    TShapeFun(3,4)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  2: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTetra10a::TTetra10a():
 +    TShapeFun(3,10)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  2: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +
 +      case  4: aCoord[0] =  0.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case  5: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case  6: aCoord[0] =  0.0;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +
 +      case  7: aCoord[0] =  0.5;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case  8: aCoord[0] =  0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case  9: aCoord[0] =  0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTetra4b::TTetra4b():
 +    TShapeFun(3,4)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TTetra10b::TTetra10b():
 +    TShapeFun(3,10)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +
 +      case  6: aCoord[0] =  0.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case  5: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case  4: aCoord[0] =  0.0;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +
 +      case  7: aCoord[0] =  0.5;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case  9: aCoord[0] =  0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case  8: aCoord[0] =  0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  THexa8a::THexa8a():
 +    TShapeFun(3,8)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  1: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  3: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  4: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  5: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  6: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      case  7: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  THexa20a::THexa20a(TInt theDim, TInt theNbRef):
 +    TShapeFun(theDim,theNbRef)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  1: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  3: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  4: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  5: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  6: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      case  7: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +
 +      case  8: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  9: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] = -1.0; break;
 +      case 10: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case 11: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] = -1.0; break;
 +      case 12: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case 13: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case 14: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case 15: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case 16: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case 17: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case 18: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      case 19: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  THexa27a::THexa27a():
 +    THexa20a(3,27)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case 20: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] = -1.0; break;
 +      case 21: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case 22: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case 23: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case 24: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case 25: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case 26: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  THexa8b::THexa8b():
 +    TShapeFun(3,8)
 +  {
 +    TInt aNbRef = GetNbRef();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  4: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  7: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  6: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      case  5: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  THexa20b::THexa20b(TInt theDim, TInt theNbRef):
 +    TShapeFun(theDim,theNbRef)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case  2: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  4: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  7: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case  6: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      case  5: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +
 +      case 11: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] = -1.0; break;
 +      case 10: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] = -1.0; break;
 +      case  9: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] = -1.0; break;
 +      case  8: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] = -1.0; break;
 +      case 16: aCoord[0] = -1.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case 19: aCoord[0] =  1.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case 18: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case 17: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case 15: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] =  1.0; break;
 +      case 14: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case 13: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  1.0; break;
 +      case 12: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPenta6a::TPenta6a():
 +    TShapeFun(3,6)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] = -0.0;  aCoord[2] =  1.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  4: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  5: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPenta6b::TPenta6b():
 +    TShapeFun(3,6)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] = -0.0;  aCoord[2] =  1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  5: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  4: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPenta15a::TPenta15a():
 +    TShapeFun(3,15)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] = -0.0;  aCoord[2] =  1.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  4: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  5: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +
 +      case  6: aCoord[0] = -1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case  7: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case  8: aCoord[0] = -1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case  9: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case 10: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case 11: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case 12: aCoord[0] =  1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case 13: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case 14: aCoord[0] =  1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPenta15b::TPenta15b():
 +    TShapeFun(3,15)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] = -1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] = -0.0;  aCoord[2] =  1.0; break;
 +      case  1: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  1.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  5: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case  4: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +
 +      case  8: aCoord[0] = -1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case  7: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case  6: aCoord[0] = -1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case 12: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case 14: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      case 13: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case 11: aCoord[0] =  1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case 10: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case  9: aCoord[0] =  1.0;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPyra5a::TPyra5a():
 +    TShapeFun(3,5)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case  4: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPyra5b::TPyra5b():
 +    TShapeFun(3,5)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){        
 +      case  0: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case  4: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPyra13a::TPyra13a():
 +    TShapeFun(3,13)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case  4: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +
 +      case  5: aCoord[0] =  0.5;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case  6: aCoord[0] = -0.5;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case  7: aCoord[0] = -0.5;  aCoord[1] = -0.5;  aCoord[2] =  0.0; break;
 +      case  8: aCoord[0] =  0.5;  aCoord[1] = -0.5;  aCoord[2] =  0.0; break;
 +      case  9: aCoord[0] =  0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case 10: aCoord[0] =  0.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case 11: aCoord[0] = -0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case 12: aCoord[0] =  0.0;  aCoord[1] = -0.5;  aCoord[2] =  0.5; break;
 +      }
 +    }
 +  }
 +  //---------------------------------------------------------------
 +  TPyra13b::TPyra13b():
 +    TShapeFun(3,13)
 +  {
 +    TInt aNbRef = myRefCoord.size();
 +    for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){
 +      TCoordSlice aCoord = GetCoord(aRefId);
 +      switch(aRefId){
 +      case  0: aCoord[0] =  1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  3: aCoord[0] =  0.0;  aCoord[1] =  1.0;  aCoord[2] =  0.0; break;
 +      case  2: aCoord[0] = -1.0;  aCoord[1] =  0.0;  aCoord[2] =  0.0; break;
 +      case  1: aCoord[0] =  0.0;  aCoord[1] = -1.0;  aCoord[2] =  0.0; break;
 +      case  4: aCoord[0] =  0.0;  aCoord[1] =  0.0;  aCoord[2] =  1.0; break;
 +
 +      case  8: aCoord[0] =  0.5;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case  7: aCoord[0] = -0.5;  aCoord[1] =  0.5;  aCoord[2] =  0.0; break;
 +      case  6: aCoord[0] = -0.5;  aCoord[1] = -0.5;  aCoord[2] =  0.0; break;
 +      case  5: aCoord[0] =  0.5;  aCoord[1] = -0.5;  aCoord[2] =  0.0; break;
 +      case  9: aCoord[0] =  0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case 12: aCoord[0] =  0.0;  aCoord[1] =  0.5;  aCoord[2] =  0.5; break;
 +      case 11: aCoord[0] = -0.5;  aCoord[1] =  0.0;  aCoord[2] =  0.5; break;
 +      case 10: aCoord[0] =  0.0;  aCoord[1] = -0.5;  aCoord[2] =  0.5; break;
 +      }
 +    }
 +  }
 +  /*!
 +   * \brief Fill definition of gauss points family
 +   */
 +
 +  TGaussDef::TGaussDef(const int geom, const int nbGauss, const int variant)
 +  {
 +    myType = geom;
 +    myCoords .reserve( nbGauss * dim() );
 +    myWeights.reserve( nbGauss );
 +
 +    switch ( geom ) {
 +
 +    case NORM_SEG2:
 +    case NORM_SEG3:
 +      if (geom == NORM_SEG2) setRefCoords( TSeg2a() );
 +      else                   setRefCoords( TSeg3a() );
 +      switch ( nbGauss ) {
 +      case 1: {
 +        add( 0.0, 2.0 ); break;
 +      }
 +      case 2: {
 +        const double a = 0.577350269189626;
 +        add(  a,  1.0 );
 +        add( -a,  1.0 ); break;
 +      }
 +      case 3: {
 +        const double a = 0.774596669241;
 +        const double P1 = 1./1.8;
 +        const double P2 = 1./1.125;
 +        add( -a,  P1 );
 +        add(  0,  P2 ); 
 +        add(  a,  P1 ); break;
 +      }
 +      case 4: {
 +        const double a  = 0.339981043584856, b  = 0.861136311594053;
 +        const double P1 = 0.652145154862546, P2 = 0.347854845137454 ;
 +        add(  a,  P1 );
 +        add( -a,  P1 );
 +        add(  b,  P2 ); 
 +        add( -b,  P2 ); break;
 +      }
 +      default:
 +        THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for SEG"<<nbGauss);
 +      }
 +      break;
 +
 +    case NORM_TRI3:
 +    case NORM_TRI6:
 +      if ( variant == 1 ) {
 +        if (geom == NORM_TRI3) setRefCoords( TTria3b() );
 +        else                   setRefCoords( TTria6b() );
 +        switch ( nbGauss ) {
 +        case 1: { // FPG1
 +          add( 1/3., 1/3., 1/2. ); break;
 +        }
 +        case 3: { // FPG3
 +          // what about COT3 ???
 +          add( 1/6., 1/6., 1/6. );
 +          add( 2/3., 1/6., 1/6. );
 +          add( 1/6., 2/3., 1/6. ); break;
 +        }
 +        case 4: { // FPG4
 +          add( 1/5., 1/5.,  25/(24*4.) );
 +          add( 3/5., 1/5.,  25/(24*4.) );
 +          add( 1/5., 3/5.,  25/(24*4.) );
 +          add( 1/3., 1/3., -27/(24*4.) ); break;
 +        }
 +        case 6: { // FPG6
 +          const double P1 = 0.11169079483905, P2 = 0.0549758718227661;
 +          const double a  = 0.445948490915965, b = 0.091576213509771;
 +          add(     b,     b, P2 ); 
 +          add( 1-2*b,     b, P2 );
 +          add(     b, 1-2*b, P2 );
 +          add(     a, 1-2*a, P1 );
 +          add(     a,     a, P1 ); 
 +          add( 1-2*a,     a, P1 ); break;
 +        }
 +        case 7: { // FPG7
 +          const double A  = 0.470142064105115;
 +          const double B  = 0.101286507323456;
 +          const double P1 = 0.066197076394253;
 +          const double P2 = 0.062969590272413;
 +          add(  1/3.,  1/3., 9/80. ); 
 +          add(     A,     A, P1 ); 
 +          add( 1-2*A,     A, P1 );
 +          add(     A, 1-2*A, P1 );
 +          add(     B,     B, P2 ); 
 +          add( 1-2*B,     B, P2 );
 +          add(     B, 1-2*B, P2 ); break;
 +        }
 +        case 12: { // FPG12
 +          const double A  = 0.063089014491502;
 +          const double B  = 0.249286745170910;
 +          const double C  = 0.310352451033785;
 +          const double D  = 0.053145049844816;
 +          const double P1 = 0.025422453185103;
 +          const double P2 = 0.058393137863189;
 +          const double P3 = 0.041425537809187;
 +          add(     A,     A, P1 ); 
 +          add( 1-2*A,     A, P1 );
 +          add(     A, 1-2*A, P1 );
 +          add(     B,     B, P2 ); 
 +          add( 1-2*B,     B, P2 );
 +          add(     B, 1-2*B, P2 );
 +          add(     C,     D, P3 );
 +          add(     D,     C, P3 );
 +          add( 1-C-D,     C, P3 );
 +          add( 1-C-D,     D, P3 );
 +          add(     C, 1-C-D, P3 );
 +          add(     D, 1-C-D, P3 ); break;
 +        }
 +        default:
 +          THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TRIA, variant 1: "
 +                     <<nbGauss);
 +        }
 +      }
 +      else if ( variant == 2 ) {
 +        if (geom == NORM_TRI3) setRefCoords( TTria3a() );
 +        else                   setRefCoords( TTria6a() );
 +        switch ( nbGauss ) {
 +        case 1: {
 +          add( -1/3., -1/3., 2. ); break;
 +        }
 +        case 3: {
 +          add( -2/3.,  1/3., 2/3. );
 +          add( -2/3., -2/3., 2/3. );
 +          add(  1/3., -2/3., 2/3. ); break;
 +        }
 +        case 6: {
 +          const double P1 = 0.11169079483905, P2 = 0.0549758718227661;
 +          const double A  = 0.445948490915965, B = 0.091576213509771;
 +          add( 2*B-1, 1-4*B, 4*P2 ); 
 +          add( 2*B-1, 2*B-1, 4*P2 );
 +          add( 1-4*B, 2*B-1, 4*P2 );
 +          add( 1-4*A, 2*A-1, 4*P1 );
 +          add( 2*A-1, 1-4*A, 4*P1 ); 
 +          add( 2*A-1, 2*A-1, 4*P1 ); break;
 +        }
 +        default:
 +          THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TRIA, variant 2: "
 +                     <<nbGauss);
 +        }
 +      }
 +      else if ( variant == 3 ) {
 +        if (geom == NORM_TRI3) setRefCoords( TTria3b() );
 +        else                   setRefCoords( TTria6b() );
 +        switch ( nbGauss ) {
 +        case 4: {
 +          add( 1/3., 1/3., -27/96 );
 +          add( 0.2 , 0.2 ,  25/96 );
 +          add( 0.6 , 0.2 ,  25/96 );
 +          add( 0.2 , 0.6 ,  25/96 ); break;
 +        }
 +        default:
 +          THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TRIA, variant 3: "
 +                     <<nbGauss);
 +        }
 +      }
 +      break;
 +
 +    case NORM_QUAD4:
 +    case NORM_QUAD8:
 +      if ( variant == 1 ) {
 +        if (geom == NORM_QUAD4) setRefCoords( TQuad4b() );
 +        else                    setRefCoords( TQuad8b() );
 +        switch ( nbGauss ) {
 +        case 1: { // FPG1
 +          add(  0,  0,  4 ); break;
 +        }
 +        case 4: { // FPG4
 +          const double a = 1/sqrt(3.);
 +          add( -a, -a,  1 );
 +          add(  a, -a,  1 );
 +          add(  a,  a,  1 );
 +          add( -a,  a,  1 ); break;
 +        }
 +        case 5: { // out from the 3 specs
 +          const double a = 0.774596669241483;
 +          add( -a, -a,  0.5 );
 +          add(  a, -a,  0.5 );
 +          add(  a,  a,  0.5 );
 +          add( -a,  a,  0.5 );
 +          add(  0,  0,  2.0 ); break;
 +        }
 +        case 9: { // FPG9
 +          const double a = 0.774596669241483;
 +          add( -a, -a,  25/81. );
 +          add(  a, -a,  25/81. );
 +          add(  a,  a,  25/81. );
 +          add( -a,  a,  25/81. );
 +          add( 0., -a,  40/81. );
 +          add(  a, 0.,  40/81. );
 +          add( 0.,  a,  40/81. );
 +          add( -a, 0.,  40/81. );
 +          add( 0., 0.,  64/81. ); break;
 +        }
 +        default:
 +          THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for QUAD, variant 1: "
 +                     <<nbGauss);
 +        }
 +      }
 +      else if ( variant == 2 ) {
 +        if (geom == NORM_QUAD4) setRefCoords( TQuad4a() );
 +        else                    setRefCoords( TQuad8a() );
 +        switch ( nbGauss ) {
 +        case 4: {
 +          const double a = 1/sqrt(3.);
 +          add( -a,  a,  1 );
 +          add( -a, -a,  1 );
 +          add(  a, -a,  1 );
 +          add(  a,  a,  1 ); break;
 +        }
 +        case 9: {
 +          const double a = 0.774596669241483;
 +          add( -a,  a,  25/81. );
 +          add( -a, -a,  25/81. );
 +          add(  a, -a,  25/81. );
 +          add(  a,  a,  25/81. );
 +          add( -a, 0.,  40/81. );
 +          add( 0., -a,  40/81. );
 +          add(  a, 0.,  40/81. );
 +          add( 0.,  a,  40/81. );
 +          add( 0., 0.,  64/81. ); break;
 +        }
 +        default:
 +          THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for QUAD, variant 1: "
 +                     <<nbGauss);
 +        }
 +      }
 +      else if ( variant == 3 ) {
 +        if (geom == NORM_QUAD4) setRefCoords( TQuad4b() );
 +        else                    setRefCoords( TQuad8b() );
 +        switch ( nbGauss ) {
 +        case 4: {
 +          const double a = 3/sqrt(3.);
 +          add( -a, -a,  1 );
 +          add( -a,  a,  1 );
 +          add(  a, -a,  1 );
 +          add(  a,  a,  1 ); break;
 +        }
 +        case 9: {
 +          const double a = sqrt(3/5.), c1 = 5/9., c2 = 8/9.;
 +          const double c12 = c1*c2, c22 = c2*c2, c1c2 = c1*c2;
 +          add( -a, -a,  c12  );
 +          add( -a, 0.,  c1c2 );
 +          add( -a,  a,  c12  );
 +          add( 0., -a,  c1c2 );
 +          add( 0., 0.,  c22  );
 +          add( 0.,  a,  c1c2 );
 +          add(  a, -a,  c12  );
 +          add(  a, 0.,  c1c2 );
 +          add(  a,  a,  c12  ); break;
 +        }
 +        default:
 +          THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for QUAD, variant 3: "
 +                     <<nbGauss);
 +        }
 +      }
 +      break;
 +
 +    case NORM_TETRA4:
 +    case NORM_TETRA10:
 +      if (geom == NORM_TETRA4) setRefCoords( TTetra4a() );
 +      else                 setRefCoords( TTetra10a() );
 +      switch ( nbGauss ) {
 +      case 4: { // FPG4
 +        const double a = (5 - sqrt(5.))/20., b = (5 + 3*sqrt(5.))/20.;
 +        add(  a,  a,  a,  1/24. );
 +        add(  a,  a,  b,  1/24. );
 +        add(  a,  b,  a,  1/24. );
 +        add(  b,  a,  a,  1/24. ); break;
 +      }
 +      case 5: { // FPG5
 +        const double a = 0.25, b = 1/6., c = 0.5;
 +        add(  a,  a,  a, -2/15. );
 +        add(  b,  b,  b,  3/40. );
 +        add(  b,  b,  c,  3/40. );
 +        add(  b,  c,  b,  3/40. );
 +        add(  c,  b,  b,  3/40. ); break;
 +      }
 +      case 15: { // FPG15
 +        const double a = 0.25;
 +        const double b1 = (7 + sqrt(15.))/34., c1 = (13 + 3*sqrt(15.))/34., d = (5 - sqrt(15.))/20.;
 +        const double b2 = (7 - sqrt(15.))/34., c2 = (13 - 3*sqrt(15.))/34., e = (5 + sqrt(15.))/20.;
 +        const double P1 = (2665 - 14*sqrt(15.))/226800.;
 +        const double P2 = (2665 + 14*sqrt(15.))/226800.;
 +        add(  a,  a,  a,  8/405.);//_____
 +        add( b1, b1, b1,  P1    );
 +        add( b1, b1, c1,  P1    );
 +        add( b1, c1, b1,  P1    );
 +        add( c1, b1, b1,  P1    );//_____
 +        add( b2, b2, b2,  P2    );
 +        add( b2, b2, c2,  P2    );
 +        add( b2, c2, b2,  P2    );
 +        add( c2, b2, b2,  P2    );//_____
 +        add(  d,  d,  e,  5/567.);
 +        add(  d,  e,  d,  5/567.);
 +        add(  e,  d,  d,  5/567.);
 +        add(  d,  e,  e,  5/567.);
 +        add(  e,  d,  e,  5/567.);
 +        add(  e,  e,  d,  5/567.);
 +        break;
 +      }
 +      default:
 +        THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TETRA: "<<nbGauss);
 +      }
 +      break;
 +
 +    case NORM_PYRA5:
 +    case NORM_PYRA13:
 +      if (geom == NORM_PYRA5) setRefCoords( TPyra5a() );
 +      else                setRefCoords( TPyra13a() );
 +      switch ( nbGauss ) {
 +      case 5: { // FPG5
 +        const double h1 = 0.1531754163448146;
 +        const double h2 = 0.6372983346207416;
 +        add(  .5,  0.,  h1,  2/15. );
 +        add(  0.,  .5,  h1,  2/15. );
 +        add( -.5,  0.,  h1,  2/15. );
 +        add(  0., -.5,  h1,  2/15. );
 +        add(  0.,  0.,  h2,  2/15. ); break;
 +      }
 +      case 6: { // FPG6
 +        const double p1 = 0.1024890634400000 ;
 +        const double p2 = 0.1100000000000000 ;
 +        const double p3 = 0.1467104129066667 ;
 +        const double a  = 0.5702963741068025 ;
 +        const double h1 = 0.1666666666666666 ;
 +        const double h2 = 0.08063183038464675;
 +        const double h3 = 0.6098484849057127 ;
 +        add(  a, 0.,  h1,  p1 );
 +        add( 0.,  a,  h1,  p1 );
 +        add( -a, 0.,  h1,  p1 );
 +        add( 0., -a,  h1,  p1 );
 +        add( 0., 0.,  h2,  p2 );
 +        add( 0., 0.,  h3,  p3 ); break;
 +      }
 +      case 27: { // FPG27
 +        const double a1  = 0.788073483; 
 +        const double b6  = 0.499369002; 
 +        const double b1  = 0.848418011; 
 +        const double c8  = 0.478508449; 
 +        const double c1  = 0.652816472; 
 +        const double d12 = 0.032303742; 
 +        const double d1  = 1.106412899;
 +        double z = 1/2., fz = b1/2*(1 - z);
 +        add(  0.,  0.,   z,  a1 ); // 1
 +        add(  fz,  fz,   z,  b6 ); // 2
 +        add( -fz,  fz,   z,  b6 ); // 3
 +        add( -fz, -fz,   z,  b6 ); // 4
 +        add(  fz, -fz,   z,  b6 ); // 5
 +        z = (1 - b1)/2.;
 +        add(  0.,  0.,   z,  b6 ); // 6
 +        z = (1 + b1)/2.;
 +        add(  0.,  0.,   z,  b6 ); // 7
 +        z = (1 - c1)/2.; fz = c1*(1 - z);
 +        add(  fz,  0.,   z,  c8 ); // 8
 +        add(  0.,  fz,   z,  c8 ); // 9
 +        add( -fz,  0.,   z,  c8 ); // 10
 +        add(  0., -fz,   z,  c8 ); // 11
 +        z = (1 + c1)/2.; fz = c1*(1 - z);
 +        add(  fz,  0.,   z,  c8 ); // 12
 +        add(  0.,  fz,   z,  c8 ); // 13
 +        add( -fz,  0.,   z,  c8 ); // 14
 +        add(  0., -fz,   z,  c8 ); // 15
 +        z = (1 - d1)/2., fz = d1/2*(1 - z);
 +        add(  fz,  fz,   z,  d12); // 16
 +        add( -fz,  fz,   z,  d12); // 17
 +        add( -fz, -fz,   z,  d12); // 18
 +        add(  fz, -fz,   z,  d12); // 19
 +        z = 1/2.; fz = d1*(1 - z);
 +        add(  fz,  0.,   z,  d12); // 20
 +        add(  0.,  fz,   z,  d12); // 21
 +        add( -fz,  0.,   z,  d12); // 22
 +        add(  0., -fz,   z,  d12); // 23
 +        z = (1 + d1)/2., fz = d1/2*(1 - z);
 +        add(  fz,  fz,   z,  d12); // 24
 +        add( -fz,  fz,   z,  d12); // 25
 +        add( -fz, -fz,   z,  d12); // 26
 +        add(  fz, -fz,   z,  d12); // 27
 +        break;
 +      }
 +      default:
 +        THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PYRA: "<<nbGauss);
 +      }
 +      break;
 +    case NORM_PENTA6:
 +    case NORM_PENTA15:
 +      if (geom == NORM_PENTA6) setRefCoords( TPenta6a() );
 +      else                 setRefCoords( TPenta15a() );
 +      switch ( nbGauss ) {
 +      case 6: { // FPG6
 +        const double a = sqrt(3.)/3.;
 +        add( -a, .5, .5,  1/6. );
 +        add( -a, 0., .5,  1/6. );
 +        add( -a, .5, 0.,  1/6. );
 +        add(  a, .5, .5,  1/6. );
 +        add(  a, 0., .5,  1/6. );
 +        add(  a, .5, 0.,  1/6. ); break;
 +      }
 +      case 8: { // FPG8
 +        const double a = 0.577350269189626;
 +        add( -a, 1/3., 1/3., -27/96. );
 +        add( -a,  0.6,  0.2,  25/96. );
 +        add( -a,  0.2,  0.6,  25/96. );
 +        add( -a,  0.2,  0.2,  25/96. );
 +        add( +a, 1/3., 1/3., -27/96. );
 +        add( +a,  0.6,  0.2,  25/96. );
 +        add( +a,  0.2,  0.6,  25/96. );
 +        add( +a,  0.2,  0.2,  25/96. ); break;
 +      }
 +      case 21: { // FPG21
 +        const double d = sqrt(3/5.), c1 = 5/9., c2 = 8/9.; // d <=> alfa
 +        const double a = (6 + sqrt(15.))/21.;
 +        const double b = (6 - sqrt(15.))/21.;
 +        const double P1 = (155 + sqrt(15.))/2400.;
 +        const double P2 = (155 - sqrt(15.))/2400.;  //___
 +        add( -d,  1/3.,  1/3., c1*9/80. );//___
 +        add( -d,     a,     a, c1*P1    );
 +        add( -d, 1-2*a,     a, c1*P1    );
 +        add( -d,     a, 1-2*a, c1*P1    );//___
 +        add( -d,     b,     b, c1*P2    );
 +        add( -d, 1-2*b,     b, c1*P2    );
 +        add( -d,     b, 1-2*b, c1*P2    );//___
 +        add( 0.,  1/3.,  1/3., c2*9/80. );//___
 +        add( 0.,     a,     a, c2*P1    );
 +        add( 0., 1-2*a,     a, c2*P1    );
 +        add( 0.,     a, 1-2*a, c2*P1    );//___
 +        add( 0.,     b,     b, c2*P2    );
 +        add( 0., 1-2*b,     b, c2*P2    );
 +        add( 0.,     b, 1-2*b, c2*P2    );//___
 +        add(  d,  1/3.,  1/3., c1*9/80. );//___
 +        add(  d,     a,     a, c1*P1    );
 +        add(  d, 1-2*a,     a, c1*P1    );
 +        add(  d,     a, 1-2*a, c1*P1    );//___
 +        add(  d,     b,     b, c1*P2    );
 +        add(  d, 1-2*b,     b, c1*P2    );
 +        add(  d,     b, 1-2*b, c1*P2    );//___
 +        break;
 +      }
 +      default:
 +        THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PENTA: " <<nbGauss);
 +      }
 +      break;
 +
 +    case NORM_HEXA8:
 +    case NORM_HEXA20:
 +      if (geom == NORM_HEXA8) setRefCoords( THexa8a() );
 +      else                    setRefCoords( THexa20a() );
 +      switch ( nbGauss ) {
 +      case 8: { // FPG8
 +        const double a = sqrt(3.)/3.;
 +        add( -a, -a, -a,  1. );
 +        add( -a, -a,  a,  1. );
 +        add( -a,  a, -a,  1. );
 +        add( -a,  a,  a,  1. );
 +        add(  a, -a, -a,  1. );
 +        add(  a, -a,  a,  1. );
 +        add(  a,  a, -a,  1. );
 +        add(  a,  a,  a,  1. ); break;
 +      }
 +      case 27: { // FPG27
 +        const double a = sqrt(3/5.), c1 = 5/9., c2 = 8/9.;
 +        const double c12 = c1*c1, c13 = c1*c1*c1;
 +        const double c22 = c2*c2, c23 = c2*c2*c2;
 +        add( -a, -a, -a,   c13  ); // 1
 +        add( -a, -a, 0., c12*c2 ); // 2
 +        add( -a, -a,  a,   c13  ); // 3
 +        add( -a, 0., -a, c12*c2 ); // 4
 +        add( -a, 0., 0., c1*c22 ); // 5
 +        add( -a, 0.,  a, c12*c2 ); // 6
 +        add( -a,  a, -a,   c13  ); // 7
 +        add( -a,  a, 0., c12*c2 ); // 8
 +        add( -a,  a,  a,   c13  ); // 9
 +        add( 0., -a, -a, c12*c2 ); // 10
 +        add( 0., -a, 0., c1*c22 ); // 11
 +        add( 0., -a,  a, c12*c2 ); // 12
 +        add( 0., 0., -a, c1*c22 ); // 13
 +        add( 0., 0., 0.,   c23  ); // 14
 +        add( 0., 0.,  a, c1*c22 ); // 15
 +        add( 0.,  a, -a, c12*c2 ); // 16
 +        add( 0.,  a, 0., c1*c22 ); // 17
 +        add( 0.,  a,  a, c12*c2 ); // 18
 +        add(  a, -a, -a,   c13  ); // 19
 +        add(  a, -a, 0., c12*c2 ); // 20
 +        add(  a, -a,  a,   c13  ); // 21
 +        add(  a, 0., -a, c12*c2 ); // 22
 +        add(  a, 0., 0., c1*c22 ); // 23
 +        add(  a, 0.,  a, c12*c2 ); // 24
 +        add(  a,  a, -a,   c13  ); // 25
 +        add(  a,  a, 0., c12*c2 ); // 26
 +        add(  a,  a,  a,   c13  ); // 27
 +        break;
 +      }
 +      default:
 +        THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PENTA: " <<nbGauss);
 +      }
 +      break;
 +
 +    default:
 +      THROW_IK_EXCEPTION("TGaussDef: unexpected EGeometrieElement: "<< geom);
 +    }
 +
 +    if ( myWeights.capacity() != myWeights.size() )
 +      THROW_IK_EXCEPTION("TGaussDef: Not all gauss points defined");
 +  }
 +}
 +  
 +//================================================================================
 +/*!
 + * \brief Return dimension for the given cell type
 + */
 +//================================================================================
 +
 +unsigned SauvUtilities::getDimension( INTERP_KERNEL::NormalizedCellType type )
 +{
 +  return type == NORM_ERROR ? -1 : INTERP_KERNEL::CellModel::GetCellModel( type ).getDimension();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Returns interlace array to transform a quadratic GIBI element to a MED one.
 + *        i-th array item gives node index in GIBI connectivity for i-th MED node
 + */
 +//================================================================================
 +
 +const int * SauvUtilities::getGibi2MedQuadraticInterlace( INTERP_KERNEL::NormalizedCellType type )
 +{
 +  static std::vector<const int*> conn;
 +  static const int hexa20 [] = {0,6,4,2, 12,18,16,14, 7,5,3,1, 19,17,15,13, 8,11,10,9};
 +  static const int penta15[] = {0,2,4, 9,11,13, 1,3,5, 10,12,14, 6,8,7};
 +  static const int pyra13 [] = {0,2,4,6, 12, 1,3,5,7, 8,9,10,11};
 +  static const int tetra10[] = {0,2,4, 9, 1,3,5, 6,7,8};
 +  static const int quad8  [] = {0,2,4,6, 1,3,5,7};
 +  static const int tria6  [] = {0,2,4, 1,3,5};
 +  static const int seg3   [] = {0,2,1};
 +  if ( conn.empty() )
 +  {
 +    conn.resize( MaxMedCellType + 1, 0 );
 +    conn[ NORM_HEXA20 ] = hexa20;
 +    conn[ NORM_PENTA15] = penta15;
 +    conn[ NORM_PYRA13 ] = pyra13;
 +    conn[ NORM_TETRA10] = tetra10;
 +    conn[ NORM_SEG3   ] = seg3;
 +    conn[ NORM_TRI6   ] = tria6;
 +    conn[ NORM_QUAD8  ] = quad8;
 +  }
 +  return conn[ type ];
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Avoid coping sortedNodeIDs
 + */
 +//================================================================================
 +
 +Cell::Cell(const Cell& ma)
 +  : _nodes(ma._nodes), _reverse(ma._reverse), _sortedNodeIDs(0), _number(ma._number)
 +{
 +  if ( ma._sortedNodeIDs )
 +    {
 +      _sortedNodeIDs = new int[ _nodes.size() ];
 +      std::copy( ma._sortedNodeIDs, ma._sortedNodeIDs + _nodes.size(), _sortedNodeIDs );
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Rerturn the i-th link of face
 + */
 +//================================================================================
 +
 +SauvUtilities::Link Cell::link(int i) const
 +{
 +  int i2 = ( i + 1 ) % _nodes.size();
 +  if ( _reverse )
 +    return std::make_pair( _nodes[i2]->_number, _nodes[i]->_number );
 +  else
 +    return std::make_pair( _nodes[i]->_number, _nodes[i2]->_number );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief creates if needed and return _sortedNodeIDs
 + */
 +//================================================================================
 +
 +const TID* Cell::getSortedNodes() const
 +{
 +  if ( !_sortedNodeIDs )
 +  {
 +    size_t l=_nodes.size();
 +    _sortedNodeIDs = new int[ l ];
 +
 +    for (size_t i=0; i!=l; ++i)
 +      _sortedNodeIDs[i]=_nodes[i]->_number;
 +    std::sort( _sortedNodeIDs, _sortedNodeIDs + l );
 +  }
 +  return _sortedNodeIDs;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Compare sorted ids of cell nodes
 + */
 +//================================================================================
 +
 +bool Cell::operator< (const Cell& ma) const
 +{
 +  if ( _nodes.size() == 1 )
 +    return _nodes[0] < ma._nodes[0];
 +
 +  const int* v1 = getSortedNodes();
 +  const int* v2 = ma.getSortedNodes();
 +  for ( const int* vEnd = v1 + _nodes.size(); v1 < vEnd; ++v1, ++v2 )
 +    if(*v1 != *v2)
 +      return *v1 < *v2;
 +  return false;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Dump a Cell
 + */
 +//================================================================================
 +
 +std::ostream& SauvUtilities::operator<< (std::ostream& os, const SauvUtilities::Cell& ma)
 +{
 +  os << "cell " << ma._number << " (" << ma._nodes.size() << " nodes) : < " << ma._nodes[0]->_number;
 +  for( size_t i=1; i!=ma._nodes.size(); ++i)
 +    os << ", " << ma._nodes[i]->_number;
 +#ifdef _DEBUG_
 +  os << " > sortedNodes: ";
 +  if ( ma._sortedNodeIDs ) {
 +    os << "< ";
 +    for( size_t i=0; i!=ma._nodes.size(); ++i)
 +      os << ( i ? ", " : "" ) << ma._sortedNodeIDs[i];
 +    os << " >";
 +  }
 +  else {
 +    os << "NULL";
 +  }
 +#endif
 +  return os;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return nb of elements in the group
 + */
 +//================================================================================
 +
 +int Group::size() const
 +{
 +  int sizze = 0;
 +  if ( !_relocTable.empty() )
 +    sizze =  _relocTable.size();
 +  else if ( _medGroup )
 +    sizze = _medGroup->getNumberOfTuples();
 +  else if ( !_cells.empty() )
 +    sizze = _cells.size();
 +  else
 +    for ( size_t i = 0; i < _groups.size(); ++i )
 +      sizze += _groups[i]->size();
 +  return sizze;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Conver gibi element type to med one
 + */
 +//================================================================================
 +
 +INTERP_KERNEL::NormalizedCellType SauvUtilities::gibi2medGeom( size_t gibiType )
 +{
 +  if ( gibiType < 1 || gibiType > NbGibiCellTypes )
 +    return NORM_ERROR;
 +
 +  return GibiTypeToMed[ gibiType - 1 ];
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Conver med element type to gibi one
 + */
 +//================================================================================
 +
 +int SauvUtilities::med2gibiGeom( INTERP_KERNEL::NormalizedCellType medGeomType )
 +{
 +  for ( unsigned int i = 0; i < NbGibiCellTypes; i++ )
 +    if ( GibiTypeToMed[ i ] == medGeomType )
 +      return i + 1;
 +
 +  return -1;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Remember the file name
 + */
 +//================================================================================
 +
 +FileReader::FileReader(const char* fileName):_fileName(fileName),_iRead(0),_nbToRead(0)
 +{
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Constructor of ASCII sauve file reader
 + */
 +//================================================================================
 +
 +ASCIIReader::ASCIIReader(const char* fileName)
 +  :FileReader(fileName),
 +   _file(-1)
 +{
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return true
 + */
 +//================================================================================
 +
 +bool ASCIIReader::isASCII() const
 +{
 +  return true;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Try to open an ASCII file
 + */
 +//================================================================================
 +
 +bool ASCIIReader::open()
 +{
 +#ifdef WIN32
 +  _file = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY);
 +#else
 +  _file = ::open (_fileName.c_str(), O_RDONLY);
 +#endif
 +  if (_file >= 0)
 +    {
 +      _start  = new char [GIBI_BufferSize]; // working buffer beginning
 +      //_tmpBuf = new char [GIBI_MaxOutputLen];
 +      _ptr    = _start;
 +      _eptr   = _start;
 +      _lineNb = 0;
 +    }
 +  else
 +    {
 +      //THROW_IK_EXCEPTION("Can't open file "<<_fileName << " fd: " << _file);
 +    }
 +  return (_file >= 0);
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Close the file
 + */
 +//================================================================================
 +
 +ASCIIReader::~ASCIIReader()
 +{
 +  if (_file >= 0)
 +    {
 +      ::close (_file);
 +      if (_start != 0L)
 +        {
 +          delete [] _start;
 +          //delete [] _tmpBuf;
 +          _start = 0;
 +        }
 +      _file = -1;
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return a next line of the file
 + */
 +//================================================================================
 +
 +bool ASCIIReader::getNextLine (char* & line, bool raiseOEF /*= true*/ )
 +{
 +  if ( getLine( line )) return true;
 +  if ( raiseOEF )
 +    THROW_IK_EXCEPTION("Unexpected EOF on ln "<<_lineNb);
 +  return false;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Read a next line of the file if necessary
 + */
 +//================================================================================
 +
 +bool ASCIIReader::getLine(char* & line)
 +{
 +  bool aResult = true;
 +  // Check the state of the buffer;
 +  // if there is too little left, read the next portion of data
 +  int nBytesRest = _eptr - _ptr;
 +  if (nBytesRest < GIBI_MaxOutputLen)
 +    {
 +      if (nBytesRest > 0)
 +        {
 +          // move the remaining portion to the buffer beginning
 +          for ( int i = 0; i < nBytesRest; ++i )
 +            _start[i] = _ptr[i];
 +          //memcpy (_tmpBuf, _ptr, nBytesRest);
 +          //memcpy (_start, _tmpBuf, nBytesRest);
 +        }
 +      else
 +        {
 +          nBytesRest = 0;
 +        }
 +      _ptr = _start;
 +      const int nBytesRead = ::read (_file,
 +                                     &_start [nBytesRest],
 +                                     GIBI_BufferSize - nBytesRest);
 +      nBytesRest += nBytesRead;
 +      _eptr = &_start [nBytesRest];
 +    }
 +  // Check the buffer for the end-of-line
 +  char * ptr = _ptr;
 +  while (true)
 +    {
 +      // Check for end-of-the-buffer, the ultimate criterion for termination
 +      if (ptr >= _eptr)
 +        {
 +          if (nBytesRest <= 0)
 +            aResult = false;
 +          else
 +            _eptr[-1] = '\0';
 +          break;
 +        }
 +      // seek the line-feed character
 +      if (ptr[0] == '\n')
 +        {
 +          if (ptr[-1] == '\r')
 +            ptr[-1] = '\0';
 +          ptr[0] = '\0';
 +          ++ptr;
 +          break;
 +        }
 +      ++ptr;
 +    }
 +  // Output the result
 +  line = _ptr;
 +  _ptr = ptr;
 +  _lineNb++;
 +
 +  return aResult;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of values
 + *  \param nbToRead - nb of fields to read
 + *  \param nbPosInLine - nb of fields in one line
 + *  \param width - field width
 + *  \param shift - shift from line beginning to the field start
 + */
 +//================================================================================
 +
 +void ASCIIReader::init( int nbToRead, int nbPosInLine, int width, int shift /*= 0*/ )
 +{
 +  _nbToRead    = nbToRead;
 +  _nbPosInLine = nbPosInLine;
 +  _width       = width;
 +  _shift       = shift;
 +  _iPos = _iRead = 0;
 +  if ( _nbToRead )
 +    {
 +      getNextLine( _curPos );
 +      _curPos = _curPos + _shift;
 +    }
 +  else
 +    {
 +      _curPos = 0;
 +    }
 +  _curLocale.clear();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of string values
 + */
 +//================================================================================
 +
 +void ASCIIReader::initNameReading(int nbValues, int width /*= 8*/)
 +{
 +  init( nbValues, 72 / ( width + 1 ), width, 1 );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of integer values
 + */
 +//================================================================================
 +
 +void ASCIIReader::initIntReading(int nbValues)
 +{
 +  init( nbValues, 10, 8 );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of real values
 + */
 +//================================================================================
 +
 +void ASCIIReader::initDoubleReading(int nbValues)
 +{
 +  init( nbValues, 3, 22 );
 +
 +  // Correction 2 of getDouble(): set "C" numeric locale to read numbers
 +  // with dot decimal point separator, as it is in SAUVE files
 +  _curLocale = setlocale(LC_NUMERIC, "C");
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return true if not all values have been read
 + */
 +//================================================================================
 +
 +bool ASCIIReader::more() const
 +{
 +  bool result = false;
 +  if ( _iRead < _nbToRead)
 +    {
 +      if ( _curPos ) result = true;
 +    }
 +  return result;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Go to the nex value
 + */
 +//================================================================================
 +
 +void ASCIIReader::next()
 +{
 +  if ( !more() )
 +    THROW_IK_EXCEPTION("SauvUtilities::ASCIIReader::next(): no more() values to read");
 +  ++_iRead;
 +  ++_iPos;
 +  if ( _iRead < _nbToRead )
 +    {
 +      if ( _iPos >= _nbPosInLine )
 +        {
 +          getNextLine( _curPos );
 +          _curPos = _curPos + _shift;
 +          _iPos = 0;
 +        }
 +      else
 +        {
 +          _curPos = _curPos + _width + _shift;
 +        }
 +    }
 +  else
 +    {
 +      _curPos = 0;
 +      if ( !_curLocale.empty() )
 +        {
 +          setlocale(LC_NUMERIC, _curLocale.c_str());
 +          _curLocale.clear();
 +        }
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current integer value
 + */
 +//================================================================================
 +
 +int ASCIIReader::getInt() const
 +{
 +  // fix for two glued ints (issue 0021009):
 +  // Line nb    |   File contents
 +  // ------------------------------------------------------------------------------------
 +  // 53619905   |       1       2       6       8
 +  // 53619906   |                                                                SCALAIRE
 +  // 53619907   |    -63312600499       1       0       0       0      -2       0       2
 +  //   where -63312600499 is actualy -633 and 12600499
 +  char hold=_curPos[_width];
 +  _curPos[_width] = '\0';
 +  int result = atoi( _curPos );
 +  _curPos[_width] = hold;
 +  return result;
 +  //return atoi(str());
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current float value
 + */
 +//================================================================================
 +
 +float ASCIIReader::getFloat() const
 +{
 +  return getDouble();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current double value
 + */
 +//================================================================================
 +
 +double ASCIIReader::getDouble() const
 +{
 +  //std::string aStr (_curPos);
 +
 +  // Correction: add missing 'E' specifier
 +  // int aPosStart = aStr.find_first_not_of(" \t");
 +  // if (aPosStart < (int)aStr.length()) {
 +  //   int aPosSign = aStr.find_first_of("+-", aPosStart + 1); // pass the leading symbol, as it can be a sign
 +  //   if (aPosSign < (int)aStr.length()) {
 +  //     if (aStr[aPosSign - 1] != 'e' && aStr[aPosSign - 1] != 'E')
 +  //       aStr.insert(aPosSign, "E", 1);
 +  //   }
 +  // }
 +
 +  // Different Correction (more optimal)
 +  // Sample:
 +  //  0.00000000000000E+00 -2.37822406690632E+01  6.03062748797469E+01
 +  //  7.70000000000000-100  7.70000000000000+100  7.70000000000000+100
 +  //0123456789012345678901234567890123456789012345678901234567890123456789
 +  const size_t posE = 18;
 +  std::string aStr (_curPos);
 +  if ( aStr.find('E') < 0 && aStr.find('e') < 0 )
 +    {
 +      if ( aStr.size() < posE+1 )
 +        THROW_IK_EXCEPTION("No more doubles (line #" << lineNb() << ")");
 +      aStr.insert( posE, "E", 1 );
 +      return atof(aStr.c_str());
 +    }
 +  return atof( _curPos );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current string value
 + */
 +//================================================================================
 +
 +std::string ASCIIReader::getName() const
 +{
 +  int len = _width;
 +  while (( _curPos[len-1] == ' ' || _curPos[len-1] == 0) && len > 0 )
 +    len--;
 +  return std::string( _curPos, len );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Constructor of a binary sauve file reader
 + */
 +//================================================================================
 +
 +XDRReader::XDRReader(const char* fileName) :FileReader(fileName), _xdrs_file(NULL)
 +{
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Close the XDR sauve file
 + */
 +//================================================================================
 +
 +XDRReader::~XDRReader()
 +{
 +#ifdef HAS_XDR  
 +  if ( _xdrs_file )
 +    {
 +      xdr_destroy((XDR*)_xdrs);
 +      free((XDR*)_xdrs);
 +      ::fclose(_xdrs_file);
 +      _xdrs_file = NULL;
 +    }
 +#endif
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return false
 + */
 +//================================================================================
 +
 +bool XDRReader::isASCII() const
 +{
 +  return false;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Try to open an XRD file
 + */
 +//================================================================================
 +
 +bool XDRReader::open()
 +{
 +  bool xdr_ok = false;
 +#ifdef HAS_XDR
 +#ifdef WIN32
 +  if ((_xdrs_file = ::fopen(_fileName.c_str(), "rb")))
 +#else 
 +  if ((_xdrs_file = ::fopen(_fileName.c_str(), "r")))
 +#endif
 +    {
 +      _xdrs = (XDR *)malloc(sizeof(XDR));
 +      xdrstdio_create((XDR*)_xdrs, _xdrs_file, XDR_DECODE);
 +
 +      const int maxsize = 10;
 +      char icha[maxsize+1];
 +      char* icha2 = icha;
 +      if (( xdr_ok = xdr_string((XDR*)_xdrs, &icha2, maxsize)))
 +        {
 +          icha[maxsize] = '\0';
 +          xdr_ok = (strcmp(icha, "CASTEM XDR") == 0);
 +        }
 +      if ( !xdr_ok )
 +        {
 +          xdr_destroy((XDR*)_xdrs);
 +          free((XDR*)_xdrs);
 +          fclose(_xdrs_file);
 +          _xdrs_file = NULL;
 +        }
 +    }
 +#endif
 +  return xdr_ok;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief A stub
 + */
 +//================================================================================
 +
 +bool XDRReader::getNextLine (char* &, bool )
 +{
 +  return true;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of values
 + *  \param nbToRead - nb of fields to read
 + *  \param width - field width
 + */
 +//================================================================================
 +
 +void XDRReader::init( int nbToRead, int width/*=0*/ )
 +{
 +  if(_iRead < _nbToRead)
 +    {
 +      std::cout << "_iRead, _nbToRead : " << _iRead << " " << _nbToRead << std::endl;
 +      std::cout << "Unfinished iteration before new one !" << std::endl;
 +      THROW_IK_EXCEPTION("SauvUtilities::XDRReader::init(): Unfinished iteration before new one !");
 +    }
 +  _iRead    = 0;
 +  _nbToRead = nbToRead;
 +  _width    = width;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of string values
 + */
 +//================================================================================
 +
 +void XDRReader::initNameReading(int nbValues, int width)
 +{
 +  init( nbValues, width );
 +  _xdr_kind = _xdr_kind_char;
 +  if(nbValues*width)
 +    {
 +      unsigned int nels = nbValues*width;
 +      _xdr_cvals = (char*)malloc((nels+1)*sizeof(char));
 +#ifdef HAS_XDR
 +      xdr_string((XDR*)_xdrs, &_xdr_cvals, nels);
 +#endif
 +      _xdr_cvals[nels] = '\0';
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of integer values
 + */
 +//================================================================================
 +
 +void XDRReader::initIntReading(int nbValues)
 +{
 +  init( nbValues );
 +  _xdr_kind = _xdr_kind_int;
 +  if(nbValues)
 +    {
 +#ifdef HAS_XDR
 +      unsigned int nels = nbValues;
 +      unsigned int actual_nels;
 +      _xdr_ivals = (int*)malloc(nels*sizeof(int));
 +      xdr_array((XDR*)_xdrs, (char **)&_xdr_ivals, &actual_nels, nels, sizeof(int), (xdrproc_t)xdr_int);
 +#endif
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Prepare for iterating over given nb of real values
 + */
 +//================================================================================
 +
 +void XDRReader::initDoubleReading(int nbValues)
 +{
 +  init( nbValues );
 +  _xdr_kind = _xdr_kind_double;
 +  if(nbValues)
 +    {
 +#ifdef HAS_XDR
 +      unsigned int nels = nbValues;
 +      unsigned int actual_nels;
 +      _xdr_dvals = (double*)malloc(nels*sizeof(double));
 +      xdr_array((XDR*)_xdrs, (char **)&_xdr_dvals, &actual_nels, nels, sizeof(double), (xdrproc_t)xdr_double);
 +#endif
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return true if not all values have been read
 + */
 +//================================================================================
 +
 +bool XDRReader::more() const
 +{
 +  return _iRead < _nbToRead;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Go to the nex value
 + */
 +//================================================================================
 +
 +void XDRReader::next()
 +{
 +  if ( !more() )
 +    THROW_IK_EXCEPTION("SauvUtilities::XDRReader::next(): no more() values to read");
 +
 +  ++_iRead;
 +  if ( _iRead < _nbToRead )
 +    {
 +    }
 +  else
 +    {
 +      if(_xdr_kind == _xdr_kind_char) free(_xdr_cvals);
 +      if(_xdr_kind == _xdr_kind_int) free(_xdr_ivals);
 +      if(_xdr_kind == _xdr_kind_double) free(_xdr_dvals);
 +      _xdr_kind = _xdr_kind_null;
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current integer value
 + */
 +//================================================================================
 +
 +int XDRReader::getInt() const
 +{
 +  if(_iRead < _nbToRead)
 +    {
 +      return _xdr_ivals[_iRead];
 +    }
 +  else
 +    {
 +      int result = 0;
 +#ifdef HAS_XDR
 +      xdr_int((XDR*)_xdrs, &result);
 +#endif
 +      return result;
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current float value
 + */
 +//================================================================================
 +
 +float  XDRReader::getFloat() const
 +{
 +  float result = 0;
 +#ifdef HAS_XDR
 +  xdr_float((XDR*)_xdrs, &result);
 +#endif
 +  return result;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current double value
 + */
 +//================================================================================
 +
 +double XDRReader::getDouble() const
 +{
 +  if(_iRead < _nbToRead)
 +    {
 +      return _xdr_dvals[_iRead];
 +    }
 +  else
 +    {
 +      double result = 0;
 +#ifdef HAS_XDR
 +      xdr_double((XDR*)_xdrs, &result);
 +#endif
 +      return result;
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return the current string value
 + */
 +//================================================================================
 +
 +std::string XDRReader::getName() const
 +{
 +  int len = _width;
 +  char* s = _xdr_cvals + _iRead*_width;
 +  while (( s[len-1] == ' ' || s[len-1] == 0) && len > 0 )
 +    len--;
 +  return std::string( s, len );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Throw an exception if not all needed data is present
 + */
 +//================================================================================
 +
 +void IntermediateMED::checkDataAvailability() const
 +{
 +  if ( _spaceDim == 0 )
 +    THROW_IK_EXCEPTION("Wrong file format"); // it is the first record in the sauve file
 +
 +  if ( _groups.empty() )
 +    THROW_IK_EXCEPTION("No elements have been read");
 +
 +  if ( _points.empty() || _nbNodes == 0 )
 +    THROW_IK_EXCEPTION("Nodes of elements are not filled");
 +
 +  if ( _coords.empty() )
 +    THROW_IK_EXCEPTION("Node coordinates are missing");
 +
 +  if ( _coords.size() < _nbNodes * _spaceDim )
 +    THROW_IK_EXCEPTION("Nodes and coordinates mismatch");
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Safely adds a new Group
 + */
 +//================================================================================
 +
 +Group* IntermediateMED::addNewGroup(std::vector<SauvUtilities::Group*>* groupsToFix)
 +{
 +  if ( _groups.size() == _groups.capacity() ) // re-allocation would occure
 +    {
 +      std::vector<Group> newGroups( _groups.size() );
 +      newGroups.push_back( Group() );
 +
 +      for ( size_t i = 0; i < _groups.size(); ++i )
 +        {
 +          // avoid copying _cells
 +          std::vector<const Cell*> cells;
 +          cells.swap( _groups[i]._cells );
 +          newGroups[i] = _groups[i];
 +          newGroups[i]._cells.swap( cells );
 +
 +          // correct pointers to sub-groups
 +          for ( size_t j = 0; j < _groups[i]._groups.size(); ++j )
 +            {
 +              int iG = _groups[i]._groups[j] - &_groups[0];
 +              newGroups[i]._groups[j] = & newGroups[ iG ];
 +            }
 +        }
 +
 +      // fix given groups
 +      if ( groupsToFix )
 +        for ( size_t i = 0; i < groupsToFix->size(); ++i )
 +          if ( (*groupsToFix)[i] )
 +            {
 +              int iG = (*groupsToFix)[i] - &_groups[0];
 +              (*groupsToFix)[i] = & newGroups[ iG ];
 +            }
 +
 +      // fix field supports
 +      for ( int isNode = 0; isNode < 2; ++isNode )
 +        {
 +          std::vector<DoubleField* >& fields = isNode ? _nodeFields : _cellFields;
 +          for ( size_t i = 0; i < fields.size(); ++i )
 +            {
 +              if ( !fields[i] ) continue;
 +              for ( size_t j = 0; j < fields[i]->_sub.size(); ++j )
 +                if ( fields[i]->_sub[j]._support )
 +                  {
 +                    int iG = fields[i]->_sub[j]._support - &_groups[0];
 +                    fields[i]->_sub[j]._support = & newGroups[ iG ];
 +                  }
 +              if ( fields[i]->_group )
 +                {
 +                  int iG = fields[i]->_group - &_groups[0];
 +                  fields[i]->_group = & newGroups[ iG ];
 +                }
 +            }
 +        }
 +
 +      _groups.swap( newGroups );
 +    }
 +  else
 +    {
 +      _groups.push_back( Group() );
 +    }
 +  return &_groups.back();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Makes ParaMEDMEM::MEDFileData from self
 + */
 +//================================================================================
 +
 +ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS()
 +{
 +  MEDCouplingAutoRefCountObjectPtr< MEDFileUMesh >  mesh   = makeMEDFileMesh();
 +  MEDCouplingAutoRefCountObjectPtr< MEDFileFields > fields = makeMEDFileFields(mesh);
 +
 +  MEDCouplingAutoRefCountObjectPtr< MEDFileMeshes > meshes = MEDFileMeshes::New();
 +  MEDCouplingAutoRefCountObjectPtr< MEDFileData >  medData = MEDFileData::New();
 +  meshes->pushMesh( mesh );
 +  medData->setMeshes( meshes );
 +  if ( fields ) medData->setFields( fields );
 +
 +  return medData.retn();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Creates ParaMEDMEM::MEDFileUMesh from its data
 + */
 +//================================================================================
 +
 +ParaMEDMEM::MEDFileUMesh* IntermediateMED::makeMEDFileMesh()
 +{
 +  // check if all needed piles are present
 +  checkDataAvailability();
 +
 +  // set long names
 +  setGroupLongNames();
 +
 +  // fix element orientation
 +  if ( _spaceDim == 2 || _spaceDim == 1 )
 +    orientElements2D();
 +  else if ( _spaceDim == 3 )
 +    orientElements3D();
 +
 +  // process groups
 +  decreaseHierarchicalDepthOfSubgroups();
 +  eraseUselessGroups();
 +  //detectMixDimGroups();
 +
 +  // assign IDs
 +  _points.numberNodes();
 +  numberElements();
 +
 +  // make the med mesh
 +
 +  MEDFileUMesh* mesh = MEDFileUMesh::New();
 +
 +  DataArrayDouble *coords = getCoords();
 +  setConnectivity( mesh, coords );
 +  setGroups( mesh );
 +
 +  coords->decrRef();
 +
 +  if ( !mesh->getName().c_str() || strlen( mesh->getName().c_str() ) == 0 )
 +    mesh->setName( "MESH" );
 +
 +  return mesh;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Set long names to groups
 + */
 +//================================================================================
 +
 +void IntermediateMED::setGroupLongNames()
 +{
 +  // IMP 0020434: mapping GIBI names to MED names
 +  // set med names to objects (mesh, fields, support, group or other)
 +
 +  std::set<int> treatedGroups;
 +
 +  std::list<nameGIBItoMED>::iterator itGIBItoMED = _listGIBItoMED_mail.begin();
 +  for (; itGIBItoMED != _listGIBItoMED_mail.end(); itGIBItoMED++)
 +    {
 +      if ( (int)_groups.size() < itGIBItoMED->gibi_id ) continue;
 +
 +      SauvUtilities::Group & grp = _groups[itGIBItoMED->gibi_id - 1];
 +
 +      // if there are several names for grp then the 1st name is the name
 +      // of grp and the rest ones are names of groups referring grp (issue 0021311)
 +      const bool isRefName = !treatedGroups.insert( itGIBItoMED->gibi_id ).second;
 +      if ( !isRefName )
 +        {
 +          grp._name = _mapStrings[ itGIBItoMED->med_id ];
 +        }
 +      else if ( !grp._refNames.empty() && grp._refNames.back().empty() )
 +        {
 +          for ( unsigned i = 0; i < grp._refNames.size(); ++i )
 +            if ( grp._refNames[i].empty() )
 +              grp._refNames[i] = _mapStrings[ (*itGIBItoMED).med_id ];
 +        }
 +      else
 +        {
 +          grp._refNames.push_back( _mapStrings[ (*itGIBItoMED).med_id ]);
 +        }
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Set long names to fields
 + */
 +//================================================================================
 +
 +void IntermediateMED::setFieldLongNames(std::set< std::string >& usedNames)
 +{
 +  std::list<nameGIBItoMED>::iterator itGIBItoMED = _listGIBItoMED_cham.begin();
 +  for (; itGIBItoMED != _listGIBItoMED_cham.end(); itGIBItoMED++)
 +    {
 +      if (itGIBItoMED->gibi_pile == PILE_FIELD)
 +        {
 +          _cellFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id];
 +        }
 +      else if (itGIBItoMED->gibi_pile == PILE_NODES_FIELD)
 +        {
 +          _nodeFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id];
 +        }
 +    } // iterate on _listGIBItoMED_cham
 +
 +  for (itGIBItoMED =_listGIBItoMED_comp.begin(); itGIBItoMED != _listGIBItoMED_comp.end(); itGIBItoMED++)
 +    {
 +      std::string medName  = _mapStrings[itGIBItoMED->med_id];
 +      std::string gibiName = _mapStrings[itGIBItoMED->gibi_id];
 +
 +      bool name_found = false;
 +      for ( int isNodal = 0; isNodal < 2 && !name_found; ++isNodal )
 +        {
 +          std::vector<DoubleField* > & fields = isNodal ? _nodeFields : _cellFields;
 +          for ( size_t ifi = 0; ifi < fields.size() && !name_found; ifi++)
 +            {
 +              if (medName.find( fields[ifi]->_name + "." ) == 0 )
 +                {
 +                  std::vector<DoubleField::_Sub_data>& aSubDs = fields[ifi]->_sub;
 +                  int nbSub = aSubDs.size();
 +                  for (int isu = 0; isu < nbSub; isu++)
 +                    for (int ico = 0; ico < aSubDs[isu].nbComponents(); ico++)
 +                      {
 +                        if (aSubDs[isu].compName(ico) == gibiName)
 +                          {
 +                            std::string medNameCompo = medName.substr( fields[ifi]->_name.size() + 1 );
 +                            fields[ifi]->_sub[isu].compName(ico) = medNameCompo;
 +                          }
 +                      }
 +                }
 +            }
 +        }
 +    } // iterate on _listGIBItoMED_comp
 +
 +  for ( size_t i = 0; i < _nodeFields.size() ; i++)
 +    usedNames.insert( _nodeFields[i]->_name );
 +  for ( size_t i = 0; i < _cellFields.size() ; i++)
 +    usedNames.insert( _cellFields[i]->_name );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Decrease hierarchical depth of subgroups
 + */
 +//================================================================================
 +
 +void IntermediateMED::decreaseHierarchicalDepthOfSubgroups()
 +{
 +  for (size_t i=0; i!=_groups.size(); ++i)
 +  {
 +    Group& grp = _groups[i];
 +    for (size_t j = 0; j < grp._groups.size(); ++j )
 +    {
 +      Group & sub_grp = *grp._groups[j];
 +      if ( !sub_grp._groups.empty() )
 +      {
 +        // replace j with its 1st subgroup
 +        grp._groups[j] = sub_grp._groups[0];
 +        // push back the rest subs
 +        grp._groups.insert( grp._groups.end(), ++sub_grp._groups.begin(), sub_grp._groups.end() );
 +      }
 +    }
 +    // remove empty sub-_groups
 +    std::vector< Group* > newSubGroups;
 +    newSubGroups.reserve( grp._groups.size() );
 +    for (size_t j = 0; j < grp._groups.size(); ++j )
 +      if ( !grp._groups[j]->empty() )
 +        newSubGroups.push_back( grp._groups[j] );
 +    if ( newSubGroups.size() < grp._groups.size() )
 +      grp._groups.swap( newSubGroups );
 +  }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Erase _groups that won't be converted
 + */
 +//================================================================================
 +
 +void IntermediateMED::eraseUselessGroups()
 +{
 +  // propagate _isProfile=true to sub-groups of composite groups
 +  // for (size_t int i=0; i!=_groups.size(); ++i)
 +  // {
 +  //   Group* grp = _groups[i];
 +  //   if ( grp->_isProfile && !grp->_groups.empty() )
 +  //     for (size_t j = 0; j < grp->_groups.size(); ++j )
 +  //       grp->_groups[j]->_isProfile=true;
 +  // }
 +  std::set<Group*> groups2convert;
 +  // keep not named sub-groups of field supports
 +  for (size_t i=0; i!=_groups.size(); ++i)
 +  {
 +    Group& grp = _groups[i];
 +    if ( grp._isProfile && !grp._groups.empty() )
 +      groups2convert.insert( grp._groups.begin(), grp._groups.end() );
 +  }
 +
 +  // keep named groups and their subgroups
 +  for (size_t i=0; i!=_groups.size(); ++i)
 +  {
 +    Group& grp = _groups[i];
 +    if ( !grp._name.empty() && !grp.empty() )
 +    {
 +      groups2convert.insert( &grp );
 +      groups2convert.insert( grp._groups.begin(), grp._groups.end() );
 +    }
 +  }
 +  // erase groups that are not in groups2convert and not _isProfile
 +  for (size_t i=0; i!=_groups.size(); ++i)
 +  {
 +    Group* grp = &_groups[i];
 +    if ( !grp->_isProfile && !groups2convert.count( grp ) )
 +    {
 +      grp->_cells.clear();
 +      grp->_groups.clear();
 +    }
 +  }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Detect _groups of mixed dimension
 + */
 +//================================================================================
 +
 +void IntermediateMED::detectMixDimGroups()
 +{
 +  //hasMixedCells = false;
 +  for ( size_t i=0; i < _groups.size(); ++i )
 +  {
 +    Group& grp = _groups[i];
 +    if ( grp._groups.size() < 2 )
 +      continue;
 +
 +    // check if sub-groups have different dimension
 +    unsigned dim1 = getDim( &grp );
 +    for ( size_t j = 1; j  < grp._groups.size(); ++j )
 +    {
 +      unsigned dim2 = getDim( grp._groups[j] );
 +      if ( dim1 != dim2 )
 +      {
 +        grp._cells.clear();
 +        grp._groups.clear();
 +        if ( !grp._name.empty() )
 +          std::cout << "Erase a group with elements of different dim |" << grp._name << "|"<< std::endl;
 +        break;
 +      }
 +    }
 +  }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Fix connectivity of elements in 2D space
 + */
 +//================================================================================
 +
 +void IntermediateMED::orientElements2D()
 +{
 +  std::set<Cell>::const_iterator elemIt, elemEnd;
 +  std::vector< std::pair<int,int> > swapVec;
 +
 +  // ------------------------------------
 +  // fix connectivity of quadratic edges
 +  // ------------------------------------
 +  std::set<Cell>& quadEdges = _cellsByType[ INTERP_KERNEL::NORM_SEG3 ];
 +  if ( !quadEdges.empty() )
 +    {
 +      elemIt = quadEdges.begin(), elemEnd = quadEdges.end();
 +      for ( ; elemIt != elemEnd; ++elemIt )
 +        ConvertQuadratic( INTERP_KERNEL::NORM_SEG3, *elemIt );
 +    }
 +
 +  CellsByDimIterator faceIt( *this, 2 );
 +  while ( const std::set<Cell > * faces = faceIt.nextType() )
 +    {
 +      TCellType cellType = faceIt.type();
 +      bool isQuadratic = getGibi2MedQuadraticInterlace( cellType );
 +
 +      getReverseVector( cellType, swapVec );
 +
 +      // ------------------------------------
 +      // fix connectivity of quadratic faces
 +      // ------------------------------------
 +      if ( isQuadratic )
 +        for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ )
 +          ConvertQuadratic( cellType, *elemIt );
 +
 +      // --------------------------
 +      // orient faces clockwise
 +      // --------------------------
 +      // COMMENTED for issue 0022612 note 17739
 +      // int iQuad = isQuadratic ? 2 : 1;
 +      // for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ )
 +      //   {
 +      //     // look for index of the most left node
 +      //     int iLeft = 0, iNode, nbNodes = elemIt->_nodes.size() / iQuad;
 +      //     double x, minX = nodeCoords( elemIt->_nodes[0] )[0];
 +      //     for ( iNode = 1; iNode < nbNodes; ++iNode )
 +      //       if (( x = nodeCoords( elemIt->_nodes[ iNode ])[ 0 ]) < minX )
 +      //         minX = x, iLeft = iNode;
 +
 +      //     // indeces of the nodes neighboring the most left one
 +      //     int iPrev = ( iLeft - 1 < 0 ) ? nbNodes - 1 : iLeft - 1;
 +      //     int iNext = ( iLeft + 1 == nbNodes ) ? 0 : iLeft + 1;
 +      //     // find components of prev-left and left-next vectors
 +      //     double xP = nodeCoords( elemIt->_nodes[ iPrev ])[ 0 ];
 +      //     double yP = nodeCoords( elemIt->_nodes[ iPrev ])[ 1 ];
 +      //     double xN = nodeCoords( elemIt->_nodes[ iNext ])[ 0 ];
 +      //     double yN = nodeCoords( elemIt->_nodes[ iNext ])[ 1 ];
 +      //     double xL = nodeCoords( elemIt->_nodes[ iLeft ])[ 0 ];
 +      //     double yL = nodeCoords( elemIt->_nodes[ iLeft ])[ 1 ];
 +      //     double xPL = xL - xP, yPL = yL - yP; // components of prev-left vector
 +      //     double xLN = xN - xL, yLN = yN - yL; // components of left-next vector
 +      //     // normalise y of the vectors
 +      //     double modPL = sqrt ( xPL * xPL + yPL * yPL );
 +      //     double modLN = sqrt ( xLN * xLN + yLN * yLN );
 +      //     if ( modLN > std::numeric_limits<double>::min() &&
 +      //          modPL > std::numeric_limits<double>::min() )
 +      //       {
 +      //         yPL /= modPL;
 +      //         yLN /= modLN;
 +      //         // summary direction of neighboring links must be positive
 +      //         bool clockwise = ( yPL + yLN > 0 );
 +      //         if ( !clockwise )
 +      //           reverse( *elemIt, swapVec );
 +      //       }
 +      //   }
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Fix connectivity of elements in 3D space
 + */
 +//================================================================================
 +
 +void IntermediateMED::orientElements3D()
 +{
 +  // set _reverse flags of faces
 +  // COMMENTED for issue 0022612 note 17739
 +  //orientFaces3D();
 +
 +  // -----------------
 +  // fix connectivity
 +  // -----------------
 +
 +  std::set<Cell>::const_iterator elemIt, elemEnd;
 +  std::vector< std::pair<int,int> > swapVec;
 +
 +  for ( int dim = 1; dim <= 3; ++dim )
 +  {
 +    CellsByDimIterator cellsIt( *this, dim );
 +    while ( const std::set<Cell > * elems = cellsIt.nextType() )
 +    {
 +      TCellType cellType = cellsIt.type();
 +      bool isQuadratic = getGibi2MedQuadraticInterlace( cellType );
 +      getReverseVector( cellType, swapVec );
 +
 +      elemIt = elems->begin(), elemEnd = elems->end();
 +      for ( ; elemIt != elemEnd; elemIt++ )
 +      {
 +        // GIBI connectivity -> MED one
 +        if( isQuadratic )
 +          ConvertQuadratic( cellType, *elemIt );
 +
 +        // reverse faces
 +        if ( elemIt->_reverse )
 +          reverse ( *elemIt, swapVec );
 +      }
 +    }
 +  }
 +
 +  // COMMENTED for issue 0022612 note 17739
 +  //orientVolumes();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Orient equally (by setting _reverse flag) all connected faces in 3D space
 + */
 +//================================================================================
 +
 +void IntermediateMED::orientFaces3D()
 +{
 +  // fill map of links and their faces
 +  std::set<const Cell*> faces;
 +  std::map<const Cell*, Group*> fgm;
 +  std::map<Link, std::list<const Cell*> > linkFacesMap;
 +  std::map<Link, std::list<const Cell*> >::iterator lfIt, lfIt2;
 +
 +  for (size_t i=0; i!=_groups.size(); ++i)
 +    {
 +      Group& grp = _groups[i];
 +      if ( !grp._cells.empty() && getDimension( grp._cellType ) == 2 )
 +        for ( size_t j = 0; j < grp._cells.size(); ++j )
 +          if ( faces.insert( grp._cells[j] ).second )
 +            {
 +              for ( size_t k = 0; k < grp._cells[j]->_nodes.size(); ++k )
 +                linkFacesMap[ grp._cells[j]->link( k ) ].push_back( grp._cells[j] );
 +              fgm.insert( std::make_pair( grp._cells[j], &grp ));
 +            }
 +    }
 +  // dump linkFacesMap
 +  //     for ( lfIt = linkFacesMap.begin(); lfIt!=linkFacesMap.end(); lfIt++) {
 +  //       cout<< "LINK: " << lfIt->first.first << "-" << lfIt->first.second << std::endl;
 +  //       std::list<const Cell*> & fList = lfIt->second;
 +  //       std::list<const Cell*>::iterator fIt = fList.begin();
 +  //       for ( ; fIt != fList.end(); fIt++ )
 +  //         cout << "\t" << **fIt << fgm[*fIt]->nom << std::endl;
 +  //     }
 +
 +  // Each oriented link must appear in one face only, else a face is reversed.
 +
 +  std::queue<const Cell*> faceQueue; /* the queue contains well oriented faces
 +                                     whose neighbors orientation is to be checked */
 +  bool manifold = true;
 +  while ( !linkFacesMap.empty() )
 +    {
 +      if ( faceQueue.empty() )
 +        {
 +          assert( !linkFacesMap.begin()->second.empty() );
 +          faceQueue.push( linkFacesMap.begin()->second.front() );
 +        }
 +      while ( !faceQueue.empty() )
 +        {
 +          const Cell* face = faceQueue.front();
 +          faceQueue.pop();
 +
 +          // loop on links of <face>
 +          for ( int i = 0; i < (int)face->_nodes.size(); ++i )
 +            {
 +              Link link = face->link( i );
 +              // find the neighbor faces
 +              lfIt = linkFacesMap.find( link );
 +              int nbFaceByLink = 0;
 +              std::list< const Cell* > ml;
 +              if ( lfIt != linkFacesMap.end() )
 +                {
 +                  std::list<const Cell*> & fList = lfIt->second;
 +                  std::list<const Cell*>::iterator fIt = fList.begin();
 +                  assert( fIt != fList.end() );
 +                  for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ )
 +                    {
 +                      ml.push_back( *fIt );
 +                      if ( *fIt != face ) // wrongly oriented neighbor face
 +                        {
 +                          const Cell* badFace = *fIt;
 +                          // reverse and remove badFace from linkFacesMap
 +                          for ( int j = 0; j < (int)badFace->_nodes.size(); ++j )
 +                            {
 +                              Link badlink = badFace->link( j );
 +                              if ( badlink == link ) continue;
 +                              lfIt2 = linkFacesMap.find( badlink );
 +                              if ( lfIt2 != linkFacesMap.end() )
 +                                {
 +                                  std::list<const Cell*> & ff = lfIt2->second;
 +                                  std::list<const Cell*>::iterator lfIt3 = find( ff.begin(), ff.end(), badFace );
 +                                  // check if badFace has been found,
 +                                  // else we can't erase it
 +                                  // case of degenerated face in edge
 +                                  if (lfIt3 != ff.end())
 +                                    {
 +                                      ff.erase( lfIt3 );
 +                                      if ( ff.empty() )
 +                                        linkFacesMap.erase( lfIt2 );
 +                                    }
 +                                }
 +                            }
 +                          badFace->_reverse = true; // reverse
 +                          //INFOS_MED( "REVERSE " << *badFace );
 +                          faceQueue.push( badFace );
 +                        }
 +                    }
 +                  linkFacesMap.erase( lfIt );
 +                }
 +              // add good neighbors to the queue
 +              Link revLink( link.second, link.first );
 +              lfIt = linkFacesMap.find( revLink );
 +              if ( lfIt != linkFacesMap.end() )
 +                {
 +                  std::list<const Cell*> & fList = lfIt->second;
 +                  std::list<const Cell*>::iterator fIt = fList.begin();
 +                  for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ )
 +                    {
 +                      ml.push_back( *fIt );
 +                      if ( *fIt != face )
 +                        faceQueue.push( *fIt );
 +                    }
 +                  linkFacesMap.erase( lfIt );
 +                }
 +              if ( nbFaceByLink > 2 )
 +                {
 +                  if ( manifold )
 +                    {
 +                      std::list<const Cell*>::iterator ii = ml.begin();
 +                      std::cout << nbFaceByLink << " faces by 1 link:" << std::endl;
 +                      for( ; ii!= ml.end(); ii++ )
 +                        std::cout << "in sub-mesh <" << fgm[ *ii ]->_name << "> " << **ii << std::endl;
 +                    }
 +                  manifold = false;
 +                }
 +            } // loop on links of the being checked face
 +        } // loop on the face queue
 +    } // while ( !linkFacesMap.empty() )
 +
 +  if ( !manifold )
 +    std::cout << " -> Non manifold mesh, faces orientation may be incorrect" << std::endl;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Orient volumes according to MED conventions:
 + * normal of a bottom (first) face should be outside
 + */
 +//================================================================================
 +
 +void IntermediateMED::orientVolumes()
 +{
 +  std::set<Cell>::const_iterator elemIt, elemEnd;
 +  std::vector< std::pair<int,int> > swapVec;
 +
 +  CellsByDimIterator cellsIt( *this, 3 );
 +  while ( const std::set<Cell > * elems = cellsIt.nextType() )
 +    {
 +      TCellType cellType = cellsIt.type();
 +      elemIt = elems->begin(), elemEnd = elems->end();
 +      int nbBottomNodes = 0;
 +      switch ( cellType )
 +        {
 +        case NORM_TETRA4:
 +        case NORM_TETRA10:
 +        case NORM_PENTA6:
 +        case NORM_PENTA15:
 +          nbBottomNodes = 3; break;
 +        case NORM_PYRA5:
 +        case NORM_PYRA13:
 +        case NORM_HEXA8:
 +        case NORM_HEXA20:
 +          nbBottomNodes = 4; break;
 +        default: continue;
 +        }
 +      getReverseVector( cellType, swapVec );
 +
 +      for ( ; elemIt != elemEnd; elemIt++ )
 +        {
 +          // find a normal to the bottom face
 +          const double* n[4];
 +          n[0] = nodeCoords( elemIt->_nodes[0]); // 3 bottom nodes
 +          n[1] = nodeCoords( elemIt->_nodes[1]);
 +          n[2] = nodeCoords( elemIt->_nodes[2]);
 +          n[3] = nodeCoords( elemIt->_nodes[nbBottomNodes]); // a top node
 +          double vec01[3]; // vector n[0]-n[1]
 +          vec01[0] = n[1][0] - n[0][0];
 +          vec01[1] = n[1][1] - n[0][1];
 +          vec01[2] = n[1][2] - n[0][2];
 +          double vec02 [3]; // vector n[0]-n[2]
 +          vec02[0] = n[2][0] - n[0][0];
 +          vec02[1] = n[2][1] - n[0][1];
 +          vec02[2] = n[2][2] - n[0][2];
 +          double normal [3]; // vec01 ^ vec02
 +          normal[0] = vec01[1] * vec02[2] - vec01[2] * vec02[1];
 +          normal[1] = vec01[2] * vec02[0] - vec01[0] * vec02[2];
 +          normal[2] = vec01[0] * vec02[1] - vec01[1] * vec02[0];
 +          // check if the 102 angle is convex
 +          if ( nbBottomNodes > 3 )
 +            {
 +              const double* n3 = nodeCoords( elemIt->_nodes[nbBottomNodes-1] );// last bottom node
 +              double vec03 [3];  // vector n[0]-n3
 +              vec03[0] = n3[0] - n[0][0];
 +              vec03[1] = n3[1] - n[0][1];
 +              vec03[2] = n3[2] - n[0][2];
 +              if ( fabs( normal[0]+normal[1]+normal[2] ) <= std::numeric_limits<double>::max() ) // vec01 || vec02
 +                {
 +                  normal[0] = vec01[1] * vec03[2] - vec01[2] * vec03[1]; // vec01 ^ vec03
 +                  normal[1] = vec01[2] * vec03[0] - vec01[0] * vec03[2];
 +                  normal[2] = vec01[0] * vec03[1] - vec01[1] * vec03[0];
 +                }
 +              else
 +                {
 +                  double vec [3]; // normal ^ vec01
 +                  vec[0] = normal[1] * vec01[2] - normal[2] * vec01[1];
 +                  vec[1] = normal[2] * vec01[0] - normal[0] * vec01[2];
 +                  vec[2] = normal[0] * vec01[1] - normal[1] * vec01[0];
 +                  double dot2 = vec[0]*vec03[0] + vec[1]*vec03[1] + vec[2]*vec03[2]; // vec*vec03
 +                  if ( dot2 < 0 ) // concave -> reverse normal
 +                    {
 +                      normal[0] *= -1;
 +                      normal[1] *= -1;
 +                      normal[2] *= -1;
 +                    }
 +                }
 +            }
 +          // direction from top to bottom
 +          double tbDir[3];
 +          tbDir[0] = n[0][0] - n[3][0];
 +          tbDir[1] = n[0][1] - n[3][1];
 +          tbDir[2] = n[0][2] - n[3][2];
 +
 +          // compare 2 directions: normal and top-bottom
 +          double dot = normal[0]*tbDir[0] + normal[1]*tbDir[1] + normal[2]*tbDir[2];
 +          if ( dot < 0. ) // need reverse
 +            reverse( *elemIt, swapVec );
 +
 +        } // loop on volumes of one geometry
 +    } // loop on 3D geometry types
 +
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Assign new IDs to nodes by skipping not used nodes and return their number
 + */
 +//================================================================================
 +
 +int NodeContainer::numberNodes()
 +{
 +  int id = 1;
 +  for ( size_t i = 0; i < _nodes.size(); ++i )
 +    for ( size_t j = 0; j < _nodes[i].size(); ++j )
 +      if ( _nodes[i][j].isUsed() )
 +        _nodes[i][j]._number = id++;
 +  return id-1;
 +}
 +
 +
 +//================================================================================
 +/*!
 + * \brief Assign new IDs to elements
 + */
 +//================================================================================
 +
 +void IntermediateMED::numberElements()
 +{
 +  std::set<Cell>::const_iterator elemIt, elemEnd;
 +
 +  // numbering _cells of type NORM_POINT1 by node number
 +  {
 +    const std::set<Cell>& points = _cellsByType[ INTERP_KERNEL::NORM_POINT1 ];
 +    elemIt = points.begin(), elemEnd = points.end();
 +    for ( ; elemIt != elemEnd; ++elemIt )
 +      elemIt->_number = elemIt->_nodes[0]->_number;
 +  }
 +
 +  // numbering 1D-3D _cells
 +  for ( int dim = 1; dim <= 3; ++dim )
 +    {
 +      // check if re-numeration is needed (to try to keep elem oreder as in sauve file )
 +      bool ok = true, renumEntity = false;
 +      CellsByDimIterator cellsIt( *this, dim );
 +      int prevNbElems = 0;
 +      while ( const std::set<Cell> * typeCells = cellsIt.nextType() )
 +        {
 +          TID minNumber = std::numeric_limits<TID>::max(), maxNumber = 0;
 +          for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt)
 +            {
 +              if ( elemIt->_number < minNumber ) minNumber = elemIt->_number;
 +              if ( elemIt->_number > maxNumber ) maxNumber = elemIt->_number;
 +            }
 +          TID typeSize = typeCells->size();
 +          if ( typeSize != maxNumber - minNumber + 1 )
 +            ok = false;
 +          if ( prevNbElems != 0 ) {
 +            if ( minNumber == 1 )
 +              renumEntity = true;
 +            else if ( prevNbElems+1 != (int)minNumber )
 +              ok = false;
 +          }
 +          prevNbElems += typeSize;
 +        }
 +
 +      if ( ok && renumEntity ) // each geom type was numerated separately
 +        {
 +          cellsIt.init( dim );
 +          prevNbElems = cellsIt.nextType()->size(); // no need to renumber the first type
 +          while ( const std::set<Cell> * typeCells = cellsIt.nextType() )
 +            {
 +              for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt)
 +                elemIt->_number += prevNbElems;
 +              prevNbElems += typeCells->size();
 +            }
 +        }
 +      if ( !ok )
 +        {
 +          int cellID=1;
 +          cellsIt.init( dim );
 +          while ( const std::set<Cell> * typeCells = cellsIt.nextType() )
 +            for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt)
 +              elemIt->_number = cellID++;
 +        }
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Creates coord array
 + */
 +//================================================================================
 +
 +ParaMEDMEM::DataArrayDouble * IntermediateMED::getCoords()
 +{
 +  DataArrayDouble* coordArray = DataArrayDouble::New();
 +  coordArray->alloc( _nbNodes, _spaceDim );
 +  double * coordPrt = coordArray->getPointer();
 +  for ( int i = 0, nb = _points.size(); i < nb; ++i )
 +    {
 +      Node* n = getNode( i+1 );
 +      if ( n->isUsed() )
 +        {
 +          const double* nCoords = nodeCoords( n );
 +          std::copy( nCoords, nCoords+_spaceDim, coordPrt );
 +          coordPrt += _spaceDim;
 +        }
 +    }
 +  return coordArray;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Sets connectivity of elements to the mesh
 + *  \param mesh - mesh to fill in
 + *  \param coords - coordinates that must be shared by all meshes of different dim
 + */
 +//================================================================================
 +
 +void IntermediateMED::setConnectivity( ParaMEDMEM::MEDFileUMesh*    mesh,
 +                                       ParaMEDMEM::DataArrayDouble* coords )
 +{
 +  int meshDim = 0;
 +
 +  mesh->setCoords( coords );
 +
 +  std::set<Cell>::const_iterator elemIt, elemEnd;
 +  for ( int dim = 3; dim > 0; --dim )
 +  {
 +    CellsByDimIterator dimCells( *this, dim );
 +
 +    int nbOfCells = 0;
 +    while ( const std::set<Cell > * cells = dimCells.nextType() )
 +      nbOfCells += cells->size();
 +    if ( nbOfCells == 0 )
 +      continue;
 +
 +    if ( !meshDim ) meshDim = dim;
 +
 +    MEDCouplingUMesh* dimMesh = MEDCouplingUMesh::New();
 +    dimMesh->setCoords( coords );
 +    dimMesh->setMeshDimension( dim );
 +    dimMesh->allocateCells( nbOfCells );
 +
 +    int prevNbCells = 0;
 +    dimCells.init( dim );
 +    while ( const std::set<Cell > * cells = dimCells.nextType() )
 +      {
 +        // fill connectivity array to take into account order of elements in the sauv file
 +        const int nbCellNodes = cells->begin()->_nodes.size();
 +        std::vector< TID > connectivity( cells->size() * nbCellNodes );
 +        int * nodalConnOfCell;
 +        for ( elemIt = cells->begin(), elemEnd = cells->end(); elemIt != elemEnd; ++elemIt )
 +          {
 +            const Cell& cell = *elemIt;
 +            const int index = cell._number - 1 - prevNbCells;
 +            nodalConnOfCell = &connectivity[ index * nbCellNodes ];
 +            if ( cell._reverse )
 +              for ( int i = nbCellNodes-1; i >= 0; --i )
 +                *nodalConnOfCell++ = cell._nodes[i]->_number - 1;
 +            else
 +              for ( int i = 0; i < nbCellNodes; ++i )
 +                *nodalConnOfCell++ = cell._nodes[i]->_number - 1;
 +          }
 +        prevNbCells += cells->size();
 +
 +        // fill dimMesh
 +        TCellType cellType = dimCells.type();
 +        nodalConnOfCell = &connectivity[0];
 +        for ( size_t i = 0; i < cells->size(); ++i, nodalConnOfCell += nbCellNodes )
 +          dimMesh->insertNextCell( cellType, nbCellNodes, nodalConnOfCell );
 +      }
 +    dimMesh->finishInsertingCells();
 +    mesh->setMeshAtLevel( dim - meshDim, dimMesh );
 +    dimMesh->decrRef();
 +  }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Fill in the mesh with groups
 + *  \param mesh - mesh to fill in
 + */
 +//================================================================================
 +
 +void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh )
 +{
 +  bool isMeshNameSet = false;
 +  const int meshDim = mesh->getMeshDimension();
 +  for ( int dim = 0; dim <= meshDim; ++dim )
 +    {
 +      const int meshDimRelToMaxExt = ( dim == 0 ? 1 : dim - meshDim );
 +
 +      std::vector<const DataArrayInt *> medGroups;
 +      std::vector<MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > refGroups;
 +      for ( size_t i = 0; i < _groups.size(); ++i )
 +        {
 +          Group& grp = _groups[i];
 +          if ( (int)getDim( &grp ) != dim &&
 +               grp._groups.empty() ) // to allow groups on diff dims
 +            continue;
 +          // convert only named groups or field supports
 +          if ( grp.empty() || (grp._name.empty() && !grp._isProfile ))
 +            continue;
 +          //if ( grp._medGroup ) continue; // already converted
 +
 +          // sort cells by ID and remember their initial order in the group
 +          TCellToOrderMap cell2order;
 +          unsigned orderInGroup = 0;
 +          std::vector< Group* > groupVec;
 +          if ( grp._groups.empty() ) groupVec.push_back( & grp );
 +          else                       groupVec = grp._groups;
 +          for ( size_t iG = 0; iG < groupVec.size(); ++iG )
 +            {
 +              Group* aG = groupVec[ iG ];
 +              if ( (int)getDim( aG ) != dim )
 +                continue;
 +              for ( size_t iC = 0; iC < aG->_cells.size(); ++iC )
 +                cell2order.insert( cell2order.end(), std::make_pair( aG->_cells[iC], orderInGroup++ ));
 +            }
 +          if ( cell2order.empty() )
 +            continue;
 +          bool isSelfIntersect = ( orderInGroup != cell2order.size() );
 +          if ( isSelfIntersect ) // self intersecting group
 +            {
 +              std::ostringstream msg;
 +              msg << "Self intersecting sub-mesh: id = " << i+1
 +                  << ", name = |" << grp._name << "|" << std::endl
 +                  << " nb unique elements = " << cell2order.size() << std::endl
 +                  << " total nb elements  = " << orderInGroup;
 +              if ( grp._isProfile )
 +                {
 +                  THROW_IK_EXCEPTION( msg.str() );
 +                }
 +              else
 +                {
 +                  std::cout << msg.str() << std::endl;
 +                }
 +            }
 +          // create a med group
 +          grp._medGroup = DataArrayInt::New();
 +          grp._medGroup->setName( grp._name.c_str() );
 +          grp._medGroup->alloc( cell2order.size(), /*nbOfCompo=*/1 );
 +          int * idsPtr = grp._medGroup->getPointer();
 +          TCellToOrderMap::iterator cell2orderIt, cell2orderEnd = cell2order.end();
 +          for ( cell2orderIt = cell2order.begin(); cell2orderIt != cell2orderEnd; ++cell2orderIt )
 +            *idsPtr++ = (*cell2orderIt).first->_number - 1;
 +
 +          // try to set the mesh name
 +          if ( !isMeshNameSet &&
 +               dim == meshDim &&
 +               !grp._name.empty() &&
 +               grp.size() == mesh->getSizeAtLevel( meshDimRelToMaxExt ))
 +            {
 +              mesh->setName( grp._name.c_str() );
 +              isMeshNameSet = true;
 +            }
 +          if ( !grp._name.empty() )
 +            {
 +              medGroups.push_back( grp._medGroup );
 +            }
 +          // set relocation table
 +          setRelocationTable( &grp, cell2order );
 +
 +          // Issue 0021311. Use case: a gibi group has references (recorded in pile 1)
 +          // and several names (pile 27) refer (pile 10) to this group.
 +          // We create a copy of this group per each named reference
 +          std::set<std::string> uniqueNames;
 +          uniqueNames.insert( grp._name );
 +          for ( unsigned iRef = 0 ; iRef < grp._refNames.size(); ++iRef )
 +            if ( !grp._refNames[ iRef ].empty() &&
 +                 uniqueNames.insert( grp._refNames[ iRef ]).second ) // for name uniqueness (23155)
 +              {
 +                refGroups.push_back( grp._medGroup->deepCpy() );
 +                refGroups.back()->setName( grp._refNames[ iRef ].c_str() );
 +                medGroups.push_back( refGroups.back() );
 +              }
 +        }
 +      mesh->setGroupsAtLevel( meshDimRelToMaxExt, medGroups );
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return true if the group is on all elements and return its relative dimension
 + */
 +//================================================================================
 +
 +bool IntermediateMED::isOnAll( const Group* grp, int & dimRel ) const
 +{
 +  int dim = getDim( grp );
 +
 +  int nbElems = 0;
 +  if ( dim == 0 )
 +    {
 +      nbElems = _nbNodes;
 +      dimRel  = 0;
 +    }
 +  else
 +    {
 +      CellsByDimIterator dimCells( *this, dim );
 +      while ( const std::set<Cell > * cells = dimCells.nextType() )
 +        nbElems += cells->size();
 +
 +      int meshDim = 3;
 +      for ( ; meshDim > 0; --meshDim )
 +        {
 +          dimCells.init( meshDim );
 +          if ( dimCells.nextType() )
 +            break;
 +        }
 +      dimRel = dim - meshDim;
 +    }
 +
 +  bool onAll = ( nbElems == grp->size() );
 +  return onAll;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Makes fields from own data
 + */
 +//================================================================================
 +
 +ParaMEDMEM::MEDFileFields * IntermediateMED::makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh)
 +{
 +  if ( _nodeFields.empty() && _cellFields.empty() ) return 0;
 +
 +  // set long names
 +  std::set< std::string > usedFieldNames;
 +  setFieldLongNames(usedFieldNames);
 +
 +  MEDFileFields* fields = MEDFileFields::New();
 +
 +  for ( size_t i = 0; i < _nodeFields.size(); ++i )
 +    setFields( _nodeFields[i], fields, mesh, i+1, usedFieldNames );
 +
 +  for ( size_t i = 0; i < _cellFields.size(); ++i )
 +    setFields( _cellFields[i], fields, mesh, i+1, usedFieldNames );
 +
 +  return fields;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Make med fields from a SauvUtilities::DoubleField
 + */
 +//================================================================================
 +
 +void IntermediateMED::setFields( SauvUtilities::DoubleField* fld,
 +                                 ParaMEDMEM::MEDFileFields*  medFields,
 +                                 ParaMEDMEM::MEDFileUMesh*   mesh,
 +                                 const TID                   castemID,
 +                                 std::set< std::string >&    usedFieldNames)
 +{
 +  bool sameNbGauss = true;
 +  if ( !fld || !fld->isMedCompatible( sameNbGauss )) return;
 +
 +  if ( !sameNbGauss )
 +    fld->splitSubWithDiffNbGauss();
 +
 +  // if ( !fld->hasCommonSupport() ):
 +  //     each sub makes MEDFileFieldMultiTS
 +  // else:
 +  //     unite several subs into a MEDCouplingFieldDouble
 +
 +  const bool uniteSubs = fld->hasCommonSupport() && sameNbGauss;
 +  if ( !uniteSubs )
 +    std::cout << "Castem field #" << castemID << " <" << fld->_name
 +              << "> is incompatible with MED format, so we split it into several fields:" << std::endl;
 +
 +  for ( size_t iSub = 0; iSub < fld->_sub.size(); )
 +    {
 +      // set field name
 +      if ( !uniteSubs || fld->_name.empty() )
 +        makeFieldNewName( usedFieldNames, fld );
 +
 +      // allocate values
 +      DataArrayDouble * values = DataArrayDouble::New();
 +      values->alloc( fld->getNbTuples(iSub), fld->_sub[iSub].nbComponents() );
 +
 +      // set values
 +      double * valPtr = values->getPointer();
 +      if ( uniteSubs )
 +        {
 +          int nbElems = fld->_group->size();
 +          for ( int elemShift = 0; elemShift < nbElems && iSub < fld->_sub.size(); )
 +            elemShift += fld->setValues( valPtr, iSub++, elemShift );
 +          setTS( fld, values, medFields, mesh );
 +        }
 +      else
 +        {
 +          fld->setValues( valPtr, iSub );
 +          setTS( fld, values, medFields, mesh, iSub++ );
 +
 +          std::cout << fld->_name << " with compoments";
 +          for ( size_t i = 0; i < (size_t)fld->_sub[iSub-1].nbComponents(); ++i )
 +            std::cout << " " << fld->_sub[iSub-1]._comp_names[ i ];
 +          std::cout << std::endl;
 +        }
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Store value array of a field into med fields
 + */
 +//================================================================================
 +
 +void IntermediateMED::setTS( SauvUtilities::DoubleField*  fld,
 +                             ParaMEDMEM::DataArrayDouble* values,
 +                             ParaMEDMEM::MEDFileFields*   medFields,
 +                             ParaMEDMEM::MEDFileUMesh*    mesh,
 +                             const int                    iSub)
 +{
 +  // treat a field support
 +  const Group* support = fld->getSupport( iSub );
 +  int dimRel;
 +  const bool onAll = isOnAll( support, dimRel );
 +  if ( !onAll && support->_name.empty() )
 +    {
 +      const_cast<Group*>(support)->_name += "PFL_" + fld->_name;
 +      support->_medGroup->setName( support->_name.c_str() );
 +    }
 +
 +  // make and fill a time-stamp
 +
 +  MEDCouplingFieldDouble * timeStamp = MEDCouplingFieldDouble::New( fld->getMedType( iSub ),
 +                                                                    fld->getMedTimeDisc() );
 +  timeStamp->setName( fld->_name.c_str() );
 +  timeStamp->setDescription( fld->_description.c_str() );
 +  // set the mesh
 +  if ( onAll )
 +    {
 +      MEDCouplingAutoRefCountObjectPtr
 +        < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel );
 +      timeStamp->setMesh( dimMesh );
 +    }
 +  else if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_NODES )
 +    {
 +      DataArrayDouble * coo = mesh->getCoords();
 +      MEDCouplingAutoRefCountObjectPtr
 +        <DataArrayDouble> subCoo = coo->selectByTupleId(support->_medGroup->begin(),
 +                                                        support->_medGroup->end());
 +      MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > nodeSubMesh =
 +        MEDCouplingUMesh::Build0DMeshFromCoords( subCoo );
 +      timeStamp->setMesh( nodeSubMesh );
 +    }
 +  else
 +    {
 +      MEDCouplingAutoRefCountObjectPtr
 +        < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel );
 +      MEDCouplingAutoRefCountObjectPtr
 +        <MEDCouplingMesh> subMesh = dimMesh->buildPart(support->_medGroup->begin(),
 +                                                       support->_medGroup->end());
 +      timeStamp->setMesh( subMesh);
 +    }
 +  // set values
 +  for ( size_t i = 0; i < (size_t)fld->_sub[iSub].nbComponents(); ++i )
 +    values->setInfoOnComponent( i, fld->_sub[iSub]._comp_names[ i ].c_str() );
 +  timeStamp->setArray( values );
 +  values->decrRef();
 +  // set gauss points
 +  if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_GAUSS_PT )
 +    {
 +      TGaussDef gaussDef( fld->_sub[iSub]._support->_cellType,
 +                          fld->_sub[iSub].nbGauss() );
 +      timeStamp->setGaussLocalizationOnType( fld->_sub[iSub]._support->_cellType,
 +                                             gaussDef.myRefCoords,
 +                                             gaussDef.myCoords,
 +                                             gaussDef.myWeights );
 +    }
 +  // get a field to add the time-stamp
 +  bool isNewMedField = false;
 +  if ( !fld->_curMedField || fld->_name != fld->_curMedField->getName() )
 +    {
 +      fld->_curMedField = MEDFileFieldMultiTS::New();
 +      isNewMedField = true;
 +    }
 +
 +  // set an order
 +  const int nbTS = fld->_curMedField->getNumberOfTS();
 +  if ( nbTS > 0 )
 +    timeStamp->setOrder( nbTS );
 +
 +  // add the time-stamp
 +  timeStamp->checkCoherency();
 +  if ( onAll )
 +    fld->_curMedField->appendFieldNoProfileSBT( timeStamp );
 +  else
 +    fld->_curMedField->appendFieldProfile( timeStamp, mesh, dimRel, support->_medGroup );
 +  timeStamp->decrRef();
 +
 +  if ( isNewMedField ) // timeStamp must be added before this
 +    {
 +      medFields->pushField( fld->_curMedField );
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Make a new unique name for a field
 + */
 +//================================================================================
 +
 +void IntermediateMED::makeFieldNewName(std::set< std::string >&    usedNames,
 +                                       SauvUtilities::DoubleField* fld )
 +{
 +  std::string base = fld->_name;
 +  if ( base.empty() )
 +    {
 +      base = "F_";
 +    }
 +  else
 +    {
 +      std::string::size_type pos = base.rfind('_');
 +      if ( pos != std::string::npos )
 +        base = base.substr( 0, pos+1 );
 +      else
 +        base += '_';
 +    }
 +
 +  int i = 1;
 +  do
 +    {
 +      fld->_name = base + SauvUtilities::toString( i++ );
 +    }
 +  while( !usedNames.insert( fld->_name ).second );
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Split sub-components with different nb of gauss points into several sub-components
 + *  \param [in,out] fld - a field to split if necessary
 + */
 +//================================================================================
 +
 +void DoubleField::splitSubWithDiffNbGauss()
 +{
 +  for ( size_t iSub = 0; iSub < _sub.size(); ++iSub )
 +    {
 +      if ( _sub[iSub].isSameNbGauss() ) continue;
 +
 +      _sub.insert( _sub.begin() + iSub + 1, 1, _Sub_data() );
 +      _Sub_data & subToSplit = _sub[iSub];
 +      _Sub_data & subNew     = _sub[iSub+1];
 +      size_t iDiff = 1;
 +      while ( subToSplit._nb_gauss[ 0 ] == subToSplit._nb_gauss[ iDiff ] )
 +        ++iDiff;
 +      subNew._support = subToSplit._support;
 +      subNew._comp_names.assign( subToSplit._comp_names.begin() + iDiff,
 +                                 subToSplit._comp_names.end() );
 +      subNew._nb_gauss.assign  ( subToSplit._nb_gauss.begin() + iDiff,
 +                                 subToSplit._nb_gauss.end() );
 +      subToSplit._comp_names.resize( iDiff );
 +      subToSplit._nb_gauss.resize  ( iDiff );
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return a vector ready to fill in
 + */
 +//================================================================================
 +
 +std::vector< double >& DoubleField::addComponent( int nb_values )
 +{
 +  _comp_values.push_back( std::vector< double >() );
 +  std::vector< double >& res = _comp_values.back();
 +  res.resize( nb_values );
 +  return res;
 +}
 +
 +DoubleField::~DoubleField()
 +{
 +  if(_curMedField)
 +    _curMedField->decrRef();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Returns a supporting group
 + */
 +//================================================================================
 +
 +const Group* DoubleField::getSupport( const int iSub ) const
 +{
 +  return _group ? _group : _sub[iSub]._support;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return true if each sub-component is a time stamp
 + */
 +//================================================================================
 +
 +bool DoubleField::isMultiTimeStamps() const
 +{
 +  if ( _sub.size() < 2 )
 +    return false;
 +  bool sameSupports = true;
 +  Group* grpp1 = _sub[0]._support;// grpp NOT grp because XDR under Windows defines grp...
 +  for ( size_t i = 1; i < _sub.size() && sameSupports; ++i )
 +    sameSupports = ( grpp1 == _sub[i]._support );
 +
 +  return sameSupports;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief True if the field can be converted into the med field
 + */
 +//================================================================================
 +
 +bool DoubleField::isMedCompatible(bool& sameNbGauss) const
 +{
 +  for ( size_t iSub = 0; iSub < _sub.size(); ++iSub )
 +    {
 +      if ( !getSupport(iSub) || !getSupport(iSub)->_medGroup )
 +        THROW_IK_EXCEPTION("SauvReader INTERNAL ERROR: NULL field support");
 +
 +      sameNbGauss = true;
 +      if ( !_sub[iSub].isSameNbGauss() )
 +        {
 +          std::cout << "Field <" << _name << "> : different nb of gauss points in components" << std::endl;
 +          sameNbGauss = false;
 +          //return false;
 +        }
 +    }
 +  return true;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief return true if all sub-components has same components and same nbGauss
 + */
 +//================================================================================
 +
 +bool DoubleField::hasSameComponentsBySupport() const
 +{
 +  std::vector< _Sub_data >::const_iterator sub_data = _sub.begin();
 +  const _Sub_data& first_sub_data = *sub_data;
 +  for ( ++sub_data ; sub_data != _sub.end(); ++sub_data )
 +  {
 +    if ( first_sub_data._comp_names != sub_data->_comp_names )
 +      return false; // diff names of components
 +
 +    if ( first_sub_data._nb_gauss != sub_data->_nb_gauss &&
 +         first_sub_data._support->_cellType == sub_data->_support->_cellType)
 +      return false; // diff nb of gauss points on same cell type
 +  }
 +  return true;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return type of MEDCouplingFieldDouble
 + */
 +//================================================================================
 +
 +ParaMEDMEM::TypeOfField DoubleField::getMedType( const int iSub ) const
 +{
 +  using namespace INTERP_KERNEL;
 +
 +  const Group* grp = hasCommonSupport() ? _group : _sub[iSub]._support;
 +  if ( _sub[iSub].nbGauss() > 1 )
 +    {
 +      const CellModel& cm = CellModel::GetCellModel( _sub[iSub]._support->_cellType );
 +      return (int) cm.getNumberOfNodes() == _sub[iSub].nbGauss() ? ON_GAUSS_NE : ON_GAUSS_PT;
 +    }
 +  else
 +    {
 +      return getDim( grp ) == 0 ? ON_NODES : ON_CELLS;
 +    }
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return TypeOfTimeDiscretization
 + */
 +//================================================================================
 +
 +ParaMEDMEM::TypeOfTimeDiscretization DoubleField::getMedTimeDisc() const
 +{
 +  return ONE_TIME;
 +  // NO_TIME = 4,
 +  // ONE_TIME = 5,
 +  // LINEAR_TIME = 6,
 +  // CONST_ON_TIME_INTERVAL = 7
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Return nb tuples to be used to allocate DataArrayDouble
 + */
 +//================================================================================
 +
 +int DoubleField::getNbTuples( const int iSub ) const
 +{
 +  int nb = 0;
 +  if ( hasCommonSupport() && !_group->_groups.empty() )
 +    for ( size_t i = 0; i < _group->_groups.size(); ++i )
 +      nb += _sub[i].nbGauss() * _sub[i]._support->size();
 +  else
 +    nb = _sub[iSub].nbGauss() * getSupport(iSub)->size();
 +  return nb;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Store values of a sub-component and return nb of elements in the iSub
 + */
 +//================================================================================
 +
 +int DoubleField::setValues( double * valPtr, const int iSub, const int elemShift ) const
 +{
 +  // find values for iSub
 +  int iComp = 0;
 +  for ( int iS = 0; iS < iSub; ++iS )
 +    iComp += _sub[iS].nbComponents();
 +  const std::vector< double > * compValues = &_comp_values[ iComp ];
 +
 +  // Set values
 +
 +  const std::vector< unsigned >& relocTable = getSupport( iSub )->_relocTable;
 +
 +  const int nbElems      = _sub[iSub]._support->size();
 +  const int nbGauss      = _sub[iSub].nbGauss();
 +  const int nbComponents = _sub[iSub].nbComponents();
 +  const int nbValsByElem = nbComponents * nbGauss;
 +
 +  // check nb values
 +  int nbVals = 0;
 +  for ( iComp = 0; iComp < nbComponents; ++iComp )
 +    nbVals += compValues[iComp].size();
 +  const bool isConstField = ( nbVals == nbComponents ); // one value per component (issue 22321)
 +  if ( !isConstField && nbVals != nbElems * nbValsByElem )
 +    THROW_IK_EXCEPTION("SauvMedConvertor.cxx: support size mismatches field size");
 +
 +  // compute nb values in previous subs
 +  int valsShift = 0;
 +  for ( int iS = iSub-1, shift = elemShift; shift > 0; --iS)
 +    {
 +      int nbE = _sub[iS]._support->size();
 +      shift -= nbE;
 +      valsShift += nbE * _sub[iS].nbComponents() * _sub[iS].nbGauss();
 +    }
 +
 +  if ( isConstField )
 +    for ( int iE = 0; iE < nbElems; ++iE )
 +      {
 +        int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift );
 +        for ( iComp = 0; iComp < nbComponents; ++iComp )
 +          valPtr[ iMed + iComp ] = compValues[iComp][ 0 ];
 +      }
 +  else
 +    for ( int iE = 0; iE < nbElems; ++iE )
 +      {
 +        int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift );
 +        for ( iComp = 0; iComp < nbComponents; ++iComp )
 +          for ( int iG = 0; iG < nbGauss; ++iG )
 +            valPtr[ iMed + iG * nbComponents + iComp ] = compValues[iComp][ iE * nbGauss + iG ];
 +      }
 +  return nbElems;
 +}
 +
 +//================================================================================
 +/*!
 + * \brief Destructor of IntermediateMED
 + */
 +//================================================================================
 +
 +IntermediateMED::~IntermediateMED()
 +{
 +  for ( size_t i = 0; i < _nodeFields.size(); ++i )
 +    if ( _nodeFields[i] )
 +      delete _nodeFields[i];
 +  _nodeFields.clear();
 +
 +  for ( size_t i = 0; i < _cellFields.size(); ++i )
 +    if ( _cellFields[i] )
 +      delete _cellFields[i];
 +  _cellFields.clear();
 +
 +  for ( size_t i = 0; i < _groups.size(); ++i )
 +    if ( _groups[i]._medGroup )
 +      _groups[i]._medGroup->decrRef();
 +}
 +
 +//================================================================================
 +/*!
 + * \brief CellsByDimIterator constructor
 + */
 +CellsByDimIterator::CellsByDimIterator( const IntermediateMED & medi, int dimm)
 +{
 +  myImed = & medi;
 +  init( dimm );
 +}
 +/*!
 + * \brief Initialize iteration on cells of given dimention
 + */
 +void CellsByDimIterator::init(const int  dimm)
 +{
 +  myCurType = -1;
 +  myTypeEnd = INTERP_KERNEL::NORM_HEXA20 + 1;
 +  myDim = dimm;
 +}
 +/*!
 + * \brief return next set of Cell's of required dimension
 + */
 +const std::set< Cell > * CellsByDimIterator::nextType()
 +{
 +  while ( ++myCurType < myTypeEnd )
 +    if ( !myImed->_cellsByType[myCurType].empty() && ( myDim < 0 || dim(false) == myDim ))
 +      return & myImed->_cellsByType[myCurType];
 +  return 0;
 +}
 +/*!
 + * \brief return dimension of cells returned by the last or further next()
 + */
 +int CellsByDimIterator::dim(const bool last) const
 +{
 +  int typp = myCurType;
 +  if ( !last )
 +    while ( typp < myTypeEnd && myImed->_cellsByType[typp].empty() )
 +      ++typp;
 +  return typp < myTypeEnd ? getDimension( TCellType( typp )) : 4;
 +}
 +// END CellsByDimIterator ========================================================
 +
index b6267238f2a5ac4696a73f868b889f459fd0275a,0000000000000000000000000000000000000000..0eb08c20600419725568319291807e3889fd27f8
mode 100644,000000..100644
--- /dev/null
@@@ -1,1097 -1,0 +1,1494 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#include "MEDLoaderTest.hxx"
 +#include "MEDLoader.hxx"
 +#include "MEDLoaderBase.hxx"
 +#include "MEDCouplingUMesh.hxx"
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +
 +#include <cmath>
++#include <numeric>
 +
 +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().c_str(),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().c_str(),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().c_str(),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().c_str(),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().c_str(),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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),2,3);
 +  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
 +  // testing kind message on error of field type.
 +  CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell("file7.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3),INTERP_KERNEL::Exception);
 +  //
 +  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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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";
 +  MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1();
 +  (const_cast<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);
 +  f1->setTime(10.55,28,29);
 +  tmp[0]=3*VAL1;
 +  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1);
 +  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);
 +  (const_cast<MEDCouplingMesh *>(f1->getMesh()))->setName(name3);
 +  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(5,(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);
 +  CPPUNIT_ASSERT_EQUAL(28,it1[2].first); CPPUNIT_ASSERT_EQUAL(29,it1[2].second);
 +  CPPUNIT_ASSERT_EQUAL(38,it1[3].first); CPPUNIT_ASSERT_EQUAL(39,it1[3].second);
 +  CPPUNIT_ASSERT_EQUAL(48,it1[4].first); CPPUNIT_ASSERT_EQUAL(49,it1[4].second);
 +  std::vector< std::pair<int,int> > it3=MEDLoader::GetNodeFieldIterations(fileName,name3,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);
 +  //
 +  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,name3,0,name1,28,29);
 +  CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13);
 +  f1->decrRef();
 +  f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,38,39);
 +  CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13);
 +  f1->decrRef();
 +  f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,48,49);
 +  CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13);
 +  f1->decrRef();
 +  //
 +  f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,8,9);
 +  CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13);
 +  f1->decrRef();
 +  f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,108,109);
 +  CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13);
 +  f1->decrRef();
 +  f1=MEDLoader::ReadFieldNode(fileName,name3,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<const 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_-3")); vec.push_back(std::string("Family_-5"));
 +  mesh2_2=MEDLoader::ReadUMeshFromFamilies(fileName,mnane,0,vec);
 +  mesh2_2->setName("mesh2");
 +  CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12));
 +  mesh2_2->decrRef();
 +  //
 +  std::vector<std::string> ret=MEDLoader::GetMeshFamiliesNamesOnGroup(fileName,"3DToto","3DMesh_1");
 +  CPPUNIT_ASSERT_EQUAL(4,(int)ret.size());
 +  CPPUNIT_ASSERT(ret[0]=="Family_-2");
 +  CPPUNIT_ASSERT(ret[1]=="Family_-3");
 +  CPPUNIT_ASSERT(ret[2]=="Family_-4");
 +  CPPUNIT_ASSERT(ret[3]=="Family_-5");
 +  //
 +  std::vector<std::string> ret1=MEDLoader::GetMeshGroupsNamesOnFamily(fileName,"3DToto","Family_-3");
 +  CPPUNIT_ASSERT_EQUAL(2,(int)ret1.size());
 +  CPPUNIT_ASSERT(ret1[0]=="3DMesh_1");
 +  CPPUNIT_ASSERT(ret1[1]=="mesh2");
 +  //
 +  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().c_str());//<- 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().c_str(),0,f1->getName().c_str(),2,7);
 +  std::vector<ParaMEDMEM::TypeOfField> types=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str());
 +  CPPUNIT_ASSERT_EQUAL(1,(int)types.size());
 +  CPPUNIT_ASSERT(types[0]==ON_CELLS);
 +  f2->checkCoherency();
 +  CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
 +  //
 +  f2->decrRef();
 +  f1->decrRef();
 +  mesh1->decrRef();
 +  mesh2->decrRef();
 +}
 +
 +/*!
 + * Test MED file profiles.
 + */
 +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[2]={1,4};//node ids are 2,4,5,3,6,7
 +  MEDCouplingFieldDouble *f2=f1->buildSubPart(arr2,arr2+2);
 +  (const_cast<MEDCouplingMesh *>(f2->getMesh()))->setName(f1->getMesh()->getName().c_str());
 +  MEDLoader::WriteField(fileName,f2,false);//<- false important for the test
 +  //
 +  MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f2->getMesh()->getName().c_str(),0,f2->getName().c_str(),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().c_str(),0,f2->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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().c_str(),0,f1->getName().c_str(),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);
 +  std::vector<ParaMEDMEM::TypeOfField> tof(MEDLoader::GetTypesOfField(fileName,"2DMesh_2","MyFieldOnGaussNE"));
 +  CPPUNIT_ASSERT_EQUAL(1,(int)tof.size());
 +  CPPUNIT_ASSERT(ON_GAUSS_NE==tof[0]);
 +  MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_NE,fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),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::testSplitIntoNameAndUnit1()
 +{
 +  std::string s(" []");
 +  std::string c,u;
 +  MEDLoaderBase::splitIntoNameAndUnit(s,c,u);
 +  CPPUNIT_ASSERT(c.empty());
 +  CPPUNIT_ASSERT(u.empty());
 +  s="   lmmm  kki jjj      ";
 +  MEDLoaderBase::strip(s);
 +  CPPUNIT_ASSERT(s=="lmmm  kki jjj");
 +  s=" ";
 +  MEDLoaderBase::strip(s);
 +  CPPUNIT_ASSERT(s.empty());
 +  s="";
 +  MEDLoaderBase::strip(s);
 +  CPPUNIT_ASSERT(s.empty());
 +  s="      ";
 +  MEDLoaderBase::strip(s);
 +  CPPUNIT_ASSERT(s.empty());
 +  s="     pp";
 +  MEDLoaderBase::strip(s);
 +  CPPUNIT_ASSERT(s=="pp");
 +}
 +
 +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().c_str(),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().c_str(),0,f1->getName().c_str(),2,7);
 +  CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12));
 +  f2->decrRef();
 +  //
 +  mesh->decrRef();
 +  f1->decrRef();
 +}
 +
 +/*!
 + * Shuffle de cells but no profile. Like pointe.med
 + */
 +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[0],&poly2[0]+poly2.size());
 +  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().c_str(),0,f_1->getName().c_str(),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().c_str(),0);
 +  CPPUNIT_ASSERT(!m3d_bis->isEqual(m3d,1e-12));
 +  m3d_bis->setName(m3d->getName().c_str());
 +  CPPUNIT_ASSERT(m3d_bis->isEqual(m3d,1e-12));
 +  MEDCouplingUMesh *m2d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName().c_str(),-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().c_str(),-1,f1->getName().c_str(),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.14,2,7);
 +  f2->checkCoherency();
 +  //
 +  MEDLoader::WriteField(fileName,f1,true);
 +  std::vector<ParaMEDMEM::TypeOfField> ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str());
 +  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().c_str());
 +  CPPUNIT_ASSERT_EQUAL(1,(int)fs.size());
 +  CPPUNIT_ASSERT(fs[0]=="FieldMix");
 +  MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f2);
 +  fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName().c_str());
 +  CPPUNIT_ASSERT_EQUAL(1,(int)fs.size());
 +  CPPUNIT_ASSERT(fs[0]=="FieldMix");
 +  //
 +  ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str());
 +  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().c_str(),0,f1->getName().c_str(),2,7);
 +  CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12));
 +  f3->decrRef();
 +  f3=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),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();
 +}
 +
++
++void MEDLoaderTest::testMEDLoaderRead1()
++{
++  using namespace std;
++  using namespace INTERP_KERNEL;
++
++  string fileName=getResourceFile("pointe.med");
++  vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str());
++  CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size());
++  MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0);
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(16,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllGeoTypes().size());
++  for(int i=0;i<12;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,mesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(701,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+90,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::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str());
++  CPPUNIT_ASSERT_EQUAL(8,(int)families.size());
++  CPPUNIT_ASSERT(families[2]=="FAMILLE_ELEMENT_3");
++  //
++  vector<string> families2;
++  families2.push_back(families[2]);
++  mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),0,families2);
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(2,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
++  CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(0));
++  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(1));
++  CPPUNIT_ASSERT_EQUAL((std::size_t)11,mesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(132,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+11,0));
++  CPPUNIT_ASSERT_EQUAL(16,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+3,0));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
++  mesh->decrRef();
++  //
++  vector<string> groups=MEDLoader::GetMeshGroupsNames(fileName.c_str(),meshNames[0].c_str());
++  CPPUNIT_ASSERT_EQUAL(5,(int)groups.size());
++  CPPUNIT_ASSERT(groups[0]=="groupe1");
++  CPPUNIT_ASSERT(groups[1]=="groupe2");
++  CPPUNIT_ASSERT(groups[2]=="groupe3");
++  CPPUNIT_ASSERT(groups[3]=="groupe4");
++  CPPUNIT_ASSERT(groups[4]=="groupe5");
++  vector<string> groups2;
++  groups2.push_back(groups[0]);
++  mesh=MEDLoader::ReadUMeshFromGroups(fileName.c_str(),meshNames[0].c_str(),0,groups2);
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(7,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
++  for(int i=0;i<6;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(i));
++  CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(6));
++  CPPUNIT_ASSERT_EQUAL((std::size_t)36,mesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(254,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+36,0));
++  CPPUNIT_ASSERT_EQUAL(141,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+8,0));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
++  mesh->decrRef();
++  //
++  std::vector<std::string> fieldsName=MEDLoader::GetCellFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str());
++  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(),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(),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::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.,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);
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue,diffValue+16),1e-12);
++  const MEDCouplingUMesh *constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0->getMesh());
++  CPPUNIT_ASSERT(constMesh);
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
++  for(int i=0;i<12;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
++  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
++  field0->decrRef();
++  //
++  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.,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);
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue2,diffValue2+48),1e-12);
++  constMesh=dynamic_cast<const MEDCouplingUMesh *>(field1->getMesh());
++  CPPUNIT_ASSERT(constMesh);
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
++  for(int i=0;i<12;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
++  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
++  field1->decrRef();
++  //fields on nodes
++  std::vector<std::string> fieldsNameNode=MEDLoader::GetNodeFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str());
++  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(),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);
++  CPPUNIT_ASSERT_EQUAL(1,its0Node[1].first);
++  CPPUNIT_ASSERT_EQUAL(-1,its0Node[1].second);
++  CPPUNIT_ASSERT_EQUAL(2,its0Node[2].first);
++  CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].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());
++  CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples());
++  const double expectedValues3[19]={1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.};
++  double diffValue3[19];
++  std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues3,diffValue3,std::minus<double>());
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12);
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12);
++  constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh());
++  CPPUNIT_ASSERT(constMesh);
++  field0Nodes->decrRef();
++  //
++  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());
++  CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples());
++  const double expectedValues4[19]={1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.,7.,7.};
++  std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues4,diffValue3,std::minus<double>());
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12);
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12);
++  constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh());
++  CPPUNIT_ASSERT(constMesh);
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
++  for(int i=0;i<12;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
++  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
++  field0Nodes->decrRef();
++  //
++  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());
++  CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples());
++  const double expectedValues5[19]={1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.};
++  std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues5,diffValue3,std::minus<double>());
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12);
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12);
++  constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh());
++  CPPUNIT_ASSERT(constMesh);
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
++  for(int i=0;i<12;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
++  CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
++  field0Nodes->decrRef();
++}
++
++void MEDLoaderTest::testMEDLoaderPolygonRead()
++{
++  using namespace std;
++  using namespace INTERP_KERNEL;
++
++  string fileName=getResourceFile("polygones.med");
++  vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str());
++  CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size());
++  CPPUNIT_ASSERT(meshNames[0]=="Bord");
++  MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0);
++  mesh->checkCoherency();
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(538,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(579,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
++  for(int i=0;i<514;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(i));
++  for(int i=514;i<538;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+1737,0),1e-12);
++  const double expectedVals1[12]={1.4851585216522212,-0.5,0.,1.4851585216522212,-0.4,0.,1.4851585216522212,-0.3,0., 1.5741585216522211, -0.5, 0. };
++  double diffValue1[12];
++  std::transform(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+12,expectedVals1,diffValue1,std::minus<double>());
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue1,diffValue1+12),1e-12);
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue1,diffValue1+12),1e-12);
++  CPPUNIT_ASSERT_EQUAL((std::size_t)2768,mesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(651050,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+2768,0));
++  CPPUNIT_ASSERT_EQUAL(725943,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+539,0));
++  mesh->decrRef();
++  //
++  std::vector<std::string> fieldsName=MEDLoader::GetCellFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str());
++  CPPUNIT_ASSERT_EQUAL(3,(int)fieldsName.size());
++  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(),meshNames[0].c_str(),fieldsName[0].c_str());
++  CPPUNIT_ASSERT_EQUAL(1,(int)its0.size());
++  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());
++  CPPUNIT_ASSERT_EQUAL(538,field->getNumberOfTuples());
++  const MEDCouplingUMesh *constMesh=dynamic_cast<const MEDCouplingUMesh *>(field->getMesh());
++  CPPUNIT_ASSERT(constMesh);
++  CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(2,constMesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(538,constMesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(579,constMesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(2,(int)constMesh->getAllGeoTypes().size());
++  for(int i=0;i<514;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,constMesh->getTypeOfCell(i));
++  for(int i=514;i<538;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,constMesh->getTypeOfCell(i));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+1737,0),1e-12);
++  std::transform(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+12,expectedVals1,diffValue1,std::minus<double>());
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue1,diffValue1+12),1e-12);
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue1,diffValue1+12),1e-12);
++  CPPUNIT_ASSERT_EQUAL((std::size_t)2768,constMesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(651050,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+2768,0));
++  CPPUNIT_ASSERT_EQUAL(725943,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+539,0));
++  const double *values=field->getArray()->getPointer();
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.87214203182918,std::accumulate(values,values+538,0.),1e-12);
++  field->decrRef();
++}
++
++void MEDLoaderTest::testMEDLoaderPolyhedronRead()
++{
++  using namespace std;
++  using namespace INTERP_KERNEL;
++
++  string fileName=getResourceFile("poly3D.med");
++  vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str());
++  CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size());
++  CPPUNIT_ASSERT(meshNames[0]=="poly3D");
++  MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0);
++  mesh->checkCoherency();
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
++  CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(0));
++  CPPUNIT_ASSERT_EQUAL(NORM_POLYHED,mesh->getTypeOfCell(1));
++  CPPUNIT_ASSERT_EQUAL(NORM_POLYHED,mesh->getTypeOfCell(2));
++  CPPUNIT_ASSERT_EQUAL((std::size_t)98,mesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(725,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+98,0));
++  CPPUNIT_ASSERT_DOUBLES_EQUAL(110.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
++  CPPUNIT_ASSERT_EQUAL(155,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+4,0));
++  mesh->decrRef();
++  //
++  mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),-1);
++  mesh->checkCoherency();
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(17,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllGeoTypes().size());
++  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((std::size_t)83,mesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(619,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+83,0));
++  mesh->decrRef();
++  //
++  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");
++  CPPUNIT_ASSERT(families[2]=="FAMILLE_FACE_TRIA32");
++  CPPUNIT_ASSERT(families[3]=="FAMILLE_ZERO");
++  vector<string> families2;
++  families2.push_back(families[0]);
++  mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),-1,families2);
++  mesh->checkCoherency();
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(1,(int)mesh->getAllGeoTypes().size());
++  for(int i=0;i<3;i++)
++    CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i));
++  CPPUNIT_ASSERT_EQUAL((std::size_t)19,mesh->getNodalConnectivity()->getNbOfElems());
++  CPPUNIT_ASSERT_EQUAL(117,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+19,0));
++  mesh->decrRef();
++  //
++  mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),0,families2);
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
++  CPPUNIT_ASSERT_EQUAL(0,mesh->getNumberOfCells());
++  CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
++  CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
++  CPPUNIT_ASSERT_EQUAL(0,(int)mesh->getAllGeoTypes().size());
++  mesh->decrRef();
++}
++
++std::string MEDLoaderTest::getResourceFile( const std::string& filename ) const
++{
++  std::string resourceFile = "";
++
++  if ( getenv("top_srcdir") ) {
++    // we are in 'make test' step
++    resourceFile = getenv("top_srcdir");
++    resourceFile += "/resources/";
++  }
++  else if ( getenv("MED_ROOT_DIR") ) {
++    // use MED_ROOT_DIR env.var
++    resourceFile = getenv("MED_ROOT_DIR");
++    resourceFile += "/share/salome/resources/med/";
++  }
++  resourceFile += filename;
++  return resourceFile;
++}
++
++
 +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_QUAD4,4,targetConn+12);
 +  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16);
 +  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6);
 +  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_QUAD4,4,targetConn+12);
 +  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16);
 +  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6);
 +  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,2,3,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->buildExtrudedMesh(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);
 +  std::vector<double> _gsCoo2(_gsCoo1);
 +  std::vector<double> _wg2(_wg1);
 +  _gsCoo2.resize(6); _wg2.resize(3);
 +  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);
 +  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,_refCoo2,_gsCoo2,_wg2);
 +  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;
 +}
 +
++
++
index e0e8429959d3b7469afe708dc09d38266a1583cd,0000000000000000000000000000000000000000..b42b3b3db4f106d4e03c9e3c0f016c2d6ad57602
mode 100644,000000..100644
--- /dev/null
@@@ -1,95 -1,0 +1,107 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __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( testSplitIntoNameAndUnit1 );
 +    CPPUNIT_TEST( testMesh3DSurfShuffleRW );
 +    CPPUNIT_TEST( testFieldShuffleRW1 );
 +    CPPUNIT_TEST( testMultiFieldShuffleRW1 );
 +    CPPUNIT_TEST( testWriteUMeshesRW1 );
 +    CPPUNIT_TEST( testMixCellAndNodesFieldRW1 );
 +    CPPUNIT_TEST( testGetAllFieldNamesRW1 );
++
++    // Previously in ParaMEDMEM:
++    CPPUNIT_TEST(testMEDLoaderRead1);
++    CPPUNIT_TEST(testMEDLoaderPolygonRead);
++    CPPUNIT_TEST(testMEDLoaderPolyhedronRead);
++
 +    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 testSplitIntoNameAndUnit1();
 +    void testMesh3DSurfShuffleRW();
 +    void testFieldShuffleRW1();
 +    void testMultiFieldShuffleRW1();
 +    void testWriteUMeshesRW1();
 +    void testMixCellAndNodesFieldRW1();
 +    void testGetAllFieldNamesRW1();
++
++    void testMEDLoaderRead1();
++    void testMEDLoaderPolygonRead();
++    void testMEDLoaderPolyhedronRead();
 +  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();
++
++    std::string getResourceFile( const std::string& filename ) const;
 +  };
 +}
 +
 +#endif
index 8f6b4cea802e432343c50312fafec9e6fc54257a,0000000000000000000000000000000000000000..7297be21caaf23c89e37eba08dda9bb155cf573b
mode 100644,000000..100644
--- /dev/null
@@@ -1,336 -1,0 +1,345 @@@
-   //!converts a pair <subdomainid,local> to a global number 
-   std::pair<int,int> BlockTopology::globalToLocal(const int global) const
-   {
-     int subdomain_id=0;
-     int position=global;
-     int size=_nb_elems;
-     int size_procs=_proc_group->size();
-     int increment=size;
-     vector<int>axis_position(_dimension);
-     vector<int>axis_offset(_dimension);
-     for (int idim=0; idim<_dimension; idim++)
-       {
-         int axis_size=_local_array_indices[idim].size()-1;
-         int axis_nb_elem=_local_array_indices[idim][axis_size];
-         increment=increment/axis_nb_elem;
-         int proc_increment = size_procs/(axis_size);
-         int axis_pos=position/increment;
-         position=position%increment;  
-         int iaxis=1;
-         while (_local_array_indices[idim][iaxis]<=axis_pos)
-           {
-             subdomain_id+=proc_increment;
-             iaxis++;
-           }
-         axis_position[idim]=axis_pos-_local_array_indices[idim][iaxis-1];
-         axis_offset[idim]=iaxis;
-       }
-     int local=0;
-     int local_increment=1;
-     for (int idim=_dimension-1; idim>=0; idim--)
-       {
-         local+=axis_position[idim]*local_increment;
-         local_increment*=_local_array_indices[idim][axis_offset[idim]]-_local_array_indices[idim][axis_offset[idim]-1];
-       }
-     return make_pair(subdomain_id,local);
-   }
-   //!converts local number to a global number
-   int BlockTopology::localToGlobal(const pair<int,int> local) const
-   {
-   
-     int subdomain_id=local.first;
-     int global=0;
-     int loc=local.second;
-     int increment=_nb_elems;
-     int proc_increment=_proc_group->size();
-     int local_increment=getNbLocalElements();
-     for (int idim=0; idim < _dimension; idim++)
-       {
-         int axis_size=_local_array_indices[idim].size()-1;
-         int axis_nb_elem=_local_array_indices[idim][axis_size];
-         increment=axis_nb_elem==0?0:increment/axis_nb_elem;
-         proc_increment = proc_increment/(axis_size);
-         int proc_axis=subdomain_id/proc_increment;
-         subdomain_id=subdomain_id%proc_increment;
-         int local_axis_nb_elem=_local_array_indices[idim][proc_axis+1]-_local_array_indices[idim][proc_axis];
-         local_increment = (local_axis_nb_elem==0)?0:(local_increment/local_axis_nb_elem);
-         int iaxis=((local_increment==0)?0:(loc/local_increment))+_local_array_indices[idim][proc_axis];
-         global+=increment*iaxis;
-         loc = (local_increment==0)?0:(loc%local_increment);
-       }
-     return global;
-   }
-   //Retrieves the local number of elements 
-   int BlockTopology::getNbLocalElements()const 
-   {
-     int position=_proc_group->myRank();
-     int nb_elem = 1;
-     int increment=1;
-     for (int i=_dimension-1; i>=0; i--)
-       {  
-         increment *=_nb_procs_per_dim[i];
-         int idim=position%increment;
-         position=position/increment;
-         int imin=_local_array_indices[i][idim];
-         int imax=_local_array_indices[i][idim+1];
-         nb_elem*=(imax-imin);
-       }
-     return nb_elem;
-   }
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "BlockTopology.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +#include "MEDCouplingCMesh.hxx"
 +#include "CommInterface.hxx"
 +#include "ProcessorGroup.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "ComponentTopology.hxx"
 +#include "InterpKernelUtilities.hxx"
 +
 +#include <vector>
 +#include <algorithm>
 +#include <utility>
 +#include <iostream>
 +
 +using namespace std;
 +
 +namespace ParaMEDMEM
 +{
++  /*!
++   * Default ctor.
++   */
++  BlockTopology::BlockTopology() :
++    _dimension(0), _nb_procs_per_dim(0),
++    _local_array_indices(0), _cycle_type(0),
++    _proc_group(NULL),_nb_elems(0),
++    _owns_processor_group(false)
++  {}
 +
 +  /*!
 +   * Constructor of a block topology from a grid. 
 +   * This preliminary version simply splits along the first axis
 +   * instead of making the best choice with respect to the 
 +   * values of the different axes. 
 +   */
 +  BlockTopology::BlockTopology(const ProcessorGroup& group, MEDCouplingCMesh *grid):
 +    _dimension(grid->getSpaceDimension()), _proc_group(&group), _owns_processor_group(false)
 +  {
 +    vector <int> axis_length(_dimension);
 +    _nb_elems=1;
 +    for (int idim=0; idim <_dimension; idim++)
 +      {
 +        DataArrayDouble *arr=grid->getCoordsAt(idim);
 +        axis_length[idim]=arr->getNbOfElems();
 +        _nb_elems*=axis_length[idim];
 +      }  
 +    //default splitting along 1st dimension
 +    _local_array_indices.resize(_dimension);
 +    _nb_procs_per_dim.resize(_dimension);
 +  
 +    _local_array_indices[0].resize(_proc_group->size()+1);
 +    _local_array_indices[0][0]=0;
 +    _nb_procs_per_dim[0]=_proc_group->size();
 +  
 +    for (int i=1; i<=_proc_group->size(); i++)
 +      {
 +        _local_array_indices[0][i]=_local_array_indices[0][i-1]+
 +          axis_length[0]/_proc_group->size();
 +        if (i<= axis_length[0]%_proc_group->size())
 +          _local_array_indices[0][i]+=1;
 +      }
 +    for (int i=1; i<_dimension; i++)
 +      {
 +        _local_array_indices[i].resize(2);
 +        _local_array_indices[i][0]=0;
 +        _local_array_indices[i][1]=axis_length[i];
 +        _nb_procs_per_dim[i]=1;
 +      }
 +    _cycle_type.resize(_dimension);
 +    for (int i=0; i<_dimension; i++)
 +      _cycle_type[i]=ParaMEDMEM::Block;  
 +  }
 +
 +  /*!
 +   * Creation of a block topology by composing 
 +   * a geometrical topology and a component topology.
 +   * This constructor is intended for creating fields 
 +   * for which the parallel distribution is made on the
 +   * components of the field rather than on the geometrical 
 +   * partitioning of the underlying mesh.
 +   * 
 +   */ 
 +  BlockTopology::BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo):_owns_processor_group(false)
 +  {
 +    // so far, the block topology can only be created if the proc group 
 +    // is either on geom_topo or on comp_topo
 +    if (geom_topo.getProcGroup()->size()>1 && comp_topo.nbBlocks()>1)
 +      throw INTERP_KERNEL::Exception(LOCALIZED("BlockTopology cannot yet be constructed with both complex geo and components topology"));
 +
 +    if (comp_topo.nbComponents()==1)
 +      {
 +        *this=geom_topo;
 +        return;
 +      }
 +    else
 +      {
 +        _dimension = geom_topo.getDimension()+1;
 +        if (comp_topo.nbBlocks()>1)
 +          _proc_group=comp_topo.getProcGroup();
 +        else
 +          _proc_group=geom_topo.getProcGroup();
 +        _local_array_indices=geom_topo._local_array_indices;
 +        vector<int> comp_indices = *(comp_topo.getBlockIndices());
 +        _local_array_indices.push_back(comp_indices);
 +        _nb_procs_per_dim=geom_topo._nb_procs_per_dim;
 +        _nb_procs_per_dim.push_back(comp_topo.nbBlocks());
 +        _cycle_type=geom_topo._cycle_type;
 +        _cycle_type.push_back(Block);
 +        _nb_elems=geom_topo.getNbElements()*comp_topo.nbComponents();
 +      }  
 +  }
 +
 +  /*! Constructor for creating a one-dimensional
 +   * topology from a processor group and a local 
 +   * number of elements on each processor
 +   * 
 +   * The function must be called only by the processors belonging
 +   * to group \a group. Calling it from a processor not belonging
 +   * to \a group will cause an MPI error, while calling from a subset
 +   * of \a group will result in a deadlock. 
 +   */
 +  BlockTopology::BlockTopology(const ProcessorGroup& group, int nb_elem):_dimension(1),_proc_group(&group),_owns_processor_group(false)
 +  {
 +    int* nbelems_per_proc = new int[group.size()];
 +    const MPIProcessorGroup* mpi_group=dynamic_cast<const MPIProcessorGroup*>(_proc_group);
 +    const MPI_Comm* comm=mpi_group->getComm();
 +    int nbtemp=nb_elem;
 +    mpi_group->getCommInterface().allGather(&nbtemp, 1, MPI_INT, 
 +                                            nbelems_per_proc, 1, MPI_INT, 
 +                                            *comm);
 +    _nb_elems=0;  
 +  
 +    //splitting along only dimension
 +    _local_array_indices.resize(1);
 +    _nb_procs_per_dim.resize(1);  
 +          
 +    _local_array_indices[0].resize(_proc_group->size()+1);
 +    _local_array_indices[0][0]=0;
 +    _nb_procs_per_dim[0]=_proc_group->size();
 +  
 +    for (int i=1; i<=_proc_group->size(); i++)
 +      {
 +        _local_array_indices[0][i]=_local_array_indices[0][i-1]+
 +          nbelems_per_proc[i-1];
 +        _nb_elems+=nbelems_per_proc[i-1];
 +      }
 +    _cycle_type.resize(1);
 +    _cycle_type[0]=ParaMEDMEM::Block;
 +    delete[] nbelems_per_proc;
 +  }
 +
 +  BlockTopology::~BlockTopology()
 +  {
 +    if (_owns_processor_group)
 +      delete _proc_group;
 +  }
 +
++  //!converts a pair <subdomainid,local> to a global number
++  std::pair<int,int> BlockTopology::globalToLocal(const int global) const
++  {
++    int subdomain_id=0;
++    int position=global;
++    int size=_nb_elems;
++    int size_procs=_proc_group->size();
++    int increment=size;
++    vector<int>axis_position(_dimension);
++    vector<int>axis_offset(_dimension);
++    for (int idim=0; idim<_dimension; idim++)
++      {
++        int axis_size=_local_array_indices[idim].size()-1;
++        int axis_nb_elem=_local_array_indices[idim][axis_size];
++        increment=increment/axis_nb_elem;
++        int proc_increment = size_procs/(axis_size);
++        int axis_pos=position/increment;
++        position=position%increment;
++        int iaxis=1;
++        while (_local_array_indices[idim][iaxis]<=axis_pos)
++          {
++            subdomain_id+=proc_increment;
++            iaxis++;
++          }
++        axis_position[idim]=axis_pos-_local_array_indices[idim][iaxis-1];
++        axis_offset[idim]=iaxis;
++      }
++    int local=0;
++    int local_increment=1;
++    for (int idim=_dimension-1; idim>=0; idim--)
++      {
++        local+=axis_position[idim]*local_increment;
++        local_increment*=_local_array_indices[idim][axis_offset[idim]]-_local_array_indices[idim][axis_offset[idim]-1];
++      }
++    return make_pair(subdomain_id,local);
++  }
++
++  //!converts local number to a global number
++  int BlockTopology::localToGlobal(const pair<int,int> local) const
++  {
++
++    int subdomain_id=local.first;
++    int global=0;
++    int loc=local.second;
++    int increment=_nb_elems;
++    int proc_increment=_proc_group->size();
++    int local_increment=getNbLocalElements();
++    for (int idim=0; idim < _dimension; idim++)
++      {
++        int axis_size=_local_array_indices[idim].size()-1;
++        int axis_nb_elem=_local_array_indices[idim][axis_size];
++        increment=axis_nb_elem==0?0:increment/axis_nb_elem;
++        proc_increment = proc_increment/(axis_size);
++        int proc_axis=subdomain_id/proc_increment;
++        subdomain_id=subdomain_id%proc_increment;
++        int local_axis_nb_elem=_local_array_indices[idim][proc_axis+1]-_local_array_indices[idim][proc_axis];
++        local_increment = (local_axis_nb_elem==0)?0:(local_increment/local_axis_nb_elem);
++        int iaxis=((local_increment==0)?0:(loc/local_increment))+_local_array_indices[idim][proc_axis];
++        global+=increment*iaxis;
++        loc = (local_increment==0)?0:(loc%local_increment);
++      }
++    return global;
++  }
++
++  //Retrieves the local number of elements
++  int BlockTopology::getNbLocalElements()const
++  {
++    int position=_proc_group->myRank();
++    int nb_elem = 1;
++    int increment=1;
++    for (int i=_dimension-1; i>=0; i--)
++      {
++        increment *=_nb_procs_per_dim[i];
++        int idim=position%increment;
++        position=position/increment;
++        int imin=_local_array_indices[i][idim];
++        int imax=_local_array_indices[i][idim+1];
++        nb_elem*=(imax-imin);
++      }
++    return nb_elem;
++  }
++
 +  /*! Retrieves the min and max indices of the domain stored locally
 +   * for each dimension. The output vector has the topology dimension
 +   * as a size and each pair <int,int> contains min and max. Indices 
 +   * range from min to max-1.
 +   */
 +  std::vector<std::pair<int,int> > BlockTopology::getLocalArrayMinMax() const
 +  {
 +    vector<pair<int,int> > local_indices (_dimension);
 +    int myrank=_proc_group->myRank();
 +    int increment=1;
 +    for (int i=_dimension-1; i>=0; i--)
 +      {  
 +        increment *=_nb_procs_per_dim[i];
 +        int idim=myrank%increment;
 +        local_indices[i].first=_local_array_indices[i][idim];
 +        local_indices[i].second=_local_array_indices[i][idim+1];
 +        cout << local_indices[i].first << " "<< local_indices[i].second<<endl;
 +      }
 +    return local_indices;
 +  }
 +
 +  /*! Serializes the data contained in the Block Topology
 +   * for communication purposes*/
 +  void BlockTopology::serialize(int* & serializer, int& size) const 
 +  {
 +    vector<int> buffer;
 +  
 +    buffer.push_back(_dimension);
 +    buffer.push_back(_nb_elems);
 +    for (int i=0; i<_dimension; i++)
 +      {
 +        buffer.push_back(_nb_procs_per_dim[i]);
 +        buffer.push_back(_cycle_type[i]);
 +        buffer.push_back(_local_array_indices[i].size());
 +        for (int j=0; j<(int)_local_array_indices[i].size(); j++)
 +          buffer.push_back(_local_array_indices[i][j]);
 +      }
 +  
 +    //serializing the comm group
 +    int size_comm=_proc_group->size();
 +    buffer.push_back(size_comm);
 +    MPIProcessorGroup world_group(_proc_group->getCommInterface());
 +    for (int i=0; i<size_comm;i++)
 +      {
 +        int world_rank=world_group.translateRank(_proc_group, i);
 +        buffer.push_back(world_rank);
 +      }
 +  
 +    serializer=new int[buffer.size()];
 +    size=buffer.size();
 +    copy(buffer.begin(), buffer.end(), serializer);
 +  }
 +
 +  /*!
 +   *
 +   * Unserializes the data contained in the Block Topology
 +   * after communication. Uses the same structure as the one used for serialize() 
 +   *
 +   */
 +  void BlockTopology::unserialize(const int* serializer,const CommInterface& comm_interface)
 +  {
 +    const int* ptr_serializer=serializer;
 +    cout << "unserialize..."<<endl;
 +    _dimension=*(ptr_serializer++);
 +    cout << "dimension "<<_dimension<<endl;
 +    _nb_elems=*(ptr_serializer++);
 +    cout << "nbelems "<<_nb_elems<<endl;
 +    _nb_procs_per_dim.resize(_dimension);
 +    _cycle_type.resize(_dimension);
 +    _local_array_indices.resize(_dimension);
 +    for (int i=0; i<_dimension; i++)
 +      {
 +        _nb_procs_per_dim[i]=*(ptr_serializer++);
 +        _cycle_type[i]=(CYCLE_TYPE)*(ptr_serializer++);
 +        _local_array_indices[i].resize(*(ptr_serializer++));
 +        for (int j=0; j<(int)_local_array_indices[i].size(); j++)
 +          _local_array_indices[i][j]=*(ptr_serializer++);
 +      }
 +    set<int> procs;
 +    int size_comm=*(ptr_serializer++);
 +    for (int i=0; i<size_comm; i++)
 +      procs.insert(*(ptr_serializer++));
 +    cout << "unserialize..."<<procs.size()<<endl;
 +    _proc_group=new MPIProcessorGroup(comm_interface,procs);
 +    _owns_processor_group=true;
 +    //TODO manage memory ownership of _proc_group  
 +  }
 +}
index eabc2ec2de519dee666239b1df6a991185c866b4,0000000000000000000000000000000000000000..37466731d6d21a4c759cf1f4dbbb5b1e9d9442f6
mode 100644,000000..100644
--- /dev/null
@@@ -1,70 -1,0 +1,80 @@@
-     BlockTopology() { }
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __BLOCKTOPOLOGY_HXX__
 +#define __BLOCKTOPOLOGY_HXX__
 +
 +#include "Topology.hxx"
 +#include "ProcessorGroup.hxx"
 +
 +#include <vector>
 +
 +namespace ParaMEDMEM
 +{
 +  class ComponentTopology;
 +  class MEDCouplingCMesh;
 +
 +  typedef enum{Block,Cycle} CYCLE_TYPE; 
 +
++  /*!
++   * \anchor BlockTopology-det
++   *
++   * A BlockTopology typically represents the split of a *structured* mesh among the processors of
++   * a common ProcessorGroup. Each processor gets a contiguous part of the cells in the mesh (a block).
++   *
++   * A BlockTopology can also be used to split a structured domain among the various components of a field.
++   *
++   * \sa ExplicitTopology
++   */
 +  class BlockTopology : public Topology
 +  {
 +  public:
++    BlockTopology();
 +    BlockTopology(const ProcessorGroup& group, MEDCouplingCMesh *grid); 
 +    BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo);
 +    BlockTopology(const ProcessorGroup& group, int nb_elem);
 +    virtual ~BlockTopology();
 +    //!Retrieves the number of elements for a given topology
 +    int getNbElements()const { return _nb_elems; }
 +    int getNbLocalElements() const;
 +    const ProcessorGroup* getProcGroup()const { return _proc_group; }
 +    std::pair<int,int> globalToLocal (const int) const ;
 +    int localToGlobal (const std::pair<int,int>) const;
 +    std::vector<std::pair<int,int> > getLocalArrayMinMax() const ;
 +    int getDimension() const { return _dimension; }
 +    void serialize(int* & serializer, int& size) const ;
 +    void unserialize(const int* serializer, const CommInterface& comm_interface);
 +  private:
 +    //dimension : 2 or 3
 +    int _dimension;
 +    //proc array
 +    std::vector<int> _nb_procs_per_dim;
 +    //stores the offsets vector  
 +    std::vector<std::vector<int> > _local_array_indices;
 +    //stores the cycle type (block or cyclic)
 +    std::vector<CYCLE_TYPE> _cycle_type;
 +    //Processor group
 +    const ProcessorGroup* _proc_group;
 +    //nb of elements
 +    int _nb_elems;
 +    bool _owns_processor_group;
 +  };
 +}
 +
 +#endif
index a94cb3eded6ceb255932b0f04e504a95691a7219,0000000000000000000000000000000000000000..cf0776595335a5fc2adc74ad354fe8cf00df1763
mode 100644,000000..100644
--- /dev/null
@@@ -1,71 -1,0 +1,72 @@@
 +# Copyright (C) 2012-2015  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, or (at your option) any later version.
 +#
 +# This library is distributed in the hope that it will be useful,
 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +# Lesser General Public License for more details.
 +#
 +# You should have received a copy of the GNU Lesser General Public
 +# License along with this library; if not, write to the Free Software
 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +#
 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +#
 +# Author : Anthony Geay (CEA/DEN)
 +
 +ADD_DEFINITIONS(${MPI_DEFINITIONS})
 +
 +INCLUDE_DIRECTORIES(
 +  ${MPI_INCLUDE_DIRS}
 +  ${CMAKE_CURRENT_SOURCE_DIR}
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints
 +  )
 +
 +SET(paramedmem_SOURCES
 +  ProcessorGroup.cxx
 +  MPIProcessorGroup.cxx
 +  ParaMESH.cxx
 +  ComponentTopology.cxx
 +  MPIAccess.cxx
 +  InterpolationMatrix.cxx
 +  OverlapInterpolationMatrix.cxx
 +  StructuredCoincidentDEC.cxx
 +  ExplicitCoincidentDEC.cxx
 +  InterpKernelDEC.cxx
 +  ElementLocator.cxx
 +  OverlapElementLocator.cxx
 +  MPIAccessDEC.cxx
 +  TimeInterpolator.cxx
 +  LinearTimeInterpolator.cxx
 +  DEC.cxx
 +  DisjointDEC.cxx
 +  OverlapDEC.cxx
 +  ExplicitTopology.cxx
 +  MxN_Mapping.cxx
 +  OverlapMapping.cxx
 +  ICoCoMEDField.cxx
 +  ICoCoField.cxx
 +  ParaFIELD.cxx
 +  ParaGRID.cxx
 +  BlockTopology.cxx
++  ExplicitMapping.cxx
 +  )
 +
 +ADD_LIBRARY(paramedmem SHARED ${paramedmem_SOURCES})
 +TARGET_LINK_LIBRARIES(paramedmem medcoupling ${MPI_LIBRARIES})
 +INSTALL(TARGETS paramedmem EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDTOOL_INSTALL_LIBS})
 +
 +FILE(GLOB paramedmem_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx")
 +INSTALL(FILES ${paramedmem_HEADERS_HXX} DESTINATION ${MEDTOOL_INSTALL_HEADERS})
 +
 +# To allow usage as SWIG dependencies:
 +SET(paramedmem_HEADERS_HXX PARENT_SCOPE)
index 948f099d88a77ce5254c3d40825da44f4f66ff8d,0000000000000000000000000000000000000000..54e06e6fc8269ba3a38187adaa82b05b53ea5ac5
mode 100644,000000..100644
--- /dev/null
@@@ -1,66 -1,0 +1,66 @@@
-     It is a helper class that gathers the calls to the MPI
-     library that are made in the %ParaMEDMEM library. This gathering
-     allows easier gathering of information about the communication
-     in the library.
-     It is typically called after the MPI_Init() call in a program. It is afterwards passed as a parameter to the constructors of %ParaMEDMEM objects so that they access the MPI library via the CommInterface.
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "CommInterface.hxx"
 +
 +namespace ParaMEDMEM
 +{
 +  /*! \anchor CommInterface-det
 +     \class CommInterface
 +
 +    The class \a CommInterface is the gateway to the MPI library.
++    It is a wrapper around all MPI calls, thus trying to abstract the rest of the code from using the direct MPI API
++    (but this is not strictly respected overall in practice ...). It is used in all
++    the \ref parallel "DEC related classes".
 +
++    It is typically instanciated after the MPI_Init() call in a program and is afterwards passed as a
++    parameter to the constructors of various \ref parallel "parallel objects" so that they access the
++    MPI library via this common interface.
 +
 +    As an example, the following code excerpt initializes a processor group made of the zero processor.
 +
 +    \verbatim
 +    #include "CommInterface.hxx"
 +    #include "ProcessorGroup.hxx"
 +
 +    int main(int argc, char** argv)
 +    {
 +    //initialization
 +    MPI_Init(&argc, &argv);
 +    ParaMEDMEM::CommInterface comm_interface;
 +
 +    //setting up a processor group with proc 0
 +    set<int> procs;
 +    procs.insert(0);
 +    ParaMEDMEM::ProcessorGroup group(procs, comm_interface);
 +
 +    //cleanup
 +    MPI_Finalize();
 +    }
 +    \endverbatim
 +  */
 +
 +  CommInterface::CommInterface()
 +  {
 +  }
 +
 +  CommInterface::~CommInterface()
 +  {
 +  }
 +}
index de11e3efe820018d673a1b5cc848d411382b1e76,0000000000000000000000000000000000000000..9b84607a382a55982a4a8ba08e3f1e29b387000e
mode 100644,000000..100644
--- /dev/null
@@@ -1,56 -1,0 +1,64 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __COMPONENTTOPOLOGY_HXX__
 +#define __COMPONENTTOPOLOGY_HXX__
 +
 +#include "Topology.hxx"
 +
 +#include <vector>
 +
 +namespace ParaMEDMEM
 +{
 +  class ProcessorGroup;
 +
++  /*!
++   * \anchor ComponentTopology-det
++   *
++   * The ComponentTopology can be used when building a ParaFIELD. It allows the splitting of the components
++   * of the field among different processors within a single processor group.
++   *
++   * \sa ParaFIELD::ParaFIELD(TypeOfField , TypeOfTimeDiscretization , ParaMESH* , const ComponentTopology& )
++   */
 +  class ComponentTopology
 +  {
 +  public:
 +    ComponentTopology(int nb_comp, ProcessorGroup* group);
 +    ComponentTopology(int nb_comp, int nb_blocks);
 +    ComponentTopology(int nb_comp);
 +    ComponentTopology();
 +    virtual ~ComponentTopology();
 +    //!returns the number of MED components in the topology
 +    int nbComponents() const { return _component_array.back(); }
 +    //!returns the number of MED components on local processor
 +    int nbLocalComponents() const ;
 +    //!returns the number of the first MED component on local processor
 +    int firstLocalComponent() const ;
 +    //!returns the number of blocks in the topology
 +    int nbBlocks()const {return _component_array.size()-1;}
 +    //!returns the block structure
 +    const std::vector<int>* getBlockIndices() const { return &_component_array; }
 +    const ProcessorGroup* getProcGroup()const { return _proc_group; } 
 +  private:
 +    std::vector<int> _component_array;
 +    ProcessorGroup* _proc_group;
 +  };
 +}
 +
 +#endif /*COMPONENTTOPOLOGY_HXX_*/
index 1b0a8675fa7a8e75c8f523eb25a20beeb27eb925,0000000000000000000000000000000000000000..6df677bbc4bfe06c55029449bc8e0ba5f1e38e1f
mode 100644,000000..100644
--- /dev/null
@@@ -1,43 -1,0 +1,52 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __DEC_HXX__
 +#define __DEC_HXX__
 +
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "NormalizedUnstructuredMesh.hxx"
 +#include "DECOptions.hxx"
 +
 +namespace ParaMEDMEM
 +{
 +  class CommInterface;
++
++  /*!
++   * DEC stands for Data Exchange Channel. See the page \ref para-dec for more on this.
++   *
++   * This class is purely abstract. See the derivations:
++   * - \ref DisjointDEC-det "DisjointDEC"
++   * - \ref NonCoincidentDEC "NonCoincidentDEC"
++   * - \ref OverlapDEC "OverlapDEC"
++   */
 +  class DEC : public DECOptions
 +  {
 +  public:
 +    DEC();
 +    void copyFrom(const DEC& other);
 +    virtual void synchronize() = 0;
 +    virtual void sendRecvData(bool way=true) = 0;
 +    virtual ~DEC();
 +  protected:
 +    const CommInterface* _comm_interface;
 +  };
 +}
 +
 +#endif
index 5572ffdca30309e126aa1e3c90c1f2e30ba3bfdf,0000000000000000000000000000000000000000..eb92712372d5fa8db41432edc3120bb35538fcd5
mode 100644,000000..100644
--- /dev/null
@@@ -1,74 -1,0 +1,129 @@@
-   //Enum describing the allToAll method used in the communication pattern
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __DECOPTIONS_HXX__
 +#define __DECOPTIONS_HXX__
 +
 +#include <string>
 +
 +namespace ParaMEDMEM
 +{
++  //! Enum describing the allToAll method used in the communication pattern
 +  typedef enum { Native, PointToPoint } AllToAllMethod;
++  //! Enum describing the time interpolation method
 +  typedef enum { WithoutTimeInterp, LinearTimeInterp } TimeInterpolationMethod;
 +
++  /*!
++   This class groups the various options accepted by all \ref para-dec "DECs" (which all inherit from %DECOptions).
++
++   The following code excerpt shows how to set options on a %DEC :
++
++   \code
++   InterpKernelDEC dec(source_group,target_group);
++   dec.setForcedRenormalization(true);
++   dec.attachLocalField(field);
++   dec.synchronize();
++   if (source_group.containsMyRank())
++     dec.sendData();
++   else
++     dec.recvData();
++   \endcode
++   *
++   *
++   */
 +  class DECOptions
 +  {
 +  protected:
 +    std::string _method;
 +    bool _asynchronous;
 +    TimeInterpolationMethod _timeInterpolationMethod;
 +    AllToAllMethod _allToAllMethod;
 +    bool _forcedRenormalization;
 +  public:
 +    DECOptions():_method("P0"),
 +                 _asynchronous(false),
 +                 _timeInterpolationMethod(WithoutTimeInterp),
 +                 _allToAllMethod(Native),
 +                 _forcedRenormalization(false)
 +    {
 +    }
 +    
 +    DECOptions(const DECOptions& deco)
 +    {
 +      _method=deco._method;
 +      _timeInterpolationMethod=deco._timeInterpolationMethod;
 +      _asynchronous=deco._asynchronous;
 +      _forcedRenormalization=deco._forcedRenormalization;
 +      _allToAllMethod=deco._allToAllMethod;
 +    }
 +    
++
++    /*!
++     * \sa setMethod()
++     */
 +    const std::string& getMethod() const { return _method; }
++    /*!
++     * Set interpolation method. Defaults to "P0".
++     */
 +    void setMethod(const char *m) { _method=m; }
 +
++    /*!
++     * \sa setTimeInterpolationMethod()
++     */
 +    TimeInterpolationMethod getTimeInterpolationMethod() const { return DECOptions::_timeInterpolationMethod; }
++    /*!
++     * Set time interpolation method. Default to WithoutTimeInterp.
++     */
 +    void setTimeInterpolationMethod(TimeInterpolationMethod it) { DECOptions::_timeInterpolationMethod=it; }
 +
++    /*!
++     * \sa setForcedRenormalization()
++     */
 +    bool getForcedRenormalization() const { return DECOptions::_forcedRenormalization; }
++
++    /*!
++     * Force renormalization of the field after it has been received so that the total sum
++     * of the field values are the same on both the sending and the receiving side. Defaults to
++     * false.
++     */
 +    void setForcedRenormalization( bool dr) { DECOptions::_forcedRenormalization = dr; }
 +
++
++    /*!
++     * \sa setAsynchronous()
++     */
 +    bool getAsynchronous() const { return DECOptions::_asynchronous; }
++
++    /*!
++     * Switch to asynchronous data transfer mode. Default is false.
++     */
 +    void setAsynchronous( bool dr) { DECOptions::_asynchronous = dr; }
 +     
++    /*!
++     * \sa setAllToAllMethod()
++     */
 +    AllToAllMethod getAllToAllMethod() const { return _allToAllMethod; }
++    /*!
++     * Set the broadcast method for synchronisation processes. Default to Native.
++     */
 +    void setAllToAllMethod(AllToAllMethod sp) { _allToAllMethod=sp; }
 +  };
 +}
 +
 +#endif
index 57e67fd2c93721871b57a49232740f8d0e8c55f6,0000000000000000000000000000000000000000..b2ba8f79555b10204eea93b98dbc3864ea76e1f6
mode 100644,000000..100644
--- /dev/null
@@@ -1,403 -1,0 +1,395 @@@
-    * Interface class for creation of a link between two
-    * processor groups for exhanging mesh or field data.
-    * The \c DEC is defined by attaching a field on the receiving or on the
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "DisjointDEC.hxx"
 +#include "CommInterface.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ComponentTopology.hxx"
 +#include "ParaFIELD.hxx"
 +#include "ParaMESH.hxx"
 +#include "ICoCoField.hxx"
 +#include "ICoCoMEDField.hxx"
 +#include "MPIProcessorGroup.hxx"
 +
 +#include <cmath>
 +#include <iostream>
 +
 +
 +namespace ParaMEDMEM
 +{
 +
 +  /*!
 +   * \anchor DisjointDEC-det
 +   * \class DisjointDEC
 +   *
-    * On top of attaching a \c ParaMEDMEM::ParaFIELD, it is possible to
-    * attach a ICoCo::Field. This class is an abstract class that enables
-    * coupling of codes that respect the ICoCo interface \ref icoco. It has two implementations:
-    * one for codes that express their fields as \ref fields "MEDCoupling fields" (ICoCo::MEDField).
++   * \section DisjointDEC-over Overview
++   *
++   * Abstract interface class representing a link between two
++   * processor groups for exchanging mesh or field data. The two processor groups must
++   * have a void intersection (\ref ParaMEDMEM::OverlapDEC "OverlapDEC" is to be considered otherwise).
++   * The %DEC is initialized by attaching a field on the receiving or on the
 +   * sending side.
-    * \section dec_options DEC Options
-    * Options supported by \c DEC objects are
 +   *
-    * <TABLE BORDER=1 >
-    * <TR><TD>Option</TD><TD>Description</TD><TD>Default value</TD></TR>
-    * <TR><TD>ForcedRenormalization</TD><TD>After receiving data, the target field is renormalized so that L2-norms of the source and target fields match.</TD><TD> false </TD></TR>
-    *</TABLE>
-    The following code excerpt shows how to set options for an object that inherits from \c DEC :
-    \code
-    InterpKernelDEC dec(source_group,target_group);
-    dec.setOptions("ForcedRenormalization",true);
-    dec.attachLocalField(field);
-    dec.synchronize();
-    if (source_group.containsMyRank())
-      dec.sendData();
-    else
-      dec.recvData();
-    \endcode
++   * The data is sent or received through calls to the (abstract) methods recvData() and sendData().
++   *
++   * One can attach either a \c ParaMEDMEM::ParaFIELD, or a
++   * \c ICoCo::Field, or directly a \c ParaMEDMEM::MEDCouplingFieldDouble instance.
++   * See the various signatures of the method DisjointDEC::attachLocalField()
++   *
++   * The derivations of this class should be considered for practical instanciation:
++   * - \ref InterpKernelDEC-det "InterpKernelDEC"
++   * - \ref ExplicitCoincidentDEC-det "ExplicitCoincidentDEC"
++   * - \ref StructuredCoincidentDEC-det "StructuredCoincidentDEC"
++   *
++   * \section DisjointDEC-options DisjointDEC options
++   * The options supported by %DisjointDEC objects are the same that the ones supported for all
++   * DECs in general and are all inherited from the class \ref ParaMEDMEM::DECOptions "DECOptions"
 +   *
 +  */
 +
-       throw INTERP_KERNEL::Exception("DisjointDEC constructor : source_ids and target_ids overlap partially or fully. This type of DEC does not support it ! OverlapDEC class could be the solution !");
 +  DisjointDEC::DisjointDEC(ProcessorGroup& source_group, ProcessorGroup& target_group):
 +      _local_field(0),
 +      _source_group(&source_group),
 +      _target_group(&target_group),
 +      _comm_interface(0),
 +      _owns_field(false),
 +      _owns_groups(false),
 +      _union_comm(MPI_COMM_NULL)
 +  {
 +    _union_group = source_group.fuse(target_group);  
 +  }
 +  
 +  DisjointDEC::DisjointDEC(const DisjointDEC& s):
 +      DEC(s),
 +      _local_field(0),
 +      _union_group(0),
 +      _source_group(0),
 +      _target_group(0),
 +      _comm_interface(0),
 +      _owns_field(false),
 +      _owns_groups(false),
 +      _union_comm(MPI_COMM_NULL)
 +  {
 +    copyInstance(s);
 +  }
 +
 +  DisjointDEC & DisjointDEC::operator=(const DisjointDEC& s)
 +  {
 +    cleanInstance();
 +    copyInstance(s);
 +    return *this;
 +     
 +  }
 +
 +  void DisjointDEC::copyInstance(const DisjointDEC& other)
 +  {
 +    DEC::copyFrom(other);
 +    if(other._target_group)
 +      {
 +        _target_group=other._target_group->deepCpy();
 +        _owns_groups=true;
 +      }
 +    if(other._source_group)
 +      {
 +        _source_group=other._source_group->deepCpy();
 +        _owns_groups=true;
 +      }
 +    if (_source_group && _target_group)
 +      _union_group = _source_group->fuse(*_target_group);
 +  }
 +
 +  DisjointDEC::DisjointDEC(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),
 +     _comm_interface(0),
 +     _union_comm(MPI_COMM_NULL)
 +  {
 +    ParaMEDMEM::CommInterface comm;
 +    // Create the list of procs including source and target
 +    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());
 +    if(union_ids.size()!=(source_ids.size()+target_ids.size()))
++      throw INTERP_KERNEL::Exception("DisjointDEC constructor : source_ids and target_ids overlap partially or fully. This type of DEC does not support it! OverlapDEC class could be the solution!");
 +    int* union_ranks_world=new int[union_ids.size()]; // ranks of sources and targets in world_comm
 +    std::copy(union_ids.begin(), union_ids.end(), union_ranks_world);
 +
 +    // Create a communicator on these procs
 +    MPI_Group union_group,world_group;
 +    comm.commGroup(world_comm,&world_group);
 +    comm.groupIncl(world_group,union_ids.size(),union_ranks_world,&union_group);
 +    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;
 +        comm.groupFree(&union_group);
 +        comm.groupFree(&world_group);
 +        return;
 +      }
 +
 +    // 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(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(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);
 +    comm.groupFree(&union_group);
 +    comm.groupFree(&world_group);
 +  }
 +
 +  DisjointDEC::~DisjointDEC()
 +  {
 +    cleanInstance();
 +  }
 +
 +  void DisjointDEC::cleanInstance()
 +  {
 +    if(_owns_field)
 +      {
 +        delete _local_field;
 +      }
 +    _local_field=0;
 +    _owns_field=false;
 +    if(_owns_groups)
 +      {
 +        delete _source_group;
 +        delete _target_group;
 +      }
 +    _owns_groups=false;
 +    _source_group=0;
 +    _target_group=0;
 +    delete _union_group;
 +    _union_group=0;
 +    if (_union_comm != MPI_COMM_NULL)
 +      _comm_interface->commFree(&_union_comm);
 +  }
 +
 +  void DisjointDEC::setNature(NatureOfField nature)
 +  {
 +    if(_local_field)
 +      _local_field->getField()->setNature(nature);
 +  }
 +
 +  /*! Attaches a local field to a DEC.
 +    If the processor is on the receiving end of the DEC, the field
 +    will be updated by a recvData() call.
 +    Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side.
 +  */
 +  void DisjointDEC::attachLocalField(const ParaFIELD *field, bool ownPt)
 +  {
 +    if(!isInUnion())
 +      return ;
 +    if(_owns_field)
 +      delete _local_field;
 +    _local_field=field;
 +    _owns_field=ownPt;
 +    _comm_interface=&(field->getTopology()->getProcGroup()->getCommInterface());
 +    compareFieldAndMethod();
 +  }
 +
 +  /*! Attaches a local field to a DEC. The method will test whether the processor
 +    is on the source or the target side and will associate the mesh underlying the 
 +    field to the local side.
 +
 +    If the processor is on the receiving end of the DEC, the field
 +    will be updated by a recvData() call.
 +    Reversely, if the processor is on the sending end, the field will be read, possibly transformed,
 +    and sent appropriately to the other side.
 +  */
 +
 +  void DisjointDEC::attachLocalField(MEDCouplingFieldDouble *field)
 +  {
 +    if(!isInUnion())
 +      return ;
 +    ProcessorGroup* local_group;
 +    if (_source_group->containsMyRank())
 +      local_group=_source_group;
 +    else if (_target_group->containsMyRank())
 +      local_group=_target_group;
 +    else
 +      throw INTERP_KERNEL::Exception("Invalid procgroup for field attachment to DEC");
 +    ParaMESH *paramesh=new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())),*local_group,field->getMesh()->getName());
 +    ParaFIELD *tmp=new ParaFIELD(field, paramesh, *local_group);
 +    tmp->setOwnSupport(true);
 +    attachLocalField(tmp,true);
 +    //_comm_interface=&(local_group->getCommInterface());
 +  }
 +
 +  /*! 
 +    Attaches a local field to a DEC.
 +    If the processor is on the receiving end of the DEC, the field
 +    will be updated by a recvData() call.
 +    Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side.
 +    The field type is a generic ICoCo Field, so that the DEC can couple a number of different fields :
 +    - a ICoCo::MEDField, that is created from a MEDCoupling structure
 +    
 +  */
 +  void DisjointDEC::attachLocalField(const ICoCo::MEDField *field)
 +  {
 +    if(!isInUnion())
 +      return ;
 +    if(!field)
 +      throw INTERP_KERNEL::Exception("DisjointDEC::attachLocalField : ICoCo::MEDField pointer is NULL !");
 +    attachLocalField(field->getField());
 +  }
 +  
 +  /*!
 +    Computes the field norm over its support 
 +    on the source side and renormalizes the field on the target side
 +    so that the norms match.
 +
 +    \f[
 +    I_{source}=\sum_{i=1}^{n_{source}}V_{i}.|\Phi^{source}_{i}|^2,
 +    \f]
 +
 +    \f[
 +    I_{target}=\sum_{i=1}^{n_{target}}V_{i}.|\Phi^{target}_{i}|^2,
 +    \f]
 +    
 +    \f[
 +    \Phi^{target}:=\Phi^{target}.\sqrt{I_{source}/I_{target}}.
 +    \f]
 +
 +  */
 +  void DisjointDEC::renormalizeTargetField(bool isWAbs)
 +  {
 +    if (_source_group->containsMyRank())
 +      for (int icomp=0; icomp<_local_field->getField()->getArray()->getNumberOfComponents(); icomp++)
 +        {
 +          double total_norm = _local_field->getVolumeIntegral(icomp+1,isWAbs);
 +          double source_norm = total_norm;
 +          _comm_interface->broadcast(&source_norm, 1, MPI_DOUBLE, 0,* dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm());
 +
 +        }
 +    if (_target_group->containsMyRank())
 +      {
 +        for (int icomp=0; icomp<_local_field->getField()->getArray()->getNumberOfComponents(); icomp++)
 +          {
 +            double total_norm = _local_field->getVolumeIntegral(icomp+1,isWAbs);
 +            double source_norm=total_norm;
 +            _comm_interface->broadcast(&source_norm, 1, MPI_DOUBLE, 0,* dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm());
 +
 +            if (fabs(total_norm)>1e-100)
 +              _local_field->getField()->applyLin(source_norm/total_norm,0.0,icomp+1);
 +          }
 +      }
 +  }
 +
 +  bool DisjointDEC::isInSourceSide() const
 +  {
 +    if(!_source_group)
 +      return false;
 +    return _source_group->containsMyRank();
 +  }
 +
 +  bool DisjointDEC::isInTargetSide() const
 +  {
 +    if(!_target_group)
 +      return false;
 +    return _target_group->containsMyRank();
 +  }
 +
 +  bool DisjointDEC::isInUnion() const
 +  {
 +    if(!_union_group)
 +      return false;
 +    return _union_group->containsMyRank();
 +  }
 +
 +  void DisjointDEC::compareFieldAndMethod() const throw(INTERP_KERNEL::Exception)
 +  {
 +    if (_local_field)
 +      {
 +        TypeOfField entity = _local_field->getField()->getTypeOfField();
 +        if ( getMethod() == "P0" )
 +          {
 +            if ( entity != ON_CELLS )
 +              throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch."
 +                                             " For P0 interpolation, field must be on MED_CELL's");
 +          }
 +        else if ( getMethod() == "P1" )
 +          {
 +            if ( entity != ON_NODES )
 +              throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch."
 +                                             " For P1 interpolation, field must be on MED_NODE's");
 +          }
 +        else if ( getMethod() == "P1d" )
 +          {
 +            if ( entity != ON_CELLS )
 +              throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch."
 +                                             " For P1d interpolation, field must be on MED_CELL's");
 +            if ( _target_group->containsMyRank() )
 +              throw INTERP_KERNEL::Exception("Projection to P1d field not supported");
 +          }
 +        else
 +          {
 +            throw INTERP_KERNEL::Exception("Unknown interpolation method. Possible methods: P0, P1, P1d");
 +          }
 +      }
 +  }
 +
 +  /*!
 +    If way==true, source procs call sendData() and target procs call recvData().
 +    if way==false, it's the other way round.
 +  */
 +  void DisjointDEC::sendRecvData(bool way)
 +  {
 +    if(!isInUnion())
 +      return;
 +    if(isInSourceSide())
 +      {
 +        if(way)
 +          sendData();
 +        else
 +          recvData();
 +      }
 +    else if(isInTargetSide())
 +      {
 +        if(way)
 +          recvData();
 +        else
 +          sendData();
 +      }
 +  }
 +}
index aec6bb901c1b14faca452d897253437257689555,0000000000000000000000000000000000000000..a4073a2920377ef28168bd3dd8bbddba143b802f
mode 100644,000000..100644
--- /dev/null
@@@ -1,90 -1,0 +1,91 @@@
-       _owns_field(false),_owns_groups(false),
-       _comm_interface(0), _union_comm(MPI_COMM_NULL)
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __DISJOINTDEC_HXX__
 +#define __DISJOINTDEC_HXX__
 +
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "NormalizedUnstructuredMesh.hxx"
 +#include "DEC.hxx"
 +
 +#include <mpi.h>
 +#include <set>
 +
 +namespace ICoCo
 +{
 +  class MEDField;
 +}
 +
 +namespace ParaMEDMEM
 +{
 +  class ProcessorGroup;
 +  class ParaFIELD;
 +  
 +  class DisjointDEC : public DEC
 +  {
 +  public:
 +    DisjointDEC():_local_field(0),_union_group(0),_source_group(0),_target_group(0),
++    _comm_interface(0),
++    _owns_field(false),_owns_groups(false),
++    _union_comm(MPI_COMM_NULL)
 +    { }
 +    DisjointDEC(ProcessorGroup& source_group, ProcessorGroup& target_group);
 +    DisjointDEC(const DisjointDEC&);
 +    DisjointDEC &operator=(const DisjointDEC& s);
 +    DisjointDEC(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);
 +    void attachLocalField(const ParaFIELD *field, bool ownPt=false);
 +    void attachLocalField(const ICoCo::MEDField *field);
 +    
 +    virtual void prepareSourceDE() = 0;
 +    virtual void prepareTargetDE() = 0;
 +    virtual void recvData() = 0;
 +    virtual void sendData() = 0;
 +    void sendRecvData(bool way=true);
 +    virtual void synchronize() = 0;
 +    virtual ~DisjointDEC();
 +    virtual void computeProcGroup() { }
 +    void renormalizeTargetField(bool isWAbs);
 +    //
 +    ProcessorGroup *getSourceGrp() const { return _source_group; }
 +    ProcessorGroup *getTargetGrp() const { return _target_group; }
 +    bool isInSourceSide() const;
 +    bool isInTargetSide() const;
 +    bool isInUnion() const;
 +  protected:
 +    void compareFieldAndMethod() const throw(INTERP_KERNEL::Exception);
 +    void cleanInstance();
 +    void copyInstance(const DisjointDEC& other);
 +  protected:
 +    const ParaFIELD* _local_field;
 +    //! Processor group representing the union of target and source processors
 +    ProcessorGroup* _union_group;
 +    ProcessorGroup* _source_group;
 +    ProcessorGroup* _target_group;
 +    
 +    const CommInterface* _comm_interface;
 +    bool _owns_field;
 +    bool _owns_groups;
 +    MPI_Comm _union_comm;
 +  };
 +}
 +
 +#endif
index a7fcfc28e63198a52fc60e9f73795310e4b1c9d7,0000000000000000000000000000000000000000..74e27545a34a867e82ac83a289409513cf9771f5
mode 100644,000000..100644
--- /dev/null
@@@ -1,718 -1,0 +1,720 @@@
-   // ==========================================================================
-   // Procedure for exchanging mesh between a distant proc and a local processor
-   // param idistantrank  proc id on distant group
-   // param distant_mesh on return , points to a local reconstruction of
-   //  the distant mesh
-   // param distant_ids on return, contains a vector defining a correspondence
-   // between the distant ids and the ids of the local reconstruction 
-   // ==========================================================================
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 <mpi.h>
 +#include "CommInterface.hxx"
 +#include "ElementLocator.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ParaFIELD.hxx"
 +#include "ParaMESH.hxx"
 +#include "ProcessorGroup.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 +#include "DirectedBoundingBox.hxx"
 +
 +#include <map>
 +#include <set>
 +#include <limits>
 +
 +using namespace std;
 +
 +//#define USE_DIRECTED_BB
 +
 +namespace ParaMEDMEM 
 +{ 
 +  ElementLocator::ElementLocator(const ParaFIELD& sourceField,
 +                                 const ProcessorGroup& distant_group,
 +                                 const ProcessorGroup& local_group)
 +    : _local_para_field(sourceField),
 +      _local_cell_mesh(sourceField.getSupport()->getCellMesh()),
 +      _local_face_mesh(sourceField.getSupport()->getFaceMesh()),
 +      _distant_group(distant_group),
 +      _local_group(local_group)
 +  { 
 +    _union_group = _local_group.fuse(distant_group);
 +    _computeBoundingBoxes();
 +    _comm=getCommunicator();
 +  }
 +
 +  ElementLocator::~ElementLocator()
 +  {
 +    delete _union_group;
 +    delete [] _domain_bounding_boxes;
 +  }
 +
 +  const MPI_Comm *ElementLocator::getCommunicator() const
 +  {
 +    MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group);
 +    return group->getComm();
 +  }
 +
 +  NatureOfField ElementLocator::getLocalNature() const
 +  {
 +    return _local_para_field.getField()->getNature();
 +  }
 +
-   // ======================
-   // Compute bounding boxes
-   // ======================
++
++  /*! Procedure for exchanging a mesh between a distant proc and a local processor
++   \param idistantrank  proc id on distant group
++   \param distant_mesh on return , points to a local reconstruction of
++          the distant mesh
++   \param distant_ids on return, contains a vector defining a correspondence
++          between the distant ids and the ids of the local reconstruction
++  */
 +  void ElementLocator::exchangeMesh(int idistantrank,
 +                                    MEDCouplingPointSet*& distant_mesh,
 +                                    int*& distant_ids)
 +  {
 +    int rank = _union_group->translateRank(&_distant_group,idistantrank);
 +
 +    if (find(_distant_proc_ids.begin(), _distant_proc_ids.end(),rank)==_distant_proc_ids.end())
 +      return;
 +   
 +    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems;
 +#ifdef USE_DIRECTED_BB
 +    INTERP_KERNEL::DirectedBoundingBox dbb;
 +    double* distant_bb = _domain_bounding_boxes+rank*dbb.dataSize(_local_cell_mesh_space_dim);
 +    dbb.setData(distant_bb);
 +    elems=_local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment());
 +#else
 +    double* distant_bb = _domain_bounding_boxes+rank*2*_local_cell_mesh_space_dim;
 +    elems=_local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment());
 +#endif
 +    
 +    DataArrayInt *distant_ids_send;
 +    MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(elems->begin(),elems->end(),distant_ids_send);
 +    _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids);
 +    distant_ids_send->decrRef();
 +    
 +    if(send_mesh)
 +      send_mesh->decrRef();
 +  }
 +
 +  void ElementLocator::exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth)
 +  {
 +    CommInterface comm_interface=_union_group->getCommInterface();
 +    MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group);
 +    const MPI_Comm* comm=(group->getComm());
 +    MPI_Status status;
 +    // it must be converted to union numbering before communication
 +    int idistRankInUnion = group->translateRank(&_distant_group,idistantrank);
 +    char *recv_buffer=new char[4];
 +    std::vector<char> send_buffer(4);
 +    std::copy(sourceMeth.begin(),sourceMeth.end(),send_buffer.begin());
 +    comm_interface.sendRecv(&send_buffer[0], 4, MPI_CHAR,idistRankInUnion, 1112,
 +                            recv_buffer, 4, MPI_CHAR,idistRankInUnion, 1112,
 +                            *comm, &status);
 +    targetMeth=recv_buffer;
 +    delete [] recv_buffer;
 +  }
 +
 +
-   // =============================================
-   // Intersect Bounding Box (with a given "irank")
-   // =============================================
 +
++  /*!
++   Compute bounding boxes
++  */
 +  void ElementLocator::_computeBoundingBoxes()
 +  {
 +    CommInterface comm_interface =_union_group->getCommInterface();
 +    MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group);
 +    const MPI_Comm* comm = group->getComm();
 +    _local_cell_mesh_space_dim = -1;
 +    if(_local_cell_mesh->getMeshDimension() != -1)
 +      _local_cell_mesh_space_dim=_local_cell_mesh->getSpaceDimension();
 +    int *spaceDimForAll=new int[_union_group->size()];
 +    comm_interface.allGather(&_local_cell_mesh_space_dim, 1, MPI_INT,
 +                             spaceDimForAll,1, MPI_INT, 
 +                             *comm);
 +    _local_cell_mesh_space_dim=*std::max_element(spaceDimForAll,spaceDimForAll+_union_group->size());
 +    _is_m1d_corr=((*std::min_element(spaceDimForAll,spaceDimForAll+_union_group->size()))==-1);
 +    for(int i=0;i<_union_group->size();i++)
 +      if(spaceDimForAll[i]!=_local_cell_mesh_space_dim && spaceDimForAll[i]!=-1)
 +        throw INTERP_KERNEL::Exception("Spacedim not matches !");
 +    delete [] spaceDimForAll;
 +#ifdef USE_DIRECTED_BB
 +    INTERP_KERNEL::DirectedBoundingBox dbb;
 +    int bbSize = dbb.dataSize(_local_cell_mesh_space_dim);
 +    _domain_bounding_boxes = new double[bbSize*_union_group->size()];
 +    if(_local_cell_mesh->getMeshDimension() != -1)
 +      dbb = INTERP_KERNEL::DirectedBoundingBox(_local_cell_mesh->getCoords()->getPointer(),
 +                                               _local_cell_mesh->getNumberOfNodes(),
 +                                               _local_cell_mesh_space_dim);
 +    std::vector<double> dbbData = dbb.getData();
 +    if ( dbbData.size() < bbSize ) dbbData.resize(bbSize,0);
 +    double * minmax= &dbbData[0];
 +#else
 +    int bbSize = 2*_local_cell_mesh_space_dim;
 +    _domain_bounding_boxes = new double[bbSize*_union_group->size()];
 +    double * minmax=new double [bbSize];
 +    if(_local_cell_mesh->getMeshDimension() != -1)
 +      _local_cell_mesh->getBoundingBox(minmax);
 +    else
 +      for(int i=0;i<_local_cell_mesh_space_dim;i++)
 +        {
 +          minmax[i*2]=-std::numeric_limits<double>::max();
 +          minmax[i*2+1]=std::numeric_limits<double>::max();
 +        }
 +#endif
 +
 +    comm_interface.allGather(minmax, bbSize, MPI_DOUBLE,
 +                             _domain_bounding_boxes,bbSize, MPI_DOUBLE, 
 +                             *comm);
 +  
 +    for (int i=0; i< _distant_group.size(); i++)
 +      {
 +        int rank=_union_group->translateRank(&_distant_group,i);
 +
 +        if (_intersectsBoundingBox(rank))
 +          {
 +            _distant_proc_ids.push_back(rank);
 +          }
 +      }
 +#ifdef USE_DIRECTED_BB
 +#else
 +    delete [] minmax;
 +#endif
 +  }
 +
 +
-   // ======================
-   // Exchanging meshes data
-   // ======================
++
++  /*!
++   * Intersect local bounding box with a given distant bounding box on "irank"
++   */
 +  bool ElementLocator::_intersectsBoundingBox(int irank)
 +  {
 +#ifdef USE_DIRECTED_BB
 +    INTERP_KERNEL::DirectedBoundingBox local_dbb, distant_dbb;
 +    local_dbb.setData( _domain_bounding_boxes+_union_group->myRank()*local_dbb.dataSize( _local_cell_mesh_space_dim ));
 +    distant_dbb.setData( _domain_bounding_boxes+irank*distant_dbb.dataSize( _local_cell_mesh_space_dim ));
 +    return !local_dbb.isDisjointWith( distant_dbb );
 +#else
 +    double*  local_bb = _domain_bounding_boxes+_union_group->myRank()*2*_local_cell_mesh_space_dim;
 +    double*  distant_bb =  _domain_bounding_boxes+irank*2*_local_cell_mesh_space_dim;
 +
 +    for (int idim=0; idim < _local_cell_mesh_space_dim; idim++)
 +      {
 +        const double eps =  1e-12;
 +        bool intersects = (distant_bb[idim*2]<local_bb[idim*2+1]+eps)
 +          && (local_bb[idim*2]<distant_bb[idim*2+1]+eps);
 +        if (!intersects) return false; 
 +      }
 +    return true;
 +#endif
 +  } 
 +
++
++  /*!
++   *  Exchange mesh data
++   */
 +  void ElementLocator::_exchangeMesh( MEDCouplingPointSet* local_mesh,
 +                                      MEDCouplingPointSet*& distant_mesh,
 +                                      int iproc_distant,
 +                                      const DataArrayInt* distant_ids_send,
 +                                      int*& distant_ids_recv)
 +  {
 +    CommInterface comm_interface=_union_group->getCommInterface();
 +  
 +    // First stage : exchanging sizes
 +    // ------------------------------
 +    vector<double> tinyInfoLocalD,tinyInfoDistantD(1);//not used for the moment
 +    vector<int> tinyInfoLocal,tinyInfoDistant;
 +    vector<string> tinyInfoLocalS;
 +    //Getting tiny info of local mesh to allow the distant proc to initialize and allocate
 +    //the transmitted mesh.
 +    local_mesh->getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS);
 +    tinyInfoLocal.push_back(distant_ids_send->getNumberOfTuples());
 +    tinyInfoDistant.resize(tinyInfoLocal.size());
 +    std::fill(tinyInfoDistant.begin(),tinyInfoDistant.end(),0);
 +    MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group);
 +    const MPI_Comm* comm=group->getComm();
 +    MPI_Status status; 
 +    
 +    // iproc_distant is the number of proc in distant group
 +    // it must be converted to union numbering before communication
 +    int iprocdistant_in_union = group->translateRank(&_distant_group,
 +                                                     iproc_distant);
 +    
 +    comm_interface.sendRecv(&tinyInfoLocal[0], tinyInfoLocal.size(), MPI_INT, iprocdistant_in_union, 1112,
 +                            &tinyInfoDistant[0], tinyInfoDistant.size(), MPI_INT,iprocdistant_in_union,1112,
 +                            *comm, &status);
 +    DataArrayInt *v1Local=0;
 +    DataArrayDouble *v2Local=0;
 +    DataArrayInt *v1Distant=DataArrayInt::New();
 +    DataArrayDouble *v2Distant=DataArrayDouble::New();
 +    //serialization of local mesh to send data to distant proc.
 +    local_mesh->serialize(v1Local,v2Local);
 +    //Building the right instance of copy of distant mesh.
 +    MEDCouplingPointSet *distant_mesh_tmp=MEDCouplingPointSet::BuildInstanceFromMeshType((MEDCouplingMeshType)tinyInfoDistant[0]);
 +    std::vector<std::string> unusedTinyDistantSts;
 +    distant_mesh_tmp->resizeForUnserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts);
 +    int nbLocalElems=0;
 +    int nbDistElem=0;
 +    int *ptLocal=0;
 +    int *ptDist=0;
 +    if(v1Local)
 +      {
 +        nbLocalElems=v1Local->getNbOfElems();
 +        ptLocal=v1Local->getPointer();
 +      }
 +    if(v1Distant)
 +      {
 +        nbDistElem=v1Distant->getNbOfElems();
 +        ptDist=v1Distant->getPointer();
 +      }
 +    comm_interface.sendRecv(ptLocal, nbLocalElems, MPI_INT,
 +                            iprocdistant_in_union, 1111,
 +                            ptDist, nbDistElem, MPI_INT,
 +                            iprocdistant_in_union,1111,
 +                            *comm, &status);
 +    nbLocalElems=0;
 +    double *ptLocal2=0;
 +    double *ptDist2=0;
 +    if(v2Local)
 +      {
 +        nbLocalElems=v2Local->getNbOfElems();
 +        ptLocal2=v2Local->getPointer();
 +      }
 +    nbDistElem=0;
 +    if(v2Distant)
 +      {
 +        nbDistElem=v2Distant->getNbOfElems();
 +        ptDist2=v2Distant->getPointer();
 +      }
 +    comm_interface.sendRecv(ptLocal2, nbLocalElems, MPI_DOUBLE,
 +                            iprocdistant_in_union, 1112,
 +                            ptDist2, nbDistElem, MPI_DOUBLE,
 +                            iprocdistant_in_union, 1112, 
 +                            *comm, &status);
 +    //
 +    distant_mesh=distant_mesh_tmp;
 +    //finish unserialization
 +    distant_mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts);
 +    //
 +    distant_ids_recv=new int[tinyInfoDistant.back()];
 +    comm_interface.sendRecv(const_cast<void *>(reinterpret_cast<const void *>(distant_ids_send->getConstPointer())),tinyInfoLocal.back(), MPI_INT,
 +                            iprocdistant_in_union, 1113,
 +                            distant_ids_recv,tinyInfoDistant.back(), MPI_INT,
 +                            iprocdistant_in_union,1113,
 +                            *comm, &status);
 +    if(v1Local)
 +      v1Local->decrRef();
 +    if(v2Local)
 +      v2Local->decrRef();
 +    if(v1Distant)
 +      v1Distant->decrRef();
 +    if(v2Distant)
 +      v2Distant->decrRef();
 +  }
 +  
 +  /*!
 +   * connected with ElementLocator::sendPolicyToWorkingSideL
 +   */
 +  void ElementLocator::recvPolicyFromLazySideW(std::vector<int>& policy)
 +  {
 +    policy.resize(_distant_proc_ids.size());
 +    int procId=0;
 +    CommInterface comm;
 +    MPI_Status status;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        int toRecv;
 +        comm.recv((void *)&toRecv,1,MPI_INT,*iter,1120,*_comm,&status);
 +        policy[procId]=toRecv;
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::recvFromWorkingSideL
 +   */
 +  void ElementLocator::sendSumToLazySideW(const std::vector< std::vector<int> >& distantLocEltIds, const std::vector< std::vector<double> >& partialSumRelToDistantIds)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        const vector<int>& eltIds=distantLocEltIds[procId];
 +        const vector<double>& valued=partialSumRelToDistantIds[procId];
 +        int lgth=eltIds.size();
 +        comm.send(&lgth,1,MPI_INT,*iter,1114,*_comm);
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&eltIds[0])),lgth,MPI_INT,*iter,1115,*_comm);
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&valued[0])),lgth,MPI_DOUBLE,*iter,1116,*_comm);
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::sendToWorkingSideL
 +   */
 +  void ElementLocator::recvSumFromLazySideW(std::vector< std::vector<double> >& globalSumRelToDistantIds)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    MPI_Status status;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        std::vector<double>& vec=globalSumRelToDistantIds[procId];
 +        comm.recv(&vec[0],vec.size(),MPI_DOUBLE,*iter,1117,*_comm,&status);
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::recvLocalIdsFromWorkingSideL
 +   */
 +  void ElementLocator::sendLocalIdsToLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        const vector<int>& eltIds=distantLocEltIds[procId];
 +        int lgth=eltIds.size();
 +        comm.send(&lgth,1,MPI_INT,*iter,1121,*_comm);
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&eltIds[0])),lgth,MPI_INT,*iter,1122,*_comm);
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::sendGlobalIdsToWorkingSideL
 +   */
 +  void ElementLocator::recvGlobalIdsFromLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds, std::vector< std::vector<int> >& globalIds)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    MPI_Status status;
 +    globalIds.resize(_distant_proc_ids.size());
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        const std::vector<int>& vec=distantLocEltIds[procId];
 +        std::vector<int>& global=globalIds[procId];
 +        global.resize(vec.size());
 +        comm.recv(&global[0],vec.size(),MPI_INT,*iter,1123,*_comm,&status);
 +      }
 +  }
 +  
 +  /*!
 +   * connected with ElementLocator::sendCandidatesGlobalIdsToWorkingSideL
 +   */
 +  void ElementLocator::recvCandidatesGlobalIdsFromLazyProcsW(std::vector< std::vector<int> >& globalIds)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    MPI_Status status;
 +    globalIds.resize(_distant_proc_ids.size());
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        std::vector<int>& global=globalIds[procId];
 +        int lgth;
 +        comm.recv(&lgth,1,MPI_INT,*iter,1132,*_comm,&status);
 +        global.resize(lgth);
 +        comm.recv(&global[0],lgth,MPI_INT,*iter,1133,*_comm,&status);
 +      }
 +  }
 +  
 +  /*!
 +   * connected with ElementLocator::recvSumFromWorkingSideL
 +   */
 +  void ElementLocator::sendPartialSumToLazyProcsW(const std::vector<int>& distantGlobIds, const std::vector<double>& sum)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    int lgth=distantGlobIds.size();
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        comm.send(&lgth,1,MPI_INT,*iter,1124,*_comm);
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&distantGlobIds[0])),lgth,MPI_INT,*iter,1125,*_comm);
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&sum[0])),lgth,MPI_DOUBLE,*iter,1126,*_comm);
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::recvCandidatesForAddElementsL
 +   */
 +  void ElementLocator::sendCandidatesForAddElementsW(const std::vector<int>& distantGlobIds)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    int lgth=distantGlobIds.size();
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&lgth)),1,MPI_INT,*iter,1128,*_comm);
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&distantGlobIds[0])),lgth,MPI_INT,*iter,1129,*_comm);
 +      }
 +  }
 +  
 +  /*!
 +   * connected with ElementLocator::sendAddElementsToWorkingSideL
 +   */
 +  void ElementLocator::recvAddElementsFromLazyProcsW(std::vector<std::vector<int> >& elementsToAdd)
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    MPI_Status status;
 +    int lgth=_distant_proc_ids.size();
 +    elementsToAdd.resize(lgth);
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        int locLgth;
 +        std::vector<int>& eltToFeed=elementsToAdd[procId];
 +        comm.recv(&locLgth,1,MPI_INT,*iter,1130,*_comm,&status);
 +        eltToFeed.resize(locLgth);
 +        comm.recv(&eltToFeed[0],locLgth,MPI_INT,*iter,1131,*_comm,&status);
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::recvPolicyFromLazySideW
 +   */
 +  int ElementLocator::sendPolicyToWorkingSideL()
 +  {
 +    CommInterface comm;
 +    int toSend;
 +    DataArrayInt *isCumulative=_local_para_field.returnCumulativeGlobalNumbering();
 +    if(isCumulative)
 +      {
 +        toSend=CUMULATIVE_POLICY;
 +        isCumulative->decrRef();
 +      }
 +    else
 +      toSend=NO_POST_TREATMENT_POLICY;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++)
 +      comm.send(&toSend,1,MPI_INT,*iter,1120,*_comm);
 +    return toSend;
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::sendSumToLazySideW
 +   */
 +  void ElementLocator::recvFromWorkingSideL()
 +  {
 +    _values_added.resize(_local_para_field.getField()->getNumberOfTuples());
 +    int procId=0;
 +    CommInterface comm;
 +    _ids_per_working_proc.resize(_distant_proc_ids.size());
 +    MPI_Status status;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        int lgth;
 +        comm.recv(&lgth,1,MPI_INT,*iter,1114,*_comm,&status);
 +        vector<int>& ids=_ids_per_working_proc[procId];
 +        ids.resize(lgth);
 +        vector<double> values(lgth);
 +        comm.recv(&ids[0],lgth,MPI_INT,*iter,1115,*_comm,&status);
 +        comm.recv(&values[0],lgth,MPI_DOUBLE,*iter,1116,*_comm,&status);
 +        for(int i=0;i<lgth;i++)
 +          _values_added[ids[i]]+=values[i];
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::recvSumFromLazySideW
 +   */
 +  void ElementLocator::sendToWorkingSideL()
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        vector<int>& ids=_ids_per_working_proc[procId];
 +        vector<double> valsToSend(ids.size());
 +        vector<double>::iterator iter3=valsToSend.begin();
 +        for(vector<int>::const_iterator iter2=ids.begin();iter2!=ids.end();iter2++,iter3++)
 +          *iter3=_values_added[*iter2];
 +        comm.send(&valsToSend[0],ids.size(),MPI_DOUBLE,*iter,1117,*_comm);
 +        //ids.clear();
 +      }
 +    //_ids_per_working_proc.clear();
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::sendLocalIdsToLazyProcsW
 +   */
 +  void ElementLocator::recvLocalIdsFromWorkingSideL()
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    _ids_per_working_proc.resize(_distant_proc_ids.size());
 +    MPI_Status status;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        int lgth;
 +        vector<int>& ids=_ids_per_working_proc[procId];
 +        comm.recv(&lgth,1,MPI_INT,*iter,1121,*_comm,&status);
 +        ids.resize(lgth);
 +        comm.recv(&ids[0],lgth,MPI_INT,*iter,1122,*_comm,&status);
 +      }
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::recvGlobalIdsFromLazyProcsW
 +   */
 +  void ElementLocator::sendGlobalIdsToWorkingSideL()
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    DataArrayInt *globalIds=_local_para_field.returnGlobalNumbering();
 +    const int *globalIdsC=globalIds->getConstPointer();
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        const vector<int>& ids=_ids_per_working_proc[procId];
 +        vector<int> valsToSend(ids.size());
 +        vector<int>::iterator iter1=valsToSend.begin();
 +        for(vector<int>::const_iterator iter2=ids.begin();iter2!=ids.end();iter2++,iter1++)
 +          *iter1=globalIdsC[*iter2];
 +        comm.send(&valsToSend[0],ids.size(),MPI_INT,*iter,1123,*_comm);
 +      }
 +    if(globalIds)
 +      globalIds->decrRef();
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::sendPartialSumToLazyProcsW
 +   */
 +  void ElementLocator::recvSumFromWorkingSideL()
 +  {
 +    int procId=0;
 +    int wProcSize=_distant_proc_ids.size();
 +    CommInterface comm;
 +    _ids_per_working_proc.resize(wProcSize);
 +    _values_per_working_proc.resize(wProcSize);
 +    MPI_Status status;
 +    std::map<int,double> sums;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        int lgth;
 +        comm.recv(&lgth,1,MPI_INT,*iter,1124,*_comm,&status);
 +        vector<int>& ids=_ids_per_working_proc[procId];
 +        vector<double>& vals=_values_per_working_proc[procId];
 +        ids.resize(lgth);
 +        vals.resize(lgth);
 +        comm.recv(&ids[0],lgth,MPI_INT,*iter,1125,*_comm,&status);
 +        comm.recv(&vals[0],lgth,MPI_DOUBLE,*iter,1126,*_comm,&status);
 +        vector<int>::const_iterator iter1=ids.begin();
 +        vector<double>::const_iterator iter2=vals.begin();
 +        for(;iter1!=ids.end();iter1++,iter2++)
 +          sums[*iter1]+=*iter2;
 +      }
 +    //assign sum to prepare sending to working side
 +    for(procId=0;procId<wProcSize;procId++)
 +      {
 +        vector<int>& ids=_ids_per_working_proc[procId];
 +        vector<double>& vals=_values_per_working_proc[procId];
 +        vector<int>::const_iterator iter1=ids.begin();
 +        vector<double>::iterator iter2=vals.begin();
 +        for(;iter1!=ids.end();iter1++,iter2++)
 +          *iter2=sums[*iter1];
 +        ids.clear();
 +      }
 +  }
 +
 +  /*!
 +   * Foreach working procs Wi compute and push it in _ids_per_working_proc3,
 +   * if it exist, local id of nodes that are in interaction with an another lazy proc than this
 +   * and that exists in this \b but with no interaction with this.
 +   * The computation is performed here. sendAddElementsToWorkingSideL is only in charge to send
 +   * precomputed _ids_per_working_proc3 attribute.
 +   * connected with ElementLocator::sendCandidatesForAddElementsW
 +   */
 +  void ElementLocator::recvCandidatesForAddElementsL()
 +  {
 +    int procId=0;
 +    int wProcSize=_distant_proc_ids.size();
 +    CommInterface comm;
 +    _ids_per_working_proc3.resize(wProcSize);
 +    MPI_Status status;
 +    std::map<int,double> sums;
 +    DataArrayInt *globalIds=_local_para_field.returnGlobalNumbering();
 +    const int *globalIdsC=globalIds->getConstPointer();
 +    int nbElts=globalIds->getNumberOfTuples();
 +    std::set<int> globalIdsS(globalIdsC,globalIdsC+nbElts);
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        const std::vector<int>& ids0=_ids_per_working_proc[procId];
 +        int lgth0=ids0.size();
 +        std::set<int> elts0;
 +        for(int i=0;i<lgth0;i++)
 +          elts0.insert(globalIdsC[ids0[i]]);
 +        int lgth;
 +        comm.recv(&lgth,1,MPI_INT,*iter,1128,*_comm,&status);
 +        vector<int> ids(lgth);
 +        comm.recv(&ids[0],lgth,MPI_INT,*iter,1129,*_comm,&status);
 +        set<int> ids1(ids.begin(),ids.end());
 +        ids.clear();
 +        set<int> tmp5,tmp6;
 +        set_intersection(globalIdsS.begin(),globalIdsS.end(),ids1.begin(),ids1.end(),inserter(tmp5,tmp5.begin()));
 +        set_difference(tmp5.begin(),tmp5.end(),elts0.begin(),elts0.end(),inserter(tmp6,tmp6.begin()));
 +        std::vector<int>& ids2=_ids_per_working_proc3[procId];
 +        ids2.resize(tmp6.size());
 +        std::copy(tmp6.begin(),tmp6.end(),ids2.begin());
 +        //global->local
 +        for(std::vector<int>::iterator iter2=ids2.begin();iter2!=ids2.end();iter2++)
 +          *iter2=std::find(globalIdsC,globalIdsC+nbElts,*iter2)-globalIdsC;
 +      }
 +    if(globalIds)
 +      globalIds->decrRef();
 +  }
 +
 +  /*!
 +   * connected with ElementLocator::recvAddElementsFromLazyProcsW
 +   */
 +  void ElementLocator::sendAddElementsToWorkingSideL()
 +  {
 +    int procId=0;
 +    CommInterface comm;
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        const std::vector<int>& vals=_ids_per_working_proc3[procId];
 +        int size=vals.size();
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&size)),1,MPI_INT,*iter,1130,*_comm);
 +        comm.send(const_cast<void *>(reinterpret_cast<const void *>(&vals[0])),size,MPI_INT,*iter,1131,*_comm);
 +      }
 +  }
 +
 +  /*!
 +   * This method sends to working side Wi only nodes in interaction with Wi \b and located on boundary, to reduce number.
 +   * connected with ElementLocator::recvCandidatesGlobalIdsFromLazyProcsW
 +   */
 +  void ElementLocator::sendCandidatesGlobalIdsToWorkingSideL()
 +  { 
 +    int procId=0;
 +    CommInterface comm;
 +    DataArrayInt *globalIds=_local_para_field.returnGlobalNumbering();
 +    const int *globalIdsC=globalIds->getConstPointer();
 +    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=_local_para_field.getSupport()->getCellMesh()->findBoundaryNodes();
 +    for(int *iter1=candidates->getPointer();iter1!=candidates->getPointer()+candidates->getNumberOfTuples();iter1++)
 +      (*iter1)=globalIdsC[*iter1];
 +    std::set<int> candidatesS(candidates->begin(),candidates->end());
 +    for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++)
 +      {
 +        const vector<int>& ids=_ids_per_working_proc[procId];
 +        vector<int> valsToSend(ids.size());
 +        vector<int>::iterator iter1=valsToSend.begin();
 +        for(vector<int>::const_iterator iter2=ids.begin();iter2!=ids.end();iter2++,iter1++)
 +          *iter1=globalIdsC[*iter2];
 +        std::set<int> tmp2(valsToSend.begin(),valsToSend.end());
 +        std::vector<int> tmp3;
 +        set_intersection(candidatesS.begin(),candidatesS.end(),tmp2.begin(),tmp2.end(),std::back_insert_iterator< std::vector<int> >(tmp3));
 +        int lgth=tmp3.size();
 +        comm.send(&lgth,1,MPI_INT,*iter,1132,*_comm);
 +        comm.send(&tmp3[0],lgth,MPI_INT,*iter,1133,*_comm);
 +      }
 +    if(globalIds)
 +      globalIds->decrRef();
 +  }
 +}
index 4853c9766c2468e02206f507a3f859a867a31319,0000000000000000000000000000000000000000..4edd27de6104472be107a21686def1f4d9584f05
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,111 @@@
-   class ParaSUPPORT;
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __ELEMENTLOCATOR_HXX__
 +#define __ELEMENTLOCATOR_HXX__
 +
 +#include "InterpolationOptions.hxx"
 +#include "MEDCouplingNatureOfField.hxx"
 +
 +#include <mpi.h>
 +#include <vector>
 +#include <set>
 +
 +namespace ParaMEDMEM
 +{
 +  class ParaFIELD;
 +  class ProcessorGroup;
 +  class InterpolationMatrix;
 +  class MEDCouplingPointSet;
 +  class DataArrayInt;
 +
++  /*! Internal class, not part of the public API. Used in InterpolationMatrix.
++   *
++   */
 +  class ElementLocator : public INTERP_KERNEL::InterpolationOptions
 +  {
 +  public:
 +    ElementLocator(const ParaFIELD& sourceField, const ProcessorGroup& distant_group, const ProcessorGroup& local_group);
 +
 +    virtual ~ElementLocator();
 +    void exchangeMesh(int idistantrank,
 +                      MEDCouplingPointSet*& target_mesh,
 +                      int*& distant_ids);
 +    void exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth);
 +    const std::vector<int>& getDistantProcIds() const { return _distant_proc_ids; }
 +    const MPI_Comm *getCommunicator() const;
 +    NatureOfField getLocalNature() const;
 +    //! This method is used to informed if there is -1D mesh on distant_group side or on local_group side.
 +    bool isM1DCorr() const { return _is_m1d_corr; }
 +    //Working side methods
 +    void recvPolicyFromLazySideW(std::vector<int>& policy);
 +    void sendSumToLazySideW(const std::vector< std::vector<int> >& distantLocEltIds, const std::vector< std::vector<double> >& partialSumRelToDistantIds);
 +    void recvSumFromLazySideW(std::vector< std::vector<double> >& globalSumRelToDistantIds);
 +    void sendCandidatesForAddElementsW(const std::vector<int>& distantGlobIds);
 +    void recvAddElementsFromLazyProcsW(std::vector<std::vector<int> >& elementsToAdd);
 +    //
 +    void sendLocalIdsToLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds);
 +    void recvGlobalIdsFromLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds, std::vector< std::vector<int> >& globalIds);
 +    void recvCandidatesGlobalIdsFromLazyProcsW(std::vector< std::vector<int> >& globalIds);
 +    void sendPartialSumToLazyProcsW(const std::vector<int>& distantGlobIds, const std::vector<double>& sum);
 +    //Lazy side methods
 +    int sendPolicyToWorkingSideL();
 +    void recvFromWorkingSideL();
 +    void sendToWorkingSideL();
 +    //
 +    void recvLocalIdsFromWorkingSideL();
 +    void sendGlobalIdsToWorkingSideL();
 +    void sendCandidatesGlobalIdsToWorkingSideL();
 +    //
 +    void recvSumFromWorkingSideL();
 +    void recvCandidatesForAddElementsL();
 +    void sendAddElementsToWorkingSideL();
 +  private:
 +    void _computeBoundingBoxes();
 +    bool _intersectsBoundingBox(int irank);
 +    void _exchangeMesh(MEDCouplingPointSet* local_mesh, MEDCouplingPointSet*& distant_mesh,
 +                       int iproc_distant, const DataArrayInt* distant_ids_send,
 +                       int*& distant_ids_recv);
 +  private:
 +    const ParaFIELD&  _local_para_field ;
 +    MEDCouplingPointSet* _local_cell_mesh;
 +    int _local_cell_mesh_space_dim;
 +    bool _is_m1d_corr;
 +    MEDCouplingPointSet* _local_face_mesh;
 +    std::vector<MEDCouplingPointSet*> _distant_cell_meshes;
 +    std::vector<MEDCouplingPointSet*> _distant_face_meshes;
 +    double* _domain_bounding_boxes;
 +    const ProcessorGroup& _distant_group;
 +    const ProcessorGroup& _local_group;
 +    ProcessorGroup* _union_group;
 +    std::vector<int> _distant_proc_ids;
 +    const MPI_Comm *_comm;
 +    //Attributes only used by lazy side
 +    std::vector<double> _values_added;
 +    std::vector< std::vector<int> > _ids_per_working_proc;
 +    std::vector< std::vector<int> > _ids_per_working_proc3;
 +    std::vector< std::vector<double> > _values_per_working_proc;
 +  public:
 +    static const int CUMULATIVE_POLICY=3;
 +    static const int NO_POST_TREATMENT_POLICY=7;
 +  };
 +
 +}
 +
 +#endif
index 5d30c60d47cbd226c8283c00e6fac38b15983ba9,0000000000000000000000000000000000000000..db0396725b3135d1e1639e8f3a0870f4e404125e
mode 100644,000000..100644
--- /dev/null
@@@ -1,393 -1,0 +1,445 @@@
-    * \anchor ExplicitCoincidentDEC-det
-    * \class ExplicitCoincidentDEC
-    *
-    * TODO: doc
-    */
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 <mpi.h>
 +#include "CommInterface.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ComponentTopology.hxx"
 +#include "ParaFIELD.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "ExplicitCoincidentDEC.hxx"
 +#include "ExplicitMapping.hxx"
 +#include "InterpKernelUtilities.hxx"
 +
 +using namespace std;
 +
 +namespace ParaMEDMEM
 +{
++
 +  /*!
-   ExplicitCoincidentDEC::ExplicitCoincidentDEC():_toposource(0),_topotarget(0)
++    \anchor ExplicitCoincidentDEC-det
++    \class ExplicitCoincidentDEC
++
++
++    This class aims at \ref interpolation "remapping fields" that have identical
++    supports (=the same underlying mesh) but different parallel topologies
++    (=different sub-domains in the mesh). It can be used to couple
++    together multi-physics codes that operate on the same domain
++    with different partitioning.
++
++    It is very similar to what the \ref StructuredCoincidentDEC-det "StructuredCoincidentDEC"
++    does, except that it works with an arbitrary user-defined topology.
++
++    The remapping between the two supports is based on identity of global
++    ids, instead of geometrical considerations (as it is the case for
++    \ref InterpKernelDEC-det "InterpKernelDEC").
++    Therefore, beware that this \ref para-dec "DEC" can not be used
++    for coincident meshes if they do *not* have the exact same numbering.
++
++    With this \ref para-dec "DEC" no projection, and no interpolation of the field data is done, contrary
++    to what happens in \ref InterpKernelDEC-det "InterpKernelDEC". It is just
++    a matter of allocating the values from one side to the other, using directly the cell
++    identifiers.
++
++    As all the other DECs, its usage requires two phases :
++    - a setup phase during which the topologies are exchanged so that
++    the target side knows from which processors it should expect
++    the data.
++    - a send/recv phase during which the field data is actually transferred.
++
++    This example illustrates the sending of a field with
++    the \c ExplicitCoincidentDEC :
++    \code
++    ...
++    ExplicitCoincidentDEC dec(groupA, groupB);
++    dec.attachLocalField(field);
++    dec.synchronize();
++    if (groupA.containsMyRank())
++    dec.recvData();
++    else if (groupB.containsMyRank())
++    dec.sendData();
++    ...
++    \endcode
++
++    Creating a ParaFIELD to be attached to the %DEC is done in exactly the same way as for
++    the other DECs, if only the partitioning of the support mesh differs.
++    In the case where the
++    fields have also different *component* topologies, creating the ParaFIELD
++    requires some more effort. See the \ref para-over "parallelism" section for more details.
++  */
++
 +
 +  /*! Constructor
 +   */
-    * Synchronizing a topology so that all the 
-    * group possesses it.
++  ExplicitCoincidentDEC::ExplicitCoincidentDEC():
++      _toposource(0),_topotarget(0),
++      _targetgroup(0), _sourcegroup(0),
++      _sendcounts(0), _recvcounts(0),
++      _senddispls(0), _recvdispls(0),
++      _recvbuffer(0), _sendbuffer(0),
++      _distant_elems(), _explicit_mapping()
 +  {  
 +  }
 +
 +  ExplicitCoincidentDEC::~ExplicitCoincidentDEC()
 +  {
 +  }
 +
 +  /*! Synchronization process for exchanging topologies
 +   */
 +  void ExplicitCoincidentDEC::synchronize()
 +  {
 +    if (_source_group->containsMyRank())
 +      {
 +        _toposource = dynamic_cast<ExplicitTopology*>(_local_field->getTopology());
 +        _sourcegroup= _toposource->getProcGroup()->createProcGroup();
 +        _targetgroup=_toposource->getProcGroup()->createComplementProcGroup();
 +      }
 +    if (_target_group->containsMyRank())
 +      {
 +        _topotarget = dynamic_cast<ExplicitTopology*>(_local_field->getTopology());
 +        _sourcegroup= _topotarget->getProcGroup()->createComplementProcGroup();
 +        _targetgroup=_topotarget->getProcGroup()->createProcGroup();
 +      }
 +  
 +    // Exchanging
 +  
 +    // Transmitting source topology to target code 
 +    broadcastTopology(_toposource,_topotarget,1000);
 +    transferMappingToSource();
 +  }
 +
 +  /*! Creates the arrays necessary for the data transfer
 +   * and fills the send array with the values of the 
 +   * source field
 +   *  */
 +  void ExplicitCoincidentDEC::prepareSourceDE()
 +  {
 +    ////////////////////////////////////
 +    //Step 1 : buffer array creation 
 +  
 +    if (!_toposource->getProcGroup()->containsMyRank())
 +      return;
 +    MPIProcessorGroup* group=new MPIProcessorGroup(_sourcegroup->getCommInterface());
 +  
 +    // Warning : the size of the target side is implicitly deduced
 +    //from the size of MPI_COMM_WORLD
 +    int target_size = _toposource->getProcGroup()->getCommInterface().worldSize()- _toposource->getProcGroup()->size()  ;
 +  
 +    vector<int>* target_arrays=new vector<int>[target_size];
 +  
 +    int nb_local = _toposource-> getNbLocalElements();
 +
 +    int union_size=group->size();
 +  
 +    _sendcounts=new int[union_size];
 +    _senddispls=new int[union_size];
 +    _recvcounts=new int[union_size];
 +    _recvdispls=new int[union_size];
 +  
 +    for (int i=0; i< union_size; i++)
 +      {
 +        _sendcounts[i]=0;
 +        _recvcounts[i]=0;
 +        _recvdispls[i]=0;
 +      }
 +    _senddispls[0]=0;
 + 
 +    int* counts=_explicit_mapping.getCounts();
 +    for (int i=0; i<group->size(); i++)
 +      _sendcounts[i]=counts[i];
 +  
 +    for (int iproc=1; iproc<group->size();iproc++)
 +      _senddispls[iproc]=_senddispls[iproc-1]+_sendcounts[iproc-1];
 +  
 +    _sendbuffer = new double [nb_local * _toposource->getNbComponents()];
 +  
 +    /////////////////////////////////////////////////////////////
 +    //Step 2 : filling the buffers with the source field values 
 +  
 +    int* counter=new int [target_size];
 +    counter[0]=0;  
 +    for (int i=1; i<target_size; i++)
 +      counter[i]=counter[i-1]+target_arrays[i-1].size();
 +  
 +  
 +    const double* value = _local_field->getField()->getArray()->getPointer();
 +  
 +    int* bufferindex= _explicit_mapping.getBufferIndex();
 +  
 +    for (int ielem=0; ielem<nb_local; ielem++)
 +      {
 +        int ncomp = _toposource->getNbComponents();
 +        for (int icomp=0; icomp<ncomp; icomp++)
 +          {
 +            _sendbuffer[ielem*ncomp+icomp]=value[bufferindex[ielem]*ncomp+icomp];
 +          }  
 +      }
 +    delete[] target_arrays;
 +    delete[] counter;
 +  }
 +
 +  /*!
 +   *  Creates the buffers for receiving the fields on the target side
 +   */
 +  void ExplicitCoincidentDEC::prepareTargetDE()
 +  {
 +    if (!_topotarget->getProcGroup()->containsMyRank())
 +      return;
 +    MPIProcessorGroup* group=new MPIProcessorGroup(_topotarget->getProcGroup()->getCommInterface());
 +
 +    vector < vector <int> > source_arrays(_sourcegroup->size());
 +    int nb_local = _topotarget-> getNbLocalElements();
 +    for (int ielem=0; ielem< nb_local ; ielem++)
 +      {
 +        //pair<int,int> source_local =_distant_elems[ielem];
 +        pair <int,int> source_local=_explicit_mapping.getDistantNumbering(ielem);
 +        source_arrays[source_local.first].push_back(source_local.second); 
 +      }  
 +    int union_size=group->size();
 +    _recvcounts=new int[union_size];
 +    _recvdispls=new int[union_size];
 +    _sendcounts=new int[union_size];
 +    _senddispls=new int[union_size];
 +    
 +    for (int i=0; i< union_size; i++)
 +      {
 +        _sendcounts[i]=0;
 +        _recvcounts[i]=0;
 +        _recvdispls[i]=0;
 +      }
 +    for (int iproc=0; iproc < _sourcegroup->size(); iproc++)
 +      {
 +        //converts the rank in target to the rank in union communicator
 +        int unionrank=group->translateRank(_sourcegroup,iproc);
 +        _recvcounts[unionrank]=source_arrays[iproc].size()*_topotarget->getNbComponents();
 +      }
 +    for (int i=1; i<union_size; i++)
 +      _recvdispls[i]=_recvdispls[i-1]+_recvcounts[i-1];
 +    _recvbuffer=new double[nb_local*_topotarget->getNbComponents()];
 +    
 +  }
 +
 + 
 +  /*!
++   * Synchronizing a topology so that all the groups get it.
 +   * 
 +   * \param toposend Topology that is transmitted. It is read on processes where it already exists, and it is created and filled on others.
 +   * \param toporecv Topology which is received.
 +   * \param tag Communication tag associated with this operation.
 +   */
 +  void ExplicitCoincidentDEC::broadcastTopology(const ExplicitTopology* toposend, ExplicitTopology* toporecv, int tag)
 +  {
 +    MPI_Status status;
 +  
 +    int* serializer=0;
 +    int size;
 +  
 +    MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface);
 +  
 +    // The send processors serialize the send topology
 +    // and send the buffers to the recv procs
 +    if (toposend !=0 && toposend->getProcGroup()->containsMyRank())
 +      {
 +        toposend->serialize(serializer, size);
 +        for (int iproc=0; iproc< group->size(); iproc++)
 +          {
 +            int itarget=iproc;
 +            if (!toposend->getProcGroup()->contains(itarget))
 +              {
 +                _comm_interface->send(&size,1,MPI_INT, itarget,tag+itarget,*(group->getComm()));
 +                _comm_interface->send(serializer, size, MPI_INT, itarget, tag+itarget,*(group->getComm()));          
 +              }
 +          }
 +      }
 +    else
 +      {
 +        vector <int> size2(group->size());
 +        int myworldrank=group->myRank();
 +        for (int iproc=0; iproc<group->size();iproc++)
 +          {
 +            int isource = iproc;
 +            if (!toporecv->getProcGroup()->contains(isource))
 +              {
 +                int nbelem;
 +                _comm_interface->recv(&nbelem, 1, MPI_INT, isource, tag+myworldrank, *(group->getComm()), &status);
 +                int* buffer = new int[nbelem];
 +                _comm_interface->recv(buffer, nbelem, MPI_INT, isource,tag+myworldrank, *(group->getComm()), &status);        
 +      
 +                ExplicitTopology* topotemp=new ExplicitTopology();
 +                topotemp->unserialize(buffer, *_comm_interface);
 +                delete[] buffer;
 +        
 +                for (int ielem=0; ielem<toporecv->getNbLocalElements(); ielem++)
 +                  {
 +                    int global = toporecv->localToGlobal(ielem);
 +                    int sendlocal=topotemp->globalToLocal(global);
 +                    if (sendlocal!=-1)
 +                      {
 +                        size2[iproc]++;
 +                        _explicit_mapping.pushBackElem(make_pair(iproc,sendlocal));
 +                      }
 +                  }
 +                delete topotemp;
 +              }
 +          }  
 +      }  
 +    MESSAGE (" rank "<<group->myRank()<< " broadcastTopology is over");
 +  }
 +
 +  void ExplicitCoincidentDEC::transferMappingToSource()
 +  {
 +
 +    MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface);
 +  
 +    // sending source->target mapping which is stored by target
 +    //in _distant_elems from target to source
 +    if (_topotarget!=0 && _topotarget->getProcGroup()->containsMyRank())
 +      {
 +        int world_size = _topotarget->getProcGroup()->getCommInterface().worldSize()  ;
 +        int* nb_transfer_union=new int[world_size];
 +        int* dummy_recv=new int[world_size];
 +        for (int i=0; i<world_size; i++)
 +          nb_transfer_union[i]=0;
 +        //converts the rank in target to the rank in union communicator
 +    
 +        for (int i=0; i<  _explicit_mapping.nbDistantDomains(); i++)
 +          {
 +            int unionrank=group->translateRank(_sourcegroup,_explicit_mapping.getDistantDomain(i));
 +            nb_transfer_union[unionrank]=_explicit_mapping.getNbDistantElems(i);
 +          }
 +        _comm_interface->allToAll(nb_transfer_union, 1, MPI_INT, dummy_recv, 1, MPI_INT, MPI_COMM_WORLD);
 +      
 +        int* sendbuffer= _explicit_mapping.serialize(_topotarget->getProcGroup()->myRank());
 +      
 +        int* sendcounts= new int [world_size];
 +        int* senddispls = new int [world_size];
 +        for (int i=0; i< world_size; i++)
 +          {
 +            sendcounts[i]=2*nb_transfer_union[i];
 +            if (i==0)
 +              senddispls[i]=0;
 +            else
 +              senddispls[i]=senddispls[i-1]+sendcounts[i-1];
 +          }
 +        int* recvcounts=new int[world_size];
 +        int* recvdispls=new int[world_size];
 +        int *dummyrecv=0;
 +        for (int i=0; i <world_size; i++)
 +          {
 +            recvcounts[i]=0;
 +            recvdispls[i]=0;
 +          }
 +        _comm_interface->allToAllV(sendbuffer, sendcounts, senddispls, MPI_INT, dummyrecv, recvcounts, senddispls, MPI_INT, MPI_COMM_WORLD);
 +      
 +      }
 +    //receiving in the source subdomains the mapping sent by targets
 +    else
 +      {
 +        int world_size = _toposource->getProcGroup()->getCommInterface().worldSize()  ;
 +        int* nb_transfer_union=new int[world_size];
 +        int* dummy_send=new int[world_size];
 +        for (int i=0; i<world_size; i++)
 +          dummy_send[i]=0;
 +        _comm_interface->allToAll(dummy_send, 1, MPI_INT, nb_transfer_union, 1, MPI_INT, MPI_COMM_WORLD);
 +      
 +        int total_size=0;
 +        for (int i=0; i< world_size; i++)
 +          total_size+=nb_transfer_union[i];
 +        int nbtarget = _targetgroup->size();
 +        int* targetranks = new int[ nbtarget];
 +        for (int i=0; i<nbtarget; i++)
 +          targetranks[i]=group->translateRank(_targetgroup,i);
 +        int* mappingbuffer= new int [total_size*2];
 +        int* sendcounts= new int [world_size];
 +        int* senddispls = new int [world_size];
 +        int* recvcounts=new int[world_size];
 +        int* recvdispls=new int[world_size];
 +        for (int i=0; i< world_size; i++)
 +          {
 +            recvcounts[i]=2*nb_transfer_union[i];
 +            if (i==0)
 +              recvdispls[i]=0;
 +            else
 +              recvdispls[i]=recvdispls[i-1]+recvcounts[i-1];
 +          }
 +
 +        int *dummysend=0;
 +        for (int i=0; i <world_size; i++)
 +          {
 +            sendcounts[i]=0;
 +            senddispls[i]=0;
 +          }
 +        _comm_interface->allToAllV(dummysend, sendcounts, senddispls, MPI_INT, mappingbuffer, recvcounts, recvdispls, MPI_INT, MPI_COMM_WORLD);
 +        _explicit_mapping.unserialize(world_size,nb_transfer_union,nbtarget, targetranks, mappingbuffer);
 +      }
 +  }
 +
 +  void ExplicitCoincidentDEC::recvData()
 +  {
 +    //MPI_COMM_WORLD is used instead of group because there is no
 +    //mechanism for creating the union group yet
 +    MESSAGE("recvData");
 +
 +    cout<<"start AllToAll"<<endl;
 +    _comm_interface->allToAllV(_sendbuffer, _sendcounts, _senddispls, MPI_DOUBLE, 
 +                               _recvbuffer, _recvcounts, _recvdispls, MPI_DOUBLE,MPI_COMM_WORLD);
 +    cout<<"end AllToAll"<<endl;
 +    int nb_local = _topotarget->getNbLocalElements();
 +    double* value=new double[nb_local*_topotarget->getNbComponents()];
 +
 +    vector<int> counters(_sourcegroup->size());
 +    counters[0]=0;
 +    for (int i=0; i<_sourcegroup->size()-1; i++)
 +      {
 +        MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface);
 +        int worldrank=group->translateRank(_sourcegroup,i);
 +        counters[i+1]=counters[i]+_recvcounts[worldrank];
 +      }
 +  
 +    for (int ielem=0; ielem<nb_local ; ielem++)
 +      {
 +        pair<int,int> distant_numbering=_explicit_mapping.getDistantNumbering(ielem);
 +        int iproc=distant_numbering.first; 
 +        int ncomp =  _topotarget->getNbComponents();
 +        for (int icomp=0; icomp< ncomp; icomp++)
 +          value[ielem*ncomp+icomp]=_recvbuffer[counters[iproc]*ncomp+icomp];
 +        counters[iproc]++;
 +      }  
 +    _local_field->getField()->getArray()->useArray(value,true,CPP_DEALLOC,nb_local,_topotarget->getNbComponents());
 +  }
 +
 +  void ExplicitCoincidentDEC::sendData()
 +  {
 +    MESSAGE ("sendData");
 +    for (int i=0; i< 4; i++)
 +      cout << _sendcounts[i]<<" ";
 +    cout <<endl;
 +    for (int i=0; i< 4; i++)
 +      cout << _senddispls[i]<<" ";
 +    cout <<endl;
 +    //MPI_COMM_WORLD is used instead of group because there is no
 +    //mechanism for creating the union group yet
 +    cout <<"start AllToAll"<<endl;
 +    _comm_interface->allToAllV(_sendbuffer, _sendcounts, _senddispls, MPI_DOUBLE, 
 +                               _recvbuffer, _recvcounts, _recvdispls, MPI_DOUBLE,MPI_COMM_WORLD);
 +  }
 +}
 +
index e83d0dc97a752baab73dfe8eac88f3d8f386dc72,0000000000000000000000000000000000000000..3098b706faf6e3cba09b3f01c7f07cc66f5f7cd5
mode 100644,000000..100644
--- /dev/null
@@@ -1,176 -1,0 +1,65 @@@
-     ExplicitMapping():_numbers(0), _domains(0), _comm_buffer(0) { }
-     ~ExplicitMapping()
-     {
-       if (_domains!=0) delete[] _domains;
-       if (_numbers!=0) delete[] _numbers;
-       if (_comm_buffer!=0) delete[] _comm_buffer;
-     }
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __EXPLICITMAPPING_HXX__
 +#define __EXPLICITMAPPING_HXX__
 +
 +#include <vector>
 +#include <map>
 +#include <set>
 +
 +namespace ParaMEDMEM
 +{
++  /*!
++   * Internal class, not part of the public API.
++   *
++   * Used by the ExplicitCoincidentDEC.
++   */
 +  class ExplicitMapping
 +  {
 +  public:
-     void pushBackElem(std::pair<int,int> idistant)
-     {
-       _mapping.push_back(idistant);
-     }
-     void  setDistantElem(int ilocal, std::pair<int,int> idistant)
-     {
-       _mapping[ilocal]=idistant;
-     }
-     int nbDistantDomains()
-     {
-       if (_distant_domains.empty())
-         {
-           for (std::vector <std::pair<int,int> >::const_iterator iter= _mapping.begin();
-                iter!=_mapping.end();
-                iter++)
-             _distant_domains.insert(iter->first);
-         }
-       return _distant_domains.size();
-     }
++    ExplicitMapping();
++    ~ExplicitMapping();
 +    
-     std::pair <int,int> getDistantNumbering(int ielem)const
-     {
-       return _mapping[ielem];
-     }
++    void pushBackElem(std::pair<int,int> idistant);
++    void  setDistantElem(int ilocal, std::pair<int,int> idistant);
++    int nbDistantDomains();
++    std::pair <int,int> getDistantNumbering(int ielem) const;
 +    
-     int getDistantDomain(int i)
-     {
-       if (_domains==0)
-         computeNumbers();
-       return _domains[i];
-     }
-     int getNbDistantElems(int i)
-     {
-       if (_numbers==0)
-         computeNumbers();
-       return _numbers[i];    
-     }
-     int* serialize(int idproc)
-     {
-       _comm_buffer=new int[_mapping.size()*2];
-       std::vector<int> offsets(_distant_domains.size());
-       offsets[0]=0;
-       for (int i=1; i<(int)_distant_domains.size();i++)
-         offsets[i]=offsets[i-1]+_numbers[i-1];
-       
-       for (int i=0; i<(int)_mapping.size(); i++)
-         {
-           int offset= offsets[_mapping[i].first];
-           _comm_buffer[offset*2]=idproc;
-           _comm_buffer[offset*2+1]=_mapping[i].second;
-           offsets[_mapping[i].first]++;
-         }
-       return _comm_buffer;
-     }
-     void unserialize(int nbprocs, int* sizes,int nbtarget, int* targetrank, int* commbuffer)
-     {
-       int total_size=0;
-       for (int i=0; i< nbprocs; i++)
-         total_size+=sizes[i];
-       
-       _mapping.resize(total_size);
-       _buffer_index=new int[total_size];
-       int indmap=0;
-       for (int i=0; i<nbprocs; i++)
-         for (int ielem=0; ielem<sizes[i]; ielem++)
-           {
-             _mapping[indmap].first=i;
-             _mapping[indmap].second=commbuffer[indmap*2+1];
-             _buffer_index[indmap]=commbuffer[indmap*2+1];
-             indmap++;
-           }  
-       _numbers=new int [nbtarget];
-       _domains=new int [nbtarget];
-       
-       int index=0;      
-       for (int i=0; i<nbtarget; i++)
-         {
-           if (sizes[targetrank[i]]>0)
-             {
-               _numbers[index]=sizes[targetrank[i]];
-               _domains[index]=i;
-               index++;
-             }
-         }
-       _send_counts=new int[nbprocs];
-       for (int i=0; i<nbprocs; i++)
-         _send_counts[i]=sizes[i];
-     }
++    int getDistantDomain(int i);
++    int getNbDistantElems(int i);
++    int* serialize(int idproc);
++    void unserialize(int nbprocs, int* sizes,int nbtarget, int* targetrank, int* commbuffer);
 +    
-     void computeNumbers()
-     {
-       std::map <int,int> counts;
-       if (_numbers==0)
-         {
-           _numbers=new int[nbDistantDomains()];
-           _domains=new int[nbDistantDomains()];
-           for (int i=0; i<(int)_mapping.size(); i++)
-             {
-               if ( counts.find(_mapping[i].first) == counts.end())
-                 counts.insert(std::make_pair(_mapping[i].first,1));
-               else
-                 (counts[_mapping[i].first])++;
-             }
-           int counter=0;
-           for (std::map<int,int>::const_iterator iter=counts.begin(); 
-                iter!=counts.end(); 
-                iter++)
-             {
-               _numbers[counter]=iter->second;
-               _domains[counter]=iter->first;
-               counter++;
-             }
-         }
-     }
 +    int* getBufferIndex() const { return _buffer_index; }
 +    int* getCounts() const { return _send_counts; }
 +  private:
 +    std::vector <std::pair<int,int> > _mapping;
 +    std::set<int> _distant_domains;
 +    int* _numbers;
 +    int* _domains;
 +    int* _comm_buffer;
 +    int* _buffer_index;
 +    int* _send_counts;
 +
++    void computeNumbers();
 +  };
 +}
 +
 +#endif
index a624623a943e7efd72f8388b62658152e569bf7e,0000000000000000000000000000000000000000..4facf53e0dd6b9be4caf5989e7c932458e938b27
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,114 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "CommInterface.hxx"
 +#include "ProcessorGroup.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "ParaMESH.hxx"
 +#include "Topology.hxx"
 +#include "ExplicitTopology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ComponentTopology.hxx"
 +
 +#include <vector>
 +#include <algorithm>
 +
 +using namespace std;
 +namespace ParaMEDMEM
 +{
 +
++ExplicitTopology::ExplicitTopology():
++   _proc_group(NULL), _nb_elems(0), _nb_components(0),
++   _loc2glob(NULL), _glob2loc()
++  {}
++
 +ExplicitTopology::ExplicitTopology(const ParaMESH& paramesh ):
 +_proc_group(paramesh.getBlockTopology()->getProcGroup()),
 +_nb_components(1)
 +{
 +  _nb_elems=paramesh.getCellMesh()->getNumberOfCells();
 +  const int* global=paramesh.getGlobalNumberingCell();
 +  _loc2glob=new int[_nb_elems]; 
 +  
 +    for (int i=0; i<_nb_elems; i++)
 +    {
 +      _loc2glob[i]=global[i];
 +      _glob2loc[global[i]]=i;
 +    }
 +}
 +
 +ExplicitTopology::ExplicitTopology(const ExplicitTopology& topo, int nb_components)
 +{
 +  _proc_group = topo._proc_group;
 +  _nb_elems = topo._nb_elems;
 +  _nb_components = nb_components;
 +  _loc2glob=new int[_nb_elems];
 +  for (int i=0; i<_nb_elems; i++)
 +    {
 +      _loc2glob[i]=topo._loc2glob[i];
 +    }
 +  _glob2loc=topo._glob2loc;
 +}
 +
 +
 +ExplicitTopology::~ExplicitTopology()
 +{
 +  if (_loc2glob != 0) delete[] _loc2glob;
 +}
 +
 +
 +/*! Serializes the data contained in the Explicit Topology
 + * for communication purposes*/
 +void ExplicitTopology::serialize(int* & serializer, int& size) const 
 +{
 +  vector <int> buffer;
 +  
 +  buffer.push_back(_nb_elems);
 +  for (int i=0; i<_nb_elems; i++)
 +  {
 +    buffer.push_back(_loc2glob[i]);
 +  }
 +    
 +  serializer=new int[buffer.size()];
 +  size=  buffer.size();
 +  copy(buffer.begin(), buffer.end(), serializer);
 +  
 +}
 +/*! Unserializes the data contained in the Explicit Topology
 + * after communication. Uses the same structure as the one used for serialize()
 + * 
 + * */
 +void ExplicitTopology::unserialize(const int* serializer,const CommInterface& comm_interface)
 +{
 +  const int* ptr_serializer=serializer;
 +  cout << "unserialize..."<<endl;
 +  _nb_elems=*ptr_serializer++;
 +  cout << "nbelems "<<_nb_elems<<endl;
 +  _loc2glob=new int[_nb_elems];
 +  for (int i=0; i<_nb_elems; i++)
 +  {
 +    _loc2glob[i]=*ptr_serializer;
 +    _glob2loc[*ptr_serializer]=i;
 +    ptr_serializer++;
 +    
 +  }
 +
 +}
 +
 +}
index a1f4cceec66a24d52a9d31ed3bf4be5f69275750,0000000000000000000000000000000000000000..d7d73f9be17441bf77187cd1abea9f405fd14268
mode 100644,000000..100644
--- /dev/null
@@@ -1,92 -1,0 +1,99 @@@
-     ExplicitTopology() { }
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __EXPLICITTOPOLOGY_HXX__
 +#define __EXPLICITTOPOLOGY_HXX__
 +
 +#include "ProcessorGroup.hxx"
 +#include "InterpKernelHashMap.hxx"
 +
 +#include <vector>
 +#include <utility>
 +#include <iostream>
 +
 +namespace ParaMEDMEM
 +{
 +  class ParaMESH;
 +  class Topology;
 +  class ComponentTopology;
 +
++  /*!
++   * \anchor ExplicitTopology-det
++   *
++   * An ExplicitTopology typically represents the split of a mesh among the processors of
++   * a common ProcessorGroup. Each processor gets a user-defined part of the cells in the mesh.
++   * \sa BlockTopology
++   */
 +  class ExplicitTopology : public Topology
 +  {
 +  public:
++    ExplicitTopology();
 +    ExplicitTopology( const ExplicitTopology& topo, int nbcomponents);
 +    ExplicitTopology(const ParaMESH &mesh);
 +    virtual ~ExplicitTopology();
 +    
 +    inline int getNbElements()const;
 +    inline int getNbLocalElements() const;
 +    const ProcessorGroup* getProcGroup()const { return _proc_group; }
 +    int localToGlobal (const std::pair<int,int> local) const { return localToGlobal(local.second); }
 +    inline int localToGlobal(int) const;
 +    inline int globalToLocal(int) const;
 +    void serialize(int* & serializer, int& size) const ;
 +    void unserialize(const int* serializer, const CommInterface& comm_interface);
 +    int getNbComponents() const { return _nb_components; }
 +  private:
 +    //Processor group
 +    const ProcessorGroup* _proc_group;
 +    //nb of elements
 +    int _nb_elems;
 +    //nb of components
 +    int _nb_components;
 +    //mapping local to global
 +    int* _loc2glob;
 +    //mapping global to local
 +    INTERP_KERNEL::HashMap<int,int> _glob2loc;
 +  };
 +
 +  //!converts a pair <subdomainid,local> to a global number 
 +  inline int ExplicitTopology::globalToLocal(const int global) const
 +  {
 +    return (_glob2loc.find(global))->second;;
 +  }
 +
 +  //!converts local number to a global number
 +  int ExplicitTopology::localToGlobal(int local) const
 +  {
 +    return _loc2glob[local];
 +  }
 +  
 +  //!Retrieves the number of elements for a given topology
 +  inline int ExplicitTopology::getNbElements() const
 +  {
 +    return _nb_elems;
 +  }
 +
 +  //Retrieves the local number of elements 
 +  inline int ExplicitTopology::getNbLocalElements()const 
 +  {
 +    return _glob2loc.size();
 +  }
 +}
 +
 +
 +#endif
index a7557e509e090093394795b18c3a0e034a815eb1,0000000000000000000000000000000000000000..7f1be4b363e79ba30112275784ff4f91085442d9
mode 100644,000000..100644
--- /dev/null
@@@ -1,292 -1,0 +1,310 @@@
-     \section dec-over Overview
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 <mpi.h>
 +#include "CommInterface.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ComponentTopology.hxx"
 +#include "ParaFIELD.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "ParaMESH.hxx"
 +#include "DEC.hxx"
 +#include "InterpolationMatrix.hxx"
 +#include "InterpKernelDEC.hxx"
 +#include "ElementLocator.hxx"
 +
 +namespace ParaMEDMEM
 +{  
 +
 +  /*!
 +    \anchor InterpKernelDEC-det
 +    \class InterpKernelDEC
 +
-     The InterpKernelDEC enables the \ref InterpKerRemapGlobal "remapping" of fields between two parallel codes.
-     This remapping is based on the computation of intersection volumes between elements from code A
-     and elements from code B. The computation is possible for 3D meshes, 2D meshes, and 3D-surface
-     meshes. Dimensions must be similar for code A and code B (for instance, though it could be
++    \section InterpKernelDEC-over Overview
 +
-     In the present version, only fields lying on elements are considered.
++    The InterpKernelDEC enables the \ref InterpKerRemapGlobal "remapping" (or interpolation) of fields between
++    two parallel codes.
++
++    The projection
++    methodology is based on the algorithms of %INTERP_KERNEL, that is to say, they work in a similar fashion than
++    what the \ref remapper "sequential remapper" does. The following \ref discretization "projection methods"
++    are supported: P0->P0 (the most common case), P1->P0, P0->P1.
++
++    The computation is possible for 3D meshes, 2D meshes, and 3D-surface
++    meshes. Dimensions must be identical for code A and code B (for instance, though it could be
 +    desirable, it is not yet possible to couple 3D surfaces with 2D surfaces).
 +
-     \image html NonCoincident_small.png "Example showing the transfer from a field based on a
-     quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle,
-     the values on quadrangles are weighted by their intersection area and summed."
++    The name "InterpKernelDEC" comes from the fact that this class uses exactly the same algorithms
++    as the sequential remapper. Both this class and the sequential
++    \ref ParaMEDMEM::MEDCouplingRemapper "MEDCouplingRemapper" are built on top of the %INTERP_KERNEL
++    algorithms (notably the computation of the intersection volumes).
++
++    Among the important properties inherited from the parent abstract class \ref DisjointDEC-det "DisjointDEC",
++    the two \ref MPIProcessorGroup-det "processor groups" (source and target) must have a void intersection.
 +
-     \image latex NonCoincident_small.eps "Example showing the transfer from a field based on a quadrangular
-      mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values
-      on quadrangles are weighted by their intersection area and summed."
++    \image html NonCoincident_small.png "Transfer of a field supported by a quadrangular mesh to a triangular mesh".
 +
-     - A use phase during which the remappings are actually performed. This corresponds to the calls to
++    \image latex NonCoincident_small.eps "Transfer of a field supported by a quadrangular mesh to a triangular mesh"
++
++    In the figure above we see the transfer of a field based on a quadrangular mesh to a new field supported by
++    a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on the
++    quadrangles are weighted by their intersection area and summed.
 +
 +    A typical use of InterpKernelDEC encompasses two distinct phases :
 +    - A setup phase during which the intersection volumes are computed and the communication structures are
 +    setup. This corresponds to calling the InterpKernelDEC::synchronize() method.
-     The following code excerpt illutrates a typical use of the InterpKernelDEC class.
++    - A running phase during which the projections are actually performed. This corresponds to the calls to
 +    sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous
 +    in the current version of the library so that recvData() and sendData() calls must be synchronized
 +    on code A and code B processor groups.
 +
-     \section interpkerneldec_options Options
-     On top of \ref dec_options, options supported by %InterpKernelDEC objects are
-     related to the underlying Intersector class. 
++    The following code excerpt illustrates a typical use of the InterpKernelDEC class.
 +
 +    \code
 +    ...
 +    InterpKernelDEC dec(groupA, groupB);
 +    dec.attachLocalField(field);
 +    dec.synchronize();
 +    if (groupA.containsMyRank())
 +    dec.recvData();
 +    else if (groupB.containsMyRank())
 +    dec.sendData();
 +    ...
 +    \endcode
 +    A \ref InterpKerRemapGlobal "remapping" of the field from the source mesh to the target mesh is performed by
 +    the function synchronise(), which computes the interpolation matrix.
 +
 +    Computing the field on the receiving side can be expressed in terms of a matrix-vector product :
 +    \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t \f$ the field on the target side and \f$ \phi_s \f$ the field
 +    on the source side.
 +    When remapping a 3D surface to another 3D surface, a projection phase is necessary to match elements
 +    from both sides. Care must be taken when defining this projection to obtain a
 +    \ref InterpKerRemapGlobal "conservative remapping".
 +
 +    In the P0-P0 case, this matrix is a plain rectangular matrix with coefficients equal to the
 +    intersection areas between triangle and quadrangles. For instance, in the above figure, the matrix
 +    is :
 +
 +    \f[
 +    \begin{tabular}{|cccc|}
 +    0.72 & 0 & 0.2 & 0 \\
 +    0.46 & 0 & 0.51 & 0.03\\
 +    0.42 & 0.53 & 0 & 0.05\\
 +    0 & 0 & 0.92 & 0.05 \\
 +    \end{tabular}
 +    \f]
 +
-     available for the %InterpKernelDEC object. The various options available for  * intersectors can
++    \section InterpKernelDEC-options Options
++    On top of the usual \ref ParaMEDMEM::DECOptions "DEC options", the options supported by %InterpKernelDEC objects are
++    related to the underlying \ref InterpKerIntersectors "intersector class".
 +    All the options available in the intersector objects are
-     dec.setOptions("DoRotate",false);
-     dec.setOptions("Precision",1e-12);
++    available for the %InterpKernelDEC object. The various options available for  intersectors can
 +    be reviewed in \ref InterpKerIntersectors.
 + 
 +    For instance :
 +    \verbatim
 +    InterpKernelDEC dec(source_group, target_group);
 +    dec.attachLocalField(field);
-   InterpKernelDEC::InterpKernelDEC():_interpolation_matrix(0)
++    dec.setDoRotate(false);
++    dec.setPrecision(1e-12);
 +    dec.synchronize();
 +    \endverbatim
 +
 +    \warning{  Options must be set before calling the synchronize method. }
 +  */
 +  
-     DisjointDEC(source_group, target_group),_interpolation_matrix(0)
++  InterpKernelDEC::InterpKernelDEC():
++    DisjointDEC(),
++    _nb_distant_points(0), _distant_coords(0),
++    _distant_locations(0), _interpolation_matrix(0)
 +  {  
 +  }
 +
 +  /*!
 +    This constructor creates an InterpKernelDEC which has \a source_group as a working side 
 +    and  \a target_group as an idle side. All the processors will actually participate, but intersection computations will be performed on the working side during the \a synchronize() phase.
 +    The constructor must be called synchronously on all processors of both processor groups.
 +
 +    \param source_group working side ProcessorGroup
 +    \param target_group lazy side ProcessorGroup
 +
 +  */
 +  InterpKernelDEC::InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group):
-                                    const MPI_Comm& world_comm):DisjointDEC(src_ids,trg_ids,world_comm),
-                                                                _interpolation_matrix(0)
++    DisjointDEC(source_group, target_group),
++    _nb_distant_points(0), _distant_coords(0),
++    _distant_locations(0), _interpolation_matrix(0)
 +  {
 +
 +  }
 +
 +  InterpKernelDEC::InterpKernelDEC(const std::set<int>& src_ids, const std::set<int>& trg_ids,
-     This method prepares all the structures necessary for sending data from a processor group to the other. It uses the mesh underlying the fields that have been set with attachLocalField method.
++                                   const MPI_Comm& world_comm):
++    DisjointDEC(src_ids,trg_ids,world_comm),
++    _nb_distant_points(0), _distant_coords(0),
++    _distant_locations(0), _interpolation_matrix(0)
 +  {
 +  }
 +
 +  InterpKernelDEC::~InterpKernelDEC()
 +  {
 +    if (_interpolation_matrix !=0)
 +      delete _interpolation_matrix;
 +  } 
 +
 +  /*! 
 +    \brief Synchronization process for exchanging topologies.
 +
-     -# Bounding boxes are computed for each subdomain,
++    This method prepares all the structures necessary for sending data from a processor group to the other. It uses the mesh
++    underlying the fields that have been set with attachLocalField method.
 +    It works in four steps :
++    -# Bounding boxes are computed for each sub-domain,
 +    -# The lazy side mesh parts that are likely to intersect the working side local processor are sent to the working side,
 +    -# The working side calls the interpolation kernel to compute the intersection between local and imported mesh.
 +    -# The lazy side is updated so that it knows the structure of the data that will be sent by
 +    the working side during a \a sendData() call.
 +
 +  */
 +  void InterpKernelDEC::synchronize()
 +  {
 +    if(!isInUnion())
 +      return ;
 +    delete _interpolation_matrix;
 +    _interpolation_matrix = new InterpolationMatrix (_local_field, *_source_group,*_target_group,*this,*this); 
 +
 +    //setting up the communication DEC on both sides  
 +    if (_source_group->containsMyRank())
 +      {
 +        //locate the distant meshes
 +        ElementLocator locator(*_local_field, *_target_group, *_source_group);
 +        //transfering option from InterpKernelDEC to ElementLocator   
 +        locator.copyOptions(*this);
 +        MEDCouplingPointSet* distant_mesh=0; 
 +        int* distant_ids=0;
 +        std::string distantMeth;
 +        for (int i=0; i<_target_group->size(); i++)
 +          {
 +            //        int idistant_proc = (i+_source_group->myRank())%_target_group->size();
 +            int idistant_proc=i;
 +
 +            //gathers pieces of the target meshes that can intersect the local mesh
 +            locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids);
 +            if (distant_mesh !=0)
 +              {
 +                locator.exchangeMethod(_method,idistant_proc,distantMeth);
 +                //adds the contribution of the distant mesh on the local one
 +                int idistant_proc_in_union=_union_group->translateRank(_target_group,idistant_proc);
 +                //std::cout <<"add contribution from proc "<<idistant_proc_in_union<<" to proc "<<_union_group->myRank()<<std::endl;
 +                _interpolation_matrix->addContribution(*distant_mesh,idistant_proc_in_union,distant_ids,_method,distantMeth);
 +                distant_mesh->decrRef();
 +                delete [] distant_ids;
 +                distant_mesh=0;
 +                distant_ids=0;
 +              }
 +          }
 +       _interpolation_matrix->finishContributionW(locator);
 +      }
 +
 +    if (_target_group->containsMyRank())
 +      {
 +        ElementLocator locator(*_local_field, *_source_group, *_target_group);
 +        //transfering option from InterpKernelDEC to ElementLocator
 +        locator.copyOptions(*this);
 +        MEDCouplingPointSet* distant_mesh=0;
 +        int* distant_ids=0;
 +        for (int i=0; i<_source_group->size(); i++)
 +          {
 +            //        int idistant_proc = (i+_target_group->myRank())%_source_group->size();
 +            int  idistant_proc=i;
 +            //gathers pieces of the target meshes that can intersect the local mesh
 +            locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids);
 +            //std::cout << " Data sent from "<<_union_group->myRank()<<" to source proc "<< idistant_proc<<std::endl;
 +            if (distant_mesh!=0)
 +              {
 +                std::string distantMeth;
 +                locator.exchangeMethod(_method,idistant_proc,distantMeth);
 +                distant_mesh->decrRef();
 +                delete [] distant_ids;
 +                distant_mesh=0;
 +                distant_ids=0;
 +              }
 +          }
 +        _interpolation_matrix->finishContributionL(locator);
 +      }
 +    _interpolation_matrix->prepare();
 +  }
 +
 +
 +  /*!
 +    Receives the data whether the processor is on the working side or on the lazy side. It must match a \a sendData() call on the other side.
 +  */
 +  void InterpKernelDEC::recvData()
 +  {
 +    if (_source_group->containsMyRank())
 +      _interpolation_matrix->transposeMultiply(*_local_field->getField());
 +    else if (_target_group->containsMyRank())
 +      {
 +        _interpolation_matrix->multiply(*_local_field->getField());
 +        if (getForcedRenormalization())
 +          renormalizeTargetField(getMeasureAbsStatus());
 +      }
 +  }
 +
 +
 +  /*!
 +    Receives the data at time \a time in asynchronous mode. The value of the field
 +    will be time-interpolated from the field values received.
 +    \param time time at which the value is desired
 +  */
 +  void InterpKernelDEC::recvData( double time )
 +  {
 +    _interpolation_matrix->getAccessDEC()->setTime(time);
 +    recvData() ;
 +  }
 +
 +  /*!
 +    Sends the data whether the processor is on the working side or on the lazy side.
 +    It must match a recvData() call on the other side.
 +  */
 +  void InterpKernelDEC::sendData()
 +  {
 +    if (_source_group->containsMyRank())
 +      {
 +    
 +        _interpolation_matrix->multiply(*_local_field->getField());
 +        if (getForcedRenormalization())
 +          renormalizeTargetField(getMeasureAbsStatus());
 +    
 +      }
 +    else if (_target_group->containsMyRank())
 +      _interpolation_matrix->transposeMultiply(*_local_field->getField());
 +  }
 +
 +  /*!
 +    Sends the data available at time \a time in asynchronous mode. 
 +    \param time time at which the value is available
 +    \param deltatime time interval between the value presently sent and the next one. 
 +  */
 +  void InterpKernelDEC::sendData( double time , double deltatime )
 +  {
 +    _interpolation_matrix->getAccessDEC()->setTime(time,deltatime);
 +    sendData() ;
 +  }
 +  
 +}
index 97fc2a3009f63e9b250fdf4623bf1b64db67a279,0000000000000000000000000000000000000000..b60c9ee54b2e8408a89108b4bc31e10f3aa7a366
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,111 @@@
-   /**! class InterpolationMatrix
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __INTERPOLATIONMATRIX_HXX__
 +#define __INTERPOLATIONMATRIX_HXX__
 +
 +#include "MPIAccessDEC.hxx"
 +#include "MxN_Mapping.hxx"
 +#include "InterpolationOptions.hxx"
 +#include "DECOptions.hxx"
 +
 +namespace ParaMEDMEM
 +{
 +  class ElementLocator;
 +
-    source field Sj to target field Ti via Ti=Vi^(-1).Wij.Sj.
++  /*!
++   Internal class, not part of the public API.
++
 +   This class enables the storage of an interpolation matrix Wij mapping
++   a source field Sj to a target field Ti via Ti=Vi^(-1).Wij.Sj.
 +   The matrix is built and stored on the processors belonging to the source
 +   group.
 +   */
 +  class InterpolationMatrix : public INTERP_KERNEL::InterpolationOptions,
 +                              public DECOptions
 +  {
 +  public:
 +    
 +    InterpolationMatrix(const ParaMEDMEM::ParaFIELD *source_field, 
 +                        const ProcessorGroup& source_group,
 +                        const ProcessorGroup& target_group,
 +                        const DECOptions& dec_opt,
 +                        const InterpolationOptions& i_opt);
 +
 +    
 +    virtual ~InterpolationMatrix();
 +    void addContribution(MEDCouplingPointSet& distant_support, int iproc_distant,
 +                         const int* distant_elems, const std::string& srcMeth, const std::string& targetMeth);
 +    void finishContributionW(ElementLocator& elementLocator);
 +    void finishContributionL(ElementLocator& elementLocator);
 +    void multiply(MEDCouplingFieldDouble& field) const;
 +    void transposeMultiply(MEDCouplingFieldDouble& field)const;
 +    void prepare();
 +    int getNbRows() const { return _row_offsets.size(); }
 +    MPIAccessDEC* getAccessDEC() { return _mapping.getAccessDEC(); }
 +  private:
 +    void computeConservVolDenoW(ElementLocator& elementLocator);
 +    void computeIntegralDenoW(ElementLocator& elementLocator);
 +    void computeRevIntegralDenoW(ElementLocator& elementLocator);
 +    void computeGlobConstraintDenoW(ElementLocator& elementLocator);
 +    void computeConservVolDenoL(ElementLocator& elementLocator);
 +    void computeIntegralDenoL(ElementLocator& elementLocator);
 +    void computeRevIntegralDenoL(ElementLocator& elementLocator);
 +    
 +    void computeLocalColSum(std::vector<double>& res) const;
 +    void computeLocalRowSum(const std::vector<int>& distantProcs, std::vector<std::vector<int> >& resPerProcI,
 +                            std::vector<std::vector<double> >& resPerProcD) const;
 +    void computeGlobalRowSum(ElementLocator& elementLocator, std::vector<std::vector<double> >& denoStrorage, std::vector<std::vector<double> >& denoStrorageInv);
 +    void computeGlobalColSum(std::vector<std::vector<double> >& denoStrorage);
 +    void resizeGlobalColSum(std::vector<std::vector<double> >& denoStrorage);
 +    void fillDSFromVM(int iproc_distant, const int* distant_elems, const std::vector< std::map<int,double> >& values, MEDCouplingFieldDouble *surf);
 +    void serializeMe(std::vector< std::vector< std::map<int,double> > >& data1, std::vector<int>& data2) const;
 +    void initialize();
 +    void findAdditionnalElements(ElementLocator& elementLocator, std::vector<std::vector<int> >& elementsToAdd,
 +                                 const std::vector<std::vector<int> >& resPerProcI, const std::vector<std::vector<int> >& globalIdsPartial);
 +    void addGhostElements(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& elementsToAdd);
 +    int mergePolicies(const std::vector<int>& policyPartial);
 +    void mergeRowSum(const std::vector< std::vector<double> >& rowsPartialSumD, const std::vector< std::vector<int> >& globalIdsPartial,
 +                     std::vector<int>& globalIdsLazySideInteraction, std::vector<double>& sumCorresponding);
 +    void mergeRowSum2(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD,
 +                      const std::vector<int>& globalIdsLazySideInteraction, const std::vector<double>& sumCorresponding);
 +    void mergeRowSum3(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD);
 +    void mergeCoeffs(const std::vector<int>& procsInInteraction, const std::vector< std::vector<int> >& rowsPartialSumI,
 +                     const std::vector<std::vector<int> >& globalIdsPartial, std::vector<std::vector<double> >& denoStrorageInv);
 +    void divideByGlobalRowSum(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& resPerProcI,
 +                              const std::vector<std::vector<double> >& resPerProcD, std::vector<std::vector<double> >& deno);
 +  private:
 +    bool isSurfaceComputationNeeded(const std::string& method) const;
 +  private:
 +    const ParaMEDMEM::ParaFIELD *_source_field;
 +    std::vector<int> _row_offsets;
 +    std::map<std::pair<int,int>, int > _col_offsets;
 +    MEDCouplingPointSet *_source_support;
 +    MxN_Mapping _mapping;
 + 
 +    const ProcessorGroup& _source_group;
 +    const ProcessorGroup& _target_group;
 +    std::vector< std::vector<double> > _target_volume;
 +    std::vector<std::vector<std::pair<int,double> > > _coeffs;
 +    std::vector<std::vector<double> > _deno_multiply;
 +    std::vector<std::vector<double> > _deno_reverse_multiply;
 +  };
 +}
 +
 +#endif
index 0128e42b24f521f6a5ee7a6d92376d63ddf8b988,0000000000000000000000000000000000000000..76eca3fc7760844f489771892e54320a6b443bc9
mode 100644,000000..100644
--- /dev/null
@@@ -1,47 -1,0 +1,52 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __LINEARTIMEINTERPOLATOR_HXX__
 +#define __LINEARTIMEINTERPOLATOR_HXX__
 +
 +#include "TimeInterpolator.hxx"
 +
 +#include <map>
 +#include <iostream>
 +
 +namespace ParaMEDMEM
 +{
 +  class DEC;
 +  
++  /*!
++   * Internal class, not part of the public API.
++   *
++   * Linear interpolation of a block of data between two given times.
++   */
 +  class LinearTimeInterpolator : public TimeInterpolator
 +  {
 +    public:  
 +      LinearTimeInterpolator( double InterpPrecision=0, int nStepBefore=1,
 +                              int nStepAfter=1 ) ;
 +      virtual ~LinearTimeInterpolator();
 +      void doInterp( double time0, double time1, double time, int recvcount,
 +                     int nbuff0, int nbuff1,
 +                     int **recvbuff0, int **recvbuff1, int *result );
 +      void doInterp( double time0, double time1, double time, int recvcount,
 +                     int nbuff0, int nbuff1,
 +                     double **recvbuff0, double **recvbuff1, double *result );
 +  };
 +}
 +
 +#endif
index f8a0e1002c8183278f8227aaaaf6b4a3bb0e77a2,0000000000000000000000000000000000000000..18184dc27c636f88185ce580d4dc0b3973ecf1fe
mode 100644,000000..100644
--- /dev/null
@@@ -1,1057 -1,0 +1,1057 @@@
-             //TODO : it is assumed actually that we have only 1 timestep before nad after
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "MPIAccessDEC.hxx"
 +
 +#include <cstring>
 +
 +using namespace std;
 +
 +namespace ParaMEDMEM
 +{    
 +
 +  /*!
 +    This constructor creates an MPIAccessDEC which has \a source_group as a working side 
 +    and  \a target_group as an idle side. 
 +    The constructor must be called synchronously on all processors of both processor groups.
 +
 +    \param source_group working side ProcessorGroup
 +    \param target_group lazy side ProcessorGroup
 +    \param Asynchronous Communication mode (default asynchronous)
 +    \param nStepBefore Number of Time step needed for the interpolation before current time
 +    \param nStepAfter Number of Time step needed for the interpolation after current time
 +
 +  */
 +
 +  MPIAccessDEC::MPIAccessDEC( const ProcessorGroup& source_group,
 +                              const ProcessorGroup& target_group,
 +                              bool Asynchronous )
 +  {
 +
 +    ProcessorGroup * union_group = source_group.fuse(target_group) ;  
 +    int i ;
 +    std::set<int> procs;
 +    for ( i = 0 ; i < union_group->size() ; i++ )
 +      {
 +        procs.insert(i) ;
 +      }
 +    MPIProcessorGroup *mpilg = static_cast<MPIProcessorGroup *>(const_cast<ProcessorGroup *>(&source_group));
 +    _MPI_union_group = new ParaMEDMEM::MPIProcessorGroup( union_group->getCommInterface(),procs,mpilg->getWorldComm());
 +    delete union_group ;
 +    _my_rank = _MPI_union_group->myRank() ;
 +    _group_size = _MPI_union_group->size() ;
 +    _MPI_access = new MPIAccess( _MPI_union_group ) ;
 +    _asynchronous = Asynchronous ;
 +    _time_messages = new vector< vector< TimeMessage > > ;
 +    _time_messages->resize( _group_size ) ;
 +    _out_of_time = new vector< bool > ;
 +    _out_of_time->resize( _group_size ) ;
 +    _data_messages_recv_count = new vector< int > ;
 +    _data_messages_recv_count->resize( _group_size ) ;
 +    for ( i = 0 ; i < _group_size ; i++ )
 +      {
 +        (*_out_of_time)[i] = false ;
 +        (*_data_messages_recv_count)[i] = 0 ;
 +      }
 +    _data_messages_type = new vector< MPI_Datatype > ;
 +    _data_messages_type->resize( _group_size ) ;
 +    _data_messages = new vector< vector< void * > > ;
 +    _data_messages->resize( _group_size ) ;
 +    _time_interpolator = NULL ;
 +    _map_of_send_buffers = new map< int , SendBuffStruct * > ;
 +  }
 +
 +  MPIAccessDEC::~MPIAccessDEC()
 +  {
 +    checkFinalSent() ;
 +    checkFinalRecv() ;
 +    delete _MPI_union_group ;
 +    delete _MPI_access ;
 +    if ( _time_interpolator )
 +      delete _time_interpolator ;
 +    if ( _time_messages )
 +      delete _time_messages ;
 +    if ( _out_of_time )
 +      delete _out_of_time ;
 +    if ( _data_messages_recv_count )
 +      delete _data_messages_recv_count ;
 +    if ( _data_messages_type )
 +      delete _data_messages_type ;
 +    if ( _data_messages )
 +      delete _data_messages ;
 +    if ( _map_of_send_buffers )
 +      delete _map_of_send_buffers ;
 +  } 
 +
 +  void MPIAccessDEC::setTimeInterpolator( TimeInterpolationMethod aTimeInterp ,
 +                                          double InterpPrecision, int nStepBefore,
 +                                          int nStepAfter )
 +  {
 +    if ( _time_interpolator )
 +      delete _time_interpolator ;
 +    switch ( aTimeInterp )
 +      {
 +      case WithoutTimeInterp :
 +        _time_interpolator = NULL ;
 +        _n_step_before = 0 ;
 +        _n_step_after = 0 ;
 +        break ;
 +      case LinearTimeInterp :
 +        _time_interpolator = new LinearTimeInterpolator( InterpPrecision , nStepBefore ,
 +                                                         nStepAfter ) ;
 +        _n_step_before = nStepBefore ;
 +        _n_step_after = nStepAfter ;
 +        int i ;
 +        for ( i = 0 ; i < _group_size ; i++ )
 +          {
 +            (*_time_messages)[ i ].resize( _n_step_before + _n_step_after ) ;
 +            (*_data_messages)[ i ].resize( _n_step_before + _n_step_after ) ;
 +            int j ;
 +            for ( j = 0 ; j < _n_step_before + _n_step_after ; j++ )
 +              {
 +                (*_time_messages)[ i ][ j ].time = -1 ;
 +                (*_time_messages)[ i ][ j ].deltatime = -1 ;
 +                (*_data_messages)[ i ][ j ] = NULL ;
 +              }
 +          }
 +        break ;
 +      }
 +  }
 +
 +  /*!
 +    Send sendcount datas from sendbuf[offset] with type sendtype to target of IntraCommunicator
 +    (Internal Protected method)
 +
 +    Returns the request identifier SendRequestId
 +
 +  */
 +  int MPIAccessDEC::send( void* sendbuf, int sendcount , int offset ,
 +                          MPI_Datatype sendtype , int target , int &SendRequestId )
 +  {
 +    int sts ;
 +    if ( _asynchronous )
 +      {
 +        if ( sendtype == MPI_INT )
 +          {
 +            sts = _MPI_access->ISend( &((int *) sendbuf)[offset] , sendcount , sendtype ,
 +                                      target , SendRequestId ) ;
 +          }
 +        else
 +          {
 +            sts = _MPI_access->ISend( &((double *) sendbuf)[offset] , sendcount , sendtype ,
 +                                      target , SendRequestId ) ;
 +          }
 +      }
 +    else
 +      {
 +        if ( sendtype == MPI_INT )
 +          {
 +            sts = _MPI_access->send( &((int *) sendbuf)[offset] , sendcount , sendtype ,
 +                                     target , SendRequestId ) ;
 +          }
 +        else
 +          {
 +            sts = _MPI_access->send( &((double *) sendbuf)[offset] , sendcount , sendtype ,
 +                                     target , SendRequestId ) ;
 +          }
 +      }
 +    return sts ;
 +  }
 +
 +  /*!
 +    Receive recvcount datas to recvbuf[offset] with type recvtype from target of IntraCommunicator
 +    (Internal Protected method)
 +
 +    Returns the request identifier RecvRequestId
 +
 +  */
 +  int MPIAccessDEC::recv( void* recvbuf, int recvcount , int offset ,
 +                          MPI_Datatype recvtype , int target , int &RecvRequestId )
 +  {
 +    int sts ;
 +    if ( _asynchronous )
 +      {
 +        if ( recvtype == MPI_INT )
 +          {
 +            sts = _MPI_access->IRecv( &((int *) recvbuf)[offset] , recvcount , recvtype ,
 +                                      target , RecvRequestId ) ;
 +          }
 +        else
 +          {
 +            sts = _MPI_access->IRecv( &((double *) recvbuf)[offset] , recvcount , recvtype ,
 +                                      target , RecvRequestId ) ;
 +          }
 +      }
 +    else
 +      {
 +        if ( recvtype == MPI_INT )
 +          {
 +            sts = _MPI_access->recv( &((int *) recvbuf)[offset] , recvcount , recvtype ,
 +                                     target , RecvRequestId ) ;
 +          }
 +        else
 +          {
 +            sts = _MPI_access->recv( &((double *) recvbuf)[offset] , recvcount , recvtype ,
 +                                     target , RecvRequestId ) ;
 +          }
 +      }
 +    return sts ;
 +  }
 +
 +  /*!
 +    Send sendcount datas from sendbuf[offset] with type sendtype to target of IntraCommunicator
 +    Receive recvcount datas to recvbuf[offset] with type recvtype from target of IntraCommunicator
 +    (Internal Protected method)
 +
 +    Returns the request identifier SendRequestId
 +    Returns the request identifier RecvRequestId
 +
 +  */
 +  int MPIAccessDEC::sendRecv( void* sendbuf, int sendcount , int sendoffset ,
 +                              MPI_Datatype sendtype ,
 +                              void* recvbuf, int recvcount , int recvoffset ,
 +                              MPI_Datatype recvtype , int target ,
 +                              int &SendRequestId , int &RecvRequestId )
 +  {
 +    int sts ;
 +    if ( _asynchronous )
 +      {
 +        if ( sendtype == MPI_INT )
 +          {
 +            if ( recvtype == MPI_INT )
 +              {
 +                sts = _MPI_access->ISendRecv( &((int *) sendbuf)[sendoffset] , sendcount ,
 +                                              sendtype , target , SendRequestId ,
 +                                              &((int *) recvbuf)[recvoffset] , recvcount ,
 +                                              recvtype , target , RecvRequestId ) ;
 +              }
 +            else
 +              {
 +                sts = _MPI_access->ISendRecv( &((int *) sendbuf)[sendoffset] , sendcount ,
 +                                              sendtype , target , SendRequestId ,
 +                                              &((double *) recvbuf)[recvoffset] ,
 +                                              recvcount , recvtype , target , RecvRequestId ) ;
 +              }
 +          }
 +        else
 +          {
 +            if ( recvtype == MPI_INT )
 +              {
 +                sts = _MPI_access->ISendRecv( &((double *) sendbuf)[sendoffset] , sendcount ,
 +                                              sendtype , target , SendRequestId ,
 +                                              &((int *) recvbuf)[recvoffset] ,
 +                                              recvcount , recvtype , target , RecvRequestId ) ;
 +              }
 +            else
 +              {
 +                sts = _MPI_access->ISendRecv( &((double *) sendbuf)[sendoffset] , sendcount ,
 +                                              sendtype , target , SendRequestId ,
 +                                              &((double *) recvbuf)[recvoffset] ,
 +                                              recvcount , recvtype , target , RecvRequestId ) ;
 +              }
 +          }
 +      }
 +    else
 +      {
 +        if ( sendtype == MPI_INT )
 +          {
 +            if ( recvtype == MPI_INT )
 +              {
 +                sts = _MPI_access->sendRecv( &((int *) sendbuf)[sendoffset] , sendcount ,
 +                                             sendtype , target , SendRequestId ,
 +                                             &((int *) recvbuf)[recvoffset] , recvcount ,
 +                                             recvtype , target , RecvRequestId ) ;
 +              }
 +            else
 +              {
 +                sts = _MPI_access->sendRecv( &((int *) sendbuf)[sendoffset] , sendcount ,
 +                                             sendtype , target , SendRequestId ,
 +                                             &((double *) recvbuf)[recvoffset] ,
 +                                             recvcount , recvtype , target , RecvRequestId ) ;
 +              }
 +          }
 +        else
 +          {
 +            if ( recvtype == MPI_INT )
 +              {
 +                sts = _MPI_access->sendRecv( &((double *) sendbuf)[sendoffset] , sendcount ,
 +                                             sendtype , target , SendRequestId ,
 +                                             &((int *) recvbuf)[recvoffset] ,
 +                                             recvcount , recvtype , target , RecvRequestId ) ;
 +              }
 +            else
 +              {
 +                sts = _MPI_access->sendRecv( &((double *) sendbuf)[sendoffset] , sendcount ,
 +                                             sendtype , target , SendRequestId ,
 +                                             &((double *) recvbuf)[recvoffset] ,
 +                                             recvcount , recvtype , target , RecvRequestId ) ;
 +              }
 +          }
 +      }
 +    return sts ;
 +  }
 +
 +  /*!
 +    Send sendcount datas from sendbuf[offset] with type sendtype to all targets of IntraCommunicator
 +    Receive recvcount datas to recvbuf[offset] with type recvtype from all targets of IntraCommunicator
 +
 +  */
 +  int MPIAccessDEC::allToAll( void* sendbuf, int sendcount, MPI_Datatype sendtype ,
 +                              void* recvbuf, int recvcount, MPI_Datatype recvtype )
 +  {
 +    if ( _time_interpolator )
 +      {
 +        return allToAllTime( sendbuf, sendcount, sendtype , recvbuf, recvcount, recvtype ) ;
 +      }
 +    int sts ;
 +    int target ;
 +    int sendoffset = 0 ;
 +    int recvoffset = 0 ;
 +    int SendRequestId ;
 +    int RecvRequestId ;
 +
 +    //Free of SendBuffers 
 +    if ( _asynchronous )
 +      checkSent() ;
 +
 +    //DoSend + DoRecv : SendRecv
 +    SendBuffStruct * aSendDataStruct = NULL ;
 +    if ( _asynchronous && sendbuf )
 +      {
 +        aSendDataStruct = new SendBuffStruct ;
 +        aSendDataStruct->SendBuffer = sendbuf ;
 +        aSendDataStruct->Counter = 0 ;
 +        aSendDataStruct->DataType = sendtype ;
 +      }
 +    for ( target = 0 ; target < _group_size ; target++ )
 +      {
 +        sts = sendRecv( sendbuf , sendcount , sendoffset , sendtype ,
 +                        recvbuf , recvcount , recvoffset , recvtype ,
 +                        target , SendRequestId , RecvRequestId ) ;
 +        if ( _asynchronous && sendbuf && sendcount )
 +          {
 +            aSendDataStruct->Counter += 1 ;
 +            (*_map_of_send_buffers)[ SendRequestId ] = aSendDataStruct ;
 +          }
 +        sendoffset += sendcount ;
 +        recvoffset += recvcount ;
 +      }
 +    if ( !_asynchronous && sendbuf )
 +      {
 +        if ( sendtype == MPI_INT )
 +          {
 +            delete [] (int *) sendbuf ;
 +          }
 +        else
 +          {
 +            delete [] (double *) sendbuf ;
 +          }
 +      }
 +    return sts ;
 +  }
 +
 +  /*!
 +    Send sendcounts[target] datas from sendbuf[sdispls[target]] with type sendtype to all targets of IntraCommunicator
 +    Receive recvcounts[target] datas to recvbuf[rdispls[target]] with type recvtype from all targets of IntraCommunicator
 +
 +  */
 +  int MPIAccessDEC::allToAllv( void* sendbuf, int* sendcounts, int* sdispls,
 +                               MPI_Datatype sendtype ,
 +                               void* recvbuf, int* recvcounts, int* rdispls,
 +                               MPI_Datatype recvtype )
 +  {
 +    if ( _time_interpolator )
 +      {
 +        return allToAllvTime( sendbuf, sendcounts, sdispls, sendtype ,
 +                              recvbuf, recvcounts, rdispls, recvtype ) ;
 +      }
 +    int sts ;
 +    int target ;
 +    int SendRequestId ;
 +    int RecvRequestId ;
 +
 +    //Free of SendBuffers 
 +    if ( _asynchronous )
 +      {
 +        checkSent() ;
 +      }
 +
 +    //DoSend + DoRecv : SendRecv
 +    SendBuffStruct * aSendDataStruct = NULL ;
 +    if ( _asynchronous && sendbuf )
 +      {
 +        aSendDataStruct = new SendBuffStruct ;
 +        aSendDataStruct->SendBuffer = sendbuf ;
 +        aSendDataStruct->Counter = 0 ;
 +        aSendDataStruct->DataType = sendtype ;
 +      }
 +    for ( target = 0 ; target < _group_size ; target++ )
 +      {
 +        if ( sendcounts[target] || recvcounts[target] )
 +          {
 +            sts = sendRecv( sendbuf , sendcounts[target] , sdispls[target] , sendtype ,
 +                            recvbuf , recvcounts[target] , rdispls[target] , recvtype ,
 +                            target , SendRequestId , RecvRequestId ) ;
 +            if ( _asynchronous && sendbuf && sendcounts[target])
 +              {
 +                aSendDataStruct->Counter += 1 ;
 +                (*_map_of_send_buffers)[ SendRequestId ] = aSendDataStruct ;
 +              }
 +          }
 +      }
 +    if ( !_asynchronous && sendbuf )
 +      {
 +        if ( sendtype == MPI_INT )
 +          {
 +            delete [] (int *) sendbuf ;
 +          }
 +        else
 +          {
 +            delete [] (double *) sendbuf ;
 +          }
 +      }
 +    return sts ;
 +  }
 +
 +  /*
 +    MPIAccessDEC and the management of SendBuffers :
 +    =================================================
 +
 +    . In the collective communications collectives we send only parts of
 +    the same buffer to each "target". So in asynchronous mode it is
 +    necessary that all parts are free before to delete/free the
 +    buffer.
 +
 +    . We assume that buffers are allocated with a new double[]. so a
 +    delete [] is done.
 +
 +    . The structure SendBuffStruct permit to keep the adress of the buffer
 +    and to manage a reference counter of that buffer. It contains
 +    also MPI_Datatype for the delete [] (double *) ... when the counter
 +    is null.
 +
 +    . The map _MapOfSendBuffers etablish the correspondance between each
 +    RequestId given by a MPI_Access->ISend(...) and a SendBuffStruct
 +    for each "target" of a part of the buffer.
 +
 +    . All that concerns only asynchronous Send. In synchronous mode,
 +    we delete senbuf just after the Send.
 +  */
 +
 +  /*
 +    MPIAccessDEC and the management of RecvBuffers :
 +    =================================================
 +
 +    If there is no interpolation, no special action is done.
 +
 +    With interpolation for each target :
 +    ------------------------------------
 +    . We have _time_messages[target] which is a vector of TimesMessages.
 +    We have 2 TimesMessages in our case with a linear interpolation.
 +    They contain the previous time(t0)/deltatime and the last
 +    time(t1)/deltatime.
 +
 +    . We have _data_messages[target] which is a vector of DatasMessages.
 +    We have 2 DatasMessages in our case with a linear interpolation.
 +    They contain the previous datas at time(t0)/deltatime and at last
 +    time(t1)/deltatime.
 +
 +    . At time _t(t*) of current processus we do the interpolation of
 +    the values of the 2 DatasMessages which are returned in the part of
 +    recvbuf corresponding to the target with t0 < t* <= t1.
 +
 +    . Because of the difference of "deltatimes" between processes, we
 +    may have t0 < t1 < t* and there is an extrapolation.
 +
 +    . The vectors _out_of_time, _DataMessagesRecvCount and _DataMessagesType
 +    contain for each target true if t* > last t1, recvcount and
 +    MPI_Datatype for the finalize of messages at the end.
 +  */
 +
 +  /*!
 +    Send a TimeMessage to all targets of IntraCommunicator
 +    Receive the TimeMessages from targets of IntraCommunicator if necessary.
 +
 +    Send sendcount datas from sendbuf[offset] with type sendtype to all targets of IntraCommunicator
 +    Returns recvcount datas to recvbuf[offset] with type recvtype after an interpolation
 +    with datas received from all targets of IntraCommunicator.
 +
 +  */
 +  int MPIAccessDEC::allToAllTime( void* sendbuf, int sendcount , MPI_Datatype sendtype ,
 +                                  void* recvbuf, int recvcount , MPI_Datatype recvtype )
 +  {
 +    int sts ;
 +    int target ;
 +    int sendoffset = 0 ;
 +    int SendTimeRequestId ;
 +    int SendDataRequestId ;
 +
 +    if ( _time_interpolator == NULL )
 +      {
 +        return MPI_ERR_OTHER ;
 +      }
 +
 +    //Free of SendBuffers 
 +    if ( _asynchronous )
 +      {
 +        checkSent() ;
 +      }
 +
 +    //DoSend : Time + SendBuff
 +    SendBuffStruct * aSendTimeStruct = NULL ;
 +    SendBuffStruct * aSendDataStruct = NULL ;
 +    if ( sendbuf && sendcount )
 +      {
 +        TimeMessage * aSendTimeMessage = new TimeMessage ;
 +        if ( _asynchronous )
 +          {
 +            aSendTimeStruct = new SendBuffStruct ;
 +            aSendTimeStruct->SendBuffer = aSendTimeMessage ;
 +            aSendTimeStruct->Counter = 0 ;
 +            aSendTimeStruct->DataType = _MPI_access->timeType() ;
 +            aSendDataStruct = new SendBuffStruct ;
 +            aSendDataStruct->SendBuffer = sendbuf ;
 +            aSendDataStruct->Counter = 0 ;
 +            aSendDataStruct->DataType = sendtype ;
 +          }
 +        aSendTimeMessage->time = _t ;
 +        aSendTimeMessage->deltatime = _dt ;
 +        for ( target = 0 ; target < _group_size ; target++ )
 +          {
 +            sts = send( aSendTimeMessage , 1 , 0 , _MPI_access->timeType() , target ,
 +                        SendTimeRequestId ) ;
 +            sts = send( sendbuf , sendcount , sendoffset , sendtype , target , SendDataRequestId ) ;
 +            if ( _asynchronous )
 +              {
 +                aSendTimeStruct->Counter += 1 ;
 +                (*_map_of_send_buffers)[ SendTimeRequestId ] = aSendTimeStruct ;
 +                aSendDataStruct->Counter += 1 ;
 +                (*_map_of_send_buffers)[ SendDataRequestId ] = aSendDataStruct ;
 +              }
 +            sendoffset += sendcount ;
 +          }
 +        if ( !_asynchronous )
 +          {
 +            delete aSendTimeMessage ;
 +            if ( sendtype == MPI_INT )
 +              {
 +                delete [] (int *) sendbuf ;
 +              }
 +            else
 +              {
 +                delete [] (double *) sendbuf ;
 +              }
 +          }
 +      }
 +
 +    //CheckTime + DoRecv + DoInterp
 +    if ( recvbuf && recvcount )
 +      {
 +        for ( target = 0 ; target < _group_size ; target++ )
 +          {
 +            int recvsize = recvcount*_MPI_access->extent( recvtype ) ;
 +            checkTime( recvcount , recvtype , target , false ) ;
 +            //===========================================================================
++            //TODO : it is assumed actually that we have only 1 timestep before and after
 +            //===========================================================================
 +            if ( _time_interpolator && (*_time_messages)[target][0].time != -1 )
 +              {
 +                if ( (*_out_of_time)[target] )
 +                  {
 +                    cout << " =====================================================" << endl
 +                         << "Recv" << _my_rank << " <-- target " << target << " t0 "
 +                         << (*_time_messages)[target][0].time << " < t1 "
 +                         << (*_time_messages)[target][1].time << " < t* " << _t << endl
 +                         << " =====================================================" << endl ;
 +                  }
 +                if ( recvtype == MPI_INT )
 +                  {
 +                    _time_interpolator->doInterp( (*_time_messages)[target][0].time,
 +                                                  (*_time_messages)[target][1].time, _t, recvcount ,
 +                                                  _n_step_before, _n_step_after,
 +                                                  (int **) &(*_data_messages)[target][0],
 +                                                  (int **) &(*_data_messages)[target][1],
 +                                                  &((int *)recvbuf)[target*recvcount] ) ;
 +                  }
 +                else
 +                  {
 +                    _time_interpolator->doInterp( (*_time_messages)[target][0].time,
 +                                                  (*_time_messages)[target][1].time, _t, recvcount ,
 +                                                  _n_step_before, _n_step_after,
 +                                                  (double **) &(*_data_messages)[target][0],
 +                                                  (double **) &(*_data_messages)[target][1],
 +                                                  &((double *)recvbuf)[target*recvcount] ) ;
 +                  }
 +              }
 +            else
 +              {
 +                char * buffdest = (char *) recvbuf ;
 +                char * buffsrc = (char *) (*_data_messages)[target][1] ;
 +                memcpy( &buffdest[target*recvsize] , buffsrc , recvsize ) ;
 +              }
 +          }
 +      }
 +
 +    return sts ;
 +  }
 +
 +  int MPIAccessDEC::allToAllvTime( void* sendbuf, int* sendcounts, int* sdispls,
 +                                   MPI_Datatype sendtype ,
 +                                   void* recvbuf, int* recvcounts, int* rdispls,
 +                                   MPI_Datatype recvtype )
 +  {
 +    int sts ;
 +    int target ;
 +    int SendTimeRequestId ;
 +    int SendDataRequestId ;
 +
 +    if ( _time_interpolator == NULL )
 +      {
 +        return MPI_ERR_OTHER ;
 +      }
 +
 +    //Free of SendBuffers 
 +    if ( _asynchronous )
 +      {
 +        checkSent() ;
 +      }
 +
 +    /*
 +      . DoSend :
 +      + We create a TimeMessage (look at that structure in MPI_Access).
 +      + If we are in asynchronous mode, we create two structures SendBuffStruct
 +      aSendTimeStruct and aSendDataStruct that we fill.
 +      + We fill the structure aSendTimeMessage with time/deltatime of
 +      the current process. "deltatime" must be nul if it is the last step of
 +      Time.
 +      + After that for each "target", we Send the TimeMessage and the part
 +      of sendbuf corresponding to that target.
 +      + If we are in asynchronous mode, we increment the counter and we add
 +      aSendTimeStruct and aSendDataStruct to _MapOfSendBuffers with the
 +      identifiers SendTimeRequestId and SendDataRequestId returned by
 +      MPI_Access->Send(...).
 +      + And if we are in synchronous mode we delete the SendMessages.
 +    */
 +    //DoSend : Time + SendBuff
 +    SendBuffStruct * aSendTimeStruct = NULL ;
 +    SendBuffStruct * aSendDataStruct = NULL ;
 +    if ( sendbuf )
 +      {
 +        TimeMessage * aSendTimeMessage = new TimeMessage ;
 +        if ( _asynchronous )
 +          {
 +            aSendTimeStruct = new SendBuffStruct ;
 +            aSendTimeStruct->SendBuffer = aSendTimeMessage ;
 +            aSendTimeStruct->Counter = 0 ;
 +            aSendTimeStruct->DataType = _MPI_access->timeType() ;
 +            aSendDataStruct = new SendBuffStruct ;
 +            aSendDataStruct->SendBuffer = sendbuf ;
 +            aSendDataStruct->Counter = 0 ;
 +            aSendDataStruct->DataType = sendtype ;
 +          }
 +        aSendTimeMessage->time = _t ;
 +        aSendTimeMessage->deltatime = _dt ;
 +        for ( target = 0 ; target < _group_size ; target++ )
 +          {
 +            if ( sendcounts[target] )
 +              {
 +                sts = send( aSendTimeMessage , 1 , 0 , _MPI_access->timeType() , target ,
 +                            SendTimeRequestId ) ;
 +                sts = send( sendbuf , sendcounts[target] , sdispls[target] , sendtype , target ,
 +                            SendDataRequestId ) ;
 +                if ( _asynchronous )
 +                  {
 +                    aSendTimeStruct->Counter += 1 ;
 +                    (*_map_of_send_buffers)[ SendTimeRequestId ] = aSendTimeStruct ;
 +                    aSendDataStruct->Counter += 1 ;
 +                    (*_map_of_send_buffers)[ SendDataRequestId ] = aSendDataStruct ;
 +                  }
 +              }
 +          }
 +        if ( !_asynchronous )
 +          {
 +            delete aSendTimeMessage ;
 +            if ( sendtype == MPI_INT )
 +              {
 +                delete [] (int *) sendbuf ;
 +              }
 +            else
 +              {
 +                delete [] (double *) sendbuf ;
 +              }
 +          }
 +      }
 +
 +    /*
 +      . CheckTime + DoRecv + DoInterp
 +      + For each target we call CheckTime
 +      + If there is a TimeInterpolator and if the TimeMessage of the target
 +      is not the first, we call the interpolator which return its
 +      results in the part of the recv buffer corresponding to the "target".
 +      + If not, there is a copy of received datas for that first step of time
 +      in the part of the recv buffer corresponding to the "target".
 +    */
 +    //CheckTime + DoRecv + DoInterp
 +    if ( recvbuf )
 +      {
 +        for ( target = 0 ; target < _group_size ; target++ )
 +          {
 +            if ( recvcounts[target] )
 +              {
 +                int recvsize = recvcounts[target]*_MPI_access->extent( recvtype ) ;
 +                checkTime( recvcounts[target] , recvtype , target , false ) ;
 +                //===========================================================================
 +                //TODO : it is assumed actually that we have only 1 timestep before nad after
 +                //===========================================================================
 +                if ( _time_interpolator && (*_time_messages)[target][0].time != -1 )
 +                  {
 +                    if ( (*_out_of_time)[target] )
 +                      {
 +                        cout << " =====================================================" << endl
 +                             << "Recv" << _my_rank << " <-- target " << target << " t0 "
 +                             << (*_time_messages)[target][0].time << " < t1 "
 +                             << (*_time_messages)[target][1].time << " < t* " << _t << endl
 +                             << " =====================================================" << endl ;
 +                      }
 +                    if ( recvtype == MPI_INT )
 +                      {
 +                        _time_interpolator->doInterp( (*_time_messages)[target][0].time,
 +                                                      (*_time_messages)[target][1].time, _t,
 +                                                      recvcounts[target] , _n_step_before, _n_step_after,
 +                                                      (int **) &(*_data_messages)[target][0],
 +                                                      (int **) &(*_data_messages)[target][1],
 +                                                      &((int *)recvbuf)[rdispls[target]] ) ;
 +                      }
 +                    else
 +                      {
 +                        _time_interpolator->doInterp( (*_time_messages)[target][0].time,
 +                                                      (*_time_messages)[target][1].time, _t,
 +                                                      recvcounts[target] , _n_step_before, _n_step_after,
 +                                                      (double **) &(*_data_messages)[target][0],
 +                                                      (double **) &(*_data_messages)[target][1],
 +                                                      &((double *)recvbuf)[rdispls[target]] ) ;
 +                      }
 +                  }
 +                else
 +                  {
 +                    char * buffdest = (char *) recvbuf ;
 +                    char * buffsrc = (char *) (*_data_messages)[target][1] ;
 +                    memcpy( &buffdest[rdispls[target]*_MPI_access->extent( recvtype )] , buffsrc ,
 +                            recvsize ) ;
 +                  }
 +              }
 +          }
 +      }
 +
 +    return sts ;
 +  }
 +
 +  /*
 +    . CheckTime(recvcount , recvtype , target , UntilEnd)
 +    + At the beginning, we read the first TimeMessage in
 +    &(*_TimeMessages)[target][1] and the first DataMessage
 +    in the allocated buffer (*_DataMessages)[target][1].
 +    + deltatime of TimesMessages must be nul if it is the last one.
 +    + While : _t(t*) is the current time of the processus.
 +    "while _t(t*) is greater than the time of the "target"
 +    (*_TimeMessages)[target][1].time and
 +    (*_TimeMessages)[target][1].deltatime is not nul",
 +    So at the end of the while we have :
 +    _t(t*) <= (*_TimeMessages)[target][1].time with
 +    _t(t*) > (*_TimeMessages)[target][0].time
 +    or we have the last TimeMessage of the "target".
 +    + If it is the finalization of the recv of TimeMessages and
 +    DataMessages (UntilEnd value is true), we execute the while
 +    until (*_TimeMessages)[target][1].deltatime is nul.
 +    + In the while :
 +    We copy the last TimeMessage in the previoud TimeMessage and
 +    we read a new TimeMessage
 +    We delete the previous DataMessage.
 +    We copy the last DataMessage pointer in the previous one.
 +    We allocate a new last DataMessage buffer
 +    (*_DataMessages)[target][1] and we read the corresponding
 +    datas in that buffe.
 +    + If the current time of the current process is greater than the
 +    last time (*_TimeMessages)[target][1].time du target, we give
 +    a true value to (*_OutOfTime)[target].
 +    (*_TimeMessages)[target][1].deltatime is nul.
 +  */
 +  int MPIAccessDEC::checkTime( int recvcount , MPI_Datatype recvtype , int target ,
 +                               bool UntilEnd )
 +  {
 +    int sts = MPI_SUCCESS ;
 +    int RecvTimeRequestId ;
 +    int RecvDataRequestId ;
 +    //Pour l'instant on cherche _time_messages[target][0] < _t <= _time_messages[target][1]
 +    //===========================================================================
 +    //TODO : it is assumed actually that we have only 1 timestep before and after
 +    //       instead of _n_step_before and _n_step_after ...
 +    //===========================================================================
 +    (*_data_messages_recv_count)[target] = recvcount ;
 +    (*_data_messages_type)[target] = recvtype ;
 +    if ( (*_time_messages)[target][1].time == -1 )
 +      {
 +        (*_time_messages)[target][0] = (*_time_messages)[target][1] ;
 +        sts = recv( &(*_time_messages)[target][1] , 1 , _MPI_access->timeType() ,
 +                    target , RecvTimeRequestId ) ;
 +        (*_data_messages)[target][0] = (*_data_messages)[target][1] ;
 +        if ( recvtype == MPI_INT )
 +          {
 +            (*_data_messages)[target][1] = new int[recvcount] ;
 +          }
 +        else
 +          {
 +            (*_data_messages)[target][1] = new double[recvcount] ;
 +          }
 +        sts = recv( (*_data_messages)[target][1] , recvcount , recvtype , target ,
 +                    RecvDataRequestId ) ;
 +      }
 +    else
 +      {
 +        while ( ( _t > (*_time_messages)[target][1].time || UntilEnd ) &&
 +                (*_time_messages)[target][1].deltatime != 0 )
 +          {
 +            (*_time_messages)[target][0] = (*_time_messages)[target][1] ;
 +            sts = recv( &(*_time_messages)[target][1] , 1 , _MPI_access->timeType() ,
 +                        target , RecvTimeRequestId ) ;
 +            if ( UntilEnd )
 +              {
 +                cout << "CheckTime" << _my_rank << " TimeMessage target " << target
 +                     << " RecvTimeRequestId " << RecvTimeRequestId << " MPITag "
 +                     << _MPI_access->recvMPITag(target) << endl ;
 +              }
 +            if ( recvtype == MPI_INT )
 +              {
 +                delete [] (int *) (*_data_messages)[target][0] ;
 +              }
 +            else
 +              {
 +                delete [] (double *) (*_data_messages)[target][0] ;
 +              }
 +            (*_data_messages)[target][0] = (*_data_messages)[target][1] ;
 +            if ( recvtype == MPI_INT )
 +              {
 +                (*_data_messages)[target][1] = new int[recvcount] ;
 +              }
 +            else
 +              {
 +                (*_data_messages)[target][1] = new double[recvcount] ;
 +              }
 +            sts = recv( (*_data_messages)[target][1] , recvcount , recvtype , target ,
 +                        RecvDataRequestId ) ;
 +            if ( UntilEnd )
 +              {
 +                cout << "CheckTime" << _my_rank << " DataMessage target " << target
 +                     << " RecvDataRequestId " << RecvDataRequestId << " MPITag "
 +                     << _MPI_access->recvMPITag(target) << endl ;
 +              }
 +          }
 +
 +        if ( _t > (*_time_messages)[target][0].time &&
 +             _t <= (*_time_messages)[target][1].time )
 +          {
 +          }
 +        else
 +          {
 +            (*_out_of_time)[target] = true ;
 +          }
 +      }
 +    return sts ;
 +  }
 +
 +  /*
 +    . CheckSent() :
 +    + call  SendRequestIds of MPI_Access in order to get all
 +    RequestIds of SendMessages of all "targets".
 +    + For each RequestId, CheckSent call "Test" of MPI_Access in order
 +    to know if the buffer is "free" (flag = true). If it is the
 +    FinalCheckSent (WithWait = true), we call Wait instead of Test.
 +    + If the buffer is "free", the counter of the structure SendBuffStruct
 +    (from _MapOfSendBuffers) is decremented.
 +    + If that counter is nul we delete the TimeMessage or the
 +    SendBuffer according to the DataType.
 +    + And we delete the structure SendBuffStruct before the suppression
 +    (erase) of that item of _MapOfSendBuffers
 +  */
 +  int MPIAccessDEC::checkSent(bool WithWait)
 +  {
 +    int sts = MPI_SUCCESS ;
 +    int flag = WithWait ;
 +    int size = _MPI_access->sendRequestIdsSize() ;
 +    int * ArrayOfSendRequests = new int[ size ] ;
 +    int nSendRequest = _MPI_access->sendRequestIds( size , ArrayOfSendRequests ) ;
 +    bool SendTrace = false ;
 +    int i ;
 +    for ( i = 0 ; i < nSendRequest ; i++ )
 +      {
 +        if ( WithWait )
 +          {
 +            if (SendTrace)
 +              {
 +                cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest
 +                    << " SendRequestId " << ArrayOfSendRequests[i] << " MPITarget "
 +                    << _MPI_access->MPITarget(ArrayOfSendRequests[i]) << " MPITag "
 +                    << _MPI_access->MPITag(ArrayOfSendRequests[i]) << " Wait :" << endl ;
 +              }
 +            sts = _MPI_access->wait( ArrayOfSendRequests[i] ) ;
 +          }
 +        else
 +          {
 +            sts = _MPI_access->test( ArrayOfSendRequests[i] , flag ) ;
 +          }
 +        if ( flag )
 +          {
 +            _MPI_access->deleteRequest( ArrayOfSendRequests[i] ) ;
 +            if ( SendTrace )
 +              {
 +                cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest
 +                     << " SendRequestId " << ArrayOfSendRequests[i]
 +                     << " flag " << flag
 +                     << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter
 +                     << " DataType " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType
 +                     << endl ;
 +              }
 +            (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter -= 1 ;
 +            if ( SendTrace )
 +              {
 +                if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == 
 +                     _MPI_access->timeType() )
 +                  {
 +                    cout << "CheckTimeSent" << _my_rank << " Request " ;
 +                  }
 +                else
 +                  {
 +                    cout << "CheckDataSent" << _my_rank << " Request " ;
 +                  }
 +                cout << ArrayOfSendRequests[i]
 +                     << " _map_of_send_buffers->SendBuffer "
 +                     << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer
 +                     << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter
 +                     << endl ;
 +              }
 +            if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter  == 0 )
 +              {
 +                if ( SendTrace )
 +                  {
 +                    cout << "CheckSent" << _my_rank << " SendRequestId " << ArrayOfSendRequests[i]
 +                         << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter
 +                         << " flag " << flag << " SendBuffer "
 +                         << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer
 +                         << " deleted. Erase in _map_of_send_buffers :" << endl ;
 +                  }
 +                if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType ==
 +                     _MPI_access->timeType() )
 +                  {
 +                    delete (TimeMessage * ) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ;
 +                  }
 +                else
 +                  {
 +                    if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == MPI_INT )
 +                      {
 +                        delete [] (int *) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ;
 +                      }
 +                    else
 +                      {
 +                        delete [] (double *) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ;
 +                      }
 +                  }
 +                delete (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ] ;
 +              }
 +            if ( SendTrace )
 +              {
 +                cout << "CheckSent" << _my_rank << " Erase in _map_of_send_buffers SendRequestId "
 +                     << ArrayOfSendRequests[i] << endl ;
 +              }
 +            (*_map_of_send_buffers).erase( ArrayOfSendRequests[i] ) ;
 +          }
 +        else if ( SendTrace )
 +          {
 +            cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest
 +                 << " SendRequestId " << ArrayOfSendRequests[i]
 +                 << " flag " << flag
 +                 << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter
 +                 << " DataType " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType
 +                 << endl ;
 +          }
 +      }
 +    if ( SendTrace )
 +      {
 +        _MPI_access->check() ;
 +      }
 +    delete [] ArrayOfSendRequests ;
 +    return sts ;
 +  }
 +
 +  int MPIAccessDEC::checkFinalRecv()
 +  {
 +    int sts = MPI_SUCCESS ;
 +    if ( _time_interpolator )
 +      {
 +        int target ;
 +        for ( target = 0 ; target < _group_size ; target++ )
 +          {
 +            if ( (*_data_messages)[target][0] != NULL )
 +              {
 +                sts = checkTime( (*_data_messages_recv_count)[target] , (*_data_messages_type)[target] ,
 +                                 target , true ) ;
 +                if ( (*_data_messages_type)[target] == MPI_INT )
 +                  {
 +                    delete [] (int *) (*_data_messages)[target][0] ;
 +                  }
 +                else
 +                  {
 +                    delete [] (double *) (*_data_messages)[target][0] ;
 +                  }
 +                (*_data_messages)[target][0] = NULL ;
 +                if ( (*_data_messages)[target][1] != NULL )
 +                  {
 +                    if ( (*_data_messages_type)[target] == MPI_INT )
 +                      {
 +                        delete [] (int *) (*_data_messages)[target][1] ;
 +                      }
 +                    else
 +                      {
 +                        delete [] (double *) (*_data_messages)[target][1] ;
 +                      }
 +                    (*_data_messages)[target][1] = NULL ;
 +                  }
 +              }
 +          }
 +      }
 +    return sts ;
 +  }
 +
 +  ostream & operator<< (ostream & f ,const TimeInterpolationMethod & interpolationmethod )
 +  {
 +    switch (interpolationmethod)
 +      {
 +      case WithoutTimeInterp :
 +        f << " WithoutTimeInterpolation ";
 +        break;
 +      case LinearTimeInterp :
 +        f << " LinearTimeInterpolation ";
 +        break;
 +      default :
 +        f << " UnknownTimeInterpolation ";
 +        break;
 +      }
 +
 +    return f;
 +  }
 +}
index e381ff61a24e06ccbb79925cbb71588f43b492b0,0000000000000000000000000000000000000000..aba86958f56b8290aa746cf8a87a9dddaeb1682d
mode 100644,000000..100644
--- /dev/null
@@@ -1,179 -1,0 +1,184 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __MPIACCESSDEC_HXX__
 +#define __MPIACCESSDEC_HXX__
 +
 +#include "MPIAccess.hxx"
 +#include "DEC.hxx"
 +#include "LinearTimeInterpolator.hxx"
 +
 +#include <map>
 +#include <iostream>
 +
 +namespace ParaMEDMEM
 +{
++  /*
++   * Internal class, not part of the public API.
++   *
++   * Another gateway to the MPI library?
++   */
 +  class MPIAccessDEC
 +  {
 +  public:  
 +    MPIAccessDEC( const ProcessorGroup& local_group, const ProcessorGroup& distant_group,
 +                  bool Asynchronous = true );
 +    virtual ~MPIAccessDEC();
 +    MPIAccess * getMPIAccess() { return _MPI_access; }
 +    const MPI_Comm* getComm() { return _MPI_union_group->getComm(); }
 +    void asynchronous( bool Asynchronous = true ) { _asynchronous = Asynchronous; }
 +    void setTimeInterpolator( TimeInterpolationMethod anInterp , double InterpPrecision=0 ,
 +                              int n_step_before=1, int nStepAfter=1 );
 +
 +    void setTime( double t ) { _t = t; _dt = -1; }
 +    void setTime( double t , double dt ) { _t = t; _dt = dt; }
 +    bool outOfTime( int target ) { return (*_out_of_time)[target]; }
 +
 +    int send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target );
 +    int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target );
 +    int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ,
 +              int &RecvRequestId , bool Asynchronous=false );
 +    int sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype ,
 +                  void* recvbuf, int recvcount , MPI_Datatype recvtype , int target );
 +
 +    int allToAll( void* sendbuf, int sendcount, MPI_Datatype sendtype ,
 +                  void* recvbuf, int recvcount, MPI_Datatype recvtype );
 +    int allToAllv( void* sendbuf, int* sendcounts, int* sdispls, MPI_Datatype sendtype ,
 +                   void* recvbuf, int* recvcounts, int* rdispls, MPI_Datatype recvtype );
 +
 +    int allToAllTime( void* sendbuf, int sendcount , MPI_Datatype sendtype ,
 +                      void* recvbuf, int recvcount , MPI_Datatype recvtype );
 +    int allToAllvTime( void* sendbuf, int* sendcounts, int* sdispls,
 +                       MPI_Datatype sendtype ,
 +                       void* recvbuf, int* recvcounts, int* rdispls,
 +                       MPI_Datatype recvtype );
 +    int checkTime( int recvcount , MPI_Datatype recvtype , int target , bool UntilEnd );
 +    int checkSent(bool WithWait=false);
 +    int checkFinalSent() { return checkSent( true ); }
 +    int checkFinalRecv();
 +  protected:
 +    int send( void* sendbuf, int sendcount , int sendoffset , MPI_Datatype sendtype ,
 +              int target, int &SendRequestId );
 +    int recv( void* recvbuf, int recvcount , int recvoffset , MPI_Datatype recvtype ,
 +              int target, int &RecvRequestId );
 +    int sendRecv( void* sendbuf, int sendcount , int sendoffset ,
 +                  MPI_Datatype sendtype , 
 +                  void* recvbuf, int recvcount , int recvoffset ,
 +                  MPI_Datatype recvtype , int target ,
 +                  int &SendRequestId ,int &RecvRequestId );
 +  private :
 +    bool _asynchronous;
 +    MPIProcessorGroup* _MPI_union_group;
 +
 +    TimeInterpolator* _time_interpolator;
 +    int _n_step_before;
 +    int _n_step_after;
 +
 +    int _my_rank;
 +    int _group_size;
 +    MPIAccess* _MPI_access;
 +
 +    // Current time and deltatime of current process
 +    double _t;
 +    double _dt;
 +
 +    // TimeMessages from each target _TimeMessages[target][Step] : TimeMessage
 +    std::vector< std::vector< TimeMessage > > *_time_messages;
 +    // Corresponding DataMessages from each target _DataMessages[target][~TimeStep]
 +    std::vector< bool >* _out_of_time;
 +    std::vector< int >* _data_messages_recv_count;
 +    std::vector< MPI_Datatype >* _data_messages_type;
 +    std::vector< std::vector< void * > >* _data_messages;
 +
 +    typedef struct
 +    {
 +      void * SendBuffer;
 +      int Counter;
 +      MPI_Datatype DataType; }
 +      SendBuffStruct;
 +    std::map< int ,  SendBuffStruct * > *_map_of_send_buffers;
 +  };
 +
 +  inline int MPIAccessDEC::send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target )
 +  {
 +    int SendRequestId;
 +    int sts;
 +    if ( _asynchronous )
 +      {
 +        sts = _MPI_access->ISend( sendbuf , sendcount , sendtype , target ,
 +                                  SendRequestId );
 +      }
 +    else
 +      {
 +        sts = _MPI_access->send( sendbuf , sendcount , sendtype , target ,
 +                                 SendRequestId );
 +        if ( sts == MPI_SUCCESS )
 +          free( sendbuf );
 +      }
 +    return sts;
 +  }
 +
 +  inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target )
 +  {
 +    int RecvRequestId;
 +    int sts;
 +    if ( _asynchronous )
 +      sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target , RecvRequestId );
 +    else
 +      sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target ,  RecvRequestId );
 +    return sts;
 +  }
 +
 +  inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype ,
 +                                 int target ,  int &RecvRequestId , bool Asynchronous )
 +  {
 +    int sts;
 +    if ( Asynchronous )
 +      sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target ,
 +                                RecvRequestId );
 +    else
 +      sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target ,
 +                               RecvRequestId );
 +    return sts;
 +  }
 +  
 +  inline int MPIAccessDEC::sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype ,
 +                                     void* recvbuf, int recvcount , MPI_Datatype recvtype ,
 +                                     int target )
 +  {
 +    int SendRequestId;
 +    int RecvRequestId;
 +    int sts;
 +    if ( _asynchronous )
 +      sts = _MPI_access->ISendRecv( sendbuf , sendcount , sendtype , target ,
 +                                    SendRequestId ,
 +                                    recvbuf , recvcount , recvtype , target ,
 +                                    RecvRequestId );
 +    else
 +      sts = _MPI_access->sendRecv( sendbuf , sendcount , sendtype , target ,
 +                                   SendRequestId ,
 +                                   recvbuf , recvcount , recvtype , target ,
 +                                   RecvRequestId );
 +    return sts;
 +  }
 +
 +  std::ostream & operator<< (std::ostream &,const TimeInterpolationMethod &);
 +}
 +
 +#endif
index 922f209201bc8f05b9c44960d1cd306bf8e7ca8e,0000000000000000000000000000000000000000..3bf01b69d864b6197cbc5a2c003be28bee1e1403
mode 100644,000000..100644
--- /dev/null
@@@ -1,254 -1,0 +1,257 @@@
-    * \anchor MPIProcessorGroup-det
-    * \class MPIProcessorGroup
-    *
-    * \section processor_group_overview Overview
-    * The MPIProcessorGroup class is used to set up processor groups that help to define
-    * the MPI topology of the couplings. They can be set up in various ways, the most common being
-    * the use of the \c MPIProcessorGroup(Comminterface, int pfirst, int plast)
-    * constructor.
-    *
-    * The following code excerpt creates two processor groups on respectively 3 and 2 processors.
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "ProcessorGroup.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "CommInterface.hxx"
 +#include "InterpolationUtils.hxx"
 +
 +#include <iostream>
 +#include <set>
 +#include <algorithm>
 +#include "mpi.h"
 +
 +using namespace std;
 +
 +
 +namespace ParaMEDMEM
 +{
 +  /*!
-    MPI_COMM_WORLD processor.This routine must be called by all processors in MPI_COMM_WORLD.
++   \anchor MPIProcessorGroup-det
++   \class MPIProcessorGroup
++
++   The MPIProcessorGroup class represents a set of distinct "processors" (computation nodes)
++   in a MPI code. It is used to define the MPI topology of code couplings.
++
++   Groups can be set up in various ways, the most common being
++   the use of the \c MPIProcessorGroup(Comminterface, int pfirst, int plast)
++   constructor.
++
++   The following code excerpt creates two processor groups on respectively 3 and 2 processors.
 +   \verbatim
 +   int main()
 +   {
 +   MPI_Init(&argc,&argv);
 +   CommInterface comm_interface;
 +   MPIProcessorGroup codeA_group(comm_interface, 0, 2);  // groups processors 0, 1 and 2
 +   MPIProcessorGroup codeB_group(comm_interface, 3, 4);  // groups processors 3 and 4
 +
 +   ...
 +   }
 +   \endverbatim
 +  */
 +
 +
 +  /*! 
 +   * Creates a processor group that is based on all the
-     ProcessorGroup(proc_group.getCommInterface()),_world_comm(MPI_COMM_WORLD)
++   processors of MPI_COMM_WORLD .This routine must be called by all processors in MPI_COMM_WORLD.
 +   \param interface CommInterface object giving access to the MPI
 +   communication layer
 +  */
 +  MPIProcessorGroup::MPIProcessorGroup(const CommInterface& interface):
 +    ProcessorGroup(interface),_world_comm(MPI_COMM_WORLD)
 +  {
 +    _comm=_world_comm;
 +    _comm_interface.commGroup(_world_comm, &_group);
 +    int size;
 +    _comm_interface.commSize(_world_comm,&size);
 +    for (int i=0; i<size; i++)
 +      _proc_ids.insert(i);
 +
 +  }
 +
 +  /*! Creates a processor group that is based on the processors included in \a proc_ids.
 +    This routine must be called by all processors in MPI_COMM_WORLD.
 +
 +    \param interface CommInterface object giving access to the MPI
 +    communication layer
 +    \param proc_ids set of ids that are to be integrated in the group. The ids number are 
 +    to be understood in terms of MPI_COMM_WORLD ranks.
 +  */
 +
 +  MPIProcessorGroup::MPIProcessorGroup(const CommInterface& interface, set<int> proc_ids, const MPI_Comm& world_comm):
 +    ProcessorGroup(interface, proc_ids), _world_comm(world_comm)
 +  {
 +    updateMPISpecificAttributes();
 +  }
 +
 +
 +  void MPIProcessorGroup::updateMPISpecificAttributes()
 +  {
 +    //Creation of a communicator 
 +    MPI_Group group_world;
 +  
 +    int size_world;
 +    _comm_interface.commSize(_world_comm,&size_world);
 +    int rank_world;
 +    _comm_interface.commRank(_world_comm,&rank_world);
 +    _comm_interface.commGroup(_world_comm, &group_world);
 +
 +    int* ranks=new int[_proc_ids.size()];
 +   
 +    // copying proc_ids in ranks
 +    copy<set<int>::const_iterator,int*> (_proc_ids.begin(), _proc_ids.end(), ranks);
 +    for (int i=0; i< (int)_proc_ids.size();i++)
 +      if (ranks[i]>size_world-1)
 +        {
 +          delete[] ranks;
 +          _comm_interface.groupFree(&group_world);  // MPI_Group is a C structure and won't get de-allocated automatically?
 +          throw INTERP_KERNEL::Exception("invalid rank in set<int> argument of MPIProcessorGroup constructor");
 +        }
 +      
 +    _comm_interface.groupIncl(group_world, _proc_ids.size(), ranks, &_group);
 +  
 +    _comm_interface.commCreate(_world_comm, _group, &_comm);
 +
 +    // clean-up
 +    delete[] ranks;
 +    _comm_interface.groupFree(&group_world);  // MPI_Group is a C structure and won't get de-allocated automatically?
 +  }
 +
 +  /*! Creates a processor group that is based on the processors between \a pstart and \a pend.
 +    This routine must be called by all processors in MPI_COMM_WORLD.
 +
 +    \param comm_interface CommInterface object giving access to the MPI
 +    communication layer
 +    \param pstart id in MPI_COMM_WORLD of the first processor in the group
 +    \param pend id in MPI_COMM_WORLD of the last processor in the group
 +  */
 +  MPIProcessorGroup::MPIProcessorGroup (const CommInterface& comm_interface, int pstart, int pend, const MPI_Comm& world_comm): ProcessorGroup(comm_interface,pstart,pend),_world_comm(world_comm)
 +  {
 +    //Creation of a communicator 
 +    MPI_Group group_world;
 +  
 +    int size_world;
 +    _comm_interface.commSize(_world_comm,&size_world);
 +    int rank_world;
 +    _comm_interface.commRank(_world_comm,&rank_world);
 +    _comm_interface.commGroup(_world_comm, &group_world);
 +
 +    if (pend>size_world-1 || pend <pstart || pstart<0)
 +      {
 +        _comm_interface.groupFree(&group_world);
 +        throw INTERP_KERNEL::Exception("invalid argument in MPIProcessorGroup constructor (comm,pfirst,plast)");
 +      }
 +    int nprocs=pend-pstart+1;
 +    int* ranks=new int[nprocs];
 +    for (int i=pstart; i<=pend;i++)
 +      {
 +        ranks[i-pstart]=i;
 +      }
 +
 +    _comm_interface.groupIncl(group_world, nprocs, ranks, &_group);
 +  
 +    _comm_interface.commCreate(_world_comm, _group, &_comm);
 +
 +    // clean-up
 +    delete[] ranks;
 +    _comm_interface.groupFree(&group_world);  // MPI_Group is a C structured and won't get de-allocated automatically?
 +  }
 +
 +  MPIProcessorGroup::MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids) :
-   MPIProcessorGroup::MPIProcessorGroup(const MPIProcessorGroup& other):ProcessorGroup(other),_world_comm(other._world_comm)
++    ProcessorGroup(proc_group.getCommInterface()),
++    _world_comm(MPI_COMM_WORLD), _group(MPI_GROUP_NULL), _comm(MPI_COMM_NULL)
 +  {
 +    cout << "MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids)" <<endl;
 +    cout << "Not implemented yet !"<<endl;
 +    exit(1);
 +  }
 +
++  MPIProcessorGroup::MPIProcessorGroup(const MPIProcessorGroup& other):
++      ProcessorGroup(other),_world_comm(other._world_comm)
 +  {
 +    updateMPISpecificAttributes();
 +  }
 +
 +  MPIProcessorGroup::~MPIProcessorGroup()
 +  {
 +    _comm_interface.groupFree(&_group);
 +    if (_comm!=_world_comm && _comm !=MPI_COMM_NULL)
 +      _comm_interface.commFree(&_comm);
 +  
 +  }
 +
 +  /*! Translation of the rank id between two processor groups. This method translates rank \a rank
 +    on the current processor group to the rank on group pointed by \a group.
 +    \param group group from which the rank is expected
 +    \param rank rank on group \a group of the processor which is to be translated
 +    \return rank on local group
 +  */
 +  int MPIProcessorGroup::translateRank(const ProcessorGroup* group, int rank) const
 +  {
 +    const MPIProcessorGroup* targetgroup=dynamic_cast<const MPIProcessorGroup*>(group);
 +    int local_rank;
 +    MPI_Group_translate_ranks(targetgroup->_group, 1, &rank, _group, &local_rank);
 +    return local_rank;
 +  }
 +  
 +  /*!Creates a processor group that is the complement of the current group 
 +    inside MPI_COMM_WORLD
 +    \return pointer to the new ProcessorGroup structure.
 +  */
 +  ProcessorGroup* MPIProcessorGroup::createComplementProcGroup() const
 +  {
 +    set <int> procs;
 +    int world_size=_comm_interface.worldSize();
 +    for (int i=0; i<world_size; i++)
 +      procs.insert(i);
 +    for (set<int>::const_iterator iter=_proc_ids.begin(); iter!= _proc_ids.end(); iter++)
 +      procs.erase(*iter);
 +    
 +    return new MPIProcessorGroup(_comm_interface, procs, _world_comm);
 +    
 +  }
 +
 +  ProcessorGroup *MPIProcessorGroup::deepCpy() const
 +  {
 +    return new MPIProcessorGroup(*this);
 +  }
 +
 +  /*!Adding processors of group \a group to local group.
 +    \param group group that is to be fused with current group
 +    \return new group formed by the fusion of local group and \a group.
 +  */
 +  ProcessorGroup*  MPIProcessorGroup::fuse (const ProcessorGroup& group) const
 +  {
 +    set <int> procs = _proc_ids;
 +    const set<int>& distant_proc_ids = group.getProcIDs();
 +    for (set<int>::const_iterator iter=distant_proc_ids.begin(); iter!=distant_proc_ids.end(); iter++)
 +      {
 +        procs.insert(*iter);
 +      }
 +    return new MPIProcessorGroup(_comm_interface, procs, _world_comm);
 +  }
 +
 +  int MPIProcessorGroup::myRank() const
 +  { 
 +    int rank;
 +    MPI_Comm_rank(_comm,&rank);
 +    return rank;
 +  }
 +  
 +  ProcessorGroup* MPIProcessorGroup::createProcGroup() const
 +  {
 +    set <int> procs;
 +    for (set<int>::const_iterator iter=_proc_ids.begin(); iter!= _proc_ids.end(); iter++)
 +      procs.insert(*iter);
 +  
 +    return new MPIProcessorGroup(_comm_interface, procs, _world_comm);
 +
 +  }
 +}
index 05ca0990e9f465a757705bc4a9586b95e21888bd,0000000000000000000000000000000000000000..a6a0bcba30ad9e5227545f23670d9ceafbd4b2c2
mode 100644,000000..100644
--- /dev/null
@@@ -1,317 -1,0 +1,315 @@@
-   MxN_Mapping::MxN_Mapping()
-   {
-   }
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "CommInterface.hxx" 
 +#include "ProcessorGroup.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "MPIAccessDEC.hxx"
 +#include "MxN_Mapping.hxx"
 +
 +using namespace std;
 +
 +namespace ParaMEDMEM
 +{
-     : DECOptions(dec_options),_union_group(source_group.fuse(target_group))
 +
 +  MxN_Mapping::MxN_Mapping(const ProcessorGroup& source_group, const ProcessorGroup& target_group,const DECOptions& dec_options)
++    : DECOptions(dec_options),
++      _union_group(source_group.fuse(target_group)),
++      _nb_comps(0), _sending_ids(), _recv_ids()
 +  {
 +    _access_DEC = new MPIAccessDEC(source_group,target_group,getAsynchronous());
 +    _access_DEC->setTimeInterpolator(getTimeInterpolationMethod());
 +    _send_proc_offsets.resize(_union_group->size()+1,0);
 +    _recv_proc_offsets.resize(_union_group->size()+1,0);
 +  
 +  }
 +
 +  MxN_Mapping::~MxN_Mapping()
 +  {
 +    delete _union_group;
 +    delete _access_DEC;
 +  }
 +
 +
 +  /*!
 +    Method registering a new element for correspondence with a distant element
 +    \param distant_proc proc rank of the distant processor (in terms of the union group)
 +    \param distant_element id of the element on the distant processor
 +  */
 +  void MxN_Mapping::addElementFromSource(int distant_proc, int distant_element)
 +  {
 +    _sending_ids.push_back(make_pair(distant_proc,distant_element));
 +    for (int i=distant_proc; i<_union_group->size(); i++)
 +      _send_proc_offsets[i+1]++;
 +  }
 +
 +  void MxN_Mapping::initialize()
 +  {
 +    _sending_ids.clear();
 +    std::fill(_send_proc_offsets.begin(),_send_proc_offsets.end(),0);
 +  }
 +
 +  void MxN_Mapping::prepareSendRecv()
 +  {
 +    CommInterface comm_interface=_union_group->getCommInterface();
 +    // sending count pattern
 +    int* nbsend=new int[_union_group->size()];
 +    int* nbrecv=new int[_union_group->size()];
 +    for (int i=0; i<_union_group->size(); i++)
 +      {
 +        nbsend[i]=_send_proc_offsets[i+1]-_send_proc_offsets[i];
 +      }
 +  
 +    MPIProcessorGroup* group = static_cast<MPIProcessorGroup*>(_union_group);
 +    const MPI_Comm* comm=group->getComm();
 +    comm_interface.allToAll(nbsend, 1, MPI_INT,
 +                            nbrecv, 1, MPI_INT,
 +                            *comm);
 +         
 +    for (int i=0; i<_union_group->size(); i++)
 +      {
 +        for (int j=i+1;j<_union_group->size()+1; j++)
 +          _recv_proc_offsets[j]+=nbrecv[i];
 +    
 +      } 
 +
 +    delete[] nbsend;
 +    delete[] nbrecv;
 +
 +    _recv_ids.resize(_recv_proc_offsets[_union_group->size()]);
 +    int* isendbuf=0;
 +    int* irecvbuf=0;
 +    if (_sending_ids.size()>0)
 +      isendbuf = new int[_sending_ids.size()];
 +    if (_recv_ids.size()>0)  
 +      irecvbuf = new int[_recv_ids.size()];
 +    int* sendcounts = new int[_union_group->size()];
 +    int* senddispls=new int[_union_group->size()];
 +    int* recvcounts=new int[_union_group->size()];
 +    int* recvdispls=new int[_union_group->size()];
 +    for (int i=0; i< _union_group->size(); i++)
 +      {
 +        sendcounts[i]=_send_proc_offsets[i+1]-_send_proc_offsets[i];
 +        senddispls[i]=_send_proc_offsets[i];
 +        recvcounts[i]=_recv_proc_offsets[i+1]-_recv_proc_offsets[i];
 +        recvdispls[i]=_recv_proc_offsets[i];
 +      }
 +    vector<int> offsets = _send_proc_offsets;
 +    for (int i=0; i<(int)_sending_ids.size();i++)
 +      {
 +        int iproc = _sending_ids[i].first;
 +        isendbuf[offsets[iproc]]=_sending_ids[i].second;
 +        offsets[iproc]++;
 +      }
 +    comm_interface.allToAllV(isendbuf, sendcounts, senddispls, MPI_INT,
 +                             irecvbuf, recvcounts, recvdispls, MPI_INT,
 +                             *comm);
 +                           
 +    for (int i=0; i< _recv_proc_offsets[_union_group->size()]; i++)
 +      _recv_ids[i]=irecvbuf[i];                           
 + 
 +    if (_sending_ids.size()>0)
 +      delete[] isendbuf;
 +    if (_recv_ids.size()>0)  
 +      delete[] irecvbuf;
 +    delete[] sendcounts;
 +    delete[]recvcounts;
 +    delete[]senddispls;
 +    delete[] recvdispls;
 +  }
 +
 +  /*! Exchanging field data between two groups of processes
 +   * 
 +   * \param field MEDCoupling field containing the values to be sent
 +   * 
 +   * The ids that were defined by addElementFromSource method
 +   * are sent.
 +   */ 
 +  void MxN_Mapping::sendRecv(double* sendfield, MEDCouplingFieldDouble& field) const 
 +  {
 +    CommInterface comm_interface=_union_group->getCommInterface();
 +    const MPIProcessorGroup* group = static_cast<const MPIProcessorGroup*>(_union_group);
 + 
 +    int nbcomp=field.getArray()->getNumberOfComponents();
 +    double* sendbuf=0;
 +    double* recvbuf=0;
 +    if (_sending_ids.size() >0)
 +      sendbuf = new double[_sending_ids.size()*nbcomp];
 +    if (_recv_ids.size()>0)
 +      recvbuf = new double[_recv_ids.size()*nbcomp];
 +    
 +    int* sendcounts = new int[_union_group->size()];
 +    int* senddispls=new int[_union_group->size()];
 +    int* recvcounts=new int[_union_group->size()];
 +    int* recvdispls=new int[_union_group->size()];
 +  
 +    for (int i=0; i< _union_group->size(); i++)
 +      {
 +        sendcounts[i]=nbcomp*(_send_proc_offsets[i+1]-_send_proc_offsets[i]);
 +        senddispls[i]=nbcomp*(_send_proc_offsets[i]);
 +        recvcounts[i]=nbcomp*(_recv_proc_offsets[i+1]-_recv_proc_offsets[i]);
 +        recvdispls[i]=nbcomp*(_recv_proc_offsets[i]);
 +      }
 +    //building the buffer of the elements to be sent
 +    vector<int> offsets = _send_proc_offsets;
 +
 +    for (int i=0; i<(int)_sending_ids.size();i++)
 +      { 
 +        int iproc = _sending_ids[i].first;
 +        for (int icomp=0; icomp<nbcomp; icomp++)
 +          sendbuf[offsets[iproc]*nbcomp+icomp]=sendfield[i*nbcomp+icomp];
 +        offsets[iproc]++;
 +      }
 +  
 +    //communication phase
 +    switch (getAllToAllMethod())
 +      {
 +      case Native:
 +        {
 +          const MPI_Comm* comm = group->getComm();
 +          comm_interface.allToAllV(sendbuf, sendcounts, senddispls, MPI_DOUBLE,
 +                                   recvbuf, recvcounts, recvdispls, MPI_DOUBLE,
 +                                   *comm);
 +        }
 +        break;
 +      case PointToPoint:
 +        _access_DEC->allToAllv(sendbuf, sendcounts, senddispls, MPI_DOUBLE,
 +                              recvbuf, recvcounts, recvdispls, MPI_DOUBLE);
 +        break;
 +      }
 +  
 +    //setting the received values in the field
 +    DataArrayDouble *fieldArr=field.getArray();
 +    double* recvptr=recvbuf;                         
 +    for (int i=0; i< _recv_proc_offsets[_union_group->size()]; i++)
 +      {
 +        for (int icomp=0; icomp<nbcomp; icomp++)
 +          {
 +            double temp = fieldArr->getIJ(_recv_ids[i],icomp);
 +            fieldArr->setIJ(_recv_ids[i],icomp,temp+*recvptr);
 +            recvptr++;
 +          }
 +      }   
 +    if (sendbuf!=0 && getAllToAllMethod()== Native)
 +      delete[] sendbuf;
 +    if (recvbuf !=0)
 +      delete[] recvbuf;
 +    delete[] sendcounts;
 +    delete[] recvcounts;
 +    delete[] senddispls; 
 +    delete[] recvdispls;
 +  
 +  }
 +
 +  /*! Exchanging field data between two groups of processes
 +   * 
 +   * \param field MEDCoupling field containing the values to be sent
 +   * 
 +   * The ids that were defined by addElementFromSource method
 +   * are sent.
 +   */ 
 +  void MxN_Mapping::reverseSendRecv(double* recvfield, MEDCouplingFieldDouble& field) const 
 +  {
 +    CommInterface comm_interface=_union_group->getCommInterface();
 +    const MPIProcessorGroup* group = static_cast<const MPIProcessorGroup*>(_union_group);
 +
 +    int nbcomp=field.getArray()->getNumberOfComponents();
 +    double* sendbuf=0;
 +    double* recvbuf=0;
 +    if (_recv_ids.size() >0)
 +      sendbuf = new double[_recv_ids.size()*nbcomp];
 +    if (_sending_ids.size()>0)
 +      recvbuf = new double[_sending_ids.size()*nbcomp];
 +
 +    int* sendcounts = new int[_union_group->size()];
 +    int* senddispls=new int[_union_group->size()];
 +    int* recvcounts=new int[_union_group->size()];
 +    int* recvdispls=new int[_union_group->size()];
 +
 +    for (int i=0; i< _union_group->size(); i++)
 +      {
 +        sendcounts[i]=nbcomp*(_recv_proc_offsets[i+1]-_recv_proc_offsets[i]);
 +        senddispls[i]=nbcomp*(_recv_proc_offsets[i]);
 +        recvcounts[i]=nbcomp*(_send_proc_offsets[i+1]-_send_proc_offsets[i]);
 +        recvdispls[i]=nbcomp*(_send_proc_offsets[i]);
 +      }
 +    //building the buffer of the elements to be sent
 +    vector<int> offsets = _recv_proc_offsets;
 +    DataArrayDouble *fieldArr=field.getArray();
 +    for (int iproc=0; iproc<_union_group->size();iproc++)
 +      for (int i=_recv_proc_offsets[iproc]; i<_recv_proc_offsets[iproc+1]; i++)
 +        {
 +          for (int icomp=0; icomp<nbcomp; icomp++)
 +            sendbuf[i*nbcomp+icomp]=fieldArr->getIJ(_recv_ids[i],icomp);
 +        }
 +
 +    //communication phase
 +    switch (getAllToAllMethod())
 +      {
 +      case Native:
 +        {
 +          const MPI_Comm* comm = group->getComm();
 +          comm_interface.allToAllV(sendbuf, sendcounts, senddispls, MPI_DOUBLE,
 +                                   recvbuf, recvcounts, recvdispls, MPI_DOUBLE,
 +                                   *comm);
 +        }
 +        break;
 +      case PointToPoint:
 +        _access_DEC->allToAllv(sendbuf, sendcounts, senddispls, MPI_DOUBLE,
 +                               recvbuf, recvcounts, recvdispls, MPI_DOUBLE);
 +        break;
 +      }
 +
 +    //setting the received values in the field
 +    double* recvptr=recvbuf;                         
 +    for (int i=0; i< _send_proc_offsets[_union_group->size()]; i++)
 +      {
 +        for (int icomp=0; icomp<nbcomp; icomp++)
 +          {
 +            recvfield[i*nbcomp+icomp]=*recvptr;
 +            recvptr++;
 +          }
 +      }
 +    if (sendbuf!=0 && getAllToAllMethod() == Native)
 +      delete[] sendbuf;
 +    if (recvbuf!=0)
 +      delete[] recvbuf;
 +    delete[] sendcounts;
 +    delete[] recvcounts;
 +    delete[] senddispls; 
 +    delete[] recvdispls;
 +  }
 +
 +  ostream & operator<< (ostream & f ,const AllToAllMethod & alltoallmethod )
 +  {
 +    switch (alltoallmethod)
 +      {
 +      case Native :
 +        f << " Native ";
 +        break;
 +      case PointToPoint :
 +        f << " PointToPoint ";
 +        break;
 +      default :
 +        f << " UnknownAllToAllMethod ";
 +        break;
 +      }
 +    return f;
 +  }
 +}
index 5aa3ce7fffd6bb3ca8b63c0be5a71a0a9126c35d,0000000000000000000000000000000000000000..cd613a8eb719674152f159123b3016d6183af2d2
mode 100644,000000..100644
--- /dev/null
@@@ -1,66 -1,0 +1,71 @@@
-     MxN_Mapping();
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __MXN_MAPPING_HXX__
 +#define __MXN_MAPPING_HXX__
 +
 +#include "MEDCouplingFieldDouble.hxx"
 +#include "MPIAccessDEC.hxx"
 +#include "DECOptions.hxx"
 +
 +#include <vector>
 +
 +namespace ParaMEDMEM
 +{
 +
 +  class ProcessorGroup;
 +
++  /*!
++   * Internal class, not part of the public API.
++   *
++   * Used by InterpolationMatrix. This class manages the mapping between a given processor and part
++   * of the mesh (cell ids).
++   */
 +  class MxN_Mapping : public DECOptions
 +  {
 +  public:
 +    MxN_Mapping(const ProcessorGroup& source_group, const ProcessorGroup& target_group, const DECOptions& dec_options);
 +    virtual ~MxN_Mapping();
 +    void addElementFromSource(int distant_proc, int distant_elem);
 +    void prepareSendRecv();
 +    void sendRecv(MEDCouplingFieldDouble& field);
 +    void sendRecv(double* sendfield, MEDCouplingFieldDouble& field) const ;
 +    void reverseSendRecv(double* recvfield, MEDCouplingFieldDouble& field) const ;
 + 
 +    //
 +    const std::vector<std::pair<int,int> >& getSendingIds() const { return _sending_ids; }
 +    const std::vector<int>& getSendProcsOffsets() const { return _send_proc_offsets; }
 +    void initialize();
 +
 +    MPIAccessDEC* getAccessDEC(){ return _access_DEC; }
 +  private :
 +    ProcessorGroup* _union_group;
 +    MPIAccessDEC * _access_DEC;
 +    int _nb_comps;
 +    std::vector<std::pair<int,int> > _sending_ids;
 +    std::vector<int> _recv_ids;
 +    std::vector<int> _send_proc_offsets;
 +    std::vector<int> _recv_proc_offsets;
 +  };
 +
 +  std::ostream & operator<< (std::ostream &,const AllToAllMethod &);
 +
 +}
 +
 +#endif
index 4f44a7f54a8ed3d943c73cc76212295cdfa737a3,0000000000000000000000000000000000000000..95b9d6acda5f208afd6a60ed61f37890a1e61733
mode 100644,000000..100644
--- /dev/null
@@@ -1,390 -1,0 +1,393 @@@
-     \c NonCoincidentDEC enables nonconservative remapping of fields 
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 <mpi.h>
 +#include "CommInterface.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ComponentTopology.hxx"
 +#include "ParaFIELD.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "DEC.hxx"
 +#include "NonCoincidentDEC.hxx"
 +
 +extern "C" {
 +#include <fvm_parall.h>
 +#include <fvm_nodal.h>
 +#include <fvm_nodal_append.h>
 +#include <fvm_locator.h>
 +}
 +
 +namespace ParaMEDMEM
 +{
 +
 +  /*!
 +    \anchor NonCoincidentDEC-det
 +    \class NonCoincidentDEC
 +
-     It is not available for 3D surfaces. The computation enables fast parallel localization, and is based on a point in element search, followed 
++    \c NonCoincidentDEC enables non-conservative remapping of fields
 +    between two parallel codes. 
 +    The computation is possible for 3D meshes and 2D meshes.
-     faster than the \ref InterpKernelDEC-det "InterpKernelDEC" which gives a
-     \ref InterpKerRemapGlobal "conservative remapping".
-     It is particularly true for the initialisation phase (synchronize)
-     which is very computationnaly intensive in \ref InterpKernelDEC-det.
++    It is not available for 3D surfaces.
++
++    The computation enables fast parallel localization, and is based on a point in element search, followed
 +    by a field evaluation at the point location. Thus, it is typically
-     In the present version, only fields lying on elements are considered. 
++    faster than the \ref InterpKernelDEC-det "InterpKernelDEC" which uses a
++    \ref InterpKerRemapGlobal "conservative remapping" (i.e. the same algorithms of volume
++    intersection as in the \ref remapper "sequential remapper")
++    It is particularly true for the initialisation phase (synchronize() method)
++    which has a significant computation cost in \ref InterpKernelDEC-det.
 +
++    In the present version, only fields lying on elements ("P0") are considered.
 +    The value is estimated by locating the barycenter of the target
 +    side cell in a source cell and sending the value of this source cell 
 +    as the value of the target cell.
 +
 +    \image html NonCoincident_small.png "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. The triangle barycenters are computed and located in the quadrangles. In a P0-P0 interpolation, the value on the quadrangle is then applied to the triangles whose barycenter lies within."
 +
 +    \image latex NonCoincident_small.eps "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. The triangle barycenters are computed and located in the quadrangles. In a P0-P0 interpolation, the value on the quadrangle is then applied to the triangles whose barycenter lies within."
 +
 +    A typical use of NonCoincidentDEC encompasses two distinct phases :
 +    - A setup phase during which the intersection volumes are computed and the communication structures are setup. This corresponds to calling the NonCoincidentDEC::synchronize() method.
 +    - A use phase during which the remappings are actually performed. This corresponds to the calls to sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous in the current version of the library so that recvData() and sendData() calls must be synchronized on code A and code B processor groups. 
 +
 +    The following code excerpt illutrates a typical use of the NonCoincidentDEC class.
 +
 +    \code
 +    ...
 +    NonCoincidentDEC dec(groupA, groupB);
 +    dec.attachLocalField(field);
 +    dec.synchronize();
 +    if (groupA.containsMyRank())
 +    dec.recvData();
 +    else if (groupB.containsMyRank())
 +    dec.sendData();
 +    ...
 +    \endcode
 +
 +    Computing the field on the receiving side can be expressed in terms 
 +    of a matrix-vector product : \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t
 +    \f$ the field on the target side and \f$ \phi_s \f$ the field on 
 +    the source side.
 +    In the P0-P0 case, this matrix is a plain rectangular matrix with one 
 +    non-zero element per row (with value 1). For instance, in the above figure, the matrix is :
 +    \f[
 +
 +    \begin{tabular}{|cccc|}
 +    1 & 0 & 0 & 0\\
 +    0 & 0 & 1 & 0\\
 +    1 & 0 & 0 & 0\\
 +    0 & 0 & 1 & 0\\
 +    \end{tabular}
 +    \f]
 +  */
 +
 +  fvm_nodal_t*  medmemMeshToFVMMesh(const MEDMEM::MESH* mesh)
 +  {
 +    // create an FVM structure from the paramesh structure
 +    std::string meshName(mesh->getName());//this line avoid that mesh->getName() object killed before fvm_nodal_create read the const char *.
 +    fvm_nodal_t * fvm_nodal = fvm_nodal_create(meshName.c_str(),mesh->getMeshDimension());
 +      
 +    //loop on cell types
 +    int nbtypes = mesh->getNumberOfTypes(MED_EN::MED_CELL);
 +    const MED_EN::medGeometryElement* types = mesh->getTypes(MED_EN::MED_CELL);
 +    for (int itype=0; itype<nbtypes; itype++)
 +      {
 +        fvm_element_t fvm_type;
 +        switch (types[itype]) 
 +          {
 +          case MED_EN::MED_TRIA3 :
 +            fvm_type=FVM_FACE_TRIA;
 +            break;
 +          case MED_EN::MED_QUAD4 :
 +            fvm_type=FVM_FACE_QUAD;
 +            break;
 +          case MED_EN::MED_TETRA4 :
 +            fvm_type=FVM_CELL_TETRA;
 +            break;
 +          case MED_EN::MED_HEXA8 :
 +            fvm_type=FVM_CELL_HEXA;
 +            break;
 +          default:
 +            throw MEDEXCEPTION(" MED type  conversion to fvm is not handled yet.");
 +            break;
 +
 +          }
 +
 +        fvm_lnum_t nbelems = mesh->getNumberOfElements(MED_EN::MED_CELL, types[itype]);
 +        fvm_lnum_t* conn = new fvm_lnum_t[nbelems*(types[itype]%100)];
 +        const int* mesh_conn =mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL, MED_EN::MED_CELL, types[itype]);
 +        for (int i=0; i<nbelems*(types[itype]%100); i++)
 +          conn[i]=mesh_conn[i]; 
 +        //swapping trias
 +        if (types[itype]==MED_EN::MED_TRIA3)
 +          {
 +            for (int i=0; i<nbelems;i++)
 +              {
 +                int tmp=conn[3*i];
 +                conn[3*i]=mesh_conn[3*i+1];
 +                conn[3*i+1]=tmp;
 +              }
 +          }
 +        //swapping tetras
 +        if (types[itype]==MED_EN::MED_TETRA4)
 +          {
 +            for (int i=0; i<nbelems;i++)
 +              {
 +                int tmp=conn[4*i];
 +                conn[4*i]=mesh_conn[4*i+1];
 +                conn[4*i+1]=tmp;
 +              }
 +          }
 +        fvm_nodal_append_by_transfer(fvm_nodal, nbelems, fvm_type,0,0,0,conn,0);
 +         
 +        int nbnodes= mesh->getNumberOfNodes();
 +        int spacedim=mesh->getSpaceDimension();
 +        fvm_coord_t* coords = new fvm_coord_t[nbnodes*spacedim];
 +        const double* mesh_coords=mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE);
 +        for (int i=0; i<nbnodes*spacedim; i++)
 +          coords[i]=mesh_coords[i];                  
 +        fvm_nodal_transfer_vertices(fvm_nodal,coords);
 +      }
 +    return fvm_nodal;
 +  }
 +  
 +  fvm_nodal_t*  medmemSupportToFVMMesh(const MEDMEM::SUPPORT* support)
 +  {
 +
 +    // create an FVM structure from the paramesh structure
 +    std::string supportName(support->getName());//this line avoid that support->getName() object killed before fvm_nodal_create read the const char *.
 +    fvm_nodal_t * fvm_nodal = fvm_nodal_create(supportName.c_str(),1);
 +      
 +    const MEDMEM::MESH* mesh= support->getMesh();
 +      
 +    //loop on cell types
 +    MED_EN::medEntityMesh entity = support->getEntity();
 +      
 +    int nbtypes = support->getNumberOfTypes();
 +    const MED_EN::medGeometryElement* types = support->getTypes();
 +    int ioffset=0;
 +    const int* type_offset = support->getNumberIndex();
 +      
 +    //browsing through all types
 +    for (int itype=0; itype<nbtypes; itype++)
 +      {
 +        fvm_element_t fvm_type;
 +        switch (types[itype]) 
 +          {
 +          case MED_EN::MED_TRIA3 :
 +            fvm_type=FVM_FACE_TRIA;
 +            break;
 +          case MED_EN::MED_QUAD4 :
 +            fvm_type=FVM_FACE_QUAD;
 +            break;
 +          case MED_EN::MED_TETRA4 :
 +            fvm_type=FVM_CELL_TETRA;
 +            break;
 +          case MED_EN::MED_HEXA8 :
 +            fvm_type=FVM_CELL_HEXA;
 +            break;
 +          default:
 +            throw MEDEXCEPTION(" MED type  conversion to fvm is not handled yet.");
 +            break;
 +
 +          }
 +        fvm_lnum_t nbelems = support->getNumberOfElements(types[itype]);
 +         
 +        //for a partial support, defining the element numbers that are taken into
 +        //account in the support
 +        fvm_lnum_t* elem_numbers=0;
 +        if (!support->isOnAllElements())
 +          {
 +            elem_numbers = const_cast<fvm_lnum_t*> (support->getNumber(types[itype]));
 +           
 +            //creating work arrays to store list of elems for partial suports
 +            if (itype>0)
 +              {
 +                fvm_lnum_t* temp = new int[nbelems];
 +                for (int i=0; i< nbelems; i++)
 +                  temp[i] = elem_numbers [i]-ioffset;
 +                ioffset+=type_offset[itype];
 +                elem_numbers = temp;
 +              }
 +          }
 +        //retrieving original mesh connectivity
 +        fvm_lnum_t* conn = const_cast<fvm_lnum_t*> (mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,entity, types[itype]));
 +       
 +        // adding the elements to the FVM structure 
 +        fvm_nodal_append_by_transfer(fvm_nodal, nbelems, fvm_type,0,0,0,conn,elem_numbers);
 +         
 +        //cleaning work arrays (for partial supports)
 +        if (!support->isOnAllElements() && itype>0)
 +          delete[] elem_numbers;
 +      
 +      }
 +    return fvm_nodal;
 +  }
 +  
 +  NonCoincidentDEC::NonCoincidentDEC()
 +  {  
 +  }
 +
 +  /*! Constructor of a non coincident \ref para-dec "DEC" with
 +   * a source group on which lies a field lying on a mesh and a 
 +   * target group on which lies a mesh.
 +   * 
 +   * \param source_group ProcessorGroup on the source side
 +   * \param target_group ProcessorGroup on the target side 
 +   */
 +  
 +  NonCoincidentDEC::NonCoincidentDEC(ProcessorGroup& source_group,
 +                                     ProcessorGroup& target_group)
 +    :DEC(source_group, target_group)
 +  {}
 +                                   
 +  NonCoincidentDEC::~NonCoincidentDEC()
 +  {
 +  }
 +
 +  /*! Synchronization process. Calling this method 
 +   * synchronizes the topologies so that the target side
 +   * gets the information which enable it to fetch the field value 
 +   * from the source side.
 +   * A typical call is : 
 +   \verbatim
 +   NonCoincidentDEC dec(source_group,target_group);
 +   dec.attachLocalField(field);
 +   dec.synchronize();
 +   \endverbatim
 +  */
 +  void NonCoincidentDEC::synchronize()
 +  {
 +  
 +    //initializing FVM parallel environment
 +    const MPI_Comm* comm=dynamic_cast<const MPIProcessorGroup*> (_union_group)->getComm();
 +    fvm_parall_set_mpi_comm(*const_cast<MPI_Comm*> (comm));
 +  
 +  
 +    //setting up the communication DEC on both sides
 +  
 +    if (_source_group->containsMyRank())
 +      {
 +        MEDMEM::MESH* mesh = _local_field->getField()->getSupport()->getMesh();
 +        fvm_nodal_t* source_nodal = ParaMEDMEM::medmemMeshToFVMMesh(mesh);
 +      
 +        int target_size = _target_group->size()  ;
 +        int start_rank=  _source_group->size();
 +        const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*> (_union_group))->getComm();
 +      
 +        _locator =  fvm_locator_create(1e-6,
 +                                       *comm,
 +                                       target_size,
 +                                       start_rank);
 +      
 +        fvm_locator_set_nodal(_locator,
 +                              source_nodal,
 +                              mesh->getSpaceDimension(),
 +                              0,
 +                              NULL,
 +                              0);
 +
 +      
 +        _nb_distant_points = fvm_locator_get_n_dist_points(_locator);
 +        _distant_coords = fvm_locator_get_dist_coords(_locator);
 +        _distant_locations = fvm_locator_get_dist_locations(_locator);
 +           
 +      }
 +    if (_target_group->containsMyRank())
 +      {
 +        MEDMEM::MESH* mesh = _local_field->getField()->getSupport()->getMesh();
 +      
 +        fvm_nodal_t* target_nodal = ParaMEDMEM::medmemMeshToFVMMesh(mesh);
 +        int source_size = _source_group->size();
 +        int start_rank=  0 ;
 +        const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*> (_union_group))->getComm();
 +      
 +        _locator = fvm_locator_create(1e-6,
 +                                      *comm,
 +                                      source_size,
 +                                      start_rank);
 +        int nbcells = mesh->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS);
 +        const MEDMEM::SUPPORT* support=_local_field->getField()->getSupport();
 +        MEDMEM::FIELD<double>* barycenter_coords = mesh->getBarycenter(support);
 +        const double* coords = barycenter_coords->getValue();
 +        fvm_locator_set_nodal(_locator,
 +                              target_nodal,
 +                              mesh->getSpaceDimension(),
 +                              nbcells,
 +                              NULL,
 +                              coords);  
 +        delete barycenter_coords;
 +      }
 +  }
 +
 +
 +  /*! This method is called on the target group in order to 
 +   * trigger the retrieveal of field data. It must 
 +   * be called synchronously with a sendData() call on 
 +   * the source group.
 +   */
 +  void NonCoincidentDEC::recvData()
 +  {
 +    int nbelems = _local_field->getField()->getSupport()->getMesh()->getNumberOfElements(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS);
 +    int nbcomp =  _local_field->getField()->getNumberOfComponents();
 +    double* values = new double [nbelems*nbcomp];
 +    fvm_locator_exchange_point_var(_locator,
 +                                   0,
 +                                   values,
 +                                   0,
 +                                   sizeof(double),
 +                                   nbcomp,
 +                                   0);
 +    _local_field->getField()->setValue(values);
 +    if (_forced_renormalization_flag)
 +      renormalizeTargetField();
 +    delete[]values;
 +  }
 +
 +  /*! This method is called on the source group in order to 
 +   * send field data. It must be called synchronously with 
 +   * a recvData() call on 
 +   * the target group.
 +   */
 +  void NonCoincidentDEC::sendData()
 +  {
 +    const double* values=_local_field->getField()->getValue();
 +    int nbcomp = _local_field->getField()->getNumberOfComponents();
 +    double* distant_values = new double [_nb_distant_points*nbcomp];
 +
 +    //cheap interpolation :  the value of the cell is transfered to the point
 +    for (int i=0; i<_nb_distant_points; i++)
 +      for (int j=0; j <nbcomp; j++)
 +        distant_values[i*nbcomp+j]=values[(_distant_locations[i]-1)*nbcomp+j];
 +  
 +    fvm_locator_exchange_point_var(_locator,
 +                                   distant_values,
 +                                   0,
 +                                   0,
 +                                   sizeof(double),
 +                                   nbcomp,
 +                                   0);
 +
 +    delete [] distant_values;
 +    if (_forced_renormalization_flag)
 +      renormalizeTargetField();
 +
 +  }
 +}
index 0c02028d761eed64d03dede4b4da1fcada604707,0000000000000000000000000000000000000000..09253d350770d8af062bb9dfcabda9d078d031f1
mode 100644,000000..100644
--- /dev/null
@@@ -1,318 -1,0 +1,323 @@@
-     a \b same \b processor \b group. On this processor group are defined two field-templates called A
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#include "OverlapDEC.hxx"
 +#include "CommInterface.hxx"
 +#include "ParaFIELD.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "OverlapElementLocator.hxx"
 +#include "OverlapInterpolationMatrix.hxx"
 +
 +namespace ParaMEDMEM
 +{
 +/*!
 +    \anchor OverlapDEC-det
 +    \class OverlapDEC
 +
++    \section OverlapDEC-over Overview
++
 +    The \c OverlapDEC enables the \ref InterpKerRemapGlobal "conservative remapping" of fields between
 +    two parallel codes. This remapping is based on the computation of intersection volumes on
-     The main difference with \ref InterpKernelDEC-det is that this \ref para-dec "DEC" manages 2 field templates
-     on each processor of the processor group (A and B) called source and target.
-     Furthermore all processors in processor group cooperates in global interpolation matrix
-     computation. In this respect \ref InterpKernelDEC is a specialization of \c OverlapDEC.
++    a \b single \b processor \b group. On this processor group are defined two field-templates called A
 +    and B. The computation is possible for 3D meshes, 2D meshes, 3D-surface meshes, 1D meshes and
 +    2D-curve meshes. Dimensions must be similar for the distribution templates A and B.
-     \section ParaMEDMEMOverlapDECAlgorithmDescription Algorithm Description
 +
-     \image html OverlapDEC1.png "Example showing the use case in order to explain the different steps."
++    The main difference with \ref InterpKernelDEC-det "InterpKernelDEC" is that this
++    \ref para-dec "DEC" works with a *single* processor group, in which processors will share the work.
++    Consequently each processor manages two \ref MEDCouplingFieldTemplatesPage "field templates" (A and B)
++    called source and target.
++    Furthermore all processors in the processor group cooperate in the global interpolation matrix
++    computation. In this respect \c InterpKernelDEC is a specialization of \c OverlapDEC.
++
++    \section ParaMEDMEMOverlapDECAlgorithmDescription Algorithm description
 +
 +    Let's consider the following use case that is ran in ParaMEDMEMTest_OverlapDEC.cxx to describes
 +    the different steps of the computation. The processor group contains 3 processors.
 +    \anchor ParaMEDMEMOverlapDECImgTest1
-     The interpolation is performed as \ref ParaMEDMEM::MEDCouplingRemapper "Remapper" does.
++    \image html OverlapDEC1.png "Example split of the source and target mesh among the 3 procs"
 +
 +    \subsection ParaMEDMEMOverlapDECAlgoStep1 Step 1 : Bounding box exchange and global interaction
 +    between procs computation.
 +
 +    In order to reduce as much as possible the amount of communications between distant processors,
 +    every processor computes a bounding box for A and B. Then a AllToAll communication is performed
 +    so that
 +    every processor can compute the \b global interactions between processor.
 +    This computation leads every processor to compute the same global TODO list expressed as a list
 +    of pair. A pair ( x, y ) means that proc \b x fieldtemplate A can interact with fieltemplate B of
 +    proc \b y because the two bounding boxes interact.
 +    In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" this computation leads to the following
 +    a \b global TODO list :
 +
 +    \b (0,0),(0,1),(1,0),(1,2),(2,0),(2,1),(2,2)
 +
 +    Here the pair (0,2) does not appear because the bounding box of fieldtemplateA of proc#2 does
 +    not intersect that of fieldtemplate B on proc#0.
 +
 +    Stage performed by ParaMEDMEM::OverlapElementLocator::computeBoundingBoxes.
 +
 +    \subsection ParaMEDMEMOverlapDECAlgoStep2 Step 2 : Computation of local TODO list
 +
 +    Starting from the global interaction previously computed in \ref ParaMEDMEMOverlapDECAlgoStep1
 +    "Step 1", each proc computes the TODO list per proc.
 +    The following rules is chosen : a pair (x,y) can be treated by either proc \#x or proc \#y,
 +    in order to reduce the amount of data transfert among
 +    processors. The algorithm chosen for load balancing is the following : Each processor has
 +    an empty \b local TODO list at the beginning. Then for each pair (k,m) in
 +    \b global TODO list, if proc\#k has less temporary local list than proc\#m pair, (k,m) is added
 +    to temparary local TODO list of proc\#k.
 +    If proc\#m has less temporary local TODO list than proc\#k pair, (k,m) is added to temporary
 +    local TODO list of proc\#m.
 +    If proc\#k and proc\#m have the same amount of temporary local TODO list pair, (k,m) is added to
 +    temporary local TODO list of proc\#k.
 +
 +    In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" this computation leads to the following
 +    local TODO list :
 +
 +    - proc\#0 : (0,0)
 +    - proc\#1 : (0,1),(1,0)
 +    - proc\#2 : (1,2),(2,0),(2,1),(2,2)
 +    
 +    The algorithm described here is not perfect for this use case, we hope to enhance it soon.
 +
 +    At this stage each proc knows precisely its \b local TODO list (with regard to interpolation).
 +    The \b local TODO list of other procs than local
 +    is kept for future computations.
 +
 +    \subsection ParaMEDMEMOverlapDECAlgoStep3 Step 3 : Matrix echange between procs
 +
 +    Knowing the \b local TODO list, the aim now is to exchange field-templates between procs.
 +    Each proc computes knowing TODO list per
 +    proc computed in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step 2" the exchange TODO list :
 +
 +    In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" the exchange TODO list gives the
 +    following results :
 +
 +    Sending TODO list per proc :
 +
 +    - proc \#0 : Send fieldtemplate A to Proc\#1, Send fieldtemplate B to Proc\#1, Send fieldtemplate
 +    B to Proc\#2
 +    - Proc \#1 : Send fieldtemplate A to Proc\#2, Send fieldtemplate B to Proc\#2
 +    - Proc \#2 : No send.
 +
 +    Receiving TODO list per proc :
 +
 +    - proc \#0 : No receiving
 +    - proc \#1 : receiving fieldtemplate A from Proc\#0,  receiving fieldtemplate B from Proc\#0
 +    - proc \#2 : receiving fieldtemplate B from Proc\#0, receiving fieldtemplate A from Proc\#1,
 +    receiving fieldtemplate B from Proc\#1
 +
 +    To avoid as much as possible large volumes of transfers between procs, only relevant parts of
 +    meshes are sent. In order for proc\#k to send fieldtemplate A to fieldtemplate B
 +    of proc \#m., proc\#k computes the part of mesh A contained in the boundingbox B of proc\#m. It
 +    implies that the corresponding cellIds or nodeIds of the
 +    corresponding part are sent to proc \#m too.
 +
 +    Let's consider the couple (k,m) in the TODO list. This couple is treated by either k or m as
 +    seen in \ref ParaMEDMEMOverlapDECAlgoStep2 "here in Step2".
 +
 +    As will be dealt in Step 6, for final matrix-vector computations, the resulting matrix of the
 +    couple (k,m) whereever it is computed (proc \#k or proc \#m)
 +    will be stored in \b proc\#m.
 +
 +    - If proc \#k is in charge (performs the matrix computation) for this couple (k,m), target ids
 +    (cells or nodes) of the mesh in proc \#m are renumbered, because proc \#m has seelected a sub mesh
 +    of the target mesh to avoid large amounts of data to transfer. In this case as proc \#m is ultimately
 +     in charge of the matrix, proc \#k must keep preciously the
 +    source ids needed to be sent to proc\#m. No problem will appear for matrix assembling in proc m
 +    for source ids because no restriction was done.
 +    Concerning source ids to be sent for the matrix-vector computation, proc k will know precisely
 +    which source ids field values to send to proc \#m.
 +    This is embodied by OverlapMapping::keepTracksOfTargetIds in proc m.
 +
 +    - If proc \#m is in charge (performs matrix computation) for this couple (k,m), source ids (cells
 +    or nodes) of the mesh in proc \#k are renumbered, because proc \#k has selected a sub mesh of the
 +     source mesh to avoid large amounts of data to transfer. In this case as proc \#k is ultimately
 +     in charge of the matrix, proc \#m receives the source ids
 +    from remote proc \#k, and thus the matrix is directly correct, no need for renumbering as
 +     in \ref ParaMEDMEMOverlapDECAlgoStep5 "Step 5". However proc \#k must
 +    keep track of the ids sent to proc \#m for te matrix-vector computation.
 +    This is incarnated by OverlapMapping::keepTracksOfSourceIds in proc k.
 +
 +    This step is performed in ParaMEDMEM::OverlapElementLocator::exchangeMeshes method.
 +
 +    \subsection ParaMEDMEMOverlapDECAlgoStep4 Step 4 : Computation of the interpolation matrix
 +
 +    After mesh exchange in \ref ParaMEDMEMOverlapDECAlgoStep3 "Step3" each processor has all the
 +    required information to treat its \b local TODO list computed in
 +    \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". This step is potentially CPU costly, which is why
 +    the \b local TODO list per proc is expected to
 +    be as well balanced as possible.
 +
++    The interpolation is performed as the \ref ParaMEDMEM::MEDCouplingRemapper "remapper" does.
 +
 +    This operation is performed by OverlapInterpolationMatrix::addContribution method.
 +
 +    \subsection ParaMEDMEMOverlapDECAlgoStep5 Step 5 : Global matrix construction.
 +    
 +    After having performed the TODO list at the end of \ref ParaMEDMEMOverlapDECAlgoStep4 "Step4"
 +    we need to assemble the final matrix.
 +    
 +    The final aim is to have a distributed matrix \f$ M_k \f$ on each proc\#k. In order to reduce
 +    data exchange during the matrix product process,
 +    \f$ M_k \f$ is built using sizeof(Proc group) \c std::vector< \c std::map<int,double> \c >.
 +
 +    For a proc\#k, it is necessary to fetch info of all matrices built in
 +    \ref ParaMEDMEMOverlapDECAlgoStep4 "Step4" where the first element in pair (i,j)
 +    is equal to k.
 +
 +    After this step, the matrix repartition is the following after a call to
 +    ParaMEDMEM::OverlapMapping::prepare :
 +
 +    - proc\#0 : (0,0),(1,0),(2,0)
 +    - proc\#1 : (0,1),(2,1)
 +    - proc\#2 : (1,2),(2,2)
 +
 +    Tuple (2,1) computed on proc 2 is stored in proc 1 after execution of the function
 +    "prepare". This is an example of item 0 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2".
 +    Tuple (0,1) computed on proc 1 is stored in proc 1 too. This is an example of item 1 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2".
 +
 +    In the end ParaMEDMEM::OverlapMapping::_proc_ids_to_send_vector_st will contain :
 +
 +    - Proc\#0 : 0,1
 +    - Proc\#1 : 0,2
 +    - Proc\#2 : 0,1,2
 +
 +    In the end ParaMEDMEM::OverlapMapping::_proc_ids_to_recv_vector_st will contain :
 +
 +    - Proc\#0 : 0,1,2
 +    - Proc\#1 : 0,2
 +    - Proc\#2 : 1,2
 +
 +    The method in charge to perform this is : ParaMEDMEM::OverlapMapping::prepare.
 +*/
 +  OverlapDEC::OverlapDEC(const std::set<int>& procIds, const MPI_Comm& world_comm):
 +      _own_group(true),_interpolation_matrix(0),
 +      _source_field(0),_own_source_field(false),
 +      _target_field(0),_own_target_field(false),
 +      _comm(MPI_COMM_NULL)
 +  {
 +    ParaMEDMEM::CommInterface comm;
 +    int *ranks_world=new int[procIds.size()]; // ranks of sources and targets in world_comm
 +    std::copy(procIds.begin(),procIds.end(),ranks_world);
 +    MPI_Group group,world_group;
 +    comm.commGroup(world_comm,&world_group);
 +    comm.groupIncl(world_group,procIds.size(),ranks_world,&group);
 +    delete [] ranks_world;
 +    comm.commCreate(world_comm,group,&_comm);
 +    comm.groupFree(&group);
 +    comm.groupFree(&world_group);
 +    if(_comm==MPI_COMM_NULL)
 +      {
 +        _group=0;
 +        return ;
 +      }
 +    std::set<int> idsUnion;
 +    for(std::size_t i=0;i<procIds.size();i++)
 +      idsUnion.insert(i);
 +    _group=new MPIProcessorGroup(comm,idsUnion,_comm);
 +  }
 +
 +  OverlapDEC::~OverlapDEC()
 +  {
 +    if(_own_group)
 +      delete _group;
 +    if(_own_source_field)
 +      delete _source_field;
 +    if(_own_target_field)
 +      delete _target_field;
 +    delete _interpolation_matrix;
 +    if (_comm != MPI_COMM_NULL)
 +      {
 +        ParaMEDMEM::CommInterface comm;
 +        comm.commFree(&_comm);
 +      }
 +  }
 +
 +  void OverlapDEC::sendRecvData(bool way)
 +  {
 +    if(way)
 +      sendData();
 +    else
 +      recvData();
 +  }
 +
 +  void OverlapDEC::sendData()
 +  {
 +    _interpolation_matrix->multiply();
 +  }
 +
 +  void OverlapDEC::recvData()
 +  {
 +    throw INTERP_KERNEL::Exception("Not implemented yet !!!!");
 +    //_interpolation_matrix->transposeMultiply();
 +  }
 +  
 +  void OverlapDEC::synchronize()
 +  {
 +    if(!isInGroup())
 +      return ;
 +    delete _interpolation_matrix;
 +    _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this);
 +    OverlapElementLocator locator(_source_field,_target_field,*_group);
 +    locator.copyOptions(*this);
 +    locator.exchangeMeshes(*_interpolation_matrix);
 +    std::vector< std::pair<int,int> > jobs=locator.getToDoList();
 +    std::string srcMeth=locator.getSourceMethod();
 +    std::string trgMeth=locator.getTargetMethod();
 +    for(std::vector< std::pair<int,int> >::const_iterator it=jobs.begin();it!=jobs.end();it++)
 +      {
 +        const MEDCouplingPointSet *src=locator.getSourceMesh((*it).first);
 +        const DataArrayInt *srcIds=locator.getSourceIds((*it).first);
 +        const MEDCouplingPointSet *trg=locator.getTargetMesh((*it).second);
 +        const DataArrayInt *trgIds=locator.getTargetIds((*it).second);
 +        _interpolation_matrix->addContribution(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second);
 +      }
 +    _interpolation_matrix->prepare(locator.getProcsInInteraction());
 +    _interpolation_matrix->computeDeno();
 +  }
 +
 +  void OverlapDEC::attachSourceLocalField(ParaFIELD *field, bool ownPt)
 +  {
 +    if(!isInGroup())
 +      return ;
 +    if(_own_source_field)
 +      delete _source_field;
 +    _source_field=field;
 +    _own_source_field=ownPt;
 +  }
 +
 +  void OverlapDEC::attachTargetLocalField(ParaFIELD *field, bool ownPt)
 +  {
 +    if(!isInGroup())
 +      return ;
 +    if(_own_target_field)
 +      delete _target_field;
 +    _target_field=field;
 +    _own_target_field=ownPt;
 +  }
 +
 +  bool OverlapDEC::isInGroup() const
 +  {
 +    if(!_group)
 +      return false;
 +    return _group->containsMyRank();
 +  }
 +}
index 48b853ca05d4aa30777cae084dcbf3168d53482d,0000000000000000000000000000000000000000..b7b9b8c2ffa17c03313108f52a82983ad15fe50d
mode 100644,000000..100644
--- /dev/null
@@@ -1,61 -1,0 +1,61 @@@
-   private:
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __OVERLAPDEC_HXX__
 +#define __OVERLAPDEC_HXX__
 +
 +#include "DEC.hxx"
 +#include "InterpolationOptions.hxx"
 +
 +#include <mpi.h>
 +
 +namespace ParaMEDMEM
 +{
 +  class OverlapInterpolationMatrix;
 +  class ProcessorGroup;
 +  class ParaFIELD;
 +
 +  class OverlapDEC : public DEC, public INTERP_KERNEL::InterpolationOptions
 +  {
 +  public:
 +    OverlapDEC(const std::set<int>& procIds,const MPI_Comm& world_comm=MPI_COMM_WORLD);
 +    virtual ~OverlapDEC();
 +    void sendRecvData(bool way=true);
 +    void sendData();
 +    void recvData();
 +    void synchronize();
 +    void attachSourceLocalField(ParaFIELD *field, bool ownPt=false);
 +    void attachTargetLocalField(ParaFIELD *field, bool ownPt=false);
 +    ProcessorGroup *getGrp() { return _group; }
 +    bool isInGroup() const;
 +  private:
 +    bool _own_group;
 +    OverlapInterpolationMatrix* _interpolation_matrix;
 +    ProcessorGroup *_group;
++
 +    ParaFIELD *_source_field;
 +    bool _own_source_field;
 +    ParaFIELD *_target_field;
 +    bool _own_target_field;
 +    MPI_Comm _comm;
 +  };
 +}
 +
 +#endif
index 13a94c821a18ca3f1028bc4cac555349053b6125,0000000000000000000000000000000000000000..6ce2677f240c559981edc513d07ca7eacd166a55
mode 100644,000000..100644
--- /dev/null
@@@ -1,92 -1,0 +1,91 @@@
-   class ParaSUPPORT;
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __OVERLAPELEMENTLOCATOR_HXX__
 +#define __OVERLAPELEMENTLOCATOR_HXX__
 +
 +#include "InterpolationOptions.hxx"
 +#include "MEDCouplingNatureOfField.hxx"
 +#include "MEDCouplingPointSet.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 +
 +#include <mpi.h>
 +#include <vector>
 +#include <map>
 +#include <set>
 +
 +namespace ParaMEDMEM
 +{
 +  class ParaFIELD;
 +  class ProcessorGroup;
 +  class OverlapInterpolationMatrix;
 +  
 +  class OverlapElementLocator : public INTERP_KERNEL::InterpolationOptions
 +  {
 +  public:
 +    OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField, const ProcessorGroup& group);
 +    virtual ~OverlapElementLocator();
 +    const MPI_Comm *getCommunicator() const;
 +    void exchangeMeshes(OverlapInterpolationMatrix& matrix);
 +    std::vector< std::pair<int,int> > getToDoList() const { return _to_do_list; }
 +    std::vector< std::vector< int > > getProcsInInteraction() const { return _proc_pairs; }
 +    std::string getSourceMethod() const;
 +    std::string getTargetMethod() const;
 +    const MEDCouplingPointSet *getSourceMesh(int procId) const;
 +    const DataArrayInt *getSourceIds(int procId) const;
 +    const MEDCouplingPointSet *getTargetMesh(int procId) const;
 +    const DataArrayInt *getTargetIds(int procId) const;
 +  private:
 +    void computeBoundingBoxes();
 +    bool intersectsBoundingBox(int i, int j) const;
 +    void sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const;
 +    void receiveRemoteMesh(int procId, bool sourceOrTarget);
 +    void sendMesh(int procId, const MEDCouplingPointSet *mesh, const DataArrayInt *idsToSend) const;
 +    void receiveMesh(int procId, MEDCouplingPointSet* &mesh, DataArrayInt *&ids) const;
 +  private:
 +    const ParaFIELD *_local_source_field;
 +    const ParaFIELD *_local_target_field;
 +    int _local_space_dim;
 +    MEDCouplingPointSet *_local_source_mesh;
 +    MEDCouplingPointSet *_local_target_mesh;
 +    std::vector<MEDCouplingPointSet*> _distant_cell_meshes;
 +    std::vector<MEDCouplingPointSet*> _distant_face_meshes;
 +    //! of size _group.size(). Contains for each source proc i, the ids of proc j the targets interact with. This vector is common for all procs in _group. 
 +    std::vector< std::vector< int > > _proc_pairs;
 +    //! list of interpolations couple to be done
 +    std::vector< std::pair<int,int> > _to_do_list;
 +    std::vector< std::pair<int,bool> > _procs_to_send;
 +    std::map<std::pair<int,bool>, MEDCouplingAutoRefCountObjectPtr< MEDCouplingPointSet > > _remote_meshes;
 +    std::map<std::pair<int,bool>, MEDCouplingAutoRefCountObjectPtr< DataArrayInt > > _remote_elems;
 +    double* _domain_bounding_boxes;
 +    const ProcessorGroup& _group;
 +    std::vector<int> _distant_proc_ids;
 +    const MPI_Comm *_comm;
 +    //Attributes only used by lazy side
 +    //std::vector<double> _values_added;
 +    //std::vector< std::vector<int> > _ids_per_working_proc;
 +    //std::vector< std::vector<int> > _ids_per_working_proc3;
 +    //std::vector< std::vector<double> > _values_per_working_proc;
 +  };
 +
 +}
 +
 +#endif
index 514deb8defbae8e999efcef2ea21dd2391c62b56,0000000000000000000000000000000000000000..2190e9adddb3f6651f162cfc51092dccbffbafa8
mode 100644,000000..100644
--- /dev/null
@@@ -1,126 -1,0 +1,131 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __OVERLAPINTERPOLATIONMATRIX_HXX__
 +#define __OVERLAPINTERPOLATIONMATRIX_HXX__
 +
 +#include "MPIAccessDEC.hxx"
 +#include "OverlapMapping.hxx"
 +#include "InterpolationOptions.hxx"
 +#include "DECOptions.hxx"
 +
 +namespace ParaMEDMEM
 +{
 +  class ParaFIELD;
 +  class MEDCouplingPointSet;
 +
++  /*!
++   * Internal class, not part of the public API.
++   *
++   * Similar to InterpolationMatrix, but for the OverlapDEC instead of the InterpKernelDEC.
++   */
 +  class OverlapInterpolationMatrix : public INTERP_KERNEL::InterpolationOptions,
 +                                     public DECOptions
 +  {
 +  public:
 +    
 +    OverlapInterpolationMatrix(ParaFIELD *source_field,
 +                               ParaFIELD *target_field,
 +                               const ProcessorGroup& group,
 +                               const DECOptions& dec_opt,
 +                               const InterpolationOptions& i_opt);
 +
 +    void keepTracksOfSourceIds(int procId, DataArrayInt *ids);
 +
 +    void keepTracksOfTargetIds(int procId, DataArrayInt *ids);
 +
 +    void addContribution(const MEDCouplingPointSet *src, const DataArrayInt *srcIds, const std::string& srcMeth, int srcProcId,
 +                         const MEDCouplingPointSet *trg, const DataArrayInt *trgIds, const std::string& trgMeth, int trgProcId);
 +
 +    void prepare(const std::vector< std::vector<int> >& procsInInteraction);
 +    
 +    void computeDeno();
 +
 +    void multiply();
 +
 +    void transposeMultiply();
 +    
 +    virtual ~OverlapInterpolationMatrix();
 +#if 0
 +    void addContribution(MEDCouplingPointSet& distant_support, int iproc_distant,
 +                         const int* distant_elems, const std::string& srcMeth, const std::string& targetMeth);
 +    void finishContributionW(ElementLocator& elementLocator);
 +    void finishContributionL(ElementLocator& elementLocator);
 +    void multiply(MEDCouplingFieldDouble& field) const;
 +    void transposeMultiply(MEDCouplingFieldDouble& field)const;
 +    void prepare();
 +    int getNbRows() const { return _row_offsets.size(); }
 +    MPIAccessDEC* getAccessDEC() { return _mapping.getAccessDEC(); }
 +  private:
 +    void computeConservVolDenoW(ElementLocator& elementLocator);
 +    void computeIntegralDenoW(ElementLocator& elementLocator);
 +    void computeRevIntegralDenoW(ElementLocator& elementLocator);
 +    void computeGlobConstraintDenoW(ElementLocator& elementLocator);
 +    void computeConservVolDenoL(ElementLocator& elementLocator);
 +    void computeIntegralDenoL(ElementLocator& elementLocator);
 +    void computeRevIntegralDenoL(ElementLocator& elementLocator);
 +    
 +    void computeLocalColSum(std::vector<double>& res) const;
 +    void computeLocalRowSum(const std::vector<int>& distantProcs, std::vector<std::vector<int> >& resPerProcI,
 +                            std::vector<std::vector<double> >& resPerProcD) const;
 +    void computeGlobalRowSum(ElementLocator& elementLocator, std::vector<std::vector<double> >& denoStrorage, std::vector<std::vector<double> >& denoStrorageInv);
 +    void computeGlobalColSum(std::vector<std::vector<double> >& denoStrorage);
 +    void resizeGlobalColSum(std::vector<std::vector<double> >& denoStrorage);
 +    void fillDSFromVM(int iproc_distant, const int* distant_elems, const std::vector< std::map<int,double> >& values, MEDCouplingFieldDouble *surf);
 +    void serializeMe(std::vector< std::vector< std::map<int,double> > >& data1, std::vector<int>& data2) const;
 +    void initialize();
 +    void findAdditionnalElements(ElementLocator& elementLocator, std::vector<std::vector<int> >& elementsToAdd,
 +                                 const std::vector<std::vector<int> >& resPerProcI, const std::vector<std::vector<int> >& globalIdsPartial);
 +    void addGhostElements(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& elementsToAdd);
 +    int mergePolicies(const std::vector<int>& policyPartial);
 +    void mergeRowSum(const std::vector< std::vector<double> >& rowsPartialSumD, const std::vector< std::vector<int> >& globalIdsPartial,
 +                     std::vector<int>& globalIdsLazySideInteraction, std::vector<double>& sumCorresponding);
 +    void mergeRowSum2(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD,
 +                      const std::vector<int>& globalIdsLazySideInteraction, const std::vector<double>& sumCorresponding);
 +    void mergeRowSum3(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD);
 +    void mergeCoeffs(const std::vector<int>& procsInInteraction, const std::vector< std::vector<int> >& rowsPartialSumI,
 +                     const std::vector<std::vector<int> >& globalIdsPartial, std::vector<std::vector<double> >& denoStrorageInv);
 +    void divideByGlobalRowSum(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& resPerProcI,
 +                              const std::vector<std::vector<double> >& resPerProcD, std::vector<std::vector<double> >& deno);
 +#endif
 +  private:
 +    bool isSurfaceComputationNeeded(const std::string& method) const;
 +    void fillDistributedMatrix(const std::vector< std::map<int,double> >& res,
 +                               const DataArrayInt *srcIds, int srcProc,
 +                               const DataArrayInt *trgIds, int trgProc);
 +    static void TransposeMatrix(const std::vector<std::map<int,double> >& matIn, int nbColsMatIn, std::vector<std::map<int,double> >& matOut);
 +  private:
 +    ParaMEDMEM::ParaFIELD *_source_field;
 +    ParaMEDMEM::ParaFIELD *_target_field;
 +    std::vector<int> _row_offsets;
 +    std::map<std::pair<int,int>, int > _col_offsets;
 +    MEDCouplingPointSet *_source_support;
 +    MEDCouplingPointSet *_target_support;
 +    OverlapMapping _mapping;
 + 
 +    const ProcessorGroup& _group;
 +    std::vector< std::vector<double> > _target_volume;
 +    std::vector<std::vector<std::pair<int,double> > > _coeffs;
 +    std::vector<std::vector<double> > _deno_multiply;
 +    std::vector<std::vector<double> > _deno_reverse_multiply;
 +  };
 +}
 +
 +#endif
index 9525247159c3a91f6b045aee73073dad51d5f9c4,0000000000000000000000000000000000000000..cfb06b1bbb62e8cd4784a5968445876633d5ba30
mode 100644,000000..100644
--- /dev/null
@@@ -1,90 -1,0 +1,97 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +// Author : Anthony Geay (CEA/DEN)
 +
 +#ifndef __OVERLAPMAPPING_HXX__
 +#define __OVERLAPMAPPING_HXX__
 +
 +#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 +
 +#include <vector>
 +#include <map>
 +
 +namespace ParaMEDMEM
 +{
 +  class ProcessorGroup;
 +  class DataArrayInt;
 +  class MEDCouplingFieldDouble;
 +
++  /*
++   * Internal class, not part of the public API.
++   *
++   * Used by the impl of OverlapInterpolationMatrix, plays an equivalent role than what the NxM_Mapping
++   * does for the InterpolationMatrix.
++   *
++   */
 +  class OverlapMapping
 +  {
 +  public:
 +    OverlapMapping(const ProcessorGroup& group);
 +    void keepTracksOfSourceIds(int procId, DataArrayInt *ids);
 +    void keepTracksOfTargetIds(int procId, DataArrayInt *ids);
 +    void addContributionST(const std::vector< std::map<int,double> >& matrixST, const DataArrayInt *srcIds, int srcProcId, const DataArrayInt *trgIds, int trgProcId);
 +    void prepare(const std::vector< std::vector<int> >& procsInInteraction, int nbOfTrgElems);
 +    void computeDenoConservativeVolumic(int nbOfTuplesTrg);
 +    void computeDenoGlobConstraint();
 +    //
 +    void multiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput) const;
 +    void transposeMultiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput);
 +  private:
 +    void serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigArr, int *count, int *offsets,
 +                                int *countForRecv, int *offsetsForRecv) const;
 +    int serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *recvStep0, const int *countStep0, const int *offsStep0,
 +                               int *&bigArrI, double *&bigArrD, int *count, int *offsets,
 +                               int *countForRecv, int *offsForRecv) const;
 +    void unserializationST(int nbOfTrgElems, const int *nbOfElemsSrcPerProc, const int *bigArrRecv, const int *bigArrRecvCounts, const int *bigArrRecvOffs,
 +                           const int *bigArrRecv2, const double *bigArrDRecv2, const int *bigArrRecv2Count, const int *bigArrRecv2Offs);
 +    void finishToFillFinalMatrixST();
 +    void prepareIdsToSendST();
 +    void updateZipSourceIdsForFuture();
 +    //void printTheMatrix() const;
 +  private:
 +    const ProcessorGroup &_group;
 +    //! vector of ids
 +    std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > _src_ids_st2;//item #1
 +    std::vector< int > _src_proc_st2;//item #1
 +    std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > _trg_ids_st2;//item #0
 +    std::vector< int > _trg_proc_st2;//item #0
 +    std::vector< int > _nb_of_src_ids_proc_st2;//item #1
 +    std::vector< int > _src_ids_proc_st2;//item #1
 +    std::vector< std::vector<int> > _src_ids_zip_st2;//same size as _src_ids_zip_proc_st2. Sorted. specifies for each id the corresponding ids to send. This is for item0 of Step2 of main algorithm
 +    std::vector< int > _src_ids_zip_proc_st2;
 +    //! vector of matrixes the first entry correspond to source proc id in _source_ids_st
 +    std::vector< std::vector< std::map<int,double> > > _matrixes_st;
 +    std::vector< std::vector<int> > _source_ids_st;
 +    std::vector< int > _source_proc_id_st;
 +    std::vector< std::vector<int> > _target_ids_st;
 +    std::vector< int > _target_proc_id_st;
 +    //! the matrix for matrix-vector product. The first dimension the set of target procs that interacts with local source mesh. The second dimension correspond to nb of local source ids. 
 +    std::vector< std::vector< std::map<int,double> > > _the_matrix_st;
 +    std::vector< int > _the_matrix_st_source_proc_id;
 +    std::vector< std::vector<int> > _the_matrix_st_source_ids;
 +    std::vector< std::vector< std::map<int,double> > > _the_deno_st;
 +    //! this attribute stores the proc ids that wait for data from this proc ids for matrix-vector computation
 +    std::vector< int > _proc_ids_to_send_vector_st;
 +    std::vector< int > _proc_ids_to_recv_vector_st;
 +    //! this attribute is of size _group.size(); for each procId in _group _source_ids_to_send_st[procId] contains tupleId to send abroad
 +    std::vector< std::vector<int> > _source_ids_to_send_st;
 +  };
 +}
 +
 +#endif
index 9995ccae18aac924f6455eb6ac4bc972adf03974,0000000000000000000000000000000000000000..e8e31e4eee00ecf7ccf4c0957d7ad3236a05214a
mode 100644,000000..100644
--- /dev/null
@@@ -1,228 -1,0 +1,227 @@@
-     It basically encapsulates
-     a MEDCouplingField with extra information related to parallel 
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ComponentTopology.hxx"
 +#include "ExplicitCoincidentDEC.hxx"
 +#include "StructuredCoincidentDEC.hxx"
 +#include "CommInterface.hxx"
 +#include "ProcessorGroup.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "ParaFIELD.hxx"
 +#include "ParaMESH.hxx"
 +#include "InterpKernelUtilities.hxx"
 +#include "InterpolationMatrix.hxx"
 +
 +#include <numeric>
 +
 +namespace ParaMEDMEM
 +{
 +  /*!
 +    \anchor ParaFIELD-det
 +    \class ParaFIELD
 +
 +    This class encapsulates parallel fields.
 +
-     It is most conveniently created by giving a pointer to a MEDCouplingField
-     object and a \c ProcessorGroup.
++    It gathers a \ref fields "MEDCouplingField" with some extra information related to the parallel
 +    topology.
 +
-     located on the same processors. In some specific cases, it might be necessary to scatter components over several processors. In this case, the constructor
-     using a ComponentTopology is required.
++    It is most conveniently created by giving a pointer to a MEDCouplingFieldDouble
++    object and a ProcessorGroup.
 +    By default, a ParaFIELD object will be constructed with all field components
-     \brief  Constructing a \c ParaFIELD from a \c ParaSUPPORT and a \c ComponentTopology.
++    located on the same processors. In some specific cases, it might be necessary to scatter components over
++    several processors. In this case, the constructor using a ComponentTopology is required.
 +
 +    */
 +
 +  /*!
 +
-     This constructor creates an empty field based on the ParaSUPPORT description 
++    \brief  Constructing a \c ParaFIELD from a \c ParaMESH and a \c ComponentTopology.
 +
-     This constructor supposes that support underlying \a subdomain_field has no ParaSUPPORT 
++    This constructor creates an empty field based on the ParaMESH description
 +    and the partitioning of components described in \a component_topology.
 +    It takes ownership over the \c _field object that it creates.
 +
 +    Here come the three ComponentTopology constructors :
 +    \verbatim
 +    ComponentTopology c; // one component in the field
 +    ComponentTopology c(6); //six components, all of them on the same processor
 +    ComponentTopology c(6, proc_group); // six components, evenly distributed over the processors of procgroup
 +    \endverbatim
 +
 +  */
 +  ParaFIELD::ParaFIELD(TypeOfField type, TypeOfTimeDiscretization td, ParaMESH* para_support, const ComponentTopology& component_topology)
 +    :_field(0),
 +     _component_topology(component_topology),_topology(0),_own_support(false),
 +     _support(para_support)
 +  {
 +    if (para_support->isStructured() || (para_support->getTopology()->getProcGroup()->size()==1 && component_topology.nbBlocks()!=1))
 +      {
 +        const BlockTopology* source_topo = dynamic_cast<const BlockTopology*>(para_support->getTopology());
 +        _topology=new BlockTopology(*source_topo,component_topology);
 +      }
 +    else
 +      {
 +        if (component_topology.nbBlocks()!=1 &&  para_support->getTopology()->getProcGroup()->size()!=1)
 +          throw INTERP_KERNEL::Exception(LOCALIZED("ParaFIELD constructor : Unstructured Support not taken into account with component topology yet"));
 +        else 
 +          {
 +            const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (para_support->getTopology());
 +            int nb_local_comp=component_topology.nbLocalComponents();
 +            _topology=new BlockTopology(*source_topo,nb_local_comp);
 +          }
 +      }
 +    int nb_components = component_topology.nbLocalComponents();
 +    if (nb_components!=0)
 +      {
 +        _field=MEDCouplingFieldDouble::New(type,td);
 +        _field->setMesh(_support->getCellMesh());
 +        DataArrayDouble *array=DataArrayDouble::New();
 +        array->alloc(_field->getNumberOfTuples(),nb_components);
 +        _field->setArray(array);
 +        array->decrRef();
 +      }
 +    else return;
 +  
 +    _field->setName("Default ParaFIELD name");
 +    _field->setDescription("Default ParaFIELD description");
 +  } 
 +
 +  /*! \brief Constructor creating the ParaFIELD
 +    from a given FIELD and a processor group. 
 +
++    This constructor supposes that support underlying \a subdomain_field has no ParaMESH
 +    attached and it therefore recreates one. It therefore takes ownership over _support. The component topology associated with the field is a basic one (all components on the same processor). 
 +  */
 +  ParaFIELD::ParaFIELD(MEDCouplingFieldDouble* subdomain_field, ParaMESH *sup, const ProcessorGroup& proc_group):
 +    _field(subdomain_field),
 +    _component_topology(ComponentTopology(_field->getNumberOfComponents())),_topology(0),_own_support(false),
 +    _support(sup)
 +  {
 +    if(_field)
 +      _field->incrRef();
 +    const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (_support->getTopology());
 +    _topology=new BlockTopology(*source_topo,_component_topology.nbLocalComponents());
 +  }
 +
 +  ParaFIELD::~ParaFIELD()
 +  {
 +    if(_field)
 +      _field->decrRef();
 +    if(_own_support)
 +      delete _support;
 +    delete _topology;
 +  }
 +
 +  void ParaFIELD::synchronizeTarget(ParaFIELD* source_field)
 +  {
 +    DisjointDEC* data_channel;
 +    if (dynamic_cast<BlockTopology*>(_topology)!=0)
 +      {
 +        data_channel=new StructuredCoincidentDEC;
 +      }
 +    else
 +      {
 +        data_channel=new ExplicitCoincidentDEC;
 +      }
 +    data_channel->attachLocalField(this);
 +    data_channel->synchronize();
 +    data_channel->prepareTargetDE();
 +    data_channel->recvData();
 +  
 +    delete data_channel;
 +  }
 +
 +  void ParaFIELD::synchronizeSource(ParaFIELD* target_field)
 +  {
 +    DisjointDEC* data_channel;
 +    if (dynamic_cast<BlockTopology*>(_topology)!=0)
 +      {
 +        data_channel=new StructuredCoincidentDEC;
 +      }
 +    else
 +      {
 +        data_channel=new ExplicitCoincidentDEC;
 +      }
 +    data_channel->attachLocalField(this);
 +    data_channel->synchronize();
 +    data_channel->prepareSourceDE();
 +    data_channel->sendData();
 +  
 +    delete data_channel;
 +  }
 +
 +  /*!
 +   * This method returns, if it exists, an array with only one component and as many as tuples as _field has.
 +   * This array gives for every element on which this->_field lies, its global number, if this->_field is nodal.
 +   * For example if _field is a nodal field : returned array will be the nodal global numbers.
 +   * The content of this method is used to inform Working side to accumulate data recieved by lazy side.
 +   */
 +  DataArrayInt* ParaFIELD::returnCumulativeGlobalNumbering() const
 +  {
 +    if(!_field)
 +      return 0;
 +    TypeOfField type=_field->getTypeOfField();
 +    switch(type)
 +      {
 +      case ON_CELLS:
 +        return 0;
 +      case ON_NODES:
 +        return _support->getGlobalNumberingNodeDA();
 +      default:
 +        return 0;
 +      }
 +  }
 +
 +  DataArrayInt* ParaFIELD::returnGlobalNumbering() const
 +  {
 +    if(!_field)
 +      return 0;
 +    TypeOfField type=_field->getTypeOfField();
 +    switch(type)
 +      {
 +      case ON_CELLS:
 +        return _support->getGlobalNumberingCellDA();
 +      case ON_NODES:
 +        return _support->getGlobalNumberingNodeDA();
 +      default:
 +        return 0;
 +      }
 +  }
 +  
 +  int ParaFIELD::nbComponents() const
 +  {
 +    return _component_topology.nbComponents();
 +  }
 +
 +
 +  /*! This method retrieves the integral of component \a icomp
 +    over the all domain. */
 +  double ParaFIELD::getVolumeIntegral(int icomp, bool isWAbs) const
 +  {
 +    CommInterface comm_interface = _topology->getProcGroup()->getCommInterface();
 +    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);
 +  
 +    return total;
 +  }
 +}
index 2f5f8936712a53fd665fcf452a5c8b979d304cd1,0000000000000000000000000000000000000000..fe0a6f9d7e0656c4cc5916dbc13fb9d31b2e00c1
mode 100644,000000..100644
--- /dev/null
@@@ -1,66 -1,0 +1,64 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __PARAFIELD_HXX__
 +#define __PARAFIELD_HXX__
 +
 +#include "MEDCouplingRefCountObject.hxx"
 +#include "ComponentTopology.hxx"
 +
 +namespace ParaMEDMEM
 +{
 +  class DataArrayInt;
 +  class ParaMESH;
 +  class ProcessorGroup;
 +  class MEDCouplingFieldDouble;
 +  class ComponentTopology;
 +  class Topology;
 +
 +  class ParaFIELD
 +  {
 +  public:
 +    ParaFIELD(TypeOfField type, TypeOfTimeDiscretization td, ParaMESH* mesh, const ComponentTopology& component_topology); 
-   
 +    ParaFIELD(MEDCouplingFieldDouble* field, ParaMESH *sup, const ProcessorGroup& group);
 +    virtual ~ParaFIELD();
++
 +    void synchronizeTarget( ParaMEDMEM::ParaFIELD* source_field);
 +    void synchronizeSource( ParaMEDMEM::ParaFIELD* target_field);
 +    MEDCouplingFieldDouble* getField() const { return _field; }
 +    void setOwnSupport(bool v) const { _own_support=v; }
 +    DataArrayInt* returnCumulativeGlobalNumbering() const;
 +    DataArrayInt* returnGlobalNumbering() const;
 +    Topology* getTopology() const { return _topology; }
 +    ParaMESH* getSupport() const  { return _support; }
 +    int nbComponents() const;
 +    double getVolumeIntegral(int icomp, bool isWAbs) const;
 +    double getL2Norm()const { return -1; }
++
 +  private:
 +    MEDCouplingFieldDouble* _field;
 +    ParaMEDMEM::ComponentTopology _component_topology;
 +    Topology* _topology; 
 +    mutable bool _own_support;
 +    ParaMESH* _support;
 +  };
 +
 +}
 +
 +#endif
index f45c1e7ac6a69b942695b5504e281c25c37eacaf,0000000000000000000000000000000000000000..8b26bd5f93aef42280ef7a585dd8dbeb19d4b835
mode 100644,000000..100644
--- /dev/null
@@@ -1,74 -1,0 +1,74 @@@
-   ParaGRID::ParaGRID(MEDCouplingCMesh* global_grid, Topology* topology) throw(INTERP_KERNEL::Exception)
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "ParaGRID.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +#include "MEDCouplingCMesh.hxx"
 +#include "InterpKernelUtilities.hxx"
 +
 +#include <iostream>
 +
 +using namespace std;
 +
 +namespace ParaMEDMEM
 +{
 +  
-   
++  ParaGRID::ParaGRID(MEDCouplingCMesh* global_grid, Topology* topology) throw(INTERP_KERNEL::Exception) :
++    _global_axis(), _my_domain_id(0)
 +  {
 +    _block_topology = dynamic_cast<BlockTopology*>(topology);
 +    if(_block_topology==0)
 +      throw INTERP_KERNEL::Exception(LOCALIZED("ParaGRID::ParaGRID topology must be block topology"));
 +    
 +    if (!_block_topology->getProcGroup()->containsMyRank())
 +      return;
 +    
 +    int dimension=_block_topology->getDimension() ;
 +    if (dimension != global_grid->getSpaceDimension())
 +      throw INTERP_KERNEL::Exception(LOCALIZED("ParaGrid::ParaGrid incompatible topology"));
 +    _grid=global_grid;
 +    _grid->incrRef();
 +    /*vector<vector<double> > xyz_array(dimension);
 +      vector<pair<int,int> > local_indices = _block_topology->getLocalArrayMinMax();
 +      vector <string> coordinates_names;
 +      vector <string> coordinates_units;
 +      for (int idim=0; idim<dimension ; idim++)
 +      {
 +      DataArrayDouble *array=global_grid->getCoordsAt(idim);
 +      double *arrayC=array->getPointer();
 +      cout << " Indices "<< local_indices[idim].first <<" "<<local_indices[idim].second<<endl;
 +      for (int i=(local_indices)[idim].first; i<(local_indices)[idim].second; i++)
 +      xyz_array[idim].push_back(arrayC[i]);
 +      coordinates_names.push_back(array->getName());
 +      coordinates_units.push_back(array->getInfoOnComponentAt(0));
 +      }
 +      _grid=MEDCouplingCMesh::New();
 +      _grid->set(xyz_array, coordinates_names,coordinates_units);
 +      _grid->setName(global_grid->getName());
 +      _grid->setDescription(global_grid->getDescription());*/
 +  }
 +
 +  ParaGRID::~ParaGRID()
 +  {
 +    if(_grid)
 +      _grid->decrRef();
 +  }
 +}
index 2335b9d6c82e0f864971e4b67784a82c31e13e17,0000000000000000000000000000000000000000..72a0109ecd374045804af4c8c13429ea13985c34
mode 100644,000000..100644
--- /dev/null
@@@ -1,51 -1,0 +1,55 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __PARAGRID_HXX__
 +#define __PARAGRID_HXX__
 +
 +#include "InterpolationUtils.hxx"
 +
 +#include <vector>
 +
 +namespace ParaMEDMEM
 +{
 +  class Topology;
 +  class BlockTopology;
 +  class MEDCouplingCMesh;
 +
++  /*!
++   * This class
++   * Equivalent of a ParaMESH for a structured mesh
++   */
 +  class ParaGRID
 +  {
 +  public:
 +    ParaGRID(MEDCouplingCMesh* global_grid, Topology* topology) throw(INTERP_KERNEL::Exception);
 +    BlockTopology * getBlockTopology() const { return _block_topology; }
 +    virtual ~ParaGRID();
 +    MEDCouplingCMesh* getGrid() const { return _grid; }
 +  private:
 +    MEDCouplingCMesh* _grid;
 +    // structured grid topology
 +    ParaMEDMEM::BlockTopology* _block_topology;
 +    // stores the x,y,z axes on the global grid
 +    std::vector<std::vector<double> > _global_axis;
 +    //id of the local grid
 +    int _my_domain_id;
 +  };
 +}
 +
 +#endif
index a6482a554c87b74317af1f7c7e76c39da7cd5cc9,0000000000000000000000000000000000000000..70b1ffff71ce11eff7b1449c8586195202280b2d
mode 100644,000000..100644
--- /dev/null
@@@ -1,122 -1,0 +1,122 @@@
- // Copyright (C) 2007-2015  CEA/DEN, EDF R&D
 +//
++// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 "ParaMESH.hxx"
 +#include "ProcessorGroup.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +
 +#include <fstream>
 +#include <vector>
 +
 +//inclusion for the namespaces
 +using namespace std;
 +
 +namespace ParaMEDMEM
 +{
 +  ParaMESH::ParaMESH( MEDCouplingPointSet *subdomain_mesh, MEDCouplingPointSet *subdomain_face,
 +            DataArrayInt *CorrespElt_local2global, DataArrayInt *CorrespFace_local2global,
 +            DataArrayInt *CorrespNod_local2global, const ProcessorGroup& proc_group ):
 +    _cell_mesh(subdomain_mesh),
 +    _face_mesh(subdomain_face),
 +    _my_domain_id(proc_group.myRank()),
 +    _block_topology (new BlockTopology(proc_group, subdomain_mesh->getNumberOfCells())),
 +    _explicit_topology(0),
 +    _node_global(CorrespNod_local2global),
 +    _face_global(CorrespFace_local2global),
 +    _cell_global(CorrespElt_local2global)
 +  {
 +    if(_cell_mesh)
 +      _cell_mesh->incrRef();
 +    if(_face_mesh)
 +      _face_mesh->incrRef();
 +    if(CorrespElt_local2global)
 +      CorrespElt_local2global->incrRef();
 +    if(CorrespFace_local2global)
 +      CorrespFace_local2global->incrRef();
 +    if(CorrespNod_local2global)
 +      CorrespNod_local2global->incrRef();
 +  }
 +
 +  ParaMESH::ParaMESH( MEDCouplingPointSet *mesh, const ProcessorGroup& proc_group, const std::string& name):
 +    _cell_mesh(mesh),
 +    _face_mesh(0),
 +    _my_domain_id(proc_group.myRank()),
 +    _block_topology (new BlockTopology(proc_group, mesh->getNumberOfCells())),
 +    _node_global(0),
 +    _face_global(0)
 +  {
 +    if(_cell_mesh)
 +      _cell_mesh->incrRef();
 +    int nb_elem=mesh->getNumberOfCells();
 +    _explicit_topology=new BlockTopology(proc_group,nb_elem);
 +    int nbOfCells=mesh->getNumberOfCells();
 +    _cell_global = DataArrayInt::New();
 +    _cell_global->alloc(nbOfCells,1);
 +    int *cellglobal=_cell_global->getPointer();
 +    int offset = _block_topology->localToGlobal(make_pair(_my_domain_id,0));
 +    for (int i=0; i<nbOfCells; i++)
 +      {
 +        cellglobal[i]=offset+i;
 +      }
 +  }
 +
 +  void ParaMESH::setNodeGlobal(DataArrayInt *nodeGlobal)
 +  {
 +    if(nodeGlobal!=_node_global)
 +      {
 +        if(_node_global)
 +          _node_global->decrRef();
 +        _node_global=nodeGlobal;
 +        if(_node_global)
 +          _node_global->incrRef();
 +      }
 +  }
 +
 +  void ParaMESH::setCellGlobal(DataArrayInt *cellGlobal)
 +  {
 +    if(cellGlobal!=_cell_global)
 +      {
 +        if(_cell_global)
 +          _cell_global->decrRef();
 +        _cell_global=cellGlobal;
 +        if(_cell_global)
 +          _cell_global->incrRef();
 +      }
 +  }
 +
 +  ParaMESH::~ParaMESH()
 +  {
 +    if(_cell_mesh)
 +      _cell_mesh->decrRef();
 +    if(_face_mesh)
 +      _face_mesh->decrRef();
 +    delete _block_topology;
 +    if(_node_global)
 +      _node_global->decrRef();
 +    if(_cell_global)
 +      _cell_global->decrRef();
 +    if(_face_global)
 +      _face_global->decrRef();
 +    delete _explicit_topology;
 +  }
 +
 +}
index 391bff5dd59b3b8dc4cb90e6bee4b6d2122e30f4,0000000000000000000000000000000000000000..06c6d754af132d0be97dc838593fe7e15ec9341a
mode 100644,000000..100644
--- /dev/null
@@@ -1,82 -1,0 +1,93 @@@
-     ParaMESH( MEDCouplingPointSet *mesh,
-               const ProcessorGroup& proc_group, const std::string& name);
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __PARAMESH_HXX__
 +#define __PARAMESH_HXX__
 +
 +#include "MEDCouplingPointSet.hxx"
 +#include "ProcessorGroup.hxx"
 +#include "MEDCouplingMemArray.hxx"
 +
 +#include <string>
 +#include <vector>
 +
 +namespace ParaMEDMEM
 +{
 +  class Topology;
 +  class BlockTopology;
 +  class DataArrayInt;
 +
++  /*!
++   * \anchor ParaMESH-det
++   *
++   * Parallel representation of an unstructured mesh.
++   *
++   * This class is very specific to the requirement of parallel code computations.
++   * Two main constructors are available:
++   * - the most simple one, taking directly a \ref meshes "MEDCoupling mesh" object
++   * - the second one (for an advanced usage), which can be used to specify an explicit topology
++   * in a parallel computation.
++   */
 +  class ParaMESH
 +  {
 +  public:
++    ParaMESH( MEDCouplingPointSet *mesh,
++              const ProcessorGroup& proc_group, const std::string& name);
 +    ParaMESH( MEDCouplingPointSet *subdomain_mesh,
 +              MEDCouplingPointSet *subdomain_face,
 +              DataArrayInt *CorrespElt_local2global,
 +              DataArrayInt *CorrespFace_local2global,
 +              DataArrayInt *CorrespNod_local2global,
 +              const ProcessorGroup& proc_group ) ;
 +
 +    virtual ~ParaMESH();
 +    void setNodeGlobal(DataArrayInt *nodeGlobal);
 +    void setCellGlobal(DataArrayInt *cellGlobal);
 +    Topology* getTopology() const { return _explicit_topology; }
 +    bool isStructured() const { return _cell_mesh->isStructured(); }
 +    MEDCouplingPointSet *getCellMesh() const { return _cell_mesh; }
 +    MEDCouplingPointSet *getFaceMesh() const { return _face_mesh; }
 +    BlockTopology* getBlockTopology() const { return _block_topology; }
 +
 +    DataArrayInt* getGlobalNumberingNodeDA() const { if(_node_global) _node_global->incrRef(); return _node_global; }
 +    DataArrayInt* getGlobalNumberingFaceDA() const { if(_face_global) _face_global->incrRef(); return _face_global; }
 +    DataArrayInt* getGlobalNumberingCellDA() const { if(_cell_global) _cell_global->incrRef(); return _cell_global; }
 +    const int* getGlobalNumberingNode() const { if(_node_global) return _node_global->getConstPointer(); return 0; }
 +    const int* getGlobalNumberingFace() const { if(_face_global) return _face_global->getConstPointer(); return 0; }
 +    const int* getGlobalNumberingCell() const { if(_cell_global) return _cell_global->getConstPointer(); return 0; }
 +
 +  private:
 +    //mesh object underlying the ParaMESH object
 +    MEDCouplingPointSet *_cell_mesh ;
 +    MEDCouplingPointSet *_face_mesh ;
 +
 +    //id of the local grid
 +    int _my_domain_id;
 +
 +    //global topology of the cells
 +    ParaMEDMEM::BlockTopology* _block_topology;
 +    Topology*  _explicit_topology;
 +    // pointers to global numberings
 +    DataArrayInt* _node_global;
 +    DataArrayInt* _face_global;
 +    DataArrayInt* _cell_global;
 +  };
 +}
 +
 +#endif
index 344704a9f77e4eebafca6f53f8372ca7b109b434,0000000000000000000000000000000000000000..972219b9e9377bd76b562da45bca86784b87dda8
mode 100644,000000..100644
--- /dev/null
@@@ -1,60 -1,0 +1,65 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __PROCESSORGROUP_HXX__
 +#define __PROCESSORGROUP_HXX__
 +
 +#include "CommInterface.hxx"
 +
 +#include <set>
 +
 +namespace ParaMEDMEM
 +{
++  /*!
++   * Abstract class defining a group of processors (computation nodes) in a parallel run of a code.
++   *
++   * See the non-abstract child \ref MPIProcessorGroup-det "MPIProcessorGroup"
++   */
 +  class ProcessorGroup
 +  {
 +  public:
 +  
 +    ProcessorGroup(const CommInterface& interface):_comm_interface(interface) { }
 +    ProcessorGroup(const CommInterface& interface, std::set<int> proc_ids):
 +      _comm_interface(interface),_proc_ids(proc_ids) { }
 +    ProcessorGroup (const ProcessorGroup& proc_group, std::set<int> proc_ids):
 +      _comm_interface(proc_group.getCommInterface()),_proc_ids(proc_ids) { }
 +    ProcessorGroup (const ProcessorGroup& other):
 +      _comm_interface(other.getCommInterface()),_proc_ids(other._proc_ids) { }
 +    ProcessorGroup (const CommInterface& interface, int start, int end);
 +    virtual ~ProcessorGroup() { }
 +    virtual ProcessorGroup *deepCpy() const = 0;
 +    virtual ProcessorGroup* fuse (const ProcessorGroup&) const = 0;
 +    virtual void intersect (ProcessorGroup&) = 0;
 +    bool contains(int rank) const { return _proc_ids.find(rank)!=_proc_ids.end(); }
 +    virtual bool containsMyRank() const = 0;
 +    int size() const  { return _proc_ids.size(); }
 +    const CommInterface& getCommInterface()const { return _comm_interface; }
 +    virtual int myRank() const = 0;
 +    virtual int translateRank(const ProcessorGroup*, int) const = 0;
 +    virtual ProcessorGroup* createComplementProcGroup() const = 0;
 +    virtual ProcessorGroup* createProcGroup() const = 0;
 +    virtual const std::set<int>& getProcIDs()const  { return _proc_ids; } 
 +  protected:
 +    const CommInterface _comm_interface;
 +    std::set<int> _proc_ids;
 +  };
 +}
 +
 +#endif
index 1e88a958154a60582810d7e0d6b2192d2fbd36f4,0000000000000000000000000000000000000000..9620ba1358bbb937ad70fc6065e1e0793f672888
mode 100644,000000..100644
--- /dev/null
@@@ -1,412 -1,0 +1,419 @@@
-     This class is meant for remapping fields that have identical
-     supports with different parallel topologies. It can be used to couple
-     together multiphysics codes that operate on the same domain
-     with different partitionings, which can be useful if one of
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 <mpi.h>
 +#include "CommInterface.hxx"
 +#include "Topology.hxx"
 +#include "BlockTopology.hxx"
 +#include "ComponentTopology.hxx"
 +#include "ParaFIELD.hxx"
 +#include "MPIProcessorGroup.hxx"
 +#include "StructuredCoincidentDEC.hxx"
 +#include "InterpKernelUtilities.hxx"
 +
 +#include <iostream>
 +
 +using namespace std;
 +
 +namespace ParaMEDMEM
 +{
 +
 +  /*!
 +    \anchor StructuredCoincidentDEC-det
 +    \class StructuredCoincidentDEC
 +
-     Also, this \ref para-dec can be used for fields that have component topologies,
++    This class aims at \ref interpolation "remapping fields" that have identical
++    structured supports (=the same underlying mesh) but different parallel topologies
++    (=different sub-domains in the structured mesh). It can be used to couple
++    together multi-physics codes that operate on the same domain
++    with different partitioning. This can be useful for example if one of
 +    the computation is much faster than the other. It can also be used 
 +    to couple together codes that share an interface that was generated
 +    in the same manner (with identical global ids). 
-     ids, instead of geometrical considerations as it is the case for
-     \ref NonCoincidentDEC-det "NonCoincidentDEC" and \ref InterpKernelDEC-det "InterpKernelDEC".
-     Therefore, this \ref para-dec "DEC" must not be used
-     for coincident meshes that do not have the same numbering.
++    Also, this \ref para-dec "DEC" can be used for fields that have component topologies,
 +    i.e., components that are scattered over several processors.
 +
 +    The remapping between the two supports is based on identity of global
-     As all the other DECs, its use is made of two phases :
++    ids, instead of geometrical considerations (as it is the case for
++    \ref InterpKernelDEC-det "InterpKernelDEC").
++    Therefore, beware that this \ref para-dec "DEC" can not be used
++    for coincident meshes if they do *not* have the exact same numbering.
 +
-     Creating a ParaFIELD to be attached to the DEC is exactly the same as for 
-     other DECs in the case when the remapping concerns similar meshes 
-     that only have different partitionings. In the case when the
-     fields have also different component topologies, creating the ParaFIELD 
-     requires some more effort. See the \ref para-over section for more details.
++    With this %DEC no projection, and no interpolation of the field data is done, contrary
++    to what happens in \ref InterpKernelDEC-det "InterpKernelDEC". It is just
++    a matter of allocating the values from one side to the other, using directly the cell
++    identifiers.
++
++    As all the other DECs, its usage requires two phases :
 +    - a setup phase during which the topologies are exchanged so that
 +    the target side knows from which processors it should expect 
 +    the data.
 +    - a send/recv phase during which the field data is actually transferred.
 +
 +    This example illustrates the sending of a field with 
 +    the \c StructuredCoincidentDEC : 
 +    \code
 +    ...
 +    StructuredCoincidentDEC dec(groupA, groupB);
 +    dec.attachLocalField(field);
 +    dec.synchronize();
 +    if (groupA.containsMyRank())
 +    dec.recvData();
 +    else if (groupB.containsMyRank())
 +    dec.sendData();
 +    ...
 +    \endcode
 +
-   StructuredCoincidentDEC::StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group):DisjointDEC(local_group,distant_group),
-                                                                                                                _topo_source(0),_topo_target(0),
-                                                                                                                _send_counts(0),_recv_counts(0),
-                                                                                                                _send_displs(0),_recv_displs(0),
-                                                                                                                _recv_buffer(0),_send_buffer(0)
++    Creating a ParaFIELD to be attached to the %DEC is done in exactly the same way as for
++    the other DECs, if only the partitioning of the support mesh differs.
++    In the case where the
++    fields have also different *component* topologies, creating the ParaFIELD
++    requires some more effort. See the \ref para-over "parallelism" section for more details.
 +  */
 +
 +
 +  StructuredCoincidentDEC::StructuredCoincidentDEC():_topo_source(0),_topo_target(0),
 +                                                     _send_counts(0),_recv_counts(0),
 +                                                     _send_displs(0),_recv_displs(0),
 +                                                     _recv_buffer(0),_send_buffer(0)
 +  {  
 +  }
 +
 +
 +  StructuredCoincidentDEC::~StructuredCoincidentDEC()
 +  {
 +    delete [] _send_buffer;
 +    delete [] _recv_buffer;
 +    delete []_send_displs;
 +    delete [] _recv_displs;
 +    delete [] _send_counts;
 +    delete [] _recv_counts;
 +    if (! _source_group->containsMyRank())
 +      delete _topo_source;
 +    if(!_target_group->containsMyRank())
 +      delete _topo_target;
 +  }
 +
++  StructuredCoincidentDEC::StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group):
++      DisjointDEC(local_group,distant_group),
++      _topo_source(0),_topo_target(0),
++      _send_counts(0),_recv_counts(0),
++      _send_displs(0),_recv_displs(0),
++      _recv_buffer(0),_send_buffer(0)
 +  {
 +  }
 +
 +  /*! Synchronization process for exchanging topologies
 +   */
 +  void StructuredCoincidentDEC::synchronizeTopology()
 +  {
 +    if (_source_group->containsMyRank())
 +      _topo_source = dynamic_cast<BlockTopology*>(_local_field->getTopology());
 +    if (_target_group->containsMyRank())
 +      _topo_target = dynamic_cast<BlockTopology*>(_local_field->getTopology());
 +  
 +    // Transmitting source topology to target code 
 +    broadcastTopology(_topo_source,1000);
 +    // Transmitting target topology to source code
 +    broadcastTopology(_topo_target,2000);
 +    if (_topo_source->getNbElements() != _topo_target->getNbElements())
 +      throw INTERP_KERNEL::Exception("Incompatible dimensions for target and source topologies");
 +
 +  }
 +
 +  /*! Creates the arrays necessary for the data transfer
 +   * and fills the send array with the values of the 
 +   * source field
 +   *  */
 +  void StructuredCoincidentDEC::prepareSourceDE()
 +  {
 +    ////////////////////////////////////
 +    //Step 1 : _buffer array creation 
 +  
 +    if (!_topo_source->getProcGroup()->containsMyRank())
 +      return;
 +    MPIProcessorGroup* group=new MPIProcessorGroup(_topo_source->getProcGroup()->getCommInterface());
 +  
 +    int myranksource = _topo_source->getProcGroup()->myRank();
 +  
 +    vector <int>* target_arrays=new vector<int>[_topo_target->getProcGroup()->size()];
 +  
 +    //cout<<" topotarget size"<<  _topo_target->getProcGroup()->size()<<endl;
 +  
 +    int nb_local = _topo_source-> getNbLocalElements();
 +    for (int ielem=0; ielem< nb_local ; ielem++)
 +      {
 +        //  cout <<"source local :"<<myranksource<<","<<ielem<<endl; 
 +        int global = _topo_source->localToGlobal(make_pair(myranksource, ielem));
 +        //  cout << "global "<<global<<endl;
 +        pair<int,int> target_local =_topo_target->globalToLocal(global);
 +        //  cout << "target local : "<<target_local.first<<","<<target_local.second<<endl; 
 +        target_arrays[target_local.first].push_back(target_local.second); 
 +      }  
 +  
 +    int union_size=group->size();
 +  
 +    _send_counts=new int[union_size];
 +    _send_displs=new int[union_size];
 +    _recv_counts=new int[union_size];
 +    _recv_displs=new int[union_size];
 +     
 +    for (int i=0; i< union_size; i++)
 +      {
 +        _send_counts[i]=0;
 +        _recv_counts[i]=0;
 +        _recv_displs[i]=0;
 +      }
 +    _send_displs[0]=0;
 +  
 +    for (int iproc=0; iproc < _topo_target->getProcGroup()->size(); iproc++)
 +      {
 +        //converts the rank in target to the rank in union communicator
 +        int unionrank=group->translateRank(_topo_target->getProcGroup(),iproc);
 +        _send_counts[unionrank]=target_arrays[iproc].size();
 +      }
 +  
 +    for (int iproc=1; iproc<group->size();iproc++)
 +      _send_displs[iproc]=_send_displs[iproc-1]+_send_counts[iproc-1];
 +  
 +    _send_buffer = new double [nb_local ];
 +
 +    /////////////////////////////////////////////////////////////
 +    //Step 2 : filling the _buffers with the source field values 
 +
 +    int* counter=new int [_topo_target->getProcGroup()->size()];
 +    counter[0]=0;  
 +    for (int i=1; i<_topo_target->getProcGroup()->size(); i++)
 +      counter[i]=counter[i-1]+target_arrays[i-1].size();
 +    
 +      
 +    const double* value = _local_field->getField()->getArray()->getPointer();
 +    //cout << "Nb local " << nb_local<<endl;
 +    for (int ielem=0; ielem<nb_local ; ielem++)
 +      {
 +        int global = _topo_source->localToGlobal(make_pair(myranksource, ielem));
 +        pair<int,int> target_local =_topo_target->globalToLocal(global);
 +        //cout <<"global : "<< global<<" local :"<<target_local.first<<" "<<target_local.second;
 +        //cout <<"counter[]"<<counter[target_local.first]<<endl;
 +        _send_buffer[counter[target_local.first]++]=value[ielem];
 +    
 +      }
 +    delete[] target_arrays;
 +    delete[] counter;
 +    delete group;
 +  }
 +
 +  /*!
 +   *  Creates the buffers for receiving the fields on the target side
 +   */
 +  void StructuredCoincidentDEC::prepareTargetDE()
 +  {
 +    if (!_topo_target->getProcGroup()->containsMyRank())
 +      return;
 +    MPIProcessorGroup* group=new MPIProcessorGroup(_topo_source->getProcGroup()->getCommInterface());
 +  
 +    int myranktarget = _topo_target->getProcGroup()->myRank();
 +  
 +    vector < vector <int> > source_arrays(_topo_source->getProcGroup()->size());
 +    int nb_local = _topo_target-> getNbLocalElements();
 +    for (int ielem=0; ielem< nb_local ; ielem++)
 +      {
 +        //  cout <<"TS target local :"<<myranktarget<<","<<ielem<<endl; 
 +        int global = _topo_target->localToGlobal(make_pair(myranktarget, ielem));
 +        //cout << "TS global "<<global<<endl;
 +        pair<int,int> source_local =_topo_source->globalToLocal(global);
 +        //  cout << "TS source local : "<<source_local.first<<","<<source_local.second<<endl; 
 +        source_arrays[source_local.first].push_back(source_local.second); 
 +      }  
 +    int union_size=group->size();
 +    _recv_counts=new int[union_size];
 +    _recv_displs=new int[union_size];
 +    _send_counts=new int[union_size];
 +    _send_displs=new int[union_size];
 +    
 +    for (int i=0; i< union_size; i++)
 +      {
 +        _send_counts[i]=0;
 +        _recv_counts[i]=0;
 +        _recv_displs[i]=0;
 +      }
 +    for (int iproc=0; iproc < _topo_source->getProcGroup()->size(); iproc++)
 +      {
 +        //converts the rank in target to the rank in union communicator
 +        int unionrank=group->translateRank(_topo_source->getProcGroup(),iproc);
 +        _recv_counts[unionrank]=source_arrays[iproc].size();
 +      }
 +    for (int i=1; i<union_size; i++)
 +      _recv_displs[i]=_recv_displs[i-1]+_recv_counts[i-1];
 +    _recv_buffer=new double[nb_local];
 +    
 +    delete group;
 +  }
 +
 + 
 +  /*!
 +   * Synchronizing a topology so that all the 
 +   * group possesses it.
 +   * 
 +   * \param topo Topology that is transmitted. It is read on processes where it already exists, and it is created and filled on others.
 +   * \param tag Communication tag associated with this operation.
 +   */
 +  void StructuredCoincidentDEC::broadcastTopology(BlockTopology*& topo, int tag)
 +  {
 +    MPI_Status status;
 +  
 +    int* serializer=0;
 +    int size;
 +  
 +    MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface);
 +  
 +    // The master proc creates a send buffer containing
 +    // a serialized topology
 +    int rank_master;
 +  
 +    if (topo!=0 && topo->getProcGroup()->myRank()==0)
 +      {
 +        MESSAGE ("Master rank");
 +        topo->serialize(serializer, size);
 +        rank_master = group->translateRank(topo->getProcGroup(),0);
 +        MESSAGE("Master rank world number is "<<rank_master);
 +        MESSAGE("World Size is "<<group->size());
 +        for (int i=0; i< group->size(); i++)
 +          {
 +            if (i!= rank_master)
 +              _comm_interface->send(&rank_master,1,MPI_INT, i,tag+i,*(group->getComm()));
 +          }
 +      }
 +    else
 +      {
 +        MESSAGE(" rank "<<group->myRank()<< " waiting ...");
 +        _comm_interface->recv(&rank_master, 1,MPI_INT, MPI_ANY_SOURCE, tag+group->myRank(), *(group->getComm()),&status);
 +        MESSAGE(" rank "<<group->myRank()<< "received master rank"<<rank_master);
 +      }
 +    // The topology is broadcasted to all processsors in the group
 +    _comm_interface->broadcast(&size, 1,MPI_INT,rank_master,*(group->getComm()));
 +  
 +    int* buffer=new int[size];
 +    if (topo!=0 && topo->getProcGroup()->myRank()==0)
 +      copy(serializer, serializer+size, buffer); 
 +    _comm_interface->broadcast(buffer,size,MPI_INT,rank_master,*(group->getComm()));
 +  
 +    // Processors which did not possess the source topology 
 +    // unserialize it
 +  
 +    BlockTopology* topotemp=new BlockTopology();
 +    topotemp->unserialize(buffer, *_comm_interface);
 +  
 +    if (topo==0) 
 +      topo=topotemp;
 +    else 
 +      delete topotemp;
 +  
 +    // Memory cleaning
 +    delete[] buffer;
 +    if (serializer!=0)
 +      delete[] serializer;
 +    MESSAGE (" rank "<<group->myRank()<< " unserialize is over");
 +    delete group;
 +  }
 +
 +
 +
 +  void StructuredCoincidentDEC::recvData()
 +  {
 +    //MPI_COMM_WORLD is used instead of group because there is no
 +    //mechanism for creating the union group yet
 +    MESSAGE("recvData");
 +    for (int i=0; i< 4; i++)
 +      cout << _recv_counts[i]<<" ";
 +    cout <<endl;
 +    for (int i=0; i< 4; i++)
 +      cout << _recv_displs[i]<<" ";
 +    cout <<endl;
 +  
 +    cout<<"start AllToAll"<<endl;
 +    MPI_Comm comm = *(dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm());
 +    _comm_interface->allToAllV(_send_buffer, _send_counts, _send_displs, MPI_DOUBLE, 
 +                               _recv_buffer, _recv_counts, _recv_displs, MPI_DOUBLE,comm);
 +    cout<<"end AllToAll"<<endl;
 +
 +    int nb_local = _topo_target->getNbLocalElements();
 +    //double* value=new double[nb_local];
 +    double* value=const_cast<double*>(_local_field->getField()->getArray()->getPointer());
 +  
 +    int myranktarget=_topo_target->getProcGroup()->myRank();
 +    vector<int> counters(_topo_source->getProcGroup()->size());
 +    counters[0]=0;
 +    for (int i=0; i<_topo_source->getProcGroup()->size()-1; i++)
 +      {
 +        MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface);
 +        int worldrank=group->translateRank(_topo_source->getProcGroup(),i);
 +        counters[i+1]=counters[i]+_recv_counts[worldrank];
 +        delete group;
 +      }
 +  
 +    for (int ielem=0; ielem<nb_local ; ielem++)
 +      {
 +        int global = _topo_target->localToGlobal(make_pair(myranktarget, ielem));
 +        pair<int,int> source_local =_topo_source->globalToLocal(global);
 +        value[ielem]=_recv_buffer[counters[source_local.first]++];
 +      }
 +  
 +  
 +    //_local_field->getField()->setValue(value);
 +  }
 +
 +  void StructuredCoincidentDEC::sendData()
 +  {
 +    MESSAGE ("sendData");
 +    for (int i=0; i< 4; i++)
 +      cout << _send_counts[i]<<" ";
 +    cout <<endl;
 +    for (int i=0; i< 4; i++)
 +      cout << _send_displs[i]<<" ";
 +    cout <<endl;
 +    cout <<"start AllToAll"<<endl;
 +    MPI_Comm comm = *(dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm());
 +    _comm_interface->allToAllV(_send_buffer, _send_counts, _send_displs, MPI_DOUBLE, 
 +                               _recv_buffer, _recv_counts, _recv_displs, MPI_DOUBLE,comm);
 +    cout<<"end AllToAll"<<endl;
 +  }
 +
 +  /*! Prepares a DEC for data exchange
 +
 +    This method broadcasts the topologies from source to target 
 +    so that the target side can analyse from which processors it
 +    is expected to receive data. 
 +  */
 +  
 +  void StructuredCoincidentDEC::synchronize()
 +  {
 +    if (_source_group->containsMyRank())
 +      {
 +        synchronizeTopology();
 +        prepareSourceDE();
 +      }
 +    else if (_target_group->containsMyRank())
 +      {
 +        synchronizeTopology();
 +        prepareTargetDE();
 +      }
 +  }
 +}
 +
index 75f63b4f04044185a19dd71deb10a5061a2755c1,0000000000000000000000000000000000000000..1653467b19ca81a60496b6a7d80852fe3c6c2b1e
mode 100644,000000..100644
--- /dev/null
@@@ -1,58 -1,0 +1,59 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __STRUCTUREDCOINCIDENTDEC_HXX__
 +#define __STRUCTUREDCOINCIDENTDEC_HXX__
 +
 +#include "DisjointDEC.hxx"
 +#include "BlockTopology.hxx"
 +
 +
 +namespace ParaMEDMEM
 +{
 +  class DEC;
 +  class BlockTopology;
++
 +  class StructuredCoincidentDEC : public DisjointDEC
 +  {
 +  public:
 +    StructuredCoincidentDEC();
 +    StructuredCoincidentDEC( ProcessorGroup& source, ProcessorGroup& target);
 +    virtual ~StructuredCoincidentDEC();
 +    void synchronize();
 +    void recvData();
 +    void sendData();
 +    void prepareSourceDE();
 +    void prepareTargetDE();
 +
 +  private :
 +    void synchronizeTopology();
 +    void broadcastTopology(BlockTopology*&, int tag);
 +
 +    BlockTopology* _topo_source;
 +    BlockTopology* _topo_target;
 +    int* _send_counts;
 +    int* _recv_counts;
 +    int* _send_displs;
 +    int* _recv_displs;
 +    double* _recv_buffer;
 +    double* _send_buffer;
 +  };
 +}
 +
 +#endif
index 30df1c5e60f786d6b74d0609d4c6a60cabc68515,0000000000000000000000000000000000000000..e284acc8e6a4a4650544fa7e8829cb19afb6aeb9
mode 100644,000000..100644
--- /dev/null
@@@ -1,51 -1,0 +1,57 @@@
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __TIMEINTERPOLATOR_HXX__
 +#define __TIMEINTERPOLATOR_HXX__
 +
 +#include "ProcessorGroup.hxx"
 +
 +#include <map>
 +#include <iostream>
 +
 +namespace ParaMEDMEM
 +{
++
++  /*!
++   * Internal class, not part of the public API.
++   *
++   * Abstract class for all time-related interpolation in a parallel context.
++   */
 +  class TimeInterpolator
 +  {
 +  public:  
 +    TimeInterpolator( double InterpPrecision, int nStepBefore=1, int nStepAfter=1 );
 +    virtual ~TimeInterpolator();
 +
 +    void setInterpParams( double InterpPrecision, int nStepBefore=1, int nStepAfter=1 ) { _interp_precision=InterpPrecision; _n_step_before=nStepBefore; _n_step_after=nStepAfter; }
 +    void steps( int &nStepBefore, int &nStepAfter ) { nStepBefore=_n_step_before; nStepAfter=_n_step_after ; }
 +    virtual void doInterp( double time0, double time1, double time, int recvcount ,
 +                           int nbuff0, int nbuff1,
 +                           int **recvbuff0, int **recvbuff1, int *result ) = 0;
 +    virtual void doInterp( double time0, double time1, double time, int recvcount ,
 +                           int nbuff0, int nbuff1,
 +                           double **recvbuff0, double **recvbuff1, double *result ) = 0;
 +  protected :
 +    double _interp_precision;
 +    int _n_step_before;
 +    int _n_step_after;
 +  };
 +}
 +
 +#endif
index 4b10f8b43cdbfe74a7c0ce85801b35e6d0ee49c2,0000000000000000000000000000000000000000..19ce03458904097b0348449b32ddd1172e3b8a4f
mode 100644,000000..100644
--- /dev/null
@@@ -1,40 -1,0 +1,45 @@@
- #include <utility>
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 __TOPOLOGY_HXX__
 +#define __TOPOLOGY_HXX__
 +
 +namespace ParaMEDMEM
 +{
 +  class ProcessorGroup;
 +
++  /*!
++   * Topology of a group of processors within a processor group. Abstract class, see derivations.
++   *
++   * \sa BlockTopology
++   * \sa ExplicitTopology
++   * \sa MPIProcessorGroup
++   */
 +  class Topology
 +  {
 +  public:
 +    Topology() { }
 +    virtual ~Topology() { }
 +    virtual int getNbElements() const = 0;
 +    virtual int getNbLocalElements() const  = 0;
 +    virtual const ProcessorGroup* getProcGroup()const  = 0;
 +  };
 +}
 +
 +#endif
index aa4336d0d21e01323c96b72b5fd8f388467d7cd2,0000000000000000000000000000000000000000..2f2b974392656461cdd6c85d312960f8eb7609a7
mode 100644,000000..100644
--- /dev/null
@@@ -1,137 -1,0 +1,136 @@@
-   ParaMEDMEMTest_MEDLoader.cxx
 +# Copyright (C) 2012-2015  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, or (at your option) any later version.
 +#
 +# 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
 +#
 +
 +ADD_DEFINITIONS(${MPI_DEFINITIONS} ${CPPUNIT_DEFINITIONS})
 +
 +INCLUDE_DIRECTORIES(
 +  ${MPI_INCLUDE_DIRS}
 +  ${CPPUNIT_INCLUDE_DIRS}
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDLoader
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL
 +  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases
 +  )
 +
 +SET(ParaMEDMEMTest_SOURCES
 +  ParaMEDMEMTest.cxx
 +  ParaMEDMEMTest_MPIProcessorGroup.cxx
 +  ParaMEDMEMTest_BlockTopology.cxx
 +  ParaMEDMEMTest_InterpKernelDEC.cxx
 +  ParaMEDMEMTest_StructuredCoincidentDEC.cxx
 +  ParaMEDMEMTest_ICoco.cxx
 +  ParaMEDMEMTest_Gauthier1.cxx
 +  ParaMEDMEMTest_FabienAPI.cxx
 +  ParaMEDMEMTest_NonCoincidentDEC.cxx
 +  ParaMEDMEMTest_OverlapDEC.cxx
 +  MPIAccessDECTest.cxx
 +  test_AllToAllDEC.cxx
 +  test_AllToAllvDEC.cxx
 +  test_AllToAllTimeDEC.cxx
 +  test_AllToAllvTimeDEC.cxx
 +  test_AllToAllvTimeDoubleDEC.cxx
 +  MPIAccessTest.cxx
 +  test_MPI_Access_Send_Recv.cxx
 +  test_MPI_Access_Cyclic_Send_Recv.cxx
 +  test_MPI_Access_SendRecv.cxx
 +  test_MPI_Access_ISend_IRecv.cxx
 +  test_MPI_Access_Cyclic_ISend_IRecv.cxx
 +  test_MPI_Access_ISendRecv.cxx
 +  test_MPI_Access_Probe.cxx
 +  test_MPI_Access_IProbe.cxx
 +  test_MPI_Access_Cancel.cxx
 +  test_MPI_Access_Send_Recv_Length.cxx
 +  test_MPI_Access_ISend_IRecv_Length.cxx
 +  test_MPI_Access_ISend_IRecv_Length_1.cxx
 +  test_MPI_Access_Time.cxx
 +  test_MPI_Access_Time_0.cxx
 +  test_MPI_Access_ISend_IRecv_BottleNeck.cxx
 +  )
 +
 +ADD_LIBRARY(ParaMEDMEMTest SHARED ${ParaMEDMEMTest_SOURCES})
 +SET_TARGET_PROPERTIES(ParaMEDMEMTest PROPERTIES COMPILE_FLAGS "")
 +TARGET_LINK_LIBRARIES(ParaMEDMEMTest paramedmem paramedloader ${CPPUNIT_LIBRARIES})
 +INSTALL(TARGETS ParaMEDMEMTest DESTINATION ${MEDTOOL_INSTALL_LIBS})
 +
 +SET(TESTSParaMEDMEM)
 +SET(TestParaMEDMEM_SOURCES
 +  TestParaMEDMEM.cxx
 +  )
 +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestParaMEDMEM)
 +
 +SET(TestMPIAccessDEC_SOURCES
 +  TestMPIAccessDEC.cxx
 +  )
 +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestMPIAccessDEC)
 +
 +SET(TestMPIAccess_SOURCES
 +  TestMPIAccess.cxx
 +  )
 +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestMPIAccess)
 +
 +SET(test_perf_SOURCES
 +  test_perf.cxx
 +  )
 +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} test_perf)
 +
 +IF(MPI2_IS_OK)
 +  SET(ParaMEDMEMTestMPI2_1_SOURCES
 +    MPI2Connector.cxx
 +    ParaMEDMEMTestMPI2_1.cxx
 +    )
 +  SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} ParaMEDMEMTestMPI2_1)
 +
 +  SET(ParaMEDMEMTestMPI2_2_SOURCES
 +    MPI2Connector.cxx
 +    ParaMEDMEMTestMPI2_2.cxx
 +    )
 +  SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} ParaMEDMEMTestMPI2_2)
 +ENDIF(MPI2_IS_OK)
 +
 +FOREACH(bintestparamem ${TESTSParaMEDMEM})
 +  ADD_EXECUTABLE(${bintestparamem} ${${bintestparamem}_SOURCES})
 +  TARGET_LINK_LIBRARIES(${bintestparamem} ParaMEDMEMTest)
 +ENDFOREACH(bintestparamem ${TESTSParaMEDMEM})
 +
 +# Now add CMake tests - test_perf, ParaMEDMEMTestMPI2_1 and ParaMEDMEMTestMPI2_2
 +# are left aside, as they are too specific
 +#
 +#  -- some tests require 2, 3, 4 or 5 procs --
 +ADD_TEST(NAME TestParaMEDMEM_Proc2 COMMAND ${MPIEXEC} -np 2 $<TARGET_FILE:TestParaMEDMEM>)
 +ADD_TEST(NAME TestParaMEDMEM_Proc3 COMMAND ${MPIEXEC} -np 3 $<TARGET_FILE:TestParaMEDMEM>)
 +ADD_TEST(NAME TestParaMEDMEM_Proc4 COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:TestParaMEDMEM>)
 +ADD_TEST(NAME TestParaMEDMEM_Proc5 COMMAND ${MPIEXEC} -np 5 $<TARGET_FILE:TestParaMEDMEM>)
 +
 +ADD_TEST(NAME TestMPIAccess_Proc2 COMMAND ${MPIEXEC} -np 2 $<TARGET_FILE:TestMPIAccess>)
 +ADD_TEST(NAME TestMPIAccess_Proc3 COMMAND ${MPIEXEC} -np 3 $<TARGET_FILE:TestMPIAccess>)
 +
 +ADD_TEST(NAME TestMPIAccessDEC_Proc4 COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:TestMPIAccessDEC>)
 +
 +# Installation rules
 +INSTALL(TARGETS ${TESTSParaMEDMEM} DESTINATION ${MEDTOOL_INSTALL_BINS})
 +SET(COMMON_HEADERS_HXX
 +  MPIMainTest.hxx
 +  MPIAccessDECTest.hxx
 +  MPIAccessTest.hxx
 +  ParaMEDMEMTest.hxx
 +  MPI2Connector.hxx
 +)
 +INSTALL(FILES ${COMMON_HEADERS_HXX} DESTINATION ${MEDTOOL_INSTALL_HEADERS})
index a8bf2b474dfbd4128f2798764dc313f1f431f244,0000000000000000000000000000000000000000..b0295a08f79be03dbd381b86cc1f8c58abf92581
mode 100644,000000..100644
--- /dev/null
@@@ -1,188 -1,0 +1,178 @@@
-   CPPUNIT_TEST(testMEDLoaderRead1);
-   CPPUNIT_TEST(testMEDLoaderPolygonRead);
-   CPPUNIT_TEST(testMEDLoaderPolyhedronRead);
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// 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 _ParaMEDMEMTEST_HXX_
 +#define _ParaMEDMEMTEST_HXX_
 +
 +#include <cppunit/extensions/HelperMacros.h>
 +
 +#include <set>
 +#include <string>
 +#include <iostream>
 +#include "mpi.h"
 +
 +
 +class ParaMEDMEMTest : public CppUnit::TestFixture
 +{
 +  CPPUNIT_TEST_SUITE( ParaMEDMEMTest );
 +  CPPUNIT_TEST(testMPIProcessorGroup_constructor);
 +  CPPUNIT_TEST(testMPIProcessorGroup_boolean);
 +  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);
 +  CPPUNIT_TEST(testInterpKernelDEC_3D);
 +  CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P0);
 +  CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P1P1P0);
 +  CPPUNIT_TEST(testInterpKernelDEC2DM1D_P0P0);
 +  CPPUNIT_TEST(testInterpKernelDECPartialProcs);
 +  CPPUNIT_TEST(testInterpKernelDEC3DSurfEmptyBBox);
 +  CPPUNIT_TEST(testOverlapDEC1);
 +
 +  CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D);
 +  CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D);
 +  CPPUNIT_TEST(testSynchronousEqualInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testSynchronousFasterSourceInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testSynchronousSlowerSourceInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testSynchronousSlowSourceInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testSynchronousFastSourceInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testAsynchronousEqualInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testAsynchronousFasterSourceInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testAsynchronousSlowerSourceInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testAsynchronousSlowSourceInterpKernelDEC_2D);
 +  CPPUNIT_TEST(testAsynchronousFastSourceInterpKernelDEC_2D);
 +#ifdef MED_ENABLE_FVM
 +  //can be added again after FVM correction for 2D
 +  //  CPPUNIT_TEST(testNonCoincidentDEC_2D);
 +  CPPUNIT_TEST(testNonCoincidentDEC_3D);
 +#endif
 +  CPPUNIT_TEST(testStructuredCoincidentDEC);
 +  CPPUNIT_TEST(testStructuredCoincidentDEC);
 +  CPPUNIT_TEST(testICoco1);
 +  CPPUNIT_TEST(testGauthier1);
 +  CPPUNIT_TEST(testGauthier2);
 +  CPPUNIT_TEST(testGauthier3);
 +  CPPUNIT_TEST(testGauthier4);
 +  CPPUNIT_TEST(testFabienAPI1);
 +  CPPUNIT_TEST(testFabienAPI2);
-   
 +  CPPUNIT_TEST_SUITE_END();
-   //
-   void testMEDLoaderRead1();
-   void testMEDLoaderPolygonRead();
-   void testMEDLoaderPolyhedronRead();
-   void testMEDLoaderWrite1();
-   void testMEDLoaderPolygonWrite();
 +
 +public:
 + 
 +  ParaMEDMEMTest():CppUnit::TestFixture(){}
 +  ~ParaMEDMEMTest(){}  
 +  void setUp(){}
 +  void tearDown(){}
 +  void testMPIProcessorGroup_constructor();
 +  void testMPIProcessorGroup_boolean();
 +  void testMPIProcessorGroup_rank();
 +  void testBlockTopology_constructor();
 +  void testBlockTopology_serialize();
 +  void testInterpKernelDEC_1D();
 +  void testInterpKernelDEC_2DCurve();
 +  void testInterpKernelDEC_2D();
 +  void testInterpKernelDEC2_2D();
 +  void testInterpKernelDEC_2DP0P1();
 +  void testInterpKernelDEC_3D();
 +  void testInterpKernelDECNonOverlapp_2D_P0P0();
 +  void testInterpKernelDECNonOverlapp_2D_P0P1P1P0();
 +  void testInterpKernelDEC2DM1D_P0P0();
 +  void testInterpKernelDECPartialProcs();
 +  void testInterpKernelDEC3DSurfEmptyBBox();
 +  void testOverlapDEC1();
 +#ifdef MED_ENABLE_FVM
 +  void testNonCoincidentDEC_2D();
 +  void testNonCoincidentDEC_3D();
 +#endif
 +  void testStructuredCoincidentDEC();
 +  void testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D();
 +  void testSynchronousEqualInterpKernelWithoutInterpDEC_2D();
 +  void testSynchronousEqualInterpKernelDEC_2D();
 +  void testSynchronousFasterSourceInterpKernelDEC_2D();
 +  void testSynchronousSlowerSourceInterpKernelDEC_2D();
 +  void testSynchronousSlowSourceInterpKernelDEC_2D();
 +  void testSynchronousFastSourceInterpKernelDEC_2D();
 +
 +  void testAsynchronousEqualInterpKernelDEC_2D();
 +  void testAsynchronousFasterSourceInterpKernelDEC_2D();
 +  void testAsynchronousSlowerSourceInterpKernelDEC_2D();
 +  void testAsynchronousSlowSourceInterpKernelDEC_2D();
 +  void testAsynchronousFastSourceInterpKernelDEC_2D();
 +  //
 +  void testICoco1();
 +  void testGauthier1();
 +  void testGauthier2();
 +  void testGauthier3();
 +  void testGauthier4();
 +  void testFabienAPI1();
 +  void testFabienAPI2();
 +
 +  std::string getResourceFile( const std::string& );
 +  std::string getTmpDirectory();
 +  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);
 +  void testInterpKernelDEC_2D_(const char *srcMeth, const char *targetMeth);
 +  void testInterpKernelDEC2_2D_(const char *srcMeth, const char *targetMeth);
 +  void testInterpKernelDEC_3D_(const char *srcMeth, const char *targetMeth);
 +};
 +
 +// to automatically remove temporary files from disk
 +class ParaMEDMEMTest_TmpFilesRemover
 +{
 +public:
 +  ParaMEDMEMTest_TmpFilesRemover() {}
 +  ~ParaMEDMEMTest_TmpFilesRemover();
 +  bool Register(const std::string theTmpFile);
 +
 +private:
 +  std::set<std::string> myTmpFiles;
 +};
 +
 +/*!
 + *  Tool to print array to stream.
 + */
 +template<class T>
 +void ParaMEDMEMTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text)
 +{
 +  stream << text << ": {";
 +  if (length > 0) {
 +    stream << array[0];
 +    for (int i = 1; i < length; i++) {
 +      stream << ", " << array[i];
 +    }
 +  }
 +  stream << "}" << std::endl;
 +}
 +
 +#endif
index f8962a780140c6543d70c9bf7bcea542184471fe,0000000000000000000000000000000000000000..01dc8227cc88d9d23c1298983a118d956789ede9
mode 100644,000000..100644
--- /dev/null
@@@ -1,399 -1,0 +1,35 @@@
- void ParaMEDMEMTest::testMEDLoaderRead1()
- {
-   string fileName=getResourceFile("pointe.med");
-   vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str());
-   CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size());
-   MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0);
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(16,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllGeoTypes().size());
-   for(int i=0;i<12;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,mesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+90,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::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str());
-   CPPUNIT_ASSERT_EQUAL(8,(int)families.size());
-   CPPUNIT_ASSERT(families[2]=="FAMILLE_ELEMENT_3");
-   //
-   vector<string> families2;
-   families2.push_back(families[2]);
-   mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),0,families2);
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(2,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
-   CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(0));
-   CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(1));
-   CPPUNIT_ASSERT_EQUAL((std::size_t)11,mesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(132,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+11,0));
-   CPPUNIT_ASSERT_EQUAL(16,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+3,0));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
-   mesh->decrRef();
-   //
-   vector<string> groups=MEDLoader::GetMeshGroupsNames(fileName.c_str(),meshNames[0].c_str());
-   CPPUNIT_ASSERT_EQUAL(5,(int)groups.size());
-   CPPUNIT_ASSERT(groups[0]=="groupe1");
-   CPPUNIT_ASSERT(groups[1]=="groupe2");
-   CPPUNIT_ASSERT(groups[2]=="groupe3");
-   CPPUNIT_ASSERT(groups[3]=="groupe4");
-   CPPUNIT_ASSERT(groups[4]=="groupe5");
-   vector<string> groups2;
-   groups2.push_back(groups[0]);
-   mesh=MEDLoader::ReadUMeshFromGroups(fileName.c_str(),meshNames[0].c_str(),0,groups2);
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(7,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
-   for(int i=0;i<6;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(i));
-   CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(6));
-   CPPUNIT_ASSERT_EQUAL((std::size_t)36,mesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(254,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+36,0));
-   CPPUNIT_ASSERT_EQUAL(141,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+8,0));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
-   mesh->decrRef();
-   //
-   std::vector<std::string> fieldsName=MEDLoader::GetCellFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str());
-   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(),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(),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::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.,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);
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue,diffValue+16),1e-12);
-   const MEDCouplingUMesh *constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0->getMesh());
-   CPPUNIT_ASSERT(constMesh);
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
-   for(int i=0;i<12;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
-   CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
-   field0->decrRef();
-   //
-   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.,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);
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue2,diffValue2+48),1e-12);
-   constMesh=dynamic_cast<const MEDCouplingUMesh *>(field1->getMesh());
-   CPPUNIT_ASSERT(constMesh);
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
-   for(int i=0;i<12;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
-   CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
-   field1->decrRef();
-   //fields on nodes
-   std::vector<std::string> fieldsNameNode=MEDLoader::GetNodeFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str());
-   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(),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);
-   CPPUNIT_ASSERT_EQUAL(1,its0Node[1].first);
-   CPPUNIT_ASSERT_EQUAL(-1,its0Node[1].second);
-   CPPUNIT_ASSERT_EQUAL(2,its0Node[2].first);
-   CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].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());
-   CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples());
-   const double expectedValues3[19]={1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.};
-   double diffValue3[19];
-   std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues3,diffValue3,std::minus<double>());
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12);
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12);
-   constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh());
-   CPPUNIT_ASSERT(constMesh);
-   field0Nodes->decrRef();
-   //
-   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());
-   CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples());
-   const double expectedValues4[19]={1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.,7.,7.};
-   std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues4,diffValue3,std::minus<double>());
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12);
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12);
-   constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh());
-   CPPUNIT_ASSERT(constMesh);
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
-   for(int i=0;i<12;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
-   CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
-   field0Nodes->decrRef();
-   //
-   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());
-   CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples());
-   const double expectedValues5[19]={1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.};
-   std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues5,diffValue3,std::minus<double>());
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12);
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12);
-   constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh());
-   CPPUNIT_ASSERT(constMesh);
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size());
-   for(int i=0;i<12;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,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((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0));
-   CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12);
-   field0Nodes->decrRef();
- }
- void ParaMEDMEMTest::testMEDLoaderPolygonRead()
- {
-   string fileName=getResourceFile("polygones.med");
-   vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str());
-   CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size());
-   CPPUNIT_ASSERT(meshNames[0]=="Bord");
-   MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0);
-   mesh->checkCoherency();
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(538,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(579,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
-   for(int i=0;i<514;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(i));
-   for(int i=514;i<538;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+1737,0),1e-12);
-   const double expectedVals1[12]={1.4851585216522212,-0.5,0.,1.4851585216522212,-0.4,0.,1.4851585216522212,-0.3,0., 1.5741585216522211, -0.5, 0. };
-   double diffValue1[12];
-   std::transform(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+12,expectedVals1,diffValue1,std::minus<double>());
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue1,diffValue1+12),1e-12);
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue1,diffValue1+12),1e-12);
-   CPPUNIT_ASSERT_EQUAL((std::size_t)2768,mesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(651050,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+2768,0));
-   CPPUNIT_ASSERT_EQUAL(725943,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+539,0));
-   mesh->decrRef();
-   //
-   std::vector<std::string> fieldsName=MEDLoader::GetCellFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str());
-   CPPUNIT_ASSERT_EQUAL(3,(int)fieldsName.size());
-   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(),meshNames[0].c_str(),fieldsName[0].c_str());
-   CPPUNIT_ASSERT_EQUAL(1,(int)its0.size());
-   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());
-   CPPUNIT_ASSERT_EQUAL(538,field->getNumberOfTuples());
-   const MEDCouplingUMesh *constMesh=dynamic_cast<const MEDCouplingUMesh *>(field->getMesh());
-   CPPUNIT_ASSERT(constMesh);
-   CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(2,constMesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(538,constMesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(579,constMesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(2,(int)constMesh->getAllGeoTypes().size());
-   for(int i=0;i<514;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,constMesh->getTypeOfCell(i));
-   for(int i=514;i<538;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,constMesh->getTypeOfCell(i));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+1737,0),1e-12);
-   std::transform(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+12,expectedVals1,diffValue1,std::minus<double>());
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue1,diffValue1+12),1e-12);
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue1,diffValue1+12),1e-12);
-   CPPUNIT_ASSERT_EQUAL((std::size_t)2768,constMesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(651050,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+2768,0));
-   CPPUNIT_ASSERT_EQUAL(725943,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+539,0));
-   const double *values=field->getArray()->getPointer();
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(2.87214203182918,std::accumulate(values,values+538,0.),1e-12);
-   field->decrRef();
- }
- void ParaMEDMEMTest::testMEDLoaderPolyhedronRead()
- {
-   string fileName=getResourceFile("poly3D.med");
-   vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str());
-   CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size());
-   CPPUNIT_ASSERT(meshNames[0]=="poly3D");
-   MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0);
-   mesh->checkCoherency();
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size());
-   CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(0));
-   CPPUNIT_ASSERT_EQUAL(NORM_POLYHED,mesh->getTypeOfCell(1));
-   CPPUNIT_ASSERT_EQUAL(NORM_POLYHED,mesh->getTypeOfCell(2));
-   CPPUNIT_ASSERT_EQUAL((std::size_t)98,mesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(725,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+98,0));
-   CPPUNIT_ASSERT_DOUBLES_EQUAL(110.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12);
-   CPPUNIT_ASSERT_EQUAL(155,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+4,0));
-   mesh->decrRef();
-   //
-   mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),-1);
-   mesh->checkCoherency();
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(17,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllGeoTypes().size());
-   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((std::size_t)83,mesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(619,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+83,0));
-   mesh->decrRef();
-   //
-   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");
-   CPPUNIT_ASSERT(families[2]=="FAMILLE_FACE_TRIA32");
-   CPPUNIT_ASSERT(families[3]=="FAMILLE_ZERO");
-   vector<string> families2;
-   families2.push_back(families[0]);
-   mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),-1,families2);
-   mesh->checkCoherency();
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(1,(int)mesh->getAllGeoTypes().size());
-   for(int i=0;i<3;i++)
-     CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i));
-   CPPUNIT_ASSERT_EQUAL((std::size_t)19,mesh->getNodalConnectivity()->getNbOfElems());
-   CPPUNIT_ASSERT_EQUAL(117,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+19,0));
-   mesh->decrRef();
-   //
-   mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),0,families2);
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension());
-   CPPUNIT_ASSERT_EQUAL(0,mesh->getNumberOfCells());
-   CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes());
-   CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension());
-   CPPUNIT_ASSERT_EQUAL(0,(int)mesh->getAllGeoTypes().size());
-   mesh->decrRef();
- }
 +// Copyright (C) 2007-2015  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, or (at your option) any later version.
 +//
 +// This library is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +// Lesser General Public License for more details.
 +//
 +// You should have received a copy of the GNU Lesser General Public
 +// License along with this library; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 +//
 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 +//
 +
 +#include "ParaMEDMEMTest.hxx"
 +#include "MEDLoader.hxx"
 +#include "MEDCouplingUMesh.hxx"
 +#include "MEDCouplingFieldDouble.hxx"
 +
 +#include <cppunit/TestAssert.h>
 +
 +#include <algorithm>
 +#include <numeric>
 +#include <iostream>
 +#include <iterator>
 +
 +using namespace std;
 +using namespace INTERP_KERNEL;
 +using namespace ParaMEDMEM;
 +