Salome HOME
getCellsContainingPoints is sensitive to 2D quadratic static cells.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingFieldDouble.cxx
index 0a7f2f8f738d08e5b5c17dd8268ca7ab879825f1..6e6d5dc21c5c55c1b0e7802e9846071fa86940a4 100644 (file)
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-// Author : Anthony Geay (CEA/DEN)
+// Author : Anthony Geay (EDF R&D)
 
 #include "MEDCouplingFieldDouble.hxx"
 #include "MEDCouplingFieldTemplate.hxx"
 #include "MEDCouplingFieldT.txx"
 #include "MEDCouplingFieldInt.hxx"
+#include "MEDCouplingFieldFloat.hxx"
 #include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingTimeDiscretization.hxx"
 #include "MEDCouplingFieldDiscretization.hxx"
-#include "MCAuto.hxx"
+#include "MCAuto.txx"
+#include "MEDCouplingVoronoi.hxx"
 #include "MEDCouplingNatureOfField.hxx"
+#include "MEDCouplingMemArray.txx"
 
 #include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGaussCoords.hxx"
 
 #include <sstream>
 #include <limits>
@@ -37,7 +41,7 @@
 
 using namespace MEDCoupling;
 
-template class MEDCouplingFieldT<double>;
+template class MEDCoupling::MEDCouplingFieldT<double>;
 
 /*!
  * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization.
@@ -172,13 +176,13 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCopy() const
  * \endif
  * \sa clone()
  */
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const
 {
-  MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCopy);
+  MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCpy);
   MCAuto<MEDCouplingFieldDiscretization> disc;
   if(_type)
     disc=_type->clone();
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),tdo,disc.retn());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()));
   ret->setMesh(getMesh());
   ret->setName(getName());
   ret->setDescription(getDescription());
@@ -186,8 +190,8 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfT
 }
 
 /*!
- * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping !
- * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach
+ * This method converts a field on nodes (\a this) to a cell field (returned field). The conversion is a \b non \b conservative remapping !
+ * This method is useful only for users that need a fast conversion from node to cell spatial discretization. The algorithm applied is simply to attach
  * to each cell the average of values on nodes constituting this cell.
  *
  * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
@@ -242,8 +246,8 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const
 }
 
 /*!
- * This method converts a field on cell (\a this) to a node field (returned field). The convertion is a \b non \b conservative remapping !
- * This method is useful only for users that need a fast convertion from cell to node spatial discretization. The algorithm applied is simply to attach
+ * This method converts a field on cell (\a this) to a node field (returned field). The conversion is a \b non \b conservative remapping !
+ * This method is useful only for users that need a fast conversion from cell to node spatial discretization. The algorithm applied is simply to attach
  * to each node the average of values on cell sharing this node. If \a this lies on a mesh having orphan nodes the values applied on them will be NaN (division by 0.).
  *
  * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
@@ -365,76 +369,6 @@ bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *
   return true;
 }
 
-/*!
- * Permutes values of \a this field according to a given permutation array for cells
- * renumbering. The underlying mesh is deeply copied and its cells are also permuted. 
- * The number of cells remains the same; for that the permutation array \a old2NewBg
- * should not contain equal ids.
- * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **.
- *
- *  \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
- *         to be equal to \a this->getMesh()->getNumberOfCells().
- *  \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation
- *         array, so that its maximal cell id to correspond to (be less than) the number
- *         of cells in mesh. This new array is then used for the renumbering. If \a 
- *         check == \c false, \a old2NewBg is used as is, that is less secure as validity 
- *         of ids in \a old2NewBg is not checked.
- *  \throw If the mesh is not set.
- *  \throw If the spatial discretization of \a this field is NULL.
- *  \throw If \a check == \c true and \a old2NewBg contains equal ids.
- *  \throw If mesh nature does not allow renumbering (e.g. structured mesh).
- * 
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".<br>
- *  \ref  py_mcfielddouble_renumberCells "Here is a Python example".
- *  \endif
- */
-void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check)
-{
-  renumberCellsWithoutMesh(old2NewBg,check);
-  MCAuto<MEDCouplingMesh> m=_mesh->deepCopy();
-  m->renumberCells(old2NewBg,check);
-  setMesh(m);
-  updateTime();
-}
-
-/*!
- * Permutes values of \a this field according to a given permutation array for cells
- * renumbering. The underlying mesh is \b not permuted. 
- * The number of cells remains the same; for that the permutation array \a old2NewBg
- * should not contain equal ids.
- * This method performs a part of job of renumberCells(). The reasonable use of this
- * method is only for multi-field instances lying on the same mesh to avoid a
- * systematic duplication and renumbering of _mesh attribute. 
- * \warning Use this method with a lot of care!
- *  \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
- *         to be equal to \a this->getMesh()->getNumberOfCells().
- *  \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation
- *         array, so that its maximal cell id to correspond to (be less than) the number
- *         of cells in mesh. This new array is then used for the renumbering. If \a 
- *         check == \c false, \a old2NewBg is used as is, that is less secure as validity 
- *         of ids in \a old2NewBg is not checked.
- *  \throw If the mesh is not set.
- *  \throw If the spatial discretization of \a this field is NULL.
- *  \throw If \a check == \c true and \a old2NewBg contains equal ids.
- *  \throw If mesh nature does not allow renumbering (e.g. structured mesh).
- */
-void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check)
-{
-  if(!_mesh)
-    throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
-  //
-  _type->renumberCells(old2NewBg,check);
-  std::vector<DataArrayDouble *> arrays;
-  timeDiscr()->getArrays(arrays);
-  std::vector<DataArray *> arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin());
-  _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check);
-  //
-  updateTime();
-}
-
 /*!
  * Permutes values of \a this field according to a given permutation array for node
  * renumbering. The underlying mesh is deeply copied and its nodes are also permuted. 
@@ -447,7 +381,7 @@ void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool
  *  \throw If the spatial discretization of \a this field is NULL.
  *  \throw If \a check == \c true and \a old2NewBg contains equal ids.
  *  \throw If mesh nature does not allow renumbering (e.g. structured mesh).
- *  \throw If values at merged nodes deffer more than \a eps.
+ *  \throw If values at merged nodes differ more than \a eps.
  * 
  *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".<br>
@@ -487,11 +421,11 @@ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps)
  *         the values differ more than \a eps, an exception is thrown.
  *  \throw If the mesh is not set.
  *  \throw If the spatial discretization of \a this field is NULL.
- *  \throw If values at merged nodes deffer more than \a eps.
+ *  \throw If values at merged nodes differ more than \a eps.
  */
 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps)
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
   std::vector<DataArrayDouble *> arrays;
   timeDiscr()->getArrays(arrays);
@@ -520,162 +454,30 @@ DataArrayInt *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) c
   return getArray()->findIdsInRange(vmin,vmax);
 }
 
-/*!
- * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()).
- * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
- * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field.
- * Parameter \a part specifies **cell ids whatever the spatial discretization of this** (
- * \ref MEDCoupling::ON_CELLS "ON_CELLS", 
- * \ref MEDCoupling::ON_NODES "ON_NODES",
- * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", 
- * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
- * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
- *
- * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6].
- * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.<br>
- * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().<br>
- * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().<br>
- * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh().
- *
- * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6].
- * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field
- * will contain 6 tuples and \a this field will lie on this restricted mesh. 
- *
- *  \param [in] part - an array of cell ids to include to the result field.
- *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed.
- *
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".<br>
- *  \ref  py_mcfielddouble_subpart1 "Here is a Python example".
- *  \endif
- *  \sa MEDCouplingFieldDouble::buildSubPartRange
- */
-
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const
+template<class U>
+typename Traits<U>::FieldType *ConvertToUField(const MEDCouplingFieldDouble *self)
 {
-  if(part==0)
-    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
-  return buildSubPart(part->begin(),part->end());
-}
-
-/*!
- * Builds a newly created field, that the caller will have the responsability to deal with.
- * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkConsistencyLight() returns without any exception thrown), **no check of this will be done**.
- * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field.
- * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this (
- * \ref MEDCoupling::ON_CELLS "ON_CELLS", 
- * \ref MEDCoupling::ON_NODES "ON_NODES",
- * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", 
- * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
- * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
- *
- * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6].
- * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples.
- *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
- *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
- *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh().
- *
- * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6].
- * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field
- * will contain 6 tuples and \a this field will lie on this restricted mesh. 
- *
- * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd )
- * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd )
- * \return a newly allocated field the caller should deal with.
- * 
- * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh().
- *
- * \if ENABLE_EXAMPLES
- * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."<br>
- * \ref py_mcfielddouble_subpart1 "Here a Python example."
- * \endif
- * \sa MEDCoupling::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange
- */
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !");
-  DataArrayInt *arrSelect;
-  MCAuto<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
-  MCAuto<DataArrayInt> arrSelect2(arrSelect);
-  MCAuto<MEDCouplingFieldDouble> ret=clone(false);//quick shallow copy.
-  const MEDCouplingFieldDiscretization *disc=getDiscretization();
-  if(disc)
-    ret->setDiscretization(MCAuto<MEDCouplingFieldDiscretization>(disc->clonePart(partBg,partEnd)));
-  ret->setMesh(m);
-  std::vector<DataArrayDouble *> arrays;
-  timeDiscr()->getArrays(arrays);
-  std::vector<DataArrayDouble *> arrs;
-  std::vector< MCAuto<DataArrayDouble> > arrsSafe;
-  const int *arrSelBg=arrSelect->begin();
-  const int *arrSelEnd=arrSelect->end();
-  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+  MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*self));
+  int t1,t2;
+  double t0(self->getTime(t1,t2));
+  MCAuto<typename Traits<U>::FieldType > ret(Traits<U>::FieldType::New(*tmp,self->getTimeDiscretization()));
+  ret->setTime(t0,t1,t2);
+  if(self->getArray())
     {
-      DataArrayDouble *arr=0;
-      if(*iter)
-        arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
-      arrs.push_back(arr); arrsSafe.push_back(arr);
+      MCAuto<typename Traits<U>::ArrayType> arr(self->getArray()->convertToOtherTypeOfArr<U>());
+      ret->setArray(arr);
     }
-  ret->timeDiscr()->setArrays(arrs,0);
   return ret.retn();
 }
 
-/*!
- * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is
- * given using a range given \a begin, \a end and \a step to optimize the part computation.
- * 
- * \sa MEDCouplingFieldDouble::buildSubPart
- */
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !");
-  DataArrayInt *arrSelect;
-  int beginOut,endOut,stepOut;
-  MCAuto<MEDCouplingMesh> m=_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect);
-  MCAuto<DataArrayInt> arrSelect2(arrSelect);
-  MCAuto<MEDCouplingFieldDouble> ret=clone(false);//quick shallow copy.
-  const MEDCouplingFieldDiscretization *disc=getDiscretization();
-  if(disc)
-    ret->setDiscretization(MCAuto<MEDCouplingFieldDiscretization>(disc->clonePartRange(begin,end,step)));
-  ret->setMesh(m);
-  std::vector<DataArrayDouble *> arrays;
-  timeDiscr()->getArrays(arrays);
-  std::vector<DataArrayDouble *> arrs;
-  std::vector< MCAuto<DataArrayDouble> > arrsSafe;
-  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
-    {
-      DataArrayDouble *arr=0;
-      if(*iter)
-        {
-          if(arrSelect)
-            {
-              const int *arrSelBg=arrSelect->begin();
-              const int *arrSelEnd=arrSelect->end();
-              arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
-            }
-          else
-            arr=(*iter)->selectByTupleIdSafeSlice(beginOut,endOut,stepOut);
-        }
-      arrs.push_back(arr); arrsSafe.push_back(arr);
-    }
-  ret->timeDiscr()->setArrays(arrs,0);
-  return ret.retn();
+MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
+{
+  return ConvertToUField<int>(this);
 }
 
-MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
+MEDCouplingFieldFloat *MEDCouplingFieldDouble::convertToFloatField() const
 {
-  MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*this));
-  int t1,t2;
-  double t0(getTime(t1,t2));
-  MCAuto<MEDCouplingFieldInt> ret(MEDCouplingFieldInt::New(*tmp,getTimeDiscretization()));
-  ret->setTime(t0,t1,t2);
-  if(getArray())
-    {
-      MCAuto<DataArrayInt> arr(getArray()->convertToIntArr());
-      ret->setArray(arr);
-    }
-  return ret.retn();
+  return ConvertToUField<float>(this);
 }
 
 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(type,MEDCouplingTimeDiscretization::New(td))
@@ -689,7 +491,7 @@ MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& f
 {
 }
 
-MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingFieldT<double>(other,deepCopy)
+MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy):MEDCouplingFieldT<double>(other,deepCpy)
 {
 }
 
@@ -738,7 +540,7 @@ double MEDCouplingFieldDouble::getMaxValue() const
 {
   std::vector<DataArrayDouble *> arrays;
   timeDiscr()->getArrays(arrays);
-  double ret=-std::numeric_limits<double>::max();
+  double ret(-std::numeric_limits<double>::max());
   bool isExistingArr=false;
   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
     {
@@ -757,7 +559,7 @@ double MEDCouplingFieldDouble::getMaxValue() const
 /*!
  * Returns the maximal value and all its locations within \a this scalar field.
  * Only the first of available data arrays is checked.
- *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
+ *  \param [out] tupleIds - a new instance of DataArrayInt containing indices of
  *               tuples holding the maximal value. The caller is to delete it using
  *               decrRef() as it is no more needed.
  *  \return double - the maximal value among all values of the first array of \a this filed.
@@ -768,7 +570,7 @@ double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const
 {
   std::vector<DataArrayDouble *> arrays;
   timeDiscr()->getArrays(arrays);
-  double ret=-std::numeric_limits<double>::max();
+  double ret(-std::numeric_limits<double>::max());
   bool isExistingArr=false;
   tupleIds=0;
   MCAuto<DataArrayInt> ret1;
@@ -802,7 +604,7 @@ double MEDCouplingFieldDouble::getMinValue() const
 {
   std::vector<DataArrayDouble *> arrays;
   timeDiscr()->getArrays(arrays);
-  double ret=std::numeric_limits<double>::max();
+  double ret(std::numeric_limits<double>::max());
   bool isExistingArr=false;
   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
     {
@@ -821,7 +623,7 @@ double MEDCouplingFieldDouble::getMinValue() const
 /*!
  * Returns the minimal value and all its locations within \a this scalar field.
  * Only the first of available data arrays is checked.
- *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
+ *  \param [out] tupleIds - a new instance of DataArrayInt containing indices of
  *               tuples holding the minimal value. The caller is to delete it using
  *               decrRef() as it is no more needed.
  *  \return double - the minimal value among all values of the first array of \a this filed.
@@ -832,7 +634,7 @@ double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const
 {
   std::vector<DataArrayDouble *> arrays;
   timeDiscr()->getArrays(arrays);
-  double ret=-std::numeric_limits<double>::max();
+  double ret(-std::numeric_limits<double>::max());
   bool isExistingArr=false;
   tupleIds=0;
   MCAuto<DataArrayInt> ret1;
@@ -881,19 +683,6 @@ double MEDCouplingFieldDouble::norm2() const
   return getArray()->norm2();
 }
 
-/*!
- * This method returns the max norm of \a this field.
- * \f[
- * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
- * \f]
- *  \throw If the data array is not set.
- */
-double MEDCouplingFieldDouble::normMax() const
-{
-  if(getArray()==0)
-    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
-  return getArray()->normMax();
-}
 
 /*!
  * Computes the weighted average of values of each component of \a this field, the weights being the
@@ -961,7 +750,7 @@ double MEDCouplingFieldDouble::normL1(int compId) const
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
   int nbComps=getArray()->getNumberOfComponents();
   if(compId<0 || compId>=nbComps)
@@ -988,7 +777,7 @@ void MEDCouplingFieldDouble::normL1(double *res) const
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
   _type->normL1(_mesh,getArray(),res);
 }
@@ -1008,7 +797,7 @@ double MEDCouplingFieldDouble::normL2(int compId) const
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
   int nbComps=getArray()->getNumberOfComponents();
   if(compId<0 || compId>=nbComps)
@@ -1035,11 +824,53 @@ void MEDCouplingFieldDouble::normL2(double *res) const
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
   _type->normL2(_mesh,getArray(),res);
 }
 
+/*!
+ * Returns the \c infinite norm of values of a given component of \a this field:
+* \f[
+ * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
+ * \f]
+ *  \param [in] compId - an index of the component of interest.
+ *  \throw If \a compId is not valid.
+           A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
+ *  \throw If the data array is not set.
+ */
+double MEDCouplingFieldDouble::normMax(int compId) const
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
+  int nbComps=getArray()->getNumberOfComponents();
+  if(compId<0 || compId>=nbComps)
+    {
+      std::ostringstream oss; oss << "MEDCouplingFieldDouble::normMax : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
+      throw INTERP_KERNEL::Exception(oss.str());
+    }
+  INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
+  getArray()->normMaxPerComponent(res);
+  return res[compId];
+}
+
+/*!
+ * Returns the \c infinite norm of values of each component of \a this field:
+ * \f[
+ * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
+ * \f]
+ *  \param [out] res - pointer to an array of result values, of size at least \a
+ *         this->getNumberOfComponents(), that is to be allocated by the caller.
+ *  \throw If the data array is not set.
+ *
+ */
+void MEDCouplingFieldDouble::normMax(double *res) const
+{
+  if(getArray()==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
+  getArray()->normMaxPerComponent(res);
+}
+
 /*!
  * Computes a sum of values of a given component of \a this field multiplied by
  * values returned by buildMeasureField().
@@ -1058,7 +889,7 @@ double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !");
   int nbComps=getArray()->getNumberOfComponents();
   if(compId<0 || compId>=nbComps)
@@ -1089,7 +920,7 @@ void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
   _type->integral(_mesh,getArray(),isWAbs,res);
 }
@@ -1119,7 +950,7 @@ void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) con
   const DataArrayDouble *arr=timeDiscr()->getArray();
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
   _type->getValueOnPos(arr,_mesh,i,j,k,res);
 }
@@ -1143,7 +974,7 @@ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) con
   const DataArrayDouble *arr=timeDiscr()->getArray();
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
   _type->getValueOn(arr,_mesh,spaceLoc,res);
 }
@@ -1171,7 +1002,7 @@ DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc,
   const DataArrayDouble *arr=timeDiscr()->getArray();
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
   return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
 }
@@ -1198,7 +1029,7 @@ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, dou
   std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !");
   std::vector<double> res2;
   for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
@@ -1244,7 +1075,7 @@ MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !");
   int nbOfTuple=_type->getNumberOfTuples(_mesh);
   timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value);
@@ -1269,7 +1100,7 @@ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate f
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
   timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
@@ -1316,7 +1147,7 @@ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& f
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
   timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
@@ -1365,7 +1196,7 @@ void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::stri
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !");
   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
   timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func);
@@ -1414,7 +1245,7 @@ void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std:
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !");
   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
   timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func);
@@ -1455,7 +1286,7 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !");
   int nbOfTuple=_type->getNumberOfTuples(_mesh);
   timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val);
@@ -1481,7 +1312,7 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
  *   - "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.)
+ *   - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.)
  *
  *  \param [in] nbOfComp - the number of components for \a this field to have.
  *  \param [in] func - the function used to compute values of \a this field.
@@ -1521,7 +1352,7 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
  *   - "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.)
+ *   - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.)
  *
  *  \param [in] nbOfComp - the number of components for \a this field to have.
  *  \param [in] func - the function used to compute values of \a this field.
@@ -1668,10 +1499,9 @@ std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
  */
 std::size_t MEDCouplingFieldDouble::getNumberOfTuples() const
 {
-  //std::cerr << " ******* MEDCouplingFieldDouble::getNumberOfTuples is deprecated : use MEDCouplingField::getNumberOfTuplesExpected instead ! ******" << std::endl;
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
   return _type->getNumberOfTuples(_mesh);
 }
@@ -1733,7 +1563,7 @@ std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWi
  */
 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
   return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
 }
@@ -1768,126 +1598,6 @@ double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId)
  */
 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
 
-void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
-{
-  tinyInfo.clear();
-  timeDiscr()->getTinySerializationStrInformation(tinyInfo);
-  tinyInfo.push_back(_name);
-  tinyInfo.push_back(_desc);
-  tinyInfo.push_back(getTimeUnit());
-}
-
-/*!
- * This method retrieves some critical values to resize and prepare remote instance.
- * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
- * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
- */
-void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !");
-  tinyInfo.clear();
-  tinyInfo.push_back((int)_type->getEnum());
-  tinyInfo.push_back((int)timeDiscr()->getEnum());
-  tinyInfo.push_back((int)_nature);
-  timeDiscr()->getTinySerializationIntInformation(tinyInfo);
-  std::vector<int> tinyInfo2;
-  _type->getTinySerializationIntInformation(tinyInfo2);
-  tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
-  tinyInfo.push_back((int)tinyInfo2.size());
-}
-
-/*!
- * This method retrieves some critical values to resize and prepare remote instance.
- * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
- */
-void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !");
-  tinyInfo.clear();
-  timeDiscr()->getTinySerializationDbleInformation(tinyInfo);
-  std::vector<double> tinyInfo2;
-  _type->getTinySerializationDbleInformation(tinyInfo2);
-  tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
-  tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
-}
-
-/*!
- * This method has to be called to the new instance filled by CORBA, MPI, File...
- * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
- * @param dataInt out parameter. If not null the pointer is already owned by \a this after the call of this method. In this case no decrRef must be applied.
- * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by \a this after the call of this method.
- *               No decrRef must be applied to every instances in returned vector.
- * \sa checkForUnserialization
- */
-void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !");
-  dataInt=0;
-  std::vector<int> tinyInfoITmp(tinyInfoI);
-  int sz=tinyInfoITmp.back();
-  tinyInfoITmp.pop_back();
-  std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
-  std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
-  timeDiscr()->resizeForUnserialization(tinyInfoI2,arrays);
-  std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
-  _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
-}
-
-/*!
- * This method is extremely close to resizeForUnserialization except that here the arrays in \a dataInt and in \a arrays are attached in \a this
- * after having checked that size is correct. This method is used in python pickeling context to avoid copy of data.
- * \sa resizeForUnserialization
- */
-void MEDCouplingFieldDouble::checkForUnserialization(const std::vector<int>& tinyInfoI, const DataArrayInt *dataInt, const std::vector<DataArrayDouble *>& arrays)
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !");
-  std::vector<int> tinyInfoITmp(tinyInfoI);
-  int sz=tinyInfoITmp.back();
-  tinyInfoITmp.pop_back();
-  std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
-  std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
-  timeDiscr()->checkForUnserialization(tinyInfoI2,arrays);
-  std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
-  _type->checkForUnserialization(tinyInfoITmp3,dataInt);
-}
-
-void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !");
-  std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
-  //
-  std::vector<double> tmp(tinyInfoD);
-  int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
-  tmp.pop_back();
-  std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
-  std::vector<double> tmp2(tmp.end()-sz,tmp.end());
-  //
-  timeDiscr()->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
-  _nature=(NatureOfField)tinyInfoI[2];
-  _type->finishUnserialization(tmp2);
-  int nbOfElemS=(int)tinyInfoS.size();
-  _name=tinyInfoS[nbOfElemS-3];
-  _desc=tinyInfoS[nbOfElemS-2];
-  setTimeUnit(tinyInfoS[nbOfElemS-1]);
-}
-
-/*!
- * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
- * The values returned must be consulted only in readonly mode.
- */
-void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
-{
-  if(!((const MEDCouplingFieldDiscretization *)_type))
-    throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform serialize !");
-  timeDiscr()->getArrays(arrays);
-  _type->getSerializationIntArray(dataInt);
-}
-
 /*!
  * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if
  * a current and the \a other meshes are different with use of specified equality
@@ -1906,7 +1616,7 @@ void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataA
  *  \throw If \a other == NULL.
  *  \throw If any of the meshes is not well defined.
  *  \throw If the two meshes do not match.
- *  \throw If field values at merged nodes (if any) deffer more than \a eps.
+ *  \throw If field values at merged nodes (if any) differ more than \a eps.
  *
  *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br>
@@ -1954,7 +1664,7 @@ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other,
  *  \throw If any of the meshes is not set or is not well defined.
  *  \throw If the two meshes do not match.
  *  \throw If the two fields are not coherent for merge.
- *  \throw If field values at merged nodes (if any) deffer more than \a eps.
+ *  \throw If field values at merged nodes (if any) differ more than \a eps.
  *
  *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br>
@@ -1987,14 +1697,14 @@ void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f,
  *  \throw If the mesh is not well defined.
  *  \throw If the spatial discretization of \a this field is NULL.
  *  \throw If the data array is not set.
- *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
+ *  \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
  */
 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
 {
   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
   if(!meshC)
     throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
   bool ret;
@@ -2026,14 +1736,14 @@ bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
  *  \throw If the mesh is not well defined.
  *  \throw If the spatial discretization of \a this field is NULL.
  *  \throw If the data array is not set.
- *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
+ *  \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
  */
 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
 {
   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
   if(!meshC)
     throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
   bool ret;
@@ -2063,14 +1773,14 @@ bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
  *  \throw If the mesh is not well defined.
  *  \throw If the spatial discretization of \a this field is NULL.
  *  \throw If the data array is not set.
- *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
+ *  \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
  */
 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
 {
   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
   if(!meshC)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !");
   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
   int oldNbOfNodes=meshC2->getNumberOfNodes();
@@ -2104,17 +1814,17 @@ bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
  *  \throw If the mesh is not well defined.
  *  \throw If the spatial discretization of \a this field is NULL.
  *  \throw If the data array is not set.
- *  \throw If field values at merged cells (if any) deffer more than \a epsOnVals.
+ *  \throw If field values at merged cells (if any) differ more than \a epsOnVals.
  */
 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
 {
   const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
   if(!meshC)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !");
   MCAuto<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCopy());
-  int oldNbOfCells=meshC2->getNumberOfCells();
+  std::size_t oldNbOfCells(meshC2->getNumberOfCells());
   MCAuto<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
   if(meshC2->getNumberOfCells()!=oldNbOfCells)
     {
@@ -2143,7 +1853,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *ori
   if(getTypeOfField()!=ON_CELLS)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
   const MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
-  MCAuto<MEDCouplingFieldDouble> ret=clone(false);
+  MCAuto<MEDCouplingFieldDouble> ret(clone(false));
   ret->setMesh(umesh);
   DataArrayInt *cellIds=0;
   MCAuto<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
@@ -2186,7 +1896,7 @@ bool MEDCouplingFieldDouble::simplexize(int policy)
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !");
   int oldNbOfCells=_mesh->getNumberOfCells();
   MCAuto<MEDCouplingMesh> meshC2(_mesh->deepCopy());
@@ -2203,6 +1913,156 @@ bool MEDCouplingFieldDouble::simplexize(int policy)
   return true;
 }
 
+/*!
+ * This method makes the hypothesis that \a this is a Gauss field. This method returns a newly created field on cells with same number of tuples than \a this.
+ * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm.
+ */
+MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
+{
+  checkConsistencyLight();
+  const MEDCouplingMesh *mesh(getMesh());
+  INTERP_KERNEL::AutoCppPtr<Voronizer> vor;
+  int meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension());
+  if(meshDim==1 && (spaceDim==1 || spaceDim==2 || spaceDim==3))
+    vor=new Voronizer1D;
+  else if(meshDim==2 && (spaceDim==2 || spaceDim==3))
+    vor=new Voronizer2D;
+  else if(meshDim==3 && spaceDim==3)
+    vor=new Voronizer3D;
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
+  return voronoizeGen(vor,eps);
+}
+
+/*!
+ * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
+ */
+MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const
+{
+  checkConsistencyLight();
+  switch(getTypeOfField())
+    {
+    case ON_NODES:
+      {
+        const MEDCouplingMesh *mesh(getMesh());
+        if(!mesh)
+          throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
+        MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
+        umesh=umesh->clone(false);
+        umesh->convertQuadraticCellsToLinear();
+        MCAuto<DataArrayInt> o2n(umesh->zipCoordsTraducer());
+        MCAuto<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(umesh->getNumberOfNodes()));
+        MCAuto<DataArrayDouble> arr(getArray()->selectByTupleIdSafe(n2o->begin(),n2o->end()));
+        MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_NODES));
+        ret->setArray(arr);
+        ret->setMesh(umesh);
+        ret->copyAllTinyAttrFrom(this);
+        return ret;
+      }
+    case ON_CELLS:
+      {
+        const MEDCouplingMesh *mesh(getMesh());
+        if(!mesh)
+          throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
+        MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
+        umesh=umesh->clone(false);
+        umesh->convertQuadraticCellsToLinear();
+        umesh->zipCoords();
+        MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
+        ret->setArray(const_cast<DataArrayDouble *>(getArray()));
+        ret->setMesh(umesh);
+        ret->copyAllTinyAttrFrom(this);
+        return ret;
+      }
+    case ON_GAUSS_PT:
+      {
+        const MEDCouplingMesh *mesh(getMesh());
+        if(!mesh)
+          throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
+        MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
+        std::set<INTERP_KERNEL::NormalizedCellType> gt(umesh->getAllGeoTypes());
+        MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
+        //
+        const MEDCouplingFieldDiscretization *disc(getDiscretization());
+        const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
+        if(!disc2)
+          throw INTERP_KERNEL::Exception("convertQuadraticCellsToLinear : Not a ON_GAUSS_PT field");
+        std::set<INTERP_KERNEL::NormalizedCellType> gt2(umesh->getAllGeoTypes());
+        std::vector< MCAuto<DataArrayInt> > cellIdsV;
+        std::vector< MCAuto<MEDCouplingUMesh> > meshesV;
+        std::vector< MEDCouplingGaussLocalization > glV;
+        bool isZipReq(false);
+        for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gt.begin();it!=gt.end();it++)
+          {
+            const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
+            MCAuto<DataArrayInt> cellIds(umesh->giveCellsWithType(*it));
+            cellIdsV.push_back(cellIds);
+            MCAuto<MEDCouplingUMesh> part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end()));
+            int id(disc2->getGaussLocalizationIdOfOneType(*it));
+            const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id));
+            if(!cm.isQuadratic())
+              {
+                glV.push_back(gl);
+              }
+            else
+              {
+                isZipReq=true;
+                part->convertQuadraticCellsToLinear();
+                INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell());
+                INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear());
+                MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights());
+                glV.push_back(gl2);
+              }
+            meshesV.push_back(part);
+          }
+        //
+        {
+          std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV));
+          umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr);
+          std::vector< const DataArrayInt * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV));
+          MCAuto<DataArrayInt> zeIds(DataArrayInt::Aggregate(zeCellIds));
+          umesh->renumberCells(zeIds->begin());
+          umesh->setName(mesh->getName());
+        }
+        //
+        if(isZipReq)
+          umesh->zipCoords();
+        ret->setArray(const_cast<DataArrayDouble *>(getArray()));
+        ret->setMesh(umesh);
+        for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++)
+          ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights());
+        ret->copyAllTinyAttrFrom(this);
+        ret->checkConsistencyLight();
+        return ret;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
+    }
+}
+
+/*!
+ * This is expected to be a 3 components vector field on nodes (if not an exception will be thrown). \a this is also expected to lie on a MEDCouplingPointSet mesh.
+ * Finally \a this is also expected to be consistent.
+ * In these conditions this method returns a newly created field (to be dealed by the caller).
+ * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
+ * 
+ * For each 3 compo tuple \a tup in \a this the returned tuple is the result of the transformation of \a tup in the new referential. This referential is defined by \a Ur, \a Uteta, \a Uz.
+ * \a Ur is the vector between \a center point and the associated node with \a tuple. \a Uz is \a vect normalized. And Uteta is the cross product of \a Uz with \a Ur.
+ *
+ * \sa DataArrayDouble::fromCartToCylGiven
+ */
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
+{
+  checkConsistencyLight();
+  const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
+  MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
+  td->copyTinyAttrFrom(*timeDiscr());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
+  ret->setMesh(getMesh());
+  ret->setName(getName());
+  return ret.retn();
+}
+
 /*!
  * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
  * every tensor of \a this 6-componental field.
@@ -2216,11 +2076,11 @@ bool MEDCouplingFieldDouble::simplexize(int policy)
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->doublyContractedProduct();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("DoublyContractedProduct");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2239,11 +2099,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->determinant();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("Determinant");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2263,11 +2123,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->eigenValues();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("EigenValues");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2286,11 +2146,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->eigenVectors();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("EigenVectors");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2311,11 +2171,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->inverse();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("Inversion");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2336,11 +2196,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->trace();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("Trace");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2360,11 +2220,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->deviator();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("Deviator");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2382,11 +2242,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->magnitude();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName("Magnitude");
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2402,11 +2262,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->maxPerTuple();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   std::ostringstream oss;
   oss << "Max_" << getName();
   ret->setName(oss.str());
@@ -2443,11 +2303,11 @@ void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftVal
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->keepSelectedComponents(compoIds);
+  MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setName(getName());
   ret->setMesh(getMesh());
   return ret.retn();
@@ -2508,9 +2368,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFie
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !");
   if(!f1->_type)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->aggregate(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->aggregate(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
   ret->setName(f1->getName());
   ret->setDescription(f1->getDescription());
   if(m1)
@@ -2562,14 +2422,14 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<co
         { ms[i]=0; ms2[i]=0; }
       tds[i]=a[i]->timeDiscr();
     }
-  MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds);
+  MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
   td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()));
   ret->setName(a[0]->getName());
   ret->setDescription(a[0]->getDescription());
   if(ms2[0])
     {
-      MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::MergeUMeshes(ms2);
+      MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
       m->copyTinyInfoFrom(ms2[0]);
       ret->setMesh(m);
     }
@@ -2593,11 +2453,13 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<co
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
 {
+  if(!f1 || !f2)
+    throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
   if(!f1->areCompatibleForMeld(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->meld(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2622,9 +2484,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingField
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
   if(!f1->areStrictlyCompatibleForMulDiv(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them!  Check support mesh, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->dot(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
+  MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret;
 }
@@ -2653,9 +2515,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCoup
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
   if(!f1->areStrictlyCompatibleForMulDiv(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->crossProduct(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2683,9 +2545,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingField
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->max(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2713,9 +2575,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingField
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->min(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2731,11 +2593,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingField
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
 {
-  if(!((const MEDCouplingFieldDiscretization *)_type))
+  if(_type.isNull())
     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
-  MEDCouplingTimeDiscretization *td=timeDiscr()->negate();
+  MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
   td->copyTinyAttrFrom(*timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
   ret->setMesh(getMesh());
   return ret.retn();
 }
@@ -2759,9 +2621,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingField
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->add(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2803,9 +2665,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplin
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->substract(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2854,9 +2716,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCoupling
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
   if(!f1->areCompatibleForMul(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->multiply(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2915,9 +2777,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFi
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
   if(!f1->areCompatibleForDiv(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->divide(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2959,9 +2821,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingField
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
   if(!f1->areCompatibleForMul(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
-  MEDCouplingTimeDiscretization *td=f1->timeDiscr()->pow(f2->timeDiscr());
+  MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
   td->copyTinyAttrFrom(*f1->timeDiscr());
-  MCAuto<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
+  MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -3044,6 +2906,78 @@ std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const
   return ret;
 }
 
+MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
+{
+  checkConsistencyLight();
+  if(!vor)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
+  MCAuto<MEDCouplingFieldDouble> fieldToWO;
+  const MEDCouplingMesh *inpMeshBase(getMesh());
+  MCAuto<MEDCouplingUMesh> inpMesh(inpMeshBase->buildUnstructured());
+  std::string meshName(inpMesh->getName());
+  if(!inpMesh->isPresenceOfQuadratic())
+    fieldToWO=clone(false);
+  else
+    {
+      fieldToWO=convertQuadraticCellsToLinear();
+      inpMeshBase=fieldToWO->getMesh();
+      inpMesh=inpMeshBase->buildUnstructured();
+    }
+  int nbCells(inpMesh->getNumberOfCells());
+  const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
+  const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
+  if(!disc2)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
+  int nbLocs(disc2->getNbOfGaussLocalization());
+  std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
+  for(int i=0;i<nbLocs;i++)
+    {
+      const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
+      if(gl.getDimension()!=vor->getDimension())
+        throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
+      MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
+      const std::vector<double>& coo(gl.getGaussCoords());
+      MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
+      coo2->rearrange(vor->getDimension());
+      //
+      MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
+      //
+      MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
+      std::vector<int> ids;
+      MCAuto<DataArrayDouble> ptsInReal;
+      disc2->getCellIdsHavingGaussLocalization(i,ids);
+      {
+        MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
+        ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
+      }
+      int nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
+      for(std::size_t j=0;j<ids.size();j++)
+        {
+          MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
+          MCAuto<DataArrayDouble> coo4(ptsInReal->selectByTupleIdSafeSlice(j*nbPtsPerCell,(j+1)*nbPtsPerCell,1));
+          elt->setCoords(coo4);
+          cells[ids[j]]=elt;
+        }
+    }
+  std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
+  MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
+  outMesh->setName(meshName);
+  MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
+  onCells->setMesh(outMesh);
+  {
+    MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
+    onCells->setArray(arr);
+  }
+  onCells->setTimeUnit(getTimeUnit());
+  {
+    int b,c;
+    double a(getTime(b,c));
+    onCells->setTime(a,b,c);
+  }
+  onCells->setName(getName());
+  return onCells;
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
 {
   MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);