]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Full synchronisation of patches across levels.
authorgeay <anthony.geay@cea.fr>
Wed, 4 Jun 2014 11:11:43 +0000 (13:11 +0200)
committergeay <anthony.geay@cea.fr>
Wed, 4 Jun 2014 11:11:43 +0000 (13:11 +0200)
src/MEDCoupling/MEDCouplingAMRAttribute.cxx
src/MEDCoupling/MEDCouplingAMRAttribute.hxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx
src/MEDCoupling/MEDCouplingStructuredMesh.cxx
src/MEDCoupling/MEDCouplingStructuredMesh.hxx
src/MEDCoupling_Swig/MEDCouplingCommon.i

index a3c652165c00a298007e3237774de2b7f91cc0ec..8af2cf6fe5a1dad4bad56d219918f8e336951cac 100644 (file)
@@ -149,6 +149,26 @@ void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghost
     fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
 }
 
+void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
+{
+  DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
+  std::size_t sz(_arrs.size());
+  if(other._arrs.size()!=sz)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
+  for(std::size_t i=0;i<sz;i++)
+    father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
+}
+
+void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
+{
+  DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
+  std::size_t sz(_arrs.size());
+  if(other._arrs.size()!=sz)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
+  for(std::size_t i=0;i<sz;i++)
+    MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
+}
+
 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
 {
   std::size_t sz(fieldNames.size());
@@ -250,10 +270,10 @@ bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen
   return false;
 }
 
-const DataArrayDoubleCollection& MEDCouplingGridCollection::retrieveFieldsAt(int pos) const
+const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
 {
   if(pos<0 || pos>(int)_map_of_dadc.size())
-    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::retrieveFieldsAt : invalid pos given in input ! Must be in [0,size) !");
+    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
   return *_map_of_dadc[pos].second;
 }
 
@@ -311,32 +331,76 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDC
     }
 }
 
-void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev) const
+/*!
+ * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
+ *
+ * \sa synchronizeFineEachOtherExt
+ */
+void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
 {
-  std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > > m;
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
+    {
+      int p1,p2;
+      if(!presenceOf((*it).first->getMesh(),p1))
+        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
+      if(!presenceOf((*it).second->getMesh(),p2))
+        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
+      const DataArrayDoubleCollection& col1(getFieldsAt(p1));
+      const DataArrayDoubleCollection& col2(getFieldsAt(p2));
+      col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
+    }
+}
+
+/*!
+ * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
+ *
+ * \sa synchronizeFineEachOther
+ */
+void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
+{
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
+    {
+      int p1,p2;
+      if(!presenceOf((*it).first->getMesh(),p1))
+        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
+      if(!presenceOf((*it).second->getMesh(),p2))
+        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
+      const DataArrayDoubleCollection& col1(getFieldsAt(p1));
+      const DataArrayDoubleCollection& col2(getFieldsAt(p2));
+      col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
+    }
+}
+
+/*!
+ * The pairs returned share the same direct father. The number of returned elements must be even.
+ */
+std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
+{
+  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++)
     {
       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
-      m[fatherOfFineMesh].push_back(std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *>(fineMesh,(*it).second));
+      m[fatherOfFineMesh].push_back(fineMesh);
     }
-  for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > >::const_iterator it0=m.begin();it0!=m.end();it0++)
+  for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
     {
-      std::size_t sz((*it0).second.size());
-      std::vector<const MEDCouplingCartesianAMRMeshGen *> v0(sz);
-      std::vector<DataArrayDoubleCollection *> v1(sz);
-      for(std::size_t i=0;i<sz;i++)
+      for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
         {
-          v0[i]=(*it0).second[i].first;
-          const DataArrayDoubleCollection *tmp((*it0).second[i].second);
-          v1[i]=const_cast<DataArrayDoubleCollection *>(tmp);
-        }
-      for(std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> >::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
-        {
-          int patchId((*it0).first->getPatchIdFromChildMesh((*it1).first));
-          DataArrayDoubleCollection::SynchronizeFineEachOther(patchId,ghostLev,(*it0).first,v0,v1);
+          int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
+          std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
+          const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
+          for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
+            {
+              const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
+              ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
+            }
         }
     }
+  if(ret.size()%2!=0)
+    throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
+  return ret;
 }
 
 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
@@ -426,12 +490,12 @@ void MEDCouplingGridCollection::updateTime() const
 /*!
  * 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(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames)
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
 {
-  return new MEDCouplingAMRAttribute(gf,fieldNames);
+  return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
 }
 
-MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames)
+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);
@@ -442,7 +506,7 @@ MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMes
       fieldNames2[i].second=(int)fieldNames[i].second.size();
       compNames[i]=fieldNames[i].second;
     }
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2));
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
   ret->spillInfoOnComponents(compNames);
   return ret.retn();
 }
@@ -474,7 +538,7 @@ std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCoup
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
         {
-          const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
           return ddc.retrieveFields();
         }
     }
@@ -491,7 +555,7 @@ const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianA
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
         {
-          const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
           return ddc.getFieldWithName(fieldName);
         }
     }
@@ -504,7 +568,7 @@ const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianA
  *
  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
  */
-MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
+MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 {
   std::vector<const DataArrayDouble *> recurseArrs;
   std::size_t lev(0);
@@ -513,7 +577,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
         {
-          const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
           recurseArrs.push_back(ddc.getFieldWithName(fieldName));
           break;
         }
@@ -524,7 +588,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO
       const MEDCouplingGridCollection *gc(_levs[i]);
       gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
     }
-  return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostLev,recurseArrs);
+  return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
 }
 
 /*!
@@ -534,7 +598,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO
  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
  *
  */
-MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
+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++)
@@ -542,13 +606,13 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(int g
       int tmp(-1);
       if((*it)->presenceOf(mesh,tmp))
         {
-          const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+          const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
           arr=ddc.getFieldWithName(fieldName);
         }
     }
   if(!arr)
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(ghostLev));
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
   ret->setMesh(im);
   ret->setArray(const_cast<DataArrayDouble *>(arr));
@@ -560,7 +624,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(int g
  * 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.
  */
-void MEDCouplingAMRAttribute::synchronizeFineToCoarse(int ghostLev)
+void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
 {
   if(_levs.empty())
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
@@ -570,15 +634,15 @@ void MEDCouplingAMRAttribute::synchronizeFineToCoarse(int ghostLev)
     {
       sz--;
       const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
-      MEDCouplingGridCollection::SynchronizeFineToCoarse(ghostLev,fine,coarse);
+      MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
     }
 }
 
 /*!
- * This method synchronizes from coarse to fine arrays and fine to fine each other (if ghostLev is >0). This method makes the hypothesis that \a this has been allocated before using
+ * 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.
  */
-void MEDCouplingAMRAttribute::synchronizeCoarseToFine(int ghostLev)
+void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
 {
   if(_levs.empty())
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
@@ -587,16 +651,16 @@ void MEDCouplingAMRAttribute::synchronizeCoarseToFine(int ghostLev)
   for(std::size_t i=1;i<sz;i++)
     {
       const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
-      MEDCouplingGridCollection::SynchronizeCoarseToFine(ghostLev,coarse,fine);
+      MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
     }
 }
 
 /*!
  * This method performs coarse to fine spread only in the ghost zone.
  * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
- * So if \a ghostLev == 0 this method has no effect.
+ * So if \a _ghost_lev == 0 this method has no effect.
  */
-void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone(int ghostLev)
+void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone()
 {
   if(_levs.empty())
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone : not any levels in this !");
@@ -605,14 +669,14 @@ void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone(int ghostLe
   for(std::size_t i=1;i<sz;i++)
     {
       const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
-      MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,coarse,fine);
+      MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
     }
 }
 
 /*!
  * This method synchronizes fine each other only in the ghost zone.
  */
-void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone(int ghostLev)
+void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone()
 {
   if(_levs.empty())
     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
@@ -623,25 +687,29 @@ void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone(int ghostLev)
       const MEDCouplingGridCollection *fine(_levs[i]);
       if(!fine)
         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
-      fine->synchronizeFineEachOther(ghostLev);
+      fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
+    }
+  // cross lev
+  for(std::size_t i=1;i<sz;i++)
+    {
+      const MEDCouplingGridCollection *fine(_levs[i]);
+      fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
     }
 }
 
 /*!
  * This method allocates all DataArrayDouble instances stored recursively in \a this.
  *
- * \param [in] ghostLev - The size of ghost zone.
- *
  * \sa dealloc
  */
-void MEDCouplingAMRAttribute::alloc(int ghostLev)
+void MEDCouplingAMRAttribute::alloc()
 {
   _tlc.resetState();
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
     {
       MEDCouplingGridCollection *elt(*it);
       if(elt)
-        elt->alloc(ghostLev);
+        elt->alloc(_ghost_lev);
       else
         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
     }
@@ -693,7 +761,7 @@ void MEDCouplingAMRAttribute::updateTime() const
 {//tony
 }
 
-MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames):MEDCouplingDataForGodFather(gf)
+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());
@@ -712,4 +780,30 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf
         }
       _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
     }
+  // updates cross levels neighbors
+  _neighbors.resize(_levs.size());
+  _cross_lev_neighbors.resize(_levs.size());
+  if(_levs.empty())
+    throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
+  std::size_t sz(_levs.size());
+  for(std::size_t i=1;i<sz;i++)
+    {
+      const MEDCouplingGridCollection *fine(_levs[i]);
+      if(!fine)
+        throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
+      _neighbors[i]=fine->findNeighbors(_ghost_lev);
+      if(i!=sz-1)
+        {
+          for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
+            {
+              std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second));
+              std::size_t fullLev(i+neighs2.size());
+              if(fullLev>=sz)
+                throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
+              std::size_t ii(i+1);
+              for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
+                _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
+            }
+        }
+    }
 }
index 726aac1e92bf21330bd274d4e4bd259302b96866..c8cc1ab551702fae2aa6b29eff4908458f7ecc1d 100644 (file)
@@ -40,6 +40,8 @@ namespace ParaMEDMEM
     static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine);
     static void SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine);
     static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine);
+    void synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const;
+    void synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const;
   private:
     DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames);
     std::size_t getHeapMemorySizeWithoutChildren() const;
@@ -58,10 +60,13 @@ namespace ParaMEDMEM
     void dealloc();
     void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
     bool presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const;
-    const DataArrayDoubleCollection& retrieveFieldsAt(int pos) const;
+    const DataArrayDoubleCollection& getFieldsAt(int pos) const;
     static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse);
     static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine);
-    void synchronizeFineEachOther(int ghostLev) const;
+    //void synchronizeFineEachOtherOld(int ghostLev) const;
+    void synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const;
+    void synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const;
+    std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > findNeighbors(int ghostLev) const;
     static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine);
     void fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const;
   private:
@@ -78,19 +83,19 @@ namespace ParaMEDMEM
   class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel
   {
   public:
-    MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames);
-    MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames);
+    MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev);
+    MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev);
     MEDCOUPLING_EXPORT void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
     MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const;
     MEDCOUPLING_EXPORT const DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
-    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
-    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
+    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
+    MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
     //
-    MEDCOUPLING_EXPORT void synchronizeFineToCoarse(int ghostLev);
-    MEDCOUPLING_EXPORT void synchronizeCoarseToFine(int ghostLev);
-    MEDCOUPLING_EXPORT void synchronizeCoarseToFineOnlyInGhostZone(int ghostLev);
-    MEDCOUPLING_EXPORT void synchronizeFineEachOtherInGhostZone(int ghostLev);
-    MEDCOUPLING_EXPORT void alloc(int ghostLev);
+    MEDCOUPLING_EXPORT void synchronizeFineToCoarse();
+    MEDCOUPLING_EXPORT void synchronizeCoarseToFine();
+    MEDCOUPLING_EXPORT void synchronizeCoarseToFineOnlyInGhostZone();
+    MEDCOUPLING_EXPORT void synchronizeFineEachOtherInGhostZone();
+    MEDCOUPLING_EXPORT void alloc();
     MEDCOUPLING_EXPORT void dealloc();
     MEDCOUPLING_EXPORT bool changeGodFather(MEDCouplingCartesianAMRMesh *gf);
     //
@@ -98,9 +103,12 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildren() const;
     MEDCOUPLING_EXPORT void updateTime() const;
   private:
-    MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames);
+    MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev);
   private:
+    int _ghost_lev;
     std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> > _levs;
+    std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > _neighbors;
+    std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > _cross_lev_neighbors;
   };
 }
 
index 9a71e5a92c69e5d141751902e693404cd5ace5d6..ced42519c8b0afb8d42aba209467dcc4d43aa257 100644 (file)
@@ -185,6 +185,92 @@ bool MEDCouplingCartesianAMRPatch::IsInMyNeighborhood(int ghostLev, const std::v
   return true;
 }
 
+std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2)
+{
+  if(!p1 || !p2)
+    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf : the input pointers must be not NULL !");
+  std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > ret;
+  std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches());
+  while(!p1Work.empty())
+    {
+      std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > retTmp;
+      std::vector<const MEDCouplingCartesianAMRPatch *> p1Work2,p2Work2;
+      for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++)
+        {
+          for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
+            {
+              if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev))
+                retTmp.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(*it1,*it2));
+            }
+          std::vector<const MEDCouplingCartesianAMRPatch *> tmp1((*it1)->getMesh()->getPatches());
+          p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end());
+        }
+      for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
+        {
+          std::vector<const MEDCouplingCartesianAMRPatch *> tmp2((*it2)->getMesh()->getPatches());
+          p2Work2.insert(p2Work2.end(),tmp2.begin(),tmp2.end());
+        }
+      ret.push_back(retTmp);
+      p1Work=p1Work2;
+      p2Work=p2Work2;
+    }
+  return ret;
+}
+
+/*!
+ * \a p1 and \a p2 are expected to be neighbors (inside the \a ghostLev zone). This method updates \a dataOnP1 only in the ghost part using a part of \a dataOnP2.
+ *
+ * \saUpdateNeighborsOfOneWithTwoExt
+ */
+void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
+{
+  const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());
+  const std::vector< std::pair<int,int> >& p2BLTR(p2->getBLTRRange());
+  UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2);
+}
+
+void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
+{//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)]
+  int dim((int)factors.size());
+  std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2]
+  std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8]
+  std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10]
+  std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)]
+  std::vector<int> fakeFactors(dim,1);
+  //
+  std::vector< std::pair<int,int> > tmp0,tmp1,tmp2;
+  MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)]
+  ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)]
+  ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)]
+  std::vector< std::pair<int,int> > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)]
+  MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)]
+  ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)]
+  MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)]
+  //
+  std::vector< std::pair<int,int> > dimsFine(p2);
+  ApplyFactorsOnCompactFrmt(dimsFine,factors);
+  ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev);
+  //
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),dataOnP2,tmp2));
+  MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,dataOnP1);
+}
+
+/*!
+ * Idem than UpdateNeighborsOfOneWithTwo, except that here \a p1 and \a p2 are not sharing the same direct father.
+ *
+ * \sa UpdateNeighborsOfOneWithTwo
+ */
+void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
+{
+  const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)]
+  std::vector< std::pair<int,int> > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)]
+  int lev(0);
+  const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev));
+  std::vector<int> offset(ComputeOffsetFromTwoToOne(ca,lev,p1,p2));//[12,4]
+  p2BLTR=MEDCouplingStructuredMesh::TranslateCompactFrmt(p2BLTR,offset);//p2BLTR=[(12,13),(4,9)]
+  UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1BLTR,p2BLTR,dataOnP1,dataOnP2);
+}
+
 std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch));
@@ -212,12 +298,13 @@ std::vector<int> MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const M
 {
   if(lev<=0)
     throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : this method is useful only for lev > 0 !");
+  int zeLev(lev-1);
   int dim(p1->getMesh()->getSpaceDimension());
   if(p2->getMesh()->getSpaceDimension()!=dim)
     throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : dimension must be the same !");
   std::vector< int > ret(dim,0);
 
-  for(int i=0;i<lev;i++)
+  for(int i=0;i<zeLev;i++)
     {
       const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh);
       const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0);
@@ -243,6 +330,56 @@ std::vector<int> MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const M
   return ret;
 }
 
+/*!
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference.
+ * \param [in] factors - the factors per axis.
+ */
+void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors)
+{
+  std::size_t sz(factors.size());
+  if(sz!=partBeforeFact.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !");
+  for(std::size_t i=0;i<sz;i++)
+    {
+      partBeforeFact[i].first*=factors[i];
+      partBeforeFact[i].second*=factors[i];
+    }
+}
+
+/*!
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
+ * \param [in] ghostSize - the ghost size of zone for all axis.
+ */
+void MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !");
+  std::size_t sz(partBeforeFact.size());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      partBeforeFact[i].first+=ghostSize;
+      partBeforeFact[i].second+=ghostSize;
+    }
+}
+
+/*!
+ * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt.
+ *
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
+ * \param [in] ghostSize - the ghost size of zone for all axis.
+ */
+void MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !");
+  std::size_t sz(partBeforeFact.size());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      partBeforeFact[i].first-=ghostSize;
+      partBeforeFact[i].second+=ghostSize;
+    }
+}
+
 MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh)
 {
 }
@@ -929,43 +1066,27 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, c
  */
 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
 {
-  int nbp(getNumberOfPatches()),dim(getSpaceDimension());
+  int nbp(getNumberOfPatches());
   if(nbp!=(int)arrsOnPatches.size())
     {
       std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
   const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId));
-  const std::vector< std::pair<int,int> >& refBLTR(refP->getBLTRRange());//[(1,4),(2,4)]
-  std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(refBLTR));//[3,2]
-  std::transform(dimsCoarse.begin(),dimsCoarse.end(),_factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8]
-  std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10]
-  std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)]
-  std::vector<int> fakeFactors(dim,1),ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
-  //
+  DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
+  std::vector<int> ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
   for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++)
     {
       const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it));
-      const std::vector< std::pair<int,int> >& otherBLTR(otherP->getBLTRRange());//[(4,5),(3,4)]
-      std::vector< std::pair<int,int> > tmp0,tmp1,tmp2;
-      MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(refBLTR,otherBLTR,tmp0,false);//tmp0=[(3,4),(1,2)]
-      ApplyFactorsOnCompactFrmt(tmp0,_factors);//tmp0=[(12,16),(4,8)]
-      ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)]
-      std::vector< std::pair<int,int> > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)]
-      MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(otherBLTR,refBLTR,tmp1,false);//tmp1=[(-3,0),(-1,1)]
-      ApplyFactorsOnCompactFrmt(tmp1,_factors);//tmp1=[(-12,-4),(-4,0)]
-      MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)]
-      //
-      std::vector< std::pair<int,int> > dimsFine(otherBLTR);
-      ApplyFactorsOnCompactFrmt(dimsFine,_factors);
-      ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev);
-      //
-      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),arrsOnPatches[*it],tmp2));
-      MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,theFieldToFill);
+      MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,refP,otherP,theFieldToFill,arrsOnPatches[*it]);
     }
 }
 
+void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const
+{
+  MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,patchToBeModified,neighborPatch,cellFieldOnPatch,cellFieldNeighbor);
+}
+
 /*!
  * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId.
  *
@@ -1134,7 +1255,7 @@ DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, c
   std::vector<int> st(_mesh->getCellGridStructure());
   std::vector< std::pair<int,int> > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st));
   std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus<int>(),2*ghostSz));
-  ApplyGhostOnCompactFrmt(p,ghostSz);
+  MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(p,ghostSz);
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p));
   return ret.retn();
 }
@@ -1230,56 +1351,6 @@ void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vecto
     }
 }
 
-/*!
- * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference.
- * \param [in] factors - the factors per axis.
- */
-void MEDCouplingCartesianAMRMeshGen::ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors)
-{
-  std::size_t sz(factors.size());
-  if(sz!=partBeforeFact.size())
-    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !");
-  for(std::size_t i=0;i<sz;i++)
-    {
-      partBeforeFact[i].first*=factors[i];
-      partBeforeFact[i].second*=factors[i];
-    }
-}
-
-/*!
- * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
- * \param [in] ghostSize - the ghost size of zone for all axis.
- */
-void MEDCouplingCartesianAMRMeshGen::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
-{
-  if(ghostSize<0)
-    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !");
-  std::size_t sz(partBeforeFact.size());
-  for(std::size_t i=0;i<sz;i++)
-    {
-      partBeforeFact[i].first+=ghostSize;
-      partBeforeFact[i].second+=ghostSize;
-    }
-}
-
-/*!
- * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt.
- *
- * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
- * \param [in] ghostSize - the ghost size of zone for all axis.
- */
-void MEDCouplingCartesianAMRMeshGen::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
-{
-  if(ghostSize<0)
-    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !");
-  std::size_t sz(partBeforeFact.size());
-  for(std::size_t i=0;i<sz;i++)
-    {
-      partBeforeFact[i].first-=ghostSize;
-      partBeforeFact[i].second+=ghostSize;
-    }
-}
-
 int MEDCouplingCartesianAMRMeshGen::GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors)
 {
   if(ghostLev<0)
@@ -1385,10 +1456,10 @@ void MEDCouplingCartesianAMRMesh::setData(MEDCouplingDataForGodFather *data)
     data->incrRef();
 }
 
-void MEDCouplingCartesianAMRMesh::allocData(int ghostLev) const
+void MEDCouplingCartesianAMRMesh::allocData() const
 {
   checkData();
-  _data->alloc(ghostLev);
+  _data->alloc();
 }
 
 void MEDCouplingCartesianAMRMesh::deallocData() const
index f5e246bdb9644a0d34d2a505017b46986aea4f84..4a6399e06796380e74315a47faea11eb9b3fdd72 100644 (file)
@@ -79,10 +79,19 @@ namespace ParaMEDMEM
     // basic set/get
     MEDCOUPLING_EXPORT const std::vector< std::pair<int,int> >& getBLTRRange() const { return _bl_tr; }
     MEDCOUPLING_EXPORT static bool IsInMyNeighborhood(int ghostLev, const std::vector< std::pair<int,int> >& p1, const std::vector< std::pair<int,int> >& p2);
+    //
+    static std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2);
+    static void UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2);
+    static void UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2);
+    static void UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2);
   private:
     std::size_t getHeapMemorySizeWithoutChildren() const;
     static const MEDCouplingCartesianAMRMeshGen *FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev);
     static std::vector<int> ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2);
+  public:
+    static void ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors);
+    static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
+    static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
   private:
     //! bottom left/top right cell range relative to \a _father
     std::vector< std::pair<int,int> > _bl_tr;
@@ -103,11 +112,11 @@ namespace ParaMEDMEM
   {
     friend class MEDCouplingCartesianAMRMesh;
   public:
-    MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse(int ghostLev) = 0;
-    MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine(int ghostLev) = 0;
-    MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineOnlyInGhostZone(int ghostLev) = 0;
-    MEDCOUPLING_EXPORT virtual void synchronizeFineEachOtherInGhostZone(int ghostLev) = 0;
-    MEDCOUPLING_EXPORT virtual void alloc(int ghostLev) = 0;
+    MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0;
+    MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0;
+    MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineOnlyInGhostZone() = 0;
+    MEDCOUPLING_EXPORT virtual void synchronizeFineEachOtherInGhostZone() = 0;
+    MEDCOUPLING_EXPORT virtual void alloc() = 0;
     MEDCOUPLING_EXPORT virtual void dealloc() = 0;
   protected:
     MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf);
@@ -162,6 +171,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const;
     // fine to fine
     MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const;
+    MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const;
     // fine to coarse
     MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const;
     MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const;
@@ -181,9 +191,6 @@ namespace ParaMEDMEM
     void checkPatchId(int patchId) const;
     void checkFactorsAndIfNotSetAssign(const std::vector<int>& factors);
     void retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> >& grids) const;
-    static void ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors);
-    static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
-    static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
     static int GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors);
     std::vector<const DataArrayDouble *> extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector<const DataArrayDouble *>& all) const;
   protected:
@@ -211,7 +218,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT const MEDCouplingDataForGodFather *getDataConst() const { return _data; }
     MEDCOUPLING_EXPORT MEDCouplingDataForGodFather *getData() { return _data; }
     MEDCOUPLING_EXPORT void setData(MEDCouplingDataForGodFather *data);
-    MEDCOUPLING_EXPORT void allocData(int ghostLev) const;
+    MEDCOUPLING_EXPORT void allocData() const;
     MEDCOUPLING_EXPORT void deallocData() const;
   private:
     MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
index d079e8288f97f27a05daa02373fcf2eb685fe254..23a236f47682f57797133fd95da4ca0fb61e1b6f 100644 (file)
@@ -1606,6 +1606,23 @@ void MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(const std::
     }
 }
 
+/*!
+ * This method performs a translation (defined by \a translation) of \a part and returns the result of translated part.
+ */
+std::vector< std::pair<int,int> > MEDCouplingStructuredMesh::TranslateCompactFrmt(const std::vector< std::pair<int,int> >& part, const std::vector<int>& translation)
+{
+  std::size_t sz(part.size());
+  if(translation.size()!=sz)
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::TranslateCompactFrmt : the size are not equal !");
+  std::vector< std::pair<int,int> > ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      ret[i].first=part[i].first+translation[i];
+      ret[i].second=part[i].second+translation[i];
+    }
+  return ret;
+}
+
 /*!
  * This method builds the explicit entity array from the structure in \a st and the range in \a partCompactFormat.
  * If the range contains invalid values regarding sructure an exception will be thrown.
index 18b8eb5526c81781f1cdefe17b45cbf5b8e77e42..0a819a3dffcbff5cc50674ae4eae1df736742f4e 100644 (file)
@@ -80,6 +80,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat);
     MEDCOUPLING_EXPORT static void ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigInAbs, std::vector< std::pair<int,int> >& partOfBigRelativeToBig, bool check=true);
     MEDCOUPLING_EXPORT static void ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigRelativeToBig, std::vector< std::pair<int,int> >& partOfBigInAbs, bool check=true);
+    MEDCOUPLING_EXPORT static std::vector< std::pair<int,int> > TranslateCompactFrmt(const std::vector< std::pair<int,int> >& part, const std::vector<int>& translation);
     MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat);
     MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd);
     MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd);
index b2e9d6e6ce2dd301d96c40aefdd46bf2daffef26..f4798c174ea641c2d3c072464ed5e16cae8ba1bb 100644 (file)
@@ -3016,6 +3016,22 @@ namespace ParaMEDMEM
         return retPy;
       }
 
+      static PyObject *TranslateCompactFrmt(PyObject *part, const std::vector<int>& translation) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::pair<int,int> > param0;
+        convertPyToVectorPairInt(part,param0);
+        std::vector< std::pair<int,int> > ret(MEDCouplingStructuredMesh::TranslateCompactFrmt(param0,translation));
+        PyObject *retPy(PyList_New(ret.size()));
+        for(std::size_t i=0;i<ret.size();i++)
+          {
+            PyObject *tmp(PyTuple_New(2));
+            PyTuple_SetItem(tmp,0,PyInt_FromLong(ret[i].first));
+            PyTuple_SetItem(tmp,1,PyInt_FromLong(ret[i].second));
+            PyList_SetItem(retPy,i,tmp);
+          }
+        return retPy;
+      }
+
       static PyObject *ChangeReferenceToGlobalOfCompactFrmt(PyObject *bigInAbs, PyObject *partOfBigRelativeToBig, bool check=true) throw(INTERP_KERNEL::Exception)
       {
         std::vector< std::pair<int,int> > param0,param1,ret;
@@ -4859,11 +4875,11 @@ namespace ParaMEDMEM
   class MEDCouplingDataForGodFather : public RefCountObject
   {
   public:
-    virtual void synchronizeFineToCoarse(int ghostLev) throw(INTERP_KERNEL::Exception);
-    virtual void synchronizeCoarseToFine(int ghostLev) throw(INTERP_KERNEL::Exception);
-    virtual void synchronizeCoarseToFineOnlyInGhostZone(int ghostLev) throw(INTERP_KERNEL::Exception);
-    virtual void synchronizeFineEachOtherInGhostZone(int ghostLev) throw(INTERP_KERNEL::Exception);
-    virtual void alloc(int ghostLev) throw(INTERP_KERNEL::Exception);
+    virtual void synchronizeFineToCoarse() throw(INTERP_KERNEL::Exception);
+    virtual void synchronizeCoarseToFine() throw(INTERP_KERNEL::Exception);
+    virtual void synchronizeCoarseToFineOnlyInGhostZone() throw(INTERP_KERNEL::Exception);
+    virtual void synchronizeFineEachOtherInGhostZone() throw(INTERP_KERNEL::Exception);
+    virtual void alloc() throw(INTERP_KERNEL::Exception);
     virtual void dealloc() throw(INTERP_KERNEL::Exception);
   };
   
@@ -4896,6 +4912,7 @@ namespace ParaMEDMEM
     void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const throw(INTERP_KERNEL::Exception);
     void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception);
     void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception);
+    void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const;
     void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception);
     void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception);
@@ -5021,7 +5038,7 @@ namespace ParaMEDMEM
   {
   public:
     void setData(MEDCouplingDataForGodFather *data) throw(INTERP_KERNEL::Exception);
-    void allocData(int ghostLev) const throw(INTERP_KERNEL::Exception);
+    void allocData() const throw(INTERP_KERNEL::Exception);
     void deallocData() const throw(INTERP_KERNEL::Exception);
     %extend
     {
@@ -5070,12 +5087,12 @@ namespace ParaMEDMEM
   class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel
   {
   public:
-    MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception);
-    MEDCouplingFieldDouble *buildCellFieldOnWithGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception);
     bool changeGodFather(MEDCouplingCartesianAMRMesh *gf) throw(INTERP_KERNEL::Exception);
     %extend
     {
-      static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames) throw(INTERP_KERNEL::Exception)
+      static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception)
       {
         std::vector< std::pair<std::string,int> > fieldNamesCpp0;
         std::vector< std::pair<std::string, std::vector<std::string> > > fieldNamesCpp1;
@@ -5083,19 +5100,19 @@ namespace ParaMEDMEM
         try
           {
             convertPyToVectorPairStringInt(fieldNames,fieldNamesCpp0);
-            ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0);
+            ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0,ghostLev);
           }
         catch(INTERP_KERNEL::Exception&)
           {
             convertPyToVectorPairStringVecString(fieldNames,fieldNamesCpp1);
-            ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1);
+            ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1,ghostLev);
           }
         return ret;
       }
 
-      MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames) throw(INTERP_KERNEL::Exception)
+      MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception)
       {
-        return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames);
+        return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames,ghostLev);
       }
       
       DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception)