]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Attributes for AMR cartesian mesh developped. Ready to test.
authorgeay <anthony.geay@cea.fr>
Mon, 2 Jun 2014 16:22:41 +0000 (18:22 +0200)
committergeay <anthony.geay@cea.fr>
Mon, 2 Jun 2014 16:22:41 +0000 (18:22 +0200)
src/MEDCoupling/MEDCouplingAMRAttribute.cxx
src/MEDCoupling/MEDCouplingAMRAttribute.hxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx
src/MEDCoupling/MEDCouplingIMesh.cxx
src/MEDCoupling/MEDCouplingIMesh.hxx
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i
src/MEDCoupling_Swig/MEDCouplingTypemaps.i

index ca83e5be347a6a228c8e15306a0e78b0832ffabd..43362076056f4524686fb14e8580dc00f861132b 100644 (file)
@@ -21,6 +21,8 @@
 #include "MEDCouplingAMRAttribute.hxx"
 #include "MEDCouplingMemArray.hxx"
 
+#include <sstream>
+
 using namespace ParaMEDMEM;
 
 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
@@ -54,6 +56,104 @@ void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::ve
     }
 }
 
+std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
+{
+  std::size_t sz(_arrs.size());
+  std::vector<DataArrayDouble *> ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const DataArrayDouble *tmp(_arrs[i]);
+      ret[i]=const_cast<DataArrayDouble *>(tmp);
+      if(ret[i])
+        ret[i]->incrRef();
+    }
+  return ret;
+}
+
+DataArrayDouble *DataArrayDoubleCollection::retrieveFieldWithName(const std::string& name) const
+{
+  std::vector<std::string> vec;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
+    {
+      const DataArrayDouble *obj(*it);
+      if(obj)
+        {
+          if(obj->getName()==name)
+            {
+              DataArrayDouble *ret(const_cast<DataArrayDouble *>(obj));
+              if(ret)
+                ret->incrRef();
+              return ret;
+            }
+          else
+            {
+              vec.push_back(obj->getName());
+            }
+        }
+    }
+  std::ostringstream oss; oss << "DataArrayDoubleCollection::retrieveFieldWithName : 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());
+}
+
+void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
+{
+  if(!fine || !coarse)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
+  std::size_t sz(coarse->_arrs.size());
+  if(fine->_arrs.size()!=sz)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
+  for(std::size_t i=0;i<sz;i++)
+    fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i],coarse->_arrs[i],ghostLev);
+}
+
+void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
+{
+  if(!fine || !coarse)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
+  std::size_t sz(coarse->_arrs.size());
+  if(fine->_arrs.size()!=sz)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
+  for(std::size_t i=0;i<sz;i++)
+    fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
+}
+
+void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
+{
+  if(!fatherOfFineMesh)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
+  std::size_t sz(children.size());
+  if(fieldsOnFine.size()!=sz)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
+  if(sz<=1)
+    return ;
+  std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
+  for(std::size_t i=0;i<sz;i++)
+    if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
+      throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
+  for(std::size_t i=1;i<sz;i++)
+    if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
+      throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
+  for(std::size_t i=0;i<nbOfCall;i++)
+    {
+      std::vector<const DataArrayDouble *> arrs(sz);
+      for(std::size_t j=0;j<sz;j++)
+        arrs[j]=fieldsOnFine[j]->_arrs[i];
+      fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
+    }
+}
+
+void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
+{
+  if(!fine || !coarse)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
+  std::size_t sz(coarse->_arrs.size());
+  if(fine->_arrs.size()!=sz)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
+  for(std::size_t i=0;i<sz;i++)
+    fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
+}
+
 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
 {
   std::size_t sz(fieldNames.size());
@@ -141,6 +241,136 @@ void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::ve
     (*it).second->spillInfoOnComponents(compNames);
 }
 
+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++)
+    {
+      if((*it).first==m)
+        {
+          pos=ret;
+          return true;
+        }
+    }
+  return false;
+}
+
+const DataArrayDoubleCollection& MEDCouplingGridCollection::retrieveFieldsAt(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) !");
+  return *_map_of_dadc[pos].second;
+}
+
+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 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++)
+        {
+          if((*it0).first==fatherOfFineMesh)
+            {
+              found=true;
+              int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
+              const DataArrayDoubleCollection *coarseDaCol((*it0).second);
+              DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
+              DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
+            }
+        }
+      if(!found)
+        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
+    }
+}
+
+void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
+{
+  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 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++)
+        {
+          if((*it0).first==fatherOfFineMesh)
+            {
+              found=true;
+              int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
+              const DataArrayDoubleCollection *fineDaCol((*it).second);
+              DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
+              DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
+            }
+        }
+      if(!found)
+        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
+    }
+}
+
+void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev) const
+{
+  std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > > 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));
+    }
+  for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > >::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++)
+        {
+          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);
+        }
+    }
+}
+
+void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
+{
+  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 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++)
+        {
+          if((*it0).first==fatherOfFineMesh)
+            {
+              found=true;
+              int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
+              const DataArrayDoubleCollection *fineDaCol((*it).second);
+              DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
+              DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
+            }
+        }
+      if(!found)
+        throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
+    }
+}
+
 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
 {
   std::size_t sz(ms.size());
@@ -193,6 +423,22 @@ MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMes
   return new MEDCouplingAMRAttribute(gf,fieldNames);
 }
 
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames)
+{
+  std::size_t sz(fieldNames.size());
+  std::vector< std::pair<std::string,int> > fieldNames2(sz);
+  std::vector< std::vector<std::string> > compNames(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      fieldNames2[i].first=fieldNames[i].first;
+      fieldNames2[i].second=(int)fieldNames[i].second.size();
+      compNames[i]=fieldNames[i].second;
+    }
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2));
+  ret->spillInfoOnComponents(compNames);
+  return ret.retn();
+}
+
 /*!
  * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
  * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New.
@@ -206,6 +452,115 @@ void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vect
     (*it)->spillInfoOnComponents(compNames);
 }
 
+/*!
+ * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
+ * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
+ *
+ * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
+ * \sa retrieveFieldOn
+ */
+std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+    {
+      int tmp(-1);
+      if((*it)->presenceOf(mesh,tmp))
+        {
+          const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+          return ddc.retrieveFields();
+        }
+    }
+  throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
+}
+
+/*!
+ * \sa retrieveFieldsOn
+ */
+DataArrayDouble *MEDCouplingAMRAttribute::retrieveFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
+      {
+        int tmp(-1);
+        if((*it)->presenceOf(mesh,tmp))
+          {
+            const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+            return ddc.retrieveFieldWithName(fieldName);
+          }
+      }
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
+}
+
+/*!
+ * 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)
+{
+  if(_levs.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
+  std::size_t sz(_levs.size());
+  //
+  while(sz>1)
+    {
+      sz--;
+      const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
+      MEDCouplingGridCollection::SynchronizeFineToCoarse(ghostLev,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
+ * MEDCouplingAMRAttribute::alloc method.
+ */
+void MEDCouplingAMRAttribute::synchronizeCoarseToFine(int ghostLev)
+{
+  if(_levs.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
+  std::size_t sz(_levs.size());
+  //
+  for(std::size_t i=1;i<sz;i++)
+    {
+      const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
+      MEDCouplingGridCollection::SynchronizeCoarseToFine(ghostLev,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.
+ */
+void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone(int ghostLev)
+{
+  if(_levs.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone : not any levels in this !");
+  std::size_t sz(_levs.size());
+  //
+  for(std::size_t i=1;i<sz;i++)
+    {
+      const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
+      MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,coarse,fine);
+    }
+}
+
+/*!
+ * This method synchronizes fine each other only in the ghost zone.
+ */
+void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone(int ghostLev)
+{
+  if(_levs.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
+  std::size_t sz(_levs.size());
+  //
+  for(std::size_t i=1;i<sz;i++)
+    {
+      const MEDCouplingGridCollection *fine(_levs[sz]);
+      if(!fine)
+        throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
+      fine->synchronizeFineEachOther(ghostLev);
+    }
+}
+
 /*!
  * This method allocates all DataArrayDouble instances stored recursively in \a this.
  *
index 6651aa416a099d7e89a0034eaec6dabb747ec455..2fe0fdda39903618e97965004b17df5962ba8ff2 100644 (file)
@@ -34,6 +34,12 @@ namespace ParaMEDMEM
     void allocTuples(int nbOfTuples);
     void dellocTuples();
     void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
+    std::vector<DataArrayDouble *> retrieveFields() const;
+    DataArrayDouble *retrieveFieldWithName(const std::string& name) const;
+    static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse);
+    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);
   private:
     DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames);
     std::size_t getHeapMemorySizeWithoutChildren() const;
@@ -51,6 +57,12 @@ namespace ParaMEDMEM
     void alloc(int ghostLev);
     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;
+    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;
+    static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine);
   private:
     MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames);
     std::size_t getHeapMemorySizeWithoutChildren() const;
@@ -65,8 +77,15 @@ namespace ParaMEDMEM
   {
   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 void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
+    MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const;
+    MEDCOUPLING_EXPORT DataArrayDouble *retrieveFieldOn(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 dealloc();
     MEDCOUPLING_EXPORT bool changeGodFather(MEDCouplingCartesianAMRMesh *gf);
index 0208d74252444c61d10a36697299ab530b01b0d0..34aec97117d2ad35070f4a647db6f464ee87ff08 100644 (file)
@@ -249,6 +249,10 @@ int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithOverlap() const
 
 /*!
  * This method returns the max number of cells covering all the space without overlapping.
+ * It returns the number of cells of the mesh with the highest resolution.
+ * The returned value is equal to the number of cells of mesh returned by buildUnstructured.
+ *
+ * \sa buildUnstructured
  */
 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithoutOverlap() const
 {
@@ -680,6 +684,17 @@ int MEDCouplingCartesianAMRMeshGen::getNumberOfPatches() const
   return (int)_patches.size();
 }
 
+int MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const
+{
+  int ret(0);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ret++)
+    {
+      if((*it)->getMesh()==mesh)
+        return ret;
+    }
+  throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh : no such a mesh in my direct progeny !");
+}
+
 const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatch(int patchId) const
 {
   checkPatchId(patchId);
@@ -771,6 +786,23 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, cons
   MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
 }
 
+/*!
+ * This method is equivalent to  fillCellFieldOnPatchGhost except that here \b ONLY \b the \b ghost \b zone will be updated
+ * in \a cellFieldOnPatch.
+ *
+ * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
+ * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
+ * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled \b only \b in \b the \b ghost \b zone.
+ * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
+ */
+void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const
+{
+  if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyOnGhostZone : the input cell field array is NULL or not allocated !");
+  const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
+  MEDCouplingIMesh::SpreadCoarseToFineGhostZone(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
+}
+
 /*!
  * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called.
  * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately.
@@ -797,6 +829,10 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, c
   fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches);
 }
 
+/*!
+ * This method updates the patch with id \a patchId considering the only the all the patches in \a this to fill ghost zone.
+ * So \b warning, the DataArrayDouble instance \a arrsOnPatches[patchId] is non const.
+ */
 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
 {
   int nbp(getNumberOfPatches()),dim(getSpaceDimension());
@@ -1173,6 +1209,6 @@ void MEDCouplingCartesianAMRMesh::checkData() const
 MEDCouplingCartesianAMRMesh::~MEDCouplingCartesianAMRMesh()
 {
   MEDCouplingDataForGodFather *data(_data);
-  if(!data)
+  if(data)
     data->changeGodFather(0);
 }
index 272b81028a035e6b79020b8eb03c1f63c1e518e5..6fbb657baddd90a8685fe6bc3ffab2d01e1bdca1 100644 (file)
@@ -98,6 +98,10 @@ 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 dealloc() = 0;
   protected:
@@ -140,15 +144,22 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void removeAllPatches();
     MEDCOUPLING_EXPORT void removePatch(int patchId);
     MEDCOUPLING_EXPORT int getNumberOfPatches() const;
+    MEDCOUPLING_EXPORT int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const;
     MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatch(int patchId) const;
     MEDCOUPLING_EXPORT bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const;
     MEDCOUPLING_EXPORT DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const;
+    // coarse to fine
     MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const;
     MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const;
+    MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const;
+    // coarse to fine + fine to fine
     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;
+    // 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;
+    //
     MEDCOUPLING_EXPORT DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const;
     //
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const;
index 6ec8c583905c6cc7bbd47dbd68b30565524b487b..4b7d628155ad8403bb8ae394e598bc86cdf6ea3e 100644 (file)
@@ -592,7 +592,8 @@ void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const
  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
  * \param [in] facts The refinement coefficient per axis.
  * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
- * \sa CondenseFineToCoarse
+ *
+ * \sa CondenseFineToCoarse,SpreadCoarseToFineGhostZone
  */
 void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
 {
@@ -670,7 +671,7 @@ void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA,
               {
                 for(int ig=0;ig<ghostSize;ig++)
                   outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
-                int kk0(kk+1);
+                int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
                 for(int i=0;i<dims[0];i++,kk0++)
                   {
                     const double *loc(inPtr+kk0*nbCompo);
@@ -700,6 +701,113 @@ void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA,
   }
 }
 
+/*!
+ * This method spreads the values of coarse data \a coarseDA into \a fineDA \b ONLY \b in \b the \b ghost \b zone (contrary to SpreadCoarseToFineGhost that spread the values everywhere).
+ *
+ * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
+ * \param [in] coarseSt The cell structure of coarse mesh.
+ * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
+ * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
+ * \param [in] facts The refinement coefficient per axis.
+ * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
+ *
+ * \sa SpreadCoarseToFineGhost
+ */
+void MEDCouplingIMesh::SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
+  if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
+  if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
+  std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+  int nbCompo(fineDA->getNumberOfComponents());
+  if(coarseDA->getNumberOfComponents()!=nbCompo)
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
+  if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
+  if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+  std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
+  if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  double *outPtr(fineDA->getPointer());
+  const double *inPtr(coarseDA->begin());
+  //
+  std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+  switch(meshDim)
+  {
+    case 1:
+      {
+        int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
+        for(int i=0;i<ghostSize;i++)
+          outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+        outPtr+=nbCompo*fact0*dims[0];
+        offset=fineLocInCoarse[0].second+ghostSize;
+        for(int i=0;i<ghostSize;i++)
+          outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+        break;
+      }
+    case 2:
+      {
+        int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
+        int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
+        for(int jg=0;jg<ghostSize;jg++)
+          {
+            for(int ig=0;ig<ghostSize;ig++)
+              outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
+            int kk0(kk+1);
+            for(int ig=0;ig<dims[0];ig++,kk0++)
+              for(int ifact=0;ifact<fact0;ifact++)
+                outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
+            for(int ik=0;ik<ghostSize;ik++)
+              outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
+          }
+        for(int j=0;j<dims[1];j++)
+          {
+            kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
+            for(int jfact=0;jfact<fact1;jfact++)
+              {
+                for(int ig=0;ig<ghostSize;ig++)
+                  outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
+                int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
+                outPtr+=fact0*nbCompo*dims[0];
+                for(int ig=0;ig<ghostSize;ig++)
+                  outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
+              }
+          }
+        kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
+        for(int jg=0;jg<ghostSize;jg++)
+          {
+            for(int ig=0;ig<ghostSize;ig++)
+              outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
+            int kk0(kk+1);
+            for(int ig=0;ig<dims[0];ig++,kk0++)
+              for(int ifact=0;ifact<fact0;ifact++)
+                outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
+            for(int ik=0;ik<ghostSize;ik++)
+              outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
+          }
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2 supported !");
+  }
+}
+
 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
 {
   if(spaceDim==_space_dim)
index f08cf7381f8562f700164bd6dd3264c998c183b8..0fbc783d1e9cd49d949cf791b2a07628e70afa44 100644 (file)
@@ -52,6 +52,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static void CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize);
     MEDCOUPLING_EXPORT static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts);
     MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize);
+    MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize);
     //
     MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const;
     MEDCOUPLING_EXPORT MEDCouplingIMesh *clone(bool recDeepCpy) const;
index b72ee4c40d71cc796bd48c6e1c0af10cf99547ce..3fa76fadb578c10818ef40ab0cae389d8bd7e77e 100644 (file)
@@ -41,6 +41,7 @@
 #include "MEDCouplingDefinitionTime.hxx"
 #include "MEDCouplingFieldDiscretization.hxx"
 #include "MEDCouplingCartesianAMRMesh.hxx"
+#include "MEDCouplingAMRAttribute.hxx"
 #include "MEDCouplingMatrix.hxx"
 #include "MEDCouplingTypemaps.i"
 
@@ -94,6 +95,13 @@ using namespace INTERP_KERNEL;
 }
 //$$$$$$$$$$$$$$$$$$
 
+////////////////////
+%typemap(out) MEDCouplingDataForGodFather*
+{
+  $result=convertDataForGodFather($1,$owner);
+}
+//$$$$$$$$$$$$$$$$$$
+
 ////////////////////
 %typemap(out) ParaMEDMEM::MEDCoupling1GTUMesh*
 {
@@ -344,6 +352,8 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::New;
 %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::getDataConst;
 %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::getData;
+%newobject ParaMEDMEM::MEDCouplingAMRAttribute::New;
+%newobject ParaMEDMEM::MEDCouplingAMRAttribute::retrieveFieldOn;
 %newobject ParaMEDMEM::DenseMatrix::New;
 %newobject ParaMEDMEM::DenseMatrix::deepCpy;
 %newobject ParaMEDMEM::DenseMatrix::shallowCpy;
@@ -381,6 +391,7 @@ using namespace INTERP_KERNEL;
 %feature("unref") MEDCouplingCartesianAMRPatchGF "$this->decrRef();"
 %feature("unref") MEDCouplingCartesianAMRPatch "$this->decrRef();"
 %feature("unref") MEDCouplingDataForGodFather "$this->decrRef();"
+%feature("unref") MEDCouplingAMRAttribute "$this->decrRef();"
 %feature("unref") DenseMatrix "$this->decrRef();"
 
 %rename(assign) *::operator=;
@@ -3219,6 +3230,13 @@ namespace ParaMEDMEM
         MEDCouplingIMesh::SpreadCoarseToFineGhost(coarseDA,coarseSt,fineDA,inp,facts,ghostSize);
       }
 
+      static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector<int>& facts, int ghostSize) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::pair<int,int> > inp;
+        convertPyToVectorPairInt(fineLocInCoarse,inp);
+        MEDCouplingIMesh::SpreadCoarseToFineGhostZone(coarseDA,coarseSt,fineDA,inp,facts,ghostSize);
+      }
+
       std::string __str__() const throw(INTERP_KERNEL::Exception)
       {
         return self->simpleRepr();
@@ -4838,7 +4856,11 @@ namespace ParaMEDMEM
   class MEDCouplingDataForGodFather : public RefCountObject
   {
   public:
-    virtual void alloc() throw(INTERP_KERNEL::Exception);
+    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 dealloc() throw(INTERP_KERNEL::Exception);
   };
   
@@ -4856,7 +4878,8 @@ namespace ParaMEDMEM
     int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception);
     bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const throw(INTERP_KERNEL::Exception);
     //
-    int getNumberOfPatches() const throw(INTERP_KERNEL::Exception);    
+    int getNumberOfPatches() const throw(INTERP_KERNEL::Exception);
+    int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
     MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const throw(INTERP_KERNEL::Exception);
     MEDCoupling1SGTUMesh *buildMeshOfDirectChildrenOnly() const throw(INTERP_KERNEL::Exception);
@@ -4867,6 +4890,7 @@ namespace ParaMEDMEM
     DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception);
     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 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);
@@ -4970,7 +4994,7 @@ namespace ParaMEDMEM
   {
   public:
     void setData(MEDCouplingDataForGodFather *data) throw(INTERP_KERNEL::Exception);
-    void allocData() const throw(INTERP_KERNEL::Exception);
+    void allocData(int ghostLev) const throw(INTERP_KERNEL::Exception);
     void deallocData() const throw(INTERP_KERNEL::Exception);
     %extend
     {
@@ -5015,6 +5039,55 @@ namespace ParaMEDMEM
       }
     }
   };
+  
+  class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel
+  {
+  public:
+    DataArrayDouble *retrieveFieldOn(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)
+      {
+        std::vector< std::pair<std::string,int> > fieldNamesCpp0;
+        std::vector< std::pair<std::string, std::vector<std::string> > > fieldNamesCpp1;
+        MEDCouplingAMRAttribute *ret(0);
+        try
+          {
+            convertPyToVectorPairStringInt(fieldNames,fieldNamesCpp0);
+            ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0);
+          }
+        catch(INTERP_KERNEL::Exception&)
+          {
+            convertPyToVectorPairStringVecString(fieldNames,fieldNamesCpp1);
+            ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1);
+          }
+        return ret;
+      }
+
+      MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames) throw(INTERP_KERNEL::Exception)
+      {
+        return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames);
+      }
+      
+      void spillInfoOnComponents(PyObject *compNames) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::vector<std::string> > compNamesCpp;
+        convertPyToVectorOfVectorOfString(compNames,compNamesCpp);
+        self->spillInfoOnComponents(compNamesCpp);
+      }
+      
+      PyObject *retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<DataArrayDouble *> ret(self->retrieveFieldsOn(mesh));
+        int sz((int)ret.size());
+        PyObject *retPy(PyList_New(sz));
+        for(int i=0;i<sz;i++)
+          PyList_SetItem(retPy,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ));
+        return retPy;
+      }
+    }
+  };
 
   class DenseMatrix : public RefCountObject, public TimeLabel
   {
index 7b76dd62ec8381fd32c575429fca5017fed6b574..d1f2da7e148c6f0ac6e222c0843badfa78d83753 100644 (file)
@@ -699,6 +699,63 @@ static void convertPyToVectorPairInt(PyObject *pyLi, std::vector< std::pair<int,
     throw INTERP_KERNEL::Exception(msg);
 }
 
+static void convertPyToVectorPairStringInt(PyObject *pyLi, std::vector< std::pair<std::string,int> >& arr) throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="convertPyToVectorPairStringInt : list must contain tuples of 2 integers only or tuple must contain tuples of 1 string and 1 integer only !";
+  if(PyList_Check(pyLi))
+    {
+      int size=PyList_Size(pyLi);
+      arr.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          if(PyTuple_Check(o))
+            {
+              int sz2=PyTuple_Size(o);
+              if(sz2!=2)
+                throw INTERP_KERNEL::Exception(msg);
+              PyObject *o_0=PyTuple_GetItem(o,0);
+              if(!PyString_Check(o_0))
+                throw INTERP_KERNEL::Exception(msg);
+              PyObject *o_1=PyTuple_GetItem(o,1);
+              if(!PyInt_Check(o_1))
+                throw INTERP_KERNEL::Exception(msg);
+              arr[i].first=PyString_AsString(o_0);
+              arr[i].second=(int)PyInt_AS_LONG(o_1);
+            }
+          else
+            throw INTERP_KERNEL::Exception(msg);
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      int size=PyTuple_Size(pyLi);
+      arr.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          if(PyTuple_Check(o))
+            {
+              int sz2=PyTuple_Size(o);
+              if(sz2!=2)
+                throw INTERP_KERNEL::Exception(msg);
+              PyObject *o_0=PyTuple_GetItem(o,0);
+              if(!PyString_Check(o_0))
+                throw INTERP_KERNEL::Exception(msg);
+              PyObject *o_1=PyTuple_GetItem(o,1);
+              if(!PyInt_Check(o_1))
+                throw INTERP_KERNEL::Exception(msg);
+              arr[i].first=PyString_AsString(o_0);
+              arr[i].second=(int)PyInt_AS_LONG(o_1);
+            }
+          else
+            throw INTERP_KERNEL::Exception(msg);
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception(msg);
+}
+
 static void convertPyToNewIntArr3(PyObject *pyLi, std::vector<int>& arr) throw(INTERP_KERNEL::Exception)
 {
   if(PyList_Check(pyLi))
@@ -957,6 +1014,93 @@ static bool fillStringVector(PyObject *pyLi, std::vector<std::string>& vec) thro
   else
     return false;
 }
+static void convertPyToVectorOfVectorOfString(PyObject *pyLi, std::vector< std::vector<std::string> >& arr) throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="convertPyToVectorOfVectorOfString : expecting list of list of strings !";
+  if(PyList_Check(pyLi))
+    {
+      Py_ssize_t sz=PyList_Size(pyLi);
+      arr.resize(sz);
+      for(int i=0;i<sz;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          if(!fillStringVector(o,arr[i]))
+            throw INTERP_KERNEL::Exception(msg);
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      Py_ssize_t sz=PyTuple_Size(pyLi);
+      arr.resize(sz);
+      for(int i=0;i<sz;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          if(!fillStringVector(o,arr[i]))
+            throw INTERP_KERNEL::Exception(msg);
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception(msg);
+}
+
+static void convertPyToVectorPairStringVecString(PyObject *pyLi, std::vector< std::pair<std::string, std::vector<std::string> > >& arr) throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="convertPyToVectorPairStringVecString : expecting list of tuples containing each exactly 2 items : one string and one vector of string !";
+  if(PyList_Check(pyLi))
+    {
+      Py_ssize_t sz=PyList_Size(pyLi);
+      arr.resize(sz);
+      for(int i=0;i<sz;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          if(PyTuple_Check(o))
+            {
+              int sz2=PyTuple_Size(o);
+              if(sz2!=2)
+                throw INTERP_KERNEL::Exception(msg);
+              std::pair<std::string, std::vector<std::string> > item;
+              PyObject *o_0=PyTuple_GetItem(o,0);
+              if(!PyString_Check(o_0))
+                throw INTERP_KERNEL::Exception(msg);
+              item.first=PyString_AsString(o_0);
+              PyObject *o_1=PyTuple_GetItem(o,1);
+              if(!fillStringVector(o_1,item.second))
+                throw INTERP_KERNEL::Exception(msg);
+              arr[i]=item;
+            }
+          else
+            throw INTERP_KERNEL::Exception(msg);
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      Py_ssize_t sz=PyTuple_Size(pyLi);
+      arr.resize(sz);
+      for(int i=0;i<sz;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          if(PyTuple_Check(o))
+            {
+              int sz2=PyTuple_Size(o);
+              if(sz2!=2)
+                throw INTERP_KERNEL::Exception(msg);
+              std::pair<std::string, std::vector<std::string> > item;
+              PyObject *o_0=PyTuple_GetItem(o,0);
+              if(!PyString_Check(o_0))
+                throw INTERP_KERNEL::Exception(msg);
+              item.first=PyString_AsString(o_0);
+              PyObject *o_1=PyTuple_GetItem(o,1);
+              if(!fillStringVector(o_1,item.second))
+                throw INTERP_KERNEL::Exception(msg);
+              arr[i]=item;
+            }
+          else
+            throw INTERP_KERNEL::Exception(msg);
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception(msg);
+}
 
 static PyObject *convertDblArrToPyList(const double *ptr, int size) throw(INTERP_KERNEL::Exception)
 {
index 0a50f88f8b69bb9fb4a9eb80db49cb071b13b468..edae657420af39cda5f371fb23b187166d6d4cb6 100644 (file)
@@ -103,6 +103,20 @@ static PyObject *convertCartesianAMRMesh(ParaMEDMEM::MEDCouplingCartesianAMRMesh
   throw INTERP_KERNEL::Exception("convertCartesianAMRMesh wrap : unrecognized type of cartesian AMR mesh !");
 }
 
+static PyObject *convertDataForGodFather(ParaMEDMEM::MEDCouplingDataForGodFather *data, int owner) throw(INTERP_KERNEL::Exception)
+{
+  if(!data)
+    {
+      Py_XINCREF(Py_None);
+      return Py_None;
+    }
+  if(dynamic_cast<ParaMEDMEM::MEDCouplingAMRAttribute *>(data))
+    {
+      return SWIG_NewPointerObj(reinterpret_cast<void*>(data),SWIGTYPE_p_ParaMEDMEM__MEDCouplingAMRAttribute,owner);
+    }
+  throw INTERP_KERNEL::Exception("convertDataForGodFather wrap : unrecognized data type for AMR !");
+}
+
 static PyObject *convertCartesianAMRPatch(ParaMEDMEM::MEDCouplingCartesianAMRPatchGen *patch, int owner) throw(INTERP_KERNEL::Exception)
 {
   if(!patch)