]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
interlevels methods.
authorgeay <anthony.geay@cea.fr>
Thu, 12 Jun 2014 16:33:35 +0000 (18:33 +0200)
committergeay <anthony.geay@cea.fr>
Thu, 12 Jun 2014 16:33:35 +0000 (18:33 +0200)
src/MEDCoupling/MEDCouplingAMRAttribute.cxx
src/MEDCoupling/MEDCouplingAMRAttribute.hxx
src/MEDCoupling_Swig/MEDCouplingCommon.i

index 9ab932819aac0f4fa115010613849388de5e7686..f27671edd748d9d701491b8151fb6aabfa9f9975 100644 (file)
@@ -32,6 +32,11 @@ DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std
   return new DataArrayDoubleCollection(fieldNames);
 }
 
+DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
+{
+  return new DataArrayDoubleCollection(*this);
+}
+
 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
 {
   std::size_t sz(_arrs.size());
@@ -64,7 +69,10 @@ void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& n
   if(sz!=nfs.size())
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
   for(std::size_t i=0;i<sz;i++)
-    _arrs[i].second=nfs[i];
+    {
+      CheckValidNature(nfs[i]);
+      _arrs[i].second=nfs[i];
+    }
 }
 
 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
@@ -217,6 +225,18 @@ DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pai
   CheckDiscriminantNames(names);
 }
 
+DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
+{
+  std::size_t sz(other._arrs.size());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      _arrs[i].second=other._arrs[i].second;
+      const DataArrayDouble *da(other._arrs[i].first);
+      if(da)
+        _arrs[i].first=da->deepCpy();
+    }
+}
+
 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(sizeof(DataArrayDoubleCollection));
@@ -278,6 +298,11 @@ MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<cons
   return new MEDCouplingGridCollection(ms,fieldNames);
 }
 
+MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy() const
+{
+  return new MEDCouplingGridCollection(*this);
+}
+
 void MEDCouplingGridCollection::alloc(int ghostLev)
 {
   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
@@ -514,6 +539,18 @@ MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MED
     }
 }
 
+MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
+{
+  std::size_t sz(other._map_of_dadc.size());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      _map_of_dadc[i].first=other._map_of_dadc[i].first;
+      const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
+      if(dac)
+        _map_of_dadc[i].second=dac->deepCpy();
+    }
+}
+
 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(sizeof(MEDCouplingGridCollection));
@@ -579,6 +616,11 @@ bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMeshGen
   return ret;
 }
 
+MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
+{
+  other._tlc.checkConst();
+}
+
 /*!
  * 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.
  */
@@ -627,6 +669,21 @@ void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs
     (*it)->spillNatures(nfs);
 }
 
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
+{
+  return new MEDCouplingAMRAttribute(*this);
+}
+
+/*!
+ * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this).
+ *
+ */
+int MEDCouplingAMRAttribute::getNumberOfLevels() const
+{
+  checkGodFatherFrozen();
+  return (int)_levs.size();
+}
+
 /*!
  * 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.
@@ -768,6 +825,8 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(ME
 /*!
  * 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.
+ *
+ * \sa synchronizeFineToCoarseBetween
  */
 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
 {
@@ -778,11 +837,32 @@ void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
   while(sz>1)
     {
       sz--;
-      const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
-      MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
+      synchronizeFineToCoarseByOneLevel((int)sz);
     }
 }
 
+/*!
+ * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
+ * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
+ * until reaching \a toLev level.
+ *
+ * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
+ * \param [in] toLev - an existing level considered as the target level to reach.
+ *
+ */
+void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
+{
+  int nbl(getNumberOfLevels());
+  if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
+  if(fromLev==toLev)
+    return ;//nothing to do
+  if(fromLev<toLev)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
+  for(int i=fromLev;i>toLev;i--)
+    synchronizeFineToCoarseByOneLevel(i);
+}
+
 /*!
  * 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.
@@ -793,11 +873,29 @@ void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
     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[i]),*coarse(_levs[i-1]);
-      MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
-    }
+  for(std::size_t i=0;i<sz-1;i++)
+    synchronizeCoarseToFineByOneLevel((int)i);
+}
+
+/*!
+ * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
+ * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
+ * until reaching \a toLev level.
+ *
+ * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
+ * \param [in] toLev - an existing level considered as the target level to reach.
+ */
+void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
+{
+  int nbl(getNumberOfLevels());
+  if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
+  if(fromLev==toLev)
+    return ;//nothing to do
+  if(fromLev>toLev)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
+  for(int i=fromLev;i<toLev;i++)
+    synchronizeCoarseToFineByOneLevel(i);
 }
 
 /*!
@@ -957,6 +1055,19 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMeshGen
     }
 }
 
+MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other):MEDCouplingDataForGodFather(other),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors)
+{
+  std::size_t sz(other._levs.size());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const MEDCouplingGridCollection *elt(other._levs[i]);
+      if(elt)
+        {
+          _levs[i]=other._levs[i]->deepCpy();
+        }
+    }
+}
+
 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
 {
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
@@ -973,3 +1084,21 @@ const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttached
     }
   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
 }
+
+void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
+{
+  int nbl(getNumberOfLevels());
+  if(level<=0 || level>=nbl)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
+  const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
+  MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
+}
+
+void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
+{
+  int nbl(getNumberOfLevels());
+  if(level<0 || level>=nbl-1)
+    throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
+  const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
+  MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
+}
index b05f704d81361e50eac3df136bc9daa7be1ca1df..2b7eb68d331374ce33c13d0f44df7484a72cd5a1 100644 (file)
@@ -32,6 +32,7 @@ namespace ParaMEDMEM
   {
   public:
     static DataArrayDoubleCollection *New(const std::vector< std::pair<std::string,int> >& fieldNames);
+    DataArrayDoubleCollection *deepCpy() const;
     void allocTuples(int nbOfTuples);
     void dellocTuples();
     void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
@@ -47,6 +48,7 @@ namespace ParaMEDMEM
     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);
+    DataArrayDoubleCollection(const DataArrayDoubleCollection& other);
     std::size_t getHeapMemorySizeWithoutChildren() const;
     std::vector<const BigMemoryObject *> getDirectChildren() const;
     void updateTime() const;
@@ -62,6 +64,7 @@ namespace ParaMEDMEM
   {
   public:
     static MEDCouplingGridCollection *New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames);
+    MEDCouplingGridCollection *deepCpy() const;
     void alloc(int ghostLev);
     void dealloc();
     void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
@@ -77,6 +80,7 @@ namespace ParaMEDMEM
     void fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const;
   private:
     MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames);
+    MEDCouplingGridCollection(const MEDCouplingGridCollection& other);
     std::size_t getHeapMemorySizeWithoutChildren() const;
     std::vector<const BigMemoryObject *> getDirectChildren() const;
     void updateTime() const;
@@ -91,7 +95,9 @@ namespace ParaMEDMEM
     friend class MEDCouplingCartesianAMRMesh;
   public:
     MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0;
+    MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) = 0;
     MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0;
+    MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) = 0;
     MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZones() = 0;
     MEDCOUPLING_EXPORT virtual void alloc() = 0;
     MEDCOUPLING_EXPORT virtual void dealloc() = 0;
@@ -100,6 +106,7 @@ namespace ParaMEDMEM
     void checkGodFatherFrozen() const;
   protected:
     virtual bool changeGodFather(MEDCouplingCartesianAMRMeshGen *gf);
+    MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other);
   protected:
     MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMeshGen> _gf;
     TimeLabelConstOverseer _tlc;
@@ -112,6 +119,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMeshGen *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 void spillNatures(const std::vector<NatureOfField>& nfs);
+    MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *deepCpy() const;
+    MEDCOUPLING_EXPORT int getNumberOfLevels() const;
     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(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
@@ -119,7 +128,9 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
     //
     MEDCOUPLING_EXPORT void synchronizeFineToCoarse();
+    MEDCOUPLING_EXPORT void synchronizeFineToCoarseBetween(int fromLev, int toLev);
     MEDCOUPLING_EXPORT void synchronizeCoarseToFine();
+    MEDCOUPLING_EXPORT void synchronizeCoarseToFineBetween(int fromLev, int toLev);
     MEDCOUPLING_EXPORT void synchronizeAllGhostZones();
     MEDCOUPLING_EXPORT void alloc();
     MEDCOUPLING_EXPORT void dealloc();
@@ -130,7 +141,10 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void updateTime() const;
   private:
     MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev);
+    MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other);
     const DataArrayDoubleCollection& findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const;
+    void synchronizeFineToCoarseByOneLevel(int level);
+    void synchronizeCoarseToFineByOneLevel(int level);
   private:
     int _ghost_lev;
     std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> > _levs;
index 1a4313ddf8452fe4d19270aeafe8d6acbe9201f0..a0c5c79946c3484ba0e1970ac40e2befe4e2bf06 100644 (file)
@@ -353,6 +353,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::__getitem__;
 %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::New;
 %newobject ParaMEDMEM::MEDCouplingAMRAttribute::New;
+%newobject ParaMEDMEM::MEDCouplingAMRAttribute::deepCpy;
 %newobject ParaMEDMEM::MEDCouplingAMRAttribute::getFieldOn;
 %newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost;
 %newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnWithGhost;
@@ -4913,7 +4914,9 @@ namespace ParaMEDMEM
   {
   public:
     virtual void synchronizeFineToCoarse() throw(INTERP_KERNEL::Exception);
+    virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception);
     virtual void synchronizeCoarseToFine() throw(INTERP_KERNEL::Exception);
+    virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception);
     virtual void synchronizeAllGhostZones() throw(INTERP_KERNEL::Exception);
     virtual void alloc() throw(INTERP_KERNEL::Exception);
     virtual void dealloc() throw(INTERP_KERNEL::Exception);
@@ -5115,6 +5118,8 @@ namespace ParaMEDMEM
   class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel
   {
   public:
+    int getNumberOfLevels() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingAMRAttribute *deepCpy() 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);
     MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception);
@@ -5143,7 +5148,7 @@ namespace ParaMEDMEM
       {
         return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames,ghostLev);
       }
-      
+
       DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception)
       {
         const DataArrayDouble *ret(self->getFieldOn(mesh,fieldName));