Salome HOME
Merge branch 'master' of ssh://git.salome-platform.org/tools/medcoupling
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingAMRAttribute.cxx
index b9c1559dee304b9c7a093c58ff17ea489989673a..4267ae29fb970c199bd7a431c1c8de90c6d717f1 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
 #include "MEDCouplingIMesh.hxx"
 
 #include <sstream>
+#include <fstream>
 
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
 
+/// @cond INTERNAL
 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
 {
   return new DataArrayDoubleCollection(fieldNames);
 }
 
-DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
+DataArrayDoubleCollection *DataArrayDoubleCollection::deepCopy() const
 {
   return new DataArrayDoubleCollection(*this);
 }
@@ -51,6 +53,21 @@ void DataArrayDoubleCollection::dellocTuples()
     _arrs[i].first->reAlloc(0);
 }
 
+void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
+{
+  std::size_t sz(_arrs.size());
+  if(sz!=other._arrs.size())
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
+  for(std::size_t i=0;i<sz;i++)
+    {
+      DataArrayDouble *thisArr(_arrs[i].first);
+      const DataArrayDouble *otherArr(other._arrs[i].first);
+      if(!thisArr || !otherArr)
+        throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
+      thisArr->deepCopyFrom(*otherArr);
+    }
+}
+
 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
 {
   std::size_t sz(_arrs.size());
@@ -75,6 +92,29 @@ void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& n
     }
 }
 
+std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
+{
+  std::size_t sz(_arrs.size());
+  std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const DataArrayDouble *elt(_arrs[i].first);
+      if(!elt)
+        throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
+      ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
+    }
+  return ret;
+}
+
+std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
+{
+  std::size_t sz(_arrs.size());
+  std::vector<NatureOfField> ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    ret[i]=_arrs[i].second;
+  return ret;
+}
+
 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
 {
   std::size_t sz(_arrs.size());
@@ -92,7 +132,7 @@ std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
 {
   std::vector<std::string> vec;
-  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
+  for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
     {
       const DataArrayDouble *obj((*it).first);
       if(obj)
@@ -108,6 +148,44 @@ const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::st
   throw INTERP_KERNEL::Exception(oss.str().c_str());
 }
 
+DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
+{
+  std::vector<std::string> vec;
+  for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
+    {
+      DataArrayDouble *obj((*it).first);
+      if(obj)
+        {
+          if(obj->getName()==name)
+            return obj;
+          else
+            vec.push_back(obj->getName());
+        }
+    }
+  std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
+  std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+DataArrayDouble *DataArrayDoubleCollection::at(int pos)
+{
+  if(pos<0 || pos>=(int)_arrs.size())
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
+  return _arrs[pos].first;
+}
+
+const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
+{
+  if(pos<0 || pos>=(int)_arrs.size())
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
+  return _arrs[pos].first;
+}
+
+int DataArrayDoubleCollection::size() const
+{
+  return (int)_arrs.size();
+}
+
 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
 {
   if(!fine || !coarse)
@@ -174,7 +252,9 @@ void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev,
   for(std::size_t i=0;i<sz;i++)
     {
       const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
-      MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first);
+      DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
+      bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
+      MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
     }
 }
 
@@ -216,11 +296,17 @@ DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pai
   for(std::size_t i=0;i<sz;i++)
     {
       const std::pair<std::string,int>& info(fieldNames[i]);
+      if(info.second<=0)
+        {
+          std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
+          oss << " It has to be >=1 !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
       _arrs[i].first=DataArrayDouble::New();
       _arrs[i].first->alloc(0,info.second);
       _arrs[i].first->setName(info.first);
       names[i]=info.second;
-      _arrs[i].second=ConservativeVolumic;
+      _arrs[i].second=IntensiveMaximum;
     }
   CheckDiscriminantNames(names);
 }
@@ -233,32 +319,28 @@ DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollec
       _arrs[i].second=other._arrs[i].second;
       const DataArrayDouble *da(other._arrs[i].first);
       if(da)
-        _arrs[i].first=da->deepCpy();
+        _arrs[i].first=da->deepCopy();
     }
 }
 
 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(sizeof(DataArrayDoubleCollection));
-  ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
+  ret+=_arrs.capacity()*sizeof(MCAuto<DataArrayDouble>);
   return ret;
 }
 
-std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
+std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
-  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
-    {
-      const DataArrayDouble *pt((*it).first);
-      if(pt)
-        ret.push_back(pt);
-    }
+  for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
+    ret.push_back((const DataArrayDouble *)(*it).first);
   return ret;
 }
 
 void DataArrayDoubleCollection::updateTime() const
 {
-  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
+  for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
     {
       const DataArrayDouble *pt((*it).first);
       if(pt)
@@ -276,7 +358,7 @@ void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::st
 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
 {
   CheckValidNature(n);
-  return n==RevIntegral || n==IntegralGlobConstraint;
+  return n==IntensiveConservation || n==ExtensiveConservation;
 }
 
 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
@@ -289,7 +371,7 @@ void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField
 
 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
 {
-  if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
+  if(n!=IntensiveMaximum && n!=ExtensiveMaximum && n!=ExtensiveConservation && n!=IntensiveConservation)
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
 }
 
@@ -298,14 +380,14 @@ MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<cons
   return new MEDCouplingGridCollection(ms,fieldNames);
 }
 
-MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
+MEDCouplingGridCollection *MEDCouplingGridCollection::deepCopy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
 {
   return new MEDCouplingGridCollection(*this,newGf,oldGf);
 }
 
 void MEDCouplingGridCollection::alloc(int ghostLev)
 {
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
     {
       int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
       DataArrayDoubleCollection *dadc((*it).second);
@@ -318,7 +400,7 @@ void MEDCouplingGridCollection::alloc(int ghostLev)
 
 void MEDCouplingGridCollection::dealloc()
 {
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
     {
       DataArrayDoubleCollection *dadc((*it).second);
       if(dadc)
@@ -330,20 +412,40 @@ void MEDCouplingGridCollection::dealloc()
 
 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
 {
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
     (*it).second->spillInfoOnComponents(compNames);
 }
 
 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
 {
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
     (*it).second->spillNatures(nfs);
 }
 
+std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
+{
+  if(_map_of_dadc.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
+  const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
+  if(!elt)
+    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
+  return elt->getInfoOnComponents();
+}
+
+std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
+{
+  if(_map_of_dadc.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
+  const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
+  if(!elt)
+    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
+  return elt->getNatures();
+}
+
 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
 {
   int ret(0);
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
     {
       if((*it).first==m)
         {
@@ -361,18 +463,64 @@ const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
   return *_map_of_dadc[pos].second;
 }
 
+DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
+{
+  if(pos<0 || pos>(int)_map_of_dadc.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
+  return *_map_of_dadc[pos].second;
+}
+
+/*!
+ * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
+ * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
+ * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure.
+ */
+void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
+{
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+    {
+      std::vector<int> deltaThis,deltaOther;
+      std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
+      std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
+      std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
+      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
+        {
+          std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
+          if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
+            {
+              std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
+              std::vector< std::pair<int,int> > pThis,pOther;
+              MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
+              MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
+              std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
+              MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
+              MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
+              std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
+              int sz((*it2).second->size());
+              for(int i=0;i<sz;i++)
+                {
+                  const DataArrayDouble *otherArr((*it2).second->at(i));
+                  DataArrayDouble *thisArr((*it).second->at(i));
+                  MCAuto<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
+                  MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
+                }
+            }
+        }
+    }
+}
+
 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
 {
   if(!fine || !coarse)
     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
-  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
-  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
+  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
+  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
     {
       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
       bool found(false);
-      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
+      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
         {
           if((*it0).first==fatherOfFineMesh)
             {
@@ -392,14 +540,14 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDC
 {
   if(!fine || !coarse)
     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
-  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
-  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
+  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
+  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
     {
       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
       bool found(false);
-      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
+      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
         {
           if((*it0).first==fatherOfFineMesh)
             {
@@ -462,7 +610,7 @@ std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCar
 {
   std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
   std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
     {
       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
@@ -491,14 +639,14 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghost
 {
   if(!fine || !coarse)
     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
-  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
-  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
+  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
+  const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
     {
       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
       bool found(false);
-      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
+      for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
         {
           if((*it0).first==fatherOfFineMesh)
             {
@@ -516,7 +664,7 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghost
 
 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
 {
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
     {
       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
       if(head==a || head->isObjectInTheProgeny(a))
@@ -548,32 +696,28 @@ MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollec
       _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
       const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
       if(dac)
-        _map_of_dadc[i].second=dac->deepCpy();
+        _map_of_dadc[i].second=dac->deepCopy();
     }
 }
 
 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(sizeof(MEDCouplingGridCollection));
-  ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
+  ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> >);
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
-    {
-      const DataArrayDoubleCollection *col((*it).second);
-      if(col)
-        ret.push_back(col);
-    }
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+    ret.push_back((const DataArrayDoubleCollection *)(*it).second);
   return ret;
 }
 
 void MEDCouplingGridCollection::updateTime() const
 {
-  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
     {
       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
       if(a)
@@ -584,12 +728,19 @@ void MEDCouplingGridCollection::updateTime() const
     }
 }
 
-MEDCouplingCartesianAMRMeshGen *MEDCouplingDataForGodFather::getMyGodFather()
+/// @endcond
+
+MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
+{
+  return _gf;
+}
+
+const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
 {
   return _gf;
 }
 
-MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf):_gf(gf),_tlc(gf)
+MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
 {
   if(!gf)
     throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
@@ -601,7 +752,7 @@ void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
   _tlc.checkConst();
 }
 
-bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
+bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
 {
   bool ret(_tlc.keepTrackOfNewTL(gf));
   if(ret)
@@ -618,9 +769,9 @@ MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataFo
   other._tlc.checkConst();
   if(deepCpyGF)
     {
-      const MEDCouplingCartesianAMRMeshGen *gf(other._gf);
+      const MEDCouplingCartesianAMRMesh *gf(other._gf);
       if(gf)
-        _gf=gf->deepCpy();
+        _gf=gf->deepCopy(0);
       _tlc.keepTrackOfNewTL(_gf);
     }
 }
@@ -628,12 +779,12 @@ MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataFo
 /*!
  * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation.
  */
-MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
 {
   return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
 }
 
-MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
 {
   std::size_t sz(fieldNames.size());
   std::vector< std::pair<std::string,int> > fieldNames2(sz);
@@ -644,7 +795,7 @@ MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMes
       fieldNames2[i].second=(int)fieldNames[i].second.size();
       compNames[i]=fieldNames[i].second;
     }
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
+  MCAuto<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
   ret->spillInfoOnComponents(compNames);
   return ret.retn();
 }
@@ -658,7 +809,7 @@ MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMes
 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
 {
   _tlc.checkConst();
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
     (*it)->spillInfoOnComponents(compNames);
 }
 
@@ -669,11 +820,11 @@ void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vect
 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
 {
   _tlc.checkConst();
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
     (*it)->spillNatures(nfs);
 }
 
-MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCopy() const
 {
   return new MEDCouplingAMRAttribute(*this,true);
 }
@@ -702,7 +853,7 @@ int MEDCouplingAMRAttribute::getNumberOfLevels() const
  */
 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
     {
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
@@ -719,7 +870,7 @@ std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCoup
  */
 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
     {
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
@@ -728,7 +879,21 @@ const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianA
           return ddc.getFieldWithName(fieldName);
         }
     }
-  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
+  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
+}
+
+DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
+{
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
+    {
+      int tmp(-1);
+      if((*it)->presenceOf(mesh,tmp))
+        {
+          DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
+          return ddc.getFieldWithName(fieldName);
+        }
+    }
+  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
 }
 
 /*!
@@ -741,7 +906,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO
 {
   std::vector<const DataArrayDouble *> recurseArrs;
   std::size_t lev(0);
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
     {
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
@@ -771,7 +936,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO
 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 {
   const DataArrayDouble *arr(0);
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
     {
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
@@ -782,8 +947,8 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCo
     }
   if(!arr)
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
+  MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
+  MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
   ret->setMesh(im);
   ret->setArray(const_cast<DataArrayDouble *>(arr));
   ret->setName(arr->getName());
@@ -800,9 +965,8 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCo
  */
 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 {
-  //tony
   const DataArrayDouble *arr(0);
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
     {
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
@@ -814,9 +978,9 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(ME
   if(!arr)
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
   //
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
+  MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
   std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
+  MCAuto<DataArrayDouble> arr2(DataArrayDouble::New());
   arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
   std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
   MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
@@ -824,16 +988,176 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(ME
   MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
   arr2->copyStringInfoFrom(*arr);
   //
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
+  MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
   ret->setMesh(mesh->getImageMesh());
   ret->setArray(arr2);
   ret->setName(arr->getName());
   return ret.retn();
 }
 
+
+std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
+{
+  static const char EXT[]=".vthb";
+  std::string baseName,extName,zeFileName;
+  MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
+  if(extName==EXT)
+    zeFileName=fileName;
+  else
+    { zeFileName=baseName; zeFileName+=EXT; }
+  //
+  std::ofstream ofs(fileName.c_str());
+  ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
+  const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
+  ofs << "  <vtkOverlappingAMR origin=\"";
+  const MEDCouplingIMesh *gfm(gf->getImageMesh());
+  std::vector<double> orig(gfm->getOrigin());
+  std::vector<double> spacing(gfm->getDXYZ());
+  int dim((int)orig.size());
+  std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
+  for(int i=0;i<dim;i++)
+    {
+      char tmp[2]; tmp[0]='X'+i; tmp[1]='\0';
+      ofs << tmp;
+    }
+  ofs << "\">\n";
+  //
+  int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
+  for(int i=0;i<maxLev;i++)
+    {
+      std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
+      std::size_t sz(patches.size());
+      std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
+      for(std::size_t j=0;j<sz;j++)
+        patchesSafe[j]=patches[j];
+      if(sz==0)
+        continue;
+      ofs << "    <Block level=\"" << i << "\" spacing=\"";
+      std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
+      ofs << "\">\n";
+      if(i!=maxLev-1)
+        {
+          std::vector<int> factors(patches[0]->getMesh()->getFactors());
+          for(int k=0;k<dim;k++)
+            spacing[k]*=1./((double) factors[k]);
+        }
+      std::size_t jj(0);
+      for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
+        {
+          ofs << "      <DataSet index=\"" << jj << "\" amr_box=\"";
+          const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
+          const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
+          if(patchCast)
+            {
+              const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF());
+              for(int pp=0;pp<dim;pp++)
+                ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
+            }
+          else
+            {
+              const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
+              std::vector<int> cgs(im->getCellGridStructure());
+              for(int pp=0;pp<dim;pp++)
+                ofs << "0 " << cgs[pp]-1 << " ";
+            }
+          ofs << "\" file=\"";
+          //
+          int tmp(-1);
+          if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
+            {
+              const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
+              std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
+              std::size_t nbFields(arrs.size());
+              std::vector< MCAuto<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
+              std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
+              std::vector< MCAuto<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
+              for(std::size_t pp=0;pp<nbFields;pp++)
+                arrsSafe[pp]=arrs[pp];
+              for(std::size_t pp=0;pp<nbFields;pp++)
+                {
+                  MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
+                  std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
+                  arrs2Safe[pp]=DataArrayDouble::New();
+                  arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
+                  std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
+                  MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
+                  std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
+                  MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
+                  arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
+                  //
+                  fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
+                  fieldsSafe[pp]->setMesh(mesh->getImageMesh());
+                  fieldsSafe[pp]->setArray(arrs2Safe[pp]);
+                  fieldsSafe[pp]->setName(arrs[pp]->getName());
+                }
+              std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
+              MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
+              //
+              ofs << vtiFileName.str() << "\">\n";
+              ofs << "      \n      </DataSet>\n";
+            }
+        }
+      ofs << "    </Block>\n";
+    }
+  //
+  ofs << "  </vtkOverlappingAMR>\n";
+  ofs << "</VTKFile>\n";
+  return zeFileName;
+}
+
+  /*!
+   * This method is useful just after a remesh after a time step computation to project values in \a this to the new
+   * mesh \a targetGF.
+   *
+   * This method performs a projection from \a this to a target AMR mesh \a targetGF.
+   * This method performs the projection by trying to transfer the finest information to \a targetGF.
+ * \b WARNING this method does not update the ghost zone, if any.
+ * The level0 of \a this god father must have the same structure than those of \a targetGF.
+ *
+ * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
+ * the number of levels in \a this and in \a targetGF are also the same.
+ */
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
+{
+  if(!targetGF)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
+  if(_levs.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
+  const MEDCouplingGridCollection *lev0(_levs[0]);
+  if(!lev0)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
+  std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
+  MCAuto<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
+  ret->spillNatures(lev0->getNatures());
+  ret->alloc();
+  int nbLevs(getNumberOfLevels());
+  if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
+  // first step copy level0
+  if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
+  const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
+  DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
+  colTarget.copyFrom(col);
+  // then go deeper and deeper
+  for(int i=1;i<nbLevs;i++)
+    {
+      ret->synchronizeCoarseToFineByOneLevel(i-1);
+      MEDCouplingGridCollection *targetCol(ret->_levs[i]);
+      if(!targetCol)
+        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
+      const MEDCouplingGridCollection *thisCol(_levs[i]);
+      if(!thisCol)
+        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
+      targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
+    }
+  return ret.retn();
+}
+
 /*!
  * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
  * MEDCouplingAMRAttribute::alloc method.
+ * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
  *
  * \sa synchronizeFineToCoarseBetween
  */
@@ -854,6 +1178,7 @@ void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
  * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
  * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
  * until reaching \a toLev level.
+ * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
  *
  * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
  * \param [in] toLev - an existing level considered as the target level to reach.
@@ -875,6 +1200,7 @@ void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int to
 /*!
  * This method synchronizes from coarse to fine arrays and fine to fine each other (if _ghost_lev is >0). This method makes the hypothesis that \a this has been allocated before using
  * MEDCouplingAMRAttribute::alloc method.
+ * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
  */
 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
 {
@@ -890,6 +1216,7 @@ void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
  * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
  * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
  * until reaching \a toLev level.
+ * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
  *
  * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
  * \param [in] toLev - an existing level considered as the target level to reach.
@@ -933,10 +1260,10 @@ void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
   // 2nd - classical direct sublevel inside common patch
   for(int i=1;i<sz;i++)
     {
-      const MEDCouplingGridCollection *fine(_levs[i]);
-      if(!fine)
+      const MEDCouplingGridCollection *curLev(_levs[i]);
+      if(!curLev)
         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
-      fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
+      curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
     }
   // 3rd - mixed level
   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
@@ -953,7 +1280,13 @@ void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
 }
 
 /*!
- * This method
+ * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here.
+ * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh).
+ * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father.
+ * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead.
+ *
+ * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other.
+ *
  */
 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
 {
@@ -962,15 +1295,53 @@ void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const ME
   int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
   if(level<0 || level>=sz-1)
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
-  const DataArrayDoubleCollection& colCoarse(findCollectionAttachedTo(mesh));
-  std::vector< const MEDCouplingCartesianAMRPatch *> directChildren(mesh->getPatches());
-  std::size_t nbOfDirChildren(directChildren.size());
-  for(std::size_t patchId=0;patchId<nbOfDirChildren;patchId++)
+  const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
+  std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
     {
-      const DataArrayDoubleCollection& colFine(findCollectionAttachedTo(directChildren[patchId]->getMesh()));
-      DataArrayDoubleCollection *colFine2(const_cast<DataArrayDoubleCollection *>(&colFine));
-      DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,mesh,(int)patchId,&colCoarse,colFine2);
+      if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
+        itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
     }
+  const MEDCouplingGridCollection *curLev(_levs[level+1]);
+  if(!curLev)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
+  curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
+}
+
+/*!
+ * This method updates \b all the patches at level \a level each other without consideration of their father.
+ * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
+ */
+void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
+{
+  int maxLev(getNumberOfLevels());
+  if(level<0 || level>=maxLev)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
+  if(level==0)
+    return ;//at level 0 only one patch -> no need to update
+  // 1st step - updates all patches pairs at level \a level sharing the same father
+  const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
+  const MEDCouplingGridCollection *curLev(_levs[level]);
+  if(!curLev)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
+  curLev->synchronizeFineEachOther(_ghost_lev,items);
+  //2nd step - updates all patches pairs at level \a level not sharing the same father
+  const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
+  curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
+}
+
+/*!
+ * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1).
+ * This method is useful to propagate to the ghost zone of childhood the modification.
+ */
+void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
+{
+  int maxLev(getNumberOfLevels());
+  if(level<=0 || level>=maxLev)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
+  const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
+  MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
+  //_cross_lev_neighbors is not needed.
 }
 
 /*!
@@ -981,7 +1352,7 @@ void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const ME
 void MEDCouplingAMRAttribute::alloc()
 {
   _tlc.resetState();
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
     {
       MEDCouplingGridCollection *elt(*it);
       if(elt)
@@ -998,7 +1369,7 @@ void MEDCouplingAMRAttribute::alloc()
 void MEDCouplingAMRAttribute::dealloc()
 {
   _tlc.checkConst();
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
     {
       MEDCouplingGridCollection *elt(*it);
       if(elt)
@@ -1008,7 +1379,7 @@ void MEDCouplingAMRAttribute::dealloc()
     }
 }
 
-bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
+bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
 {
   bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
   return ret;
@@ -1017,19 +1388,15 @@ bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf
 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(sizeof(MEDCouplingAMRAttribute));
-  ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
+  ret+=_levs.capacity()*sizeof(MCAuto<MEDCouplingGridCollection>);
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
-    {
-      const MEDCouplingGridCollection *elt(*it);
-      if(elt)
-        ret.push_back(elt);
-    }
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+    ret.push_back((const MEDCouplingGridCollection *)*it);
   return ret;
 }
 
@@ -1037,7 +1404,7 @@ void MEDCouplingAMRAttribute::updateTime() const
 {//tony
 }
 
-MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
+MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
 {
   //gf non empty, checked by constructor
   int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
@@ -1046,7 +1413,7 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMeshGen
     {
       std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
       std::size_t sz(patches.size());
-      std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
+      std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
       for(std::size_t j=0;j<sz;j++)
         patchesSafe[j]=patches[j];
       std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
@@ -1093,14 +1460,53 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute&
       const MEDCouplingGridCollection *elt(other._levs[i]);
       if(elt)
         {
-          _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
+          _levs[i]=other._levs[i]->deepCopy(_gf,other._gf);
+        }
+    }
+  //_cross_lev_neighbors(other._cross_lev_neighbors)
+  sz=other._neighbors.size();
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
+      std::size_t sz2(neigh2.size());
+      std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
+      for(std::size_t j=0;j<sz2;j++)
+        {
+          const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
+          std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
+          neigh3[j].first=_gf->getPatchAtPosition(pp1);
+          neigh3[j].second=_gf->getPatchAtPosition(pp2);
+        }
+    }
+  //
+  sz=other._mixed_lev_neighbors.size();
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
+      std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
+      _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
+      _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
+    }
+  //
+  sz=other._cross_lev_neighbors.size();
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
+      std::size_t sz2(neigh2.size());
+      std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
+      for(std::size_t j=0;j<sz2;j++)
+        {
+          const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
+          std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
+          neigh3[j].first=_gf->getPatchAtPosition(pp1);
+          neigh3[j].second=_gf->getPatchAtPosition(pp2);
         }
     }
 }
 
 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+  for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
     {
       const MEDCouplingGridCollection *elt(*it);
       if(elt)