Salome HOME
scotch6.0.4 needs pthread... Quick and dirty solution to be improved
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingFieldDouble.cxx
index 4a1d54ba2c601c377a61731573971561ef95f2e9..d88b627f2f4fd6628455567f1396282a49fef069 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.txx"
 #include "MEDCouplingVoronoi.hxx"
 #include "MEDCouplingNatureOfField.hxx"
+#include "MEDCouplingMemArray.txx"
 
 #include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGaussCoords.hxx"
 
 #include <sstream>
 #include <limits>
@@ -38,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.
@@ -173,9 +176,9 @@ 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();
@@ -187,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
@@ -243,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
@@ -366,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(_type.isNull())
-    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. 
@@ -448,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>
@@ -488,7 +421,7 @@ 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)
 {
@@ -521,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
-{
-  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
+template<class U>
+typename Traits<U>::FieldType *ConvertToUField(const MEDCouplingFieldDouble *self)
 {
-  if(_type.isNull())
-    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
+MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
 {
-  if(_type.isNull())
-    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();
+  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))
@@ -690,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)
 {
 }
 
@@ -758,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.
@@ -822,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.
@@ -1768,126 +1569,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(_type.isNull())
-    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(_type.isNull())
-    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(_type.isNull())
-    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(_type.isNull())
-    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(_type.isNull())
-    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(_type.isNull())
-    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 +1587,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 +1635,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,7 +1668,7 @@ 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)
 {
@@ -2026,7 +1707,7 @@ 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)
 {
@@ -2063,7 +1744,7 @@ 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)
 {
@@ -2104,7 +1785,7 @@ 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)
 {
@@ -2114,7 +1795,7 @@ bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
   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)
     {
@@ -2224,9 +1905,115 @@ MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) con
   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.
- * Finaly \a this is also expected to be consistent.
+ * 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.
  * 
@@ -3095,9 +2882,20 @@ MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voroni
   checkConsistencyLight();
   if(!vor)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
-  const MEDCouplingMesh *inpMesh(getMesh());
+  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(getDiscretization());
+  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");
@@ -3120,25 +2918,25 @@ MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voroni
       MCAuto<DataArrayDouble> ptsInReal;
       disc2->getCellIdsHavingGaussLocalization(i,ids);
       {
-        MCAuto<MEDCouplingUMesh> tmp4(inpMesh->buildUnstructured());
-        MCAuto<MEDCouplingUMesh> subMesh(tmp4->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
+        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 i=0;i<ids.size();i++)
+      for(std::size_t j=0;j<ids.size();j++)
         {
           MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
-          MCAuto<DataArrayDouble> coo(ptsInReal->selectByTupleIdSafeSlice(i*nbPtsPerCell,(i+1)*nbPtsPerCell,1));
-          elt->setCoords(coo);
-          cells[ids[i]]=elt;
+          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(getArray()->deepCopy());
+    MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
     onCells->setArray(arr);
   }
   onCells->setTimeUnit(getTimeUnit());
@@ -3172,4 +2970,3 @@ const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
     throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
   return retc;
 }
-