Salome HOME
Mesh::getNumberOfCells returns std::size_t
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingIMesh.cxx
index 4b3da324ab9f5517c144cb0c4662e9782c073bbd..329c545842892ff659fd29508d5055ea01738a83 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  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
@@ -28,7 +28,7 @@
 #include <sstream>
 #include <numeric>
 
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
 
 MEDCouplingIMesh::MEDCouplingIMesh():_space_dim(-1)
 {
@@ -56,7 +56,7 @@ MEDCouplingIMesh *MEDCouplingIMesh::New()
 MEDCouplingIMesh *MEDCouplingIMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
                                         const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(new MEDCouplingIMesh);
+  MCAuto<MEDCouplingIMesh> ret(new MEDCouplingIMesh);
   ret->setName(meshName);
   ret->setSpaceDimension(spaceDim);
   ret->setNodeStruct(nodeStrctStart,nodeStrctStop);
@@ -65,7 +65,7 @@ MEDCouplingIMesh *MEDCouplingIMesh::New(const std::string& meshName, int spaceDi
   return ret.retn();
 }
 
-MEDCouplingMesh *MEDCouplingIMesh::deepCpy() const
+MEDCouplingIMesh *MEDCouplingIMesh::deepCopy() const
 {
   return clone(true);
 }
@@ -75,6 +75,38 @@ MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const
   return new MEDCouplingIMesh(*this,recDeepCpy);
 }
 
+const DataArrayDouble *MEDCouplingIMesh::getDirectAccessOfCoordsArrIfInStructure() const
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getDirectAccessOfCoordsArrIfInStructure : MEDCouplingIMesh does not aggregate array of coordinates !");
+}
+
+/*!
+ * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis.
+ * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone.
+ *
+ * \param [in] ghostLev - the ghost level expected
+ * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller.
+ * \throw if \a ghostLev < 0.
+ */
+MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const
+{
+  if(ghostLev<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !");
+  checkConsistencyLight();
+  int spaceDim(getSpaceDimension());
+  double origin[3],dxyz[3];
+  int structure[3];
+  for(int i=0;i<spaceDim;i++)
+    {
+      origin[i]=_origin[i]-ghostLev*_dxyz[i];
+      dxyz[i]=_dxyz[i];
+      structure[i]=_structure[i]+2*ghostLev;
+    }
+  MCAuto<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim));
+  ret->copyTinyInfoFrom(this);
+  return ret.retn();
+}
+
 void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop)
 {
   checkSpaceDimension();
@@ -143,7 +175,7 @@ std::string MEDCouplingIMesh::getAxisUnit() const
  */
 double MEDCouplingIMesh::getMeasureOfAnyCell() const
 {
-  checkCoherency();
+  checkConsistencyLight();
   int dim(getSpaceDimension());
   double ret(1.);
   for(int i=0;i<dim;i++)
@@ -160,8 +192,8 @@ double MEDCouplingIMesh::getMeasureOfAnyCell() const
  */
 MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const
 {
-  checkCoherency();
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> ret(MEDCouplingCMesh::New());
+  checkConsistencyLight();
+  MCAuto<MEDCouplingCMesh> ret(MEDCouplingCMesh::New());
   try
   { ret->copyTinyInfoFrom(this); }
   catch(INTERP_KERNEL::Exception& ) { }
@@ -169,7 +201,7 @@ MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const
   std::vector<std::string> infos(buildInfoOnComponents());
   for(int i=0;i<spaceDim;i++)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]);
+      MCAuto<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]);
       arr->iota(); arr->applyLin(_dxyz[i],_origin[i]);
       ret->setCoordsAt(i,arr);
     }
@@ -186,7 +218,7 @@ void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors)
 {
   if((int)factors.size()!=_space_dim)
     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !");
-  checkCoherency();
+  checkConsistencyLight();
   std::vector<int> structure(_structure,_structure+3);
   std::vector<double> dxyz(_dxyz,_dxyz+3);
   for(int i=0;i<_space_dim;i++)
@@ -211,11 +243,11 @@ void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors)
  *
  * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell.
  *
- * \throw if \a this does not pass the \c checkCoherency test.
+ * \throw if \a this does not pass the \c checkConsistencyLight test.
  */
 MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
 {
-  checkCoherency();
+  checkConsistencyLight();
   int spaceDim(getSpaceDimension()),nodeSt[3];
   double dxyz[3];
   for(int i=0;i<spaceDim;i++)
@@ -231,7 +263,7 @@ MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
           dxyz[i]=_dxyz[i];
         }
     }
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim));
+  MCAuto<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim));
   ret->copyTinyInfoFrom(this);
   return ret.retn();
 }
@@ -241,15 +273,18 @@ MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
  * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
  * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged.
  *
- * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
  * \param [in] coarseSt The cell structure of coarse mesh.
  * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
  * \param [in] facts The refinement coefficient per axis.
- * \sa SpreadCoarseToFine
+ * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
+ *
+ * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine
  */
-void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts)
+void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA)
 {
+  if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !");
   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !");
   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
@@ -264,6 +299,13 @@ void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   int nbTuplesFine(fineDA->getNumberOfTuples());
+  if(nbOfTuplesInFineExp==0)
+    {
+      if(nbTuplesFine==0)
+        return ;
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !");
+    }
   if(nbTuplesFine%nbOfTuplesInFineExp!=0)
     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !");
   int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
@@ -352,6 +394,142 @@ void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std
   }
 }
 
+/*!
+ * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
+ * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
+ * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged.
+ *
+ * \param [in] coarseSt The cell structure of coarse mesh.
+ * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
+ * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
+ * \param [in] facts The refinement coefficient per axis.
+ * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
+ * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
+ *
+ * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost
+ */
+void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !");
+  if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !");
+  if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !");
+  std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+  int nbCompo(fineDA->getNumberOfComponents());
+  if(coarseDA->getNumberOfComponents()!=nbCompo)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !");
+  if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
+  if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+  std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
+  if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  double *outPtr(coarseDA->getPointer());
+  const double *inPtr(fineDA->begin());
+  //
+  std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  switch(meshDim)
+  {
+    case 1:
+      {
+        int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]);
+        inPtr+=ghostSize*nbCompo;
+        for(int i=0;i<dims[0];i++)
+          {
+            double *loc(outPtr+(offset+i)*nbCompo);
+            for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+              {
+                if(ifact!=0)
+                  std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+                else
+                  std::copy(inPtr,inPtr+nbCompo,loc);
+              }
+          }
+        break;
+      }
+    case 2:
+      {
+        int nxwg(coarseSt[0]+2*ghostSize);
+        int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]);
+        inPtr+=(dims[0]*fact0+2*ghostSize)*ghostSize*nbCompo;
+        for(int j=0;j<dims[1];j++)
+          {
+             for(int jfact=0;jfact<fact1;jfact++)
+              {
+                inPtr+=ghostSize*nbCompo;
+                for(int i=0;i<dims[0];i++)
+                  {
+                    double *loc(outPtr+(kk+i)*nbCompo);
+                    for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+                      {
+                        if(jfact!=0 || ifact!=0)
+                          std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+                        else
+                          std::copy(inPtr,inPtr+nbCompo,loc);
+                      }
+                  }
+                inPtr+=ghostSize*nbCompo;
+              }
+            kk+=nxwg;
+          }
+        break;
+      }
+    case 3:
+      {
+        int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize));
+        int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]);
+        inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo;
+        for(int k=0;k<dims[2];k++)
+          {
+            for(int kfact=0;kfact<fact2;kfact++)
+              {
+                inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
+                for(int j=0;j<dims[1];j++)
+                  {
+                    int kky(j*nxwg);
+                    for(int jfact=0;jfact<fact1;jfact++)
+                      {
+                        inPtr+=ghostSize*nbCompo;
+                        for(int i=0;i<dims[0];i++)
+                          {
+                            double *loc(outPtr+(kky+kk+i)*nbCompo);
+                            for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+                              {
+                                if(kfact!=0 || jfact!=0 || ifact!=0)
+                                  std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+                                else
+                                  std::copy(inPtr,inPtr+nbCompo,loc);
+                              }
+                          }
+                        inPtr+=ghostSize*nbCompo;
+                      }
+                  }
+                inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
+              }
+            kk+=nxywg;
+          }
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !");
+  }
+}
+
 /*!
  * This method spreads the values of coarse data \a coarseDA into \a fineDA.
  *
@@ -360,10 +538,12 @@ void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std
  * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
  * \param [in] facts The refinement coefficient per axis.
- * \sa CondenseFineToCoarse
+ * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
  */
 void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts)
 {
+  if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+      throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
@@ -451,6 +631,183 @@ void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const
   }
 }
 
+/*!
+ * This method spreads the values of coarse data \a coarseDA into \a fineDA.
+ *
+ * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
+ * \param [in] coarseSt The cell structure of coarse mesh.
+ * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
+ * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
+ * \param [in] facts The refinement coefficient per axis.
+ * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
+ *
+ * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone
+ */
+void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
+  if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
+  if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
+  std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+  int nbCompo(fineDA->getNumberOfComponents());
+  if(coarseDA->getNumberOfComponents()!=nbCompo)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
+  if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
+  if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+  std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
+  if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  double *outPtr(fineDA->getPointer());
+  const double *inPtr(coarseDA->begin());
+  //
+  switch(meshDim)
+  {
+    case 1:
+      {
+        std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+        int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
+        for(int i=0;i<ghostSize;i++)
+          outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+        offset=fineLocInCoarse[0].first+ghostSize;
+        for(int i=0;i<dims[0];i++)
+          {
+            const double *loc(inPtr+(offset+i)*nbCompo);
+            for(int ifact=0;ifact<fact0;ifact++)
+              outPtr=std::copy(loc,loc+nbCompo,outPtr);
+          }
+        offset=fineLocInCoarse[0].second+ghostSize;
+        for(int i=0;i<ghostSize;i++)
+          outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+        break;
+      }
+    case 2:
+      {
+        SpreadCoarseToFineGhost2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        break;
+      }
+    case 3:
+      {
+        std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+        int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
+        int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
+        int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
+        for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+          SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        offset+=nxyWgCoarse;
+        for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
+          for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
+            SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+          SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2, 3 supported !");
+  }
+}
+
+/*!
+ * This method spreads the values of coarse data \a coarseDA into \a fineDA \b ONLY \b in \b the \b ghost \b zone (contrary to SpreadCoarseToFineGhost that spread the values everywhere).
+ *
+ * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
+ * \param [in] coarseSt The cell structure of coarse mesh.
+ * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
+ * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
+ * \param [in] facts The refinement coefficient per axis.
+ * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
+ *
+ * \sa SpreadCoarseToFineGhost
+ */
+void MEDCouplingIMesh::SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
+  if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
+  if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
+  std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+  int nbCompo(fineDA->getNumberOfComponents());
+  if(coarseDA->getNumberOfComponents()!=nbCompo)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
+  if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
+  if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+  std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
+  if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  double *outPtr(fineDA->getPointer());
+  const double *inPtr(coarseDA->begin());
+  //
+  std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  switch(meshDim)
+  {
+    case 1:
+      {
+        int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
+        for(int i=0;i<ghostSize;i++)
+          outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+        outPtr+=nbCompo*fact0*dims[0];
+        offset=fineLocInCoarse[0].second+ghostSize;
+        for(int i=0;i<ghostSize;i++)
+          outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+        break;
+      }
+    case 2:
+      {
+        SpreadCoarseToFineGhostZone2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        break;
+      }
+    case 3:
+      {
+        int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
+        int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
+        int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
+        for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+          SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        offset+=nxyWgCoarse;
+        for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
+          for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
+            SpreadCoarseToFineGhostZone2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+          SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2, 3 supported !");
+  }
+}
+
 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
 {
   if(spaceDim==_space_dim)
@@ -469,7 +826,7 @@ std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
   return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
 }
 
-std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildrenWithNull() const
 {
   return std::vector<const BigMemoryObject *>();
 }
@@ -571,8 +928,8 @@ void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int ce
 }
 
 /*!
- * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too).
- * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same !
+ * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingIMesh instance too).
+ * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingIMesh, \a this and \a other are the same !
  */
 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
                                                        DataArrayInt *&cellCor) const
@@ -581,25 +938,20 @@ void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *ot
     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
 }
 
-void MEDCouplingIMesh::checkCoherency() const
+void MEDCouplingIMesh::checkConsistencyLight() const
 {
   checkSpaceDimension();
   for(int i=0;i<_space_dim;i++)
     if(_structure[i]<1)
       {
-        std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
+        std::ostringstream oss; oss << "MEDCouplingIMesh::checkConsistencyLight : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
 }
 
-void MEDCouplingIMesh::checkCoherency1(double eps) const
+void MEDCouplingIMesh::checkConsistency(double eps) const
 {
-  checkCoherency();
-}
-
-void MEDCouplingIMesh::checkCoherency2(double eps) const
-{
-  checkCoherency1(eps);
+  checkConsistencyLight();
 }
 
 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
@@ -617,7 +969,7 @@ std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
 
 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
 {
-  checkCoherency();
+  checkConsistencyLight();
   int dim(getSpaceDimension());
   if(dim!=(int)cellPart.size())
     {
@@ -626,7 +978,7 @@ MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::v
     }
   double retOrigin[3]={0.,0.,0.};
   int retStruct[3]={0,0,0};
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy()));
+  MCAuto<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCopy()));
   for(int i=0;i<dim;i++)
     {
       int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
@@ -646,7 +998,7 @@ MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::v
     }
   ret->setNodeStruct(retStruct,retStruct+dim);
   ret->setOrigin(retOrigin,retOrigin+dim);
-  ret->checkCoherency();
+  ret->checkConsistencyLight();
   return ret.retn();
 }
 
@@ -697,12 +1049,20 @@ std::string MEDCouplingIMesh::advancedRepr() const
 
 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
 {
-  checkCoherency();
+  checkConsistencyLight();
   int dim(getSpaceDimension());
   for(int idim=0; idim<dim; idim++)
     {
       bbox[2*idim]=_origin[idim];
-      bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*_structure[idim];
+      int coeff(_structure[idim]);
+      if(_structure[idim]<0)
+        {
+          std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      if(_structure[idim]>1)
+        coeff=_structure[idim]-1;
+      bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
     }
 }
 
@@ -719,7 +1079,7 @@ void MEDCouplingIMesh::getBoundingBox(double *bbox) const
  */
 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
 {
-  checkCoherency();
+  checkConsistencyLight();
   std::string name="MeasureOfMesh_";
   name+=getName();
   int nbelem(getNumberOfCells());
@@ -763,6 +1123,12 @@ int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) cons
   return ret;
 }
 
+void MEDCouplingIMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
+{
+  int ret(getCellContainingPoint(pos,eps));
+  elts.push_back(ret);
+}
+
 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
 {
   throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
@@ -814,8 +1180,8 @@ MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other)
  */
 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
 {
-  checkCoherency();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
+  checkConsistencyLight();
+  MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
   int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
   ret->alloc(nbNodes,spaceDim);
   double *pt(ret->getPointer());
@@ -839,10 +1205,10 @@ DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
  *          components. The caller is to delete this array using decrRef() as it is
  *          no more needed.
  */
-DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
+DataArrayDouble *MEDCouplingIMesh::computeCellCenterOfMass() const
 {
-  checkCoherency();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
+  checkConsistencyLight();
+  MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
   int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
   ret->alloc(nbCells,spaceDim);
   double *pt(ret->getPointer()),shiftOrigin[3];
@@ -861,7 +1227,7 @@ DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
 
 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
 {
-  return MEDCouplingIMesh::getBarycenterAndOwner();
+  return MEDCouplingIMesh::computeCellCenterOfMass();
 }
 
 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
@@ -920,7 +1286,7 @@ void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, con
 
 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
 {
-  checkCoherency();
+  checkConsistencyLight();
   std::ostringstream extent,origin,spacing;
   for(int i=0;i<3;i++)
     {
@@ -974,6 +1340,11 @@ void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
   stream << stream1.str();
 }
 
+std::string MEDCouplingIMesh::getVTKFileExtension() const
+{
+  return std::string("vti");
+}
+
 std::string MEDCouplingIMesh::getVTKDataSetType() const
 {
   return std::string("ImageData");
@@ -1035,3 +1406,96 @@ int MEDCouplingIMesh::FindIntRoot(int val, int order)
         return ret2;
     }
 }
+
+void MEDCouplingIMesh::SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
+{
+  double *outPtrWork(outPtr);
+  std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
+  int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
+  for(int jg=0;jg<ghostSize;jg++)
+    {
+      for(int ig=0;ig<ghostSize;ig++)
+        outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
+      int kk0(kk+1);
+      for(int ig=0;ig<dims[0];ig++,kk0++)
+        for(int ifact=0;ifact<fact0;ifact++)
+          outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
+      for(int ik=0;ik<ghostSize;ik++)
+        outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
+    }
+  for(int j=0;j<dims[1];j++)
+    {
+      kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
+      for(int jfact=0;jfact<fact1;jfact++)
+        {
+          for(int ig=0;ig<ghostSize;ig++)
+            outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
+          int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
+          for(int i=0;i<dims[0];i++,kk0++)
+            {
+              const double *loc(inPtr+kk0*nbCompo);
+              for(int ifact=0;ifact<fact0;ifact++)
+                outPtrWork=std::copy(loc,loc+nbCompo,outPtrWork);
+            }
+          for(int ig=0;ig<ghostSize;ig++)
+            outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
+        }
+    }
+  kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
+  for(int jg=0;jg<ghostSize;jg++)
+    {
+      for(int ig=0;ig<ghostSize;ig++)
+        outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
+      int kk0(kk+1);
+      for(int ig=0;ig<dims[0];ig++,kk0++)
+        for(int ifact=0;ifact<fact0;ifact++)
+          outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
+      for(int ik=0;ik<ghostSize;ik++)
+        outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
+    }
+}
+
+void MEDCouplingIMesh::SpreadCoarseToFineGhostZone2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
+{
+  double *outPtr2(outPtr);
+  std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
+  int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
+  for(int jg=0;jg<ghostSize;jg++)
+    {
+      for(int ig=0;ig<ghostSize;ig++)
+        outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
+      int kk0(kk+1);
+      for(int ig=0;ig<dims[0];ig++,kk0++)
+        for(int ifact=0;ifact<fact0;ifact++)
+          outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
+      for(int ik=0;ik<ghostSize;ik++)
+        outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
+    }
+  for(int j=0;j<dims[1];j++)
+    {
+      kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
+      for(int jfact=0;jfact<fact1;jfact++)
+        {
+          for(int ig=0;ig<ghostSize;ig++)
+            outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
+          int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
+          outPtr2+=fact0*nbCompo*dims[0];
+          for(int ig=0;ig<ghostSize;ig++)
+            outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
+        }
+    }
+  kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
+  for(int jg=0;jg<ghostSize;jg++)
+    {
+      for(int ig=0;ig<ghostSize;ig++)
+        outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
+      int kk0(kk+1);
+      for(int ig=0;ig<dims[0];ig++,kk0++)
+        for(int ifact=0;ifact<fact0;ifact++)
+          outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
+      for(int ik=0;ik<ghostSize;ik++)
+        outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
+    }
+}