Salome HOME
Small but useful DataArrayInt::checkUniformAndGuess
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingCMesh.cxx
index bd6233b93535f961bc25e89d36b22004632c7673..f640504926209fefa8031892de5c73d5ee22faf5 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDCouplingCMesh.hxx"
-#include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingMemArray.hxx"
 #include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingCurveLinearMesh.hxx"
+
+#include "InterpKernelAutoPtr.hxx"
 
 #include <functional>
 #include <algorithm>
 #include <sstream>
 #include <numeric>
 
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
 
 MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0)
 {
 }
 
-MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingMesh(other)
+MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy)
 {
   if(deepCopy)
     {
       if(other._x_array)
-        _x_array=other._x_array->deepCpy();
+        _x_array=other._x_array->deepCopy();
       else
         _x_array=0;
       if(other._y_array)
-        _y_array=other._y_array->deepCpy();
+        _y_array=other._y_array->deepCopy();
       else
         _y_array=0;
       if(other._z_array)
-        _z_array=other._z_array->deepCpy();
+        _z_array=other._z_array->deepCopy();
       else
         _z_array=0;
     }
@@ -80,14 +82,14 @@ MEDCouplingCMesh *MEDCouplingCMesh::New()
   return new MEDCouplingCMesh;
 }
 
-MEDCouplingCMesh *MEDCouplingCMesh::New(const char *meshName)
+MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName)
 {
-  MEDCouplingCMesh *ret=new MEDCouplingCMesh;
+  MEDCouplingCMesh *ret(new MEDCouplingCMesh);
   ret->setName(meshName);
   return ret;
 }
 
-MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const
+MEDCouplingCMesh *MEDCouplingCMesh::deepCopy() const
 {
   return clone(true);
 }
@@ -97,6 +99,25 @@ MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const
   return new MEDCouplingCMesh(*this,recDeepCpy);
 }
 
+const DataArrayDouble *MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure() const
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure : MEDCouplingCMesh does not aggregate array of coordinates !");
+}
+
+MEDCouplingCurveLinearMesh *MEDCouplingCMesh::buildCurveLinear() const
+{
+  checkConsistencyLight();
+  int dim(getSpaceDimension());
+  MCAuto<MEDCouplingCurveLinearMesh> ret(MEDCouplingCurveLinearMesh::New());
+  ret->MEDCouplingStructuredMesh::operator=(*this);
+  INTERP_KERNEL::AutoPtr<int> ngs(new int[dim]);
+  getNodeGridStructure(ngs);
+  ret->setNodeGridStructure(ngs,ngs+dim);
+  MCAuto<DataArrayDouble> coo(getCoordinatesAndOwner());
+  ret->setCoords(coo);
+  return ret.retn();
+}
+
 void MEDCouplingCMesh::updateTime() const
 {
   if(_x_array)
@@ -107,16 +128,30 @@ void MEDCouplingCMesh::updateTime() const
     updateTimeWith(*_z_array);
 }
 
+std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const
+{
+  return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
+}
+
+std::vector<const BigMemoryObject *> MEDCouplingCMesh::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret;
+  ret.push_back(_x_array);
+  ret.push_back(_y_array);
+  ret.push_back(_z_array);
+  return ret;
+}
+
 /*!
  * This method copyies all tiny strings from other (name and components name).
  * @throw if other and this have not same mesh type.
  */
-void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
-{ 
-  const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
+void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
+{
+  MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
+  const MEDCouplingCMesh *otherC(dynamic_cast<const MEDCouplingCMesh *>(other));
   if(!otherC)
     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
-  MEDCouplingMesh::copyTinyStringsFrom(other);
   if(_x_array && otherC->_x_array)
     _x_array->copyStringInfoFrom(*otherC->_x_array);
   if(_y_array && otherC->_y_array)
@@ -125,7 +160,7 @@ void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(I
     _z_array->copyStringInfoFrom(*otherC->_z_array);
 }
 
-bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
+bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
 {
   if(!other)
     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !");
@@ -135,7 +170,7 @@ bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec
       reason="mesh given in input is not castable in MEDCouplingCMesh !";
       return false;
     }
-  if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason))
+  if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
     return false;
   const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
   const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
@@ -178,29 +213,29 @@ bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other
 }
 
 void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
-                                            DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+                                            DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
 {
   if(!isEqualWithoutConsideringStr(other,prec))
     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !");
 }
 
 /*!
- * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCMesh instance too).
- * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCMesh, 'this' and 'other' are the same !
+ * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingCMesh instance too).
+ * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingCMesh, \a this and \a other are the same !
  */
 void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
-                                                       DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+                                                       DataArrayInt *&cellCor) const
 {
-  const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
-  if(!otherC)
-    throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !");
+  if(!isEqualWithoutConsideringStr(other,prec))
+    throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
 }
 
-void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::checkConsistencyLight() const
 {
   const char msg0[]="Invalid ";
   const char msg1[]=" array ! Must contain more than 1 element.";
   const char msg2[]=" array ! Must be with only one component.";
+  getSpaceDimension();// here to check that no holes in arrays !
   if(_x_array)
     {
       if(_x_array->getNbOfElems()<2)
@@ -226,7 +261,6 @@ void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
           std::ostringstream os; os << msg0 << 'Y' << msg2;
           throw INTERP_KERNEL::Exception(os.str().c_str());
         }
-      
     }
   if(_z_array)
     {
@@ -243,9 +277,9 @@ void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
     }
 }
 
-void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::checkConsistency(double eps) const
 {
-  checkCoherency();
+  checkConsistencyLight();
   if(_x_array)
     _x_array->checkMonotonic(true, eps);
   if(_y_array)
@@ -254,194 +288,74 @@ void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Ex
     _z_array->checkMonotonic(true, eps);
 }
 
-void MEDCouplingCMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::getNodeGridStructure(int *res) const
 {
-  checkCoherency1(eps);
+  std::vector<int> ret(getNodeGridStructure());
+  std::copy(ret.begin(),ret.end(),res);
 }
 
-int MEDCouplingCMesh::getNumberOfCells() const
+std::vector<int> MEDCouplingCMesh::getNodeGridStructure() const
 {
-  int ret=1;
+  static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !";
+  std::vector<int> ret;
+  bool isOK(true);
   if(_x_array)
-    ret*=_x_array->getNbOfElems()-1;
-  if(_y_array)
-    ret*=_y_array->getNbOfElems()-1;
-  if(_z_array)
-    ret*=_z_array->getNbOfElems()-1;
-  return ret;
-}
-
-int MEDCouplingCMesh::getNumberOfNodes() const
-{
-  int ret=1;
-  if(_x_array)
-    ret*=_x_array->getNbOfElems();
-  if(_y_array)
-    ret*=_y_array->getNbOfElems();
-  if(_z_array)
-    ret*=_z_array->getNbOfElems();
-  return ret;
-}
-
-void MEDCouplingCMesh::getSplitCellValues(int *res) const
-{
-  int spaceDim=getSpaceDimension();
-  for(int l=0;l<spaceDim;l++)
     {
-      int val=1;
-      for(int p=0;p<spaceDim-l-1;p++)
-        val*=getCoordsAt(p)->getNbOfElems()-1;
-      res[spaceDim-l-1]=val;
+      if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1)
+        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !");
+      ret.push_back(_x_array->getNumberOfTuples());
     }
-}
-
-void MEDCouplingCMesh::getSplitNodeValues(int *res) const
-{
-  int spaceDim=getSpaceDimension();
-  for(int l=0;l<spaceDim;l++)
-    {
-      int val=1;
-      for(int p=0;p<spaceDim-l-1;p++)
-        val*=getCoordsAt(p)->getNbOfElems();
-      res[spaceDim-l-1]=val;
-    }
-}
-
-int MEDCouplingCMesh::getCellIdFromPos(int i, int j, int k) const
-{
-  int tmp[3]={i,j,k};
-  int tmp2[3];
-  int spaceDim=getSpaceDimension();
-  getSplitCellValues(tmp2);
-  std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
-  return std::accumulate(tmp,tmp+spaceDim,0);
-}
-
-int MEDCouplingCMesh::getNodeIdFromPos(int i, int j, int k) const
-{
-  int tmp[3]={i,j,k};
-  int tmp2[3];
-  int spaceDim=getSpaceDimension();
-  getSplitNodeValues(tmp2);
-  std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
-  return std::accumulate(tmp,tmp+spaceDim,0);
-}
-
-void MEDCouplingCMesh::GetPosFromId(int nodeId, int spaceDim, const int *split, int *res)
-{
-  int work=nodeId;
-  for(int i=spaceDim-1;i>=0;i--)
+  else
+    isOK=false;
+  if(_y_array)
     {
-      int pos=work/split[i];
-      work=work%split[i];
-      res[i]=pos;
+      if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1)
+        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !");
+      if(!isOK)
+        throw INTERP_KERNEL::Exception(MSG);
+      ret.push_back(_y_array->getNumberOfTuples());
     }
-}
-
-int MEDCouplingCMesh::getSpaceDimension() const
-{
-  int ret=0;
-  if(_x_array)
-    ret++;
-  if(_y_array)
-    ret++;
+  else
+    isOK=false;
   if(_z_array)
-    ret++;
-  return ret;
-}
-
-int MEDCouplingCMesh::getMeshDimension() const
-{
-  return getSpaceDimension();
-}
-
-INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) const
-{
-  switch(getMeshDimension())
     {
-    case 3:
-      return INTERP_KERNEL::NORM_HEXA8;
-    case 2:
-      return INTERP_KERNEL::NORM_QUAD4;
-    case 1:
-      return INTERP_KERNEL::NORM_SEG2;
-    default:
-      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
+      if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1)
+        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !");
+      if(!isOK)
+        throw INTERP_KERNEL::Exception(MSG);
+      ret.push_back(_z_array->getNumberOfTuples());
     }
+  return ret;
 }
 
-std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingCMesh::getAllGeoTypes() const
+MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
 {
-  INTERP_KERNEL::NormalizedCellType ret;
-  switch(getMeshDimension())
+  checkConsistencyLight();
+  int dim(getSpaceDimension());
+  if(dim!=(int)cellPart.size())
     {
-    case 3:
-      ret=INTERP_KERNEL::NORM_HEXA8;
-      break;
-    case 2:
-      ret=INTERP_KERNEL::NORM_QUAD4;
-      break;
-    case 1:
-      ret=INTERP_KERNEL::NORM_SEG2;
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getAllGeoTypes !");
+      std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  std::set<INTERP_KERNEL::NormalizedCellType> ret2;
-  ret2.insert(ret);
-  return ret2;
-}
-
-int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
-{
-  int ret=getNumberOfCells();
-  int dim=getMeshDimension();
-  switch(type)
+  MCAuto<MEDCouplingCMesh> ret(dynamic_cast<MEDCouplingCMesh *>(deepCopy()));
+  for(int i=0;i<dim;i++)
     {
-    case INTERP_KERNEL::NORM_HEXA8:
-      if(dim==3)
-        return ret;
-    case INTERP_KERNEL::NORM_QUAD4:
-      if(dim==2)
-        return ret;
-    case INTERP_KERNEL::NORM_SEG2:
-      if(dim==1)
-        return ret;
-    default:
-      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
+      MCAuto<DataArrayDouble> tmp(ret->getCoordsAt(i)->selectByTupleIdSafeSlice(cellPart[i].first,cellPart[i].second+1,1));
+      ret->setCoordsAt(i,tmp);
     }
-  return 0;
+  return ret.retn();
 }
 
-void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
+/*!
+ * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that.
+ * This method throws exceptions if the not null arrays defining this are not contiguously at the end. For example X!=0,Y==0,Z!=0 will throw.
+ */
+int MEDCouplingCMesh::getSpaceDimension() const
 {
-  int spaceDim=getSpaceDimension();
-  int tmpCell[3],tmpNode[3];
-  getSplitCellValues(tmpCell);
-  getSplitNodeValues(tmpNode);
-  int tmp2[3];
-  GetPosFromId(cellId,spaceDim,tmpCell,tmp2);
-  switch(spaceDim)
-    {
-    case 1:
-      conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1);
-      break;
-    case 2:
-      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1);
-      conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]);
-      break;
-    case 3:
-      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]);
-      conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]);
-      conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]);
-      conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]);
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !");
-    };
+  return (int)getNodeGridStructure().size();
 }
 
-void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
 {
   int tmp[3];
   int spaceDim=getSpaceDimension();
@@ -463,7 +377,7 @@ std::string MEDCouplingCMesh::simpleRepr() const
   double tt=getTime(tmpp1,tmpp2);
   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
-  ret << "Mesh and SpaceDimension dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
+  ret << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
   if(_x_array)
     {
       ret << "X Array :\n";
@@ -487,10 +401,23 @@ std::string MEDCouplingCMesh::advancedRepr() const
   return simpleRepr();
 }
 
-const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception)
+/*!
+ * Returns a DataArrayDouble holding positions of nodes along a given axis.
+ * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
+ *  \param [in] i - an index of axis, a value from [0,1,2].
+ *  \return const DataArrayDouble * - a pointer to the data array of node coordinates
+ *         referred by \a this mesh.
+ *  \throw If \a i is not one of [0,1,2].
+ *
+ *  \if ENABLE_EXAMPLES
+ *  \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
+ *  \ref  py_mccmesh_getCoordsAt "Here is a Python example".
+ *  \endif
+ */
+const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const
 {
   switch(i)
-    {
+  {
     case 0:
       return _x_array;
     case 1:
@@ -499,13 +426,26 @@ const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_K
       return _z_array;
     default:
       throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
-    }
+  }
 }
 
-DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Exception)
+/*!
+ * Returns a DataArrayDouble holding positions of nodes along a given axis.
+ * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
+ *  \param [in] i - an index of axis, a value from [0,1,2].
+ *  \return const DataArrayDouble * - a pointer to the data array of node coordinates
+ *         referred by \a this mesh.
+ *  \throw If \a i is not one of [0,1,2].
+ *
+ *  \if ENABLE_EXAMPLES
+ *  \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
+ *  \ref  py_mccmesh_getCoordsAt "Here is a Python example".
+ *  \endif
+ */
+DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i)
 {
   switch(i)
-    {
+  {
     case 0:
       return _x_array;
     case 1:
@@ -514,11 +454,27 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Excep
       return _z_array;
     default:
       throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
-    }
+  }
 }
 
-void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception)
+/*!
+ * Sets node coordinates along a given axis. For more info on Cartesian meshes, see 
+ * \ref MEDCouplingCMeshPage.
+ *  \param [in] i - an index of axis, a value in range [0,1,2].
+ *  \param [in] arr - DataArrayDouble holding positions of nodes along the i-th
+ *         axis. It must be an array of one component.
+ *  \throw If \a arr->getNumberOfComponents() != 1.
+ *  \throw If \a i is not one of [0,1,2].
+ *
+ *  \if ENABLE_EXAMPLES
+ *  \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
+ *  \ref  medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
+ *  \endif
+ */
+void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr)
 {
+  if(arr)
+    arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt");
   DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
   if(i<0 || i>2)
     throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
@@ -533,8 +489,31 @@ void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTE
     }
 }
 
+/*!
+ * Sets node coordinates along some of the tree axes. This method updates all the
+ * three node coordinates arrays at once. For more info on Cartesian meshes, see 
+ * \ref MEDCouplingCMeshPage.
+ *  \param [in] coordsX - DataArrayDouble holding positions of nodes along the X
+ *         axis. It must be an array of one component or \c NULL.
+ *  \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y
+ *         axis. It must be an array of one component or \c NULL.
+ *  \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z
+ *         axis. It must be an array of one component or \c NULL.
+ *  \throw If \a coords*->getNumberOfComponents() != 1.
+ *
+ *  \if ENABLE_EXAMPLES
+ *  \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
+ *  \ref  medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
+ *  \endif
+ */
 void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ)
 {
+  if(coordsX)
+    coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX");
+  if(coordsY)
+    coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY");
+  if(coordsZ)
+    coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ");
   if(_x_array)
     _x_array->decrRef();
   _x_array=const_cast<DataArrayDouble *>(coordsX);
@@ -553,107 +532,6 @@ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArray
   declareAsNew();
 }
 
-/*!
- * See MEDCouplingUMesh::getDistributionOfTypes for more information
- */
-std::vector<int> MEDCouplingCMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
-{
-  //only one type of cell
-  std::vector<int> ret(3);
-  ret[0]=getTypeOfCell(0);
-  ret[1]=getNumberOfCells();
-  ret[2]=0; //ret[3*k+2]==0 because it has no sense here
-  return ret;
-}
-
-/*!
- * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information
- */
-DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
-{
-  if(code.empty())
-    throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code is empty, should not !");
-  std::size_t sz=code.size();
-  if(sz!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !");
-
-  int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]);
-  if(code[2]==-1)
-    {
-      if(code[1]==nbCells)
-        return 0;
-      else
-        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of cells mismatch !");
-    }
-  else
-    {
-      if(code[2]<-1) 
-        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !");
-      if(code[2]>=(int)idsPerType.size()) 
-        throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !");
-      return idsPerType[code[2]]->deepCpy();
-    }
-}
-
-/*!
- * See MEDCouplingUMesh::splitProfilePerType for more information
- */
-void MEDCouplingCMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
-{
-  int nbCells=getNumberOfCells();
-  code.resize(3);
-  code[0]=(int)getTypeOfCell(0);
-  code[1]=nbCells;
-  code[2]=0;
-  idsInPflPerType.push_back(profile->deepCpy());
-  idsPerType.push_back(profile->deepCpy());
-}
-
-MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
-{
-  int spaceDim=getSpaceDimension();
-  MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim);
-  DataArrayDouble *coords=getCoordinatesAndOwner();
-  ret->setCoords(coords);
-  coords->decrRef();
-  switch(spaceDim)
-    {
-    case 1:
-      fill1DUnstructuredMesh(ret);
-      break;
-    case 2:
-      fill2DUnstructuredMesh(ret);
-      break;
-    case 3:
-      fill3DUnstructuredMesh(ret);
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !");
-    };
-  return ret;
-}
-
-MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const
-{
-  MEDCouplingUMesh *um=buildUnstructured();
-  MEDCouplingMesh *ret=um->buildPart(start,end);
-  um->decrRef();
-  return ret;
-}
-
-MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
-{
-  MEDCouplingUMesh *um=buildUnstructured();
-  MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr);
-  um->decrRef();
-  return ret;
-}
-
-DataArrayInt *MEDCouplingCMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
-{
-  throw INTERP_KERNEL::Exception("MEDCouplingCMesh::simplexize : not available for Cartesian mesh !");
-}
-
 void MEDCouplingCMesh::getBoundingBox(double *bbox) const
 {
   int dim=getSpaceDimension();
@@ -672,19 +550,31 @@ void MEDCouplingCMesh::getBoundingBox(double *bbox) const
     }
 }
 
+/*!
+ * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
+ * mesh.<br>
+ * For 1D cells, the returned field contains lengths.<br>
+ * For 2D cells, the returned field contains areas.<br>
+ * For 3D cells, the returned field contains volumes.
+ *  \param [in] isAbs - a not used parameter.
+ *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
+ *         and one time . The caller is to delete this field using decrRef() as it is no
+ *         more needed.
+ */
 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
 {
   std::string name="MeasureOfMesh_";
   name+=getName();
   int nbelem=getNumberOfCells();
-  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS);
-  field->setName(name.c_str());
+  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  field->setName(name);
   DataArrayDouble* array=DataArrayDouble::New();
   array->alloc(nbelem,1);
   double *area_vol=array->getPointer();
   field->setArray(array) ;
   array->decrRef();
   field->setMesh(const_cast<MEDCouplingCMesh *>(this));
+  field->synchronizeTimeWithMesh();
   int tmp[3];
   getSplitCellValues(tmp);
   int dim=getSpaceDimension();
@@ -713,23 +603,6 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) cons
   //return 0;
 }
 
-MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const
-{
-  if(getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
-  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
-  DataArrayDouble *array=DataArrayDouble::New();
-  int nbOfCells=getNumberOfCells();
-  array->alloc(nbOfCells,3);
-  double *vals=array->getPointer();
-  for(int i=0;i<nbOfCells;i++)
-    { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
-  ret->setArray(array);
-  array->decrRef();
-  ret->setMesh(this);
-  return ret;
-}
-
 int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
 {
   int dim=getSpaceDimension();
@@ -760,11 +633,23 @@ int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) cons
   return ret;
 }
 
+void MEDCouplingCMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
+{
+  int ret(getCellContainingPoint(pos,eps));
+  elts.push_back(ret);
+}
+
 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
 {
-  throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to StructuredMesh to apply it !");
+  throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh to apply it !");
 }
 
+/*!
+ * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
+ * component of the \a vector to all node coordinates of a corresponding axis.
+ *  \param [in] vector - the translation vector whose size must be not less than \a
+ *         this->getSpaceDimension().
+ */
 void MEDCouplingCMesh::translate(const double *vector)
 {
   if(_x_array)
@@ -778,6 +663,12 @@ void MEDCouplingCMesh::translate(const double *vector)
                    _z_array->getPointer(),std::bind2nd(std::plus<double>(),vector[2]));
 }
 
+/*!
+ * Applies scaling transformation to all nodes of \a this mesh.
+ *  \param [in] point - coordinates of a scaling center. This array is to be of
+ *         size \a this->getSpaceDimension() at least.
+ *  \param [in] factor - a scale factor.
+ */
 void MEDCouplingCMesh::scale(const double *point, double factor)
 {
   for(int i=0;i<3;i++)
@@ -802,13 +693,19 @@ MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other)
   return 0;
 }
 
+/*!
+ * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
+ *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
+ *          this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
+ *          components. The caller is to delete this array using decrRef() as it is
+ *          no more needed.
+ */
 DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
 {
-  DataArrayDouble *ret=DataArrayDouble::New();
-  int spaceDim=getSpaceDimension();
-  int nbNodes=getNumberOfNodes();
+  MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
+  int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
   ret->alloc(nbNodes,spaceDim);
-  double *pt=ret->getPointer();
+  double *pt(ret->getPointer());
   int tmp[3];
   getSplitNodeValues(tmp);
   const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
@@ -816,7 +713,7 @@ DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
   for(int j=0;j<spaceDim;j++)
     {
       tabsPtr[j]=tabs[j]->getConstPointer();
-      ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str());
+      ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
     }
   int tmp2[3];
   for(int i=0;i<nbNodes;i++)
@@ -825,10 +722,18 @@ DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
       for(int j=0;j<spaceDim;j++)
         pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
     }
-  return ret;
+  return ret.retn();
 }
 
-DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const
+/*!
+ * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
+ * computed by averaging coordinates of cell nodes.
+ *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
+ *          this->getNumberOfCells() tuples per \a this->getSpaceDimension()
+ *          components. The caller is to delete this array using decrRef() as it is
+ *          no more needed.
+ */
+DataArrayDouble *MEDCouplingCMesh::computeCellCenterOfMass() const
 {
   DataArrayDouble *ret=DataArrayDouble::New();
   int spaceDim=getSpaceDimension();
@@ -842,7 +747,7 @@ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const
   for(int j=0;j<spaceDim;j++)
     {
       int sz=tabs[j]->getNbOfElems()-1;
-      ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str());
+      ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
       const double *srcPtr=tabs[j]->getConstPointer();
       tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz);
       std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>());
@@ -858,98 +763,14 @@ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const
   return ret;
 }
 
-void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
-{
-  throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
-}
-
-void MEDCouplingCMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const
+DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const
 {
-  const DataArrayDouble *c=getCoordsAt(0);
-  int nbOfCells=c->getNbOfElems()-1;
-  DataArrayInt *connI=DataArrayInt::New();
-  connI->alloc(nbOfCells+1,1);
-  int *ci=connI->getPointer();
-  DataArrayInt *conn=DataArrayInt::New();
-  conn->alloc(3*nbOfCells,1);
-  ci[0]=0;
-  int *cp=conn->getPointer();
-  for(int i=0;i<nbOfCells;i++)
-    {
-      cp[3*i]=(int)INTERP_KERNEL::NORM_SEG2;
-      cp[3*i+1]=i;
-      cp[3*i+2]=i+1;
-      ci[i+1]=3*(i+1);
-    }
-  m->setConnectivity(conn,connI,true);
-  conn->decrRef();
-  connI->decrRef();
+  return MEDCouplingCMesh::computeCellCenterOfMass();
 }
 
-void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const
+void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check)
 {
-  const DataArrayDouble *c1=getCoordsAt(0);
-  const DataArrayDouble *c2=getCoordsAt(1);
-  int n1=c1->getNbOfElems()-1;
-  int n2=c2->getNbOfElems()-1;
-  DataArrayInt *connI=DataArrayInt::New();
-  connI->alloc(n1*n2+1,1);
-  int *ci=connI->getPointer();
-  DataArrayInt *conn=DataArrayInt::New();
-  conn->alloc(5*n1*n2,1);
-  ci[0]=0;
-  int *cp=conn->getPointer();
-  int pos=0;
-  for(int j=0;j<n2;j++)
-    for(int i=0;i<n1;i++,pos++)
-      {
-        cp[5*pos]=(int)INTERP_KERNEL::NORM_QUAD4;
-        cp[5*pos+1]=i+1+j*(n1+1);
-        cp[5*pos+2]=i+j*(n1+1);
-        cp[5*pos+3]=i+(j+1)*(n1+1);
-        cp[5*pos+4]=i+1+(j+1)*(n1+1);
-        ci[pos+1]=5*(pos+1);
-    }
-  m->setConnectivity(conn,connI,true);
-  conn->decrRef();
-  connI->decrRef();
-}
-
-void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const
-{
-  const DataArrayDouble *c1=getCoordsAt(0);
-  const DataArrayDouble *c2=getCoordsAt(1);
-  const DataArrayDouble *c3=getCoordsAt(2);
-  int n1=c1->getNbOfElems()-1;
-  int n2=c2->getNbOfElems()-1;
-  int n3=c3->getNbOfElems()-1;
-  DataArrayInt *connI=DataArrayInt::New();
-  connI->alloc(n1*n2*n3+1,1);
-  int *ci=connI->getPointer();
-  DataArrayInt *conn=DataArrayInt::New();
-  conn->alloc(9*n1*n2*n3,1);
-  ci[0]=0;
-  int *cp=conn->getPointer();
-  int pos=0;
-  for(int k=0;k<n3;k++)
-    for(int j=0;j<n2;j++)
-      for(int i=0;i<n1;i++,pos++)
-        {
-          cp[9*pos]=(int)INTERP_KERNEL::NORM_HEXA8;
-          int tmp=(n1+1)*(n2+1);
-          cp[9*pos+1]=i+1+j*(n1+1)+k*tmp;
-          cp[9*pos+2]=i+j*(n1+1)+k*tmp;
-          cp[9*pos+3]=i+(j+1)*(n1+1)+k*tmp;
-          cp[9*pos+4]=i+1+(j+1)*(n1+1)+k*tmp;
-          cp[9*pos+5]=i+1+j*(n1+1)+(k+1)*tmp;
-          cp[9*pos+6]=i+j*(n1+1)+(k+1)*tmp;
-          cp[9*pos+7]=i+(j+1)*(n1+1)+(k+1)*tmp;
-          cp[9*pos+8]=i+1+(j+1)*(n1+1)+(k+1)*tmp;
-          ci[pos+1]=9*(pos+1);
-        }
-  m->setConnectivity(conn,connI,true);
-  conn->decrRef();
-  connI->decrRef();
+  throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
 }
 
 void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
@@ -1012,9 +833,9 @@ void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
 void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
                                        const std::vector<std::string>& littleStrings)
 {
-  setName(littleStrings[0].c_str());
-  setDescription(littleStrings[1].c_str());
-  setTimeUnit(littleStrings[2].c_str());
+  setName(littleStrings[0]);
+  setDescription(littleStrings[1]);
+  setTimeUnit(littleStrings[2]);
   DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
   const double *data=a2->getConstPointer();
   for(int i=0;i<3;i++)
@@ -1023,7 +844,7 @@ void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, con
         {
           (*(thisArr[i]))=DataArrayDouble::New();
           (*(thisArr[i]))->alloc(tinyInfo[i],1);
-          (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3].c_str());
+          (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]);
           std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
           data+=tinyInfo[i];
         }
@@ -1031,12 +852,94 @@ void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, con
   setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]);
 }
 
-void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
+{
+  std::ostringstream extent;
+  DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+  for(int i=0;i<3;i++)
+    {
+      if(thisArr[i])
+        { extent << "0 " <<  thisArr[i]->getNumberOfTuples()-1 << " "; }
+      else
+        { extent << "0 0 "; }
+    }
+  ofs << "  <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
+  ofs << "    <Piece Extent=\"" << extent.str() << "\">\n";
+  ofs << "      <PointData>\n" << pointData << std::endl;
+  ofs << "      </PointData>\n";
+  ofs << "      <CellData>\n" << cellData << std::endl;
+  ofs << "      </CellData>\n";
+  ofs << "      <Coordinates>\n";
+  for(int i=0;i<3;i++)
+    {
+      if(thisArr[i])
+        thisArr[i]->writeVTK(ofs,8,"Array",byteData);
+      else
+        {
+          MCAuto<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1);
+          coo->setIJ(0,0,0.);
+          coo->writeVTK(ofs,8,"Array",byteData);
+        }
+    }
+  ofs << "      </Coordinates>\n";
+  ofs << "    </Piece>\n";
+  ofs << "  </" << getVTKDataSetType() << ">\n";
+}
+
+void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const
+{
+  stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
+  const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+  std::ostringstream stream2[3];
+  bool isDef[3];
+  int nbOfCells=1,nbOfNodes=1;
+  for(int i=0;i<3;i++)
+    {
+      isDef[i]=thisArr[i]!=0;
+      if(isDef[i])
+        {    
+          char tmp='X'+i;
+          stream2[i] << tmp << " positions array ";
+          if(!thisArr[i]->isAllocated())
+            stream2[i] << "set but not allocated.";
+          else
+            {
+              int nbCompo=thisArr[i]->getNumberOfComponents();
+              if(nbCompo==1)
+                {
+                  int nbTuples=thisArr[i]->getNumberOfTuples();
+                  if(nbTuples<1)
+                    { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; }
+                  else
+                    {
+                      stream2[i] << "(length=" << nbTuples << ")" << ": ";
+                      thisArr[i]->reprQuickOverviewData(stream2[i],200);
+                      if(nbOfCells!=-1)
+                        { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; }
+                    }
+                }
+              else
+                { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; }
+            }
+        }
+    }
+  if(!isDef[0] && !isDef[1] && !isDef[2])
+    { stream << " No arrays set !"; return; }
+  if(nbOfCells>=0)
+    { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; }
+  for(int i=0;i<3;i++)
+    {
+      if(isDef[i])
+        stream << std::endl << stream2[i].str();
+    }
+}
+
+std::string MEDCouplingCMesh::getVTKFileExtension() const
 {
-  throw INTERP_KERNEL::Exception("MEDCouplingCMesh::writeVTKLL : not implemented yet !");
+  return std::string("vtr");
 }
 
-std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
+std::string MEDCouplingCMesh::getVTKDataSetType() const
 {
   return std::string("RectilinearGrid");
 }