Salome HOME
Addition unloadArraysWithoutDataLoss methods in MEDFileFields, MEDFileAnyTypeFieldMul...
authorgeay <anthony.geay@cea.fr>
Tue, 25 Feb 2014 09:37:54 +0000 (10:37 +0100)
committergeay <anthony.geay@cea.fr>
Tue, 25 Feb 2014 09:37:54 +0000 (10:37 +0100)
src/MEDLoader/MEDFileField.cxx
src/MEDLoader/MEDFileField.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py

index e69aaf127e43e6d1fba2b02c6cc8cab7a7a2575c..04ad5b5b72ab9c686019ae8a263c9c133bf6f6ba 100644 (file)
@@ -3398,11 +3398,6 @@ std::string MEDFileFieldGlobsReal::getFileName() const
   return contentNotNull()->getFileName();
 }
 
-std::string MEDFileFieldGlobsReal::getFileName2() const
-{
-  return contentNotNull()->getFileName2();
-}
-
 /*!
  * Returns a localization object by its name.
  *  \param [in] locName - the name of the localization of interest.
@@ -5598,15 +5593,29 @@ void MEDFileAnyTypeField1TS::loadArraysIfNecessary()
 
 /*!
  * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false.
- * This method does not release arrays set outside the context of a MED file.
+ * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file.
+ * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss instead.
  * 
- * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary
+ * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary, MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss
  */
 void MEDFileAnyTypeField1TS::unloadArrays()
 {
   contentNotNullBase()->unloadArrays();
 }
 
+/*!
+ * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect.
+ * This method is the symetrical method of MEDFileAnyTypeField1TS::loadArraysIfNecessary.
+ * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database.
+ * 
+ * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary
+ */
+void MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss()
+{
+  if(!getFileName().empty())
+    contentNotNullBase()->unloadArrays();
+}
+
 void MEDFileAnyTypeField1TS::writeLL(med_idt fid) const
 {
   int nbComp=getNumberOfComponents();
@@ -6117,7 +6126,7 @@ MEDFileField1TS::MEDFileField1TS()
  */
 MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const
 {
-  if(getFileName2().empty())
+  if(getFileName().empty())
     throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !");
   MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNull());
@@ -6149,7 +6158,7 @@ MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int m
  */
 MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const
 {
-  if(getFileName2().empty())
+  if(getFileName().empty())
     throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !");
   MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNull());
@@ -6242,7 +6251,7 @@ MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type,
  */
 MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol) const
 {
-  if(getFileName2().empty())
+  if(getFileName().empty())
     throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !");
   MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNull());
@@ -6509,7 +6518,7 @@ const MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() const
 
 MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const
 {
-  if(getFileName2().empty())
+  if(getFileName().empty())
     throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !");
   MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut2;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut2,*contentNotNull());
@@ -6556,7 +6565,7 @@ DataArrayInt *MEDFileIntField1TS::ReturnSafelyDataArrayInt(MEDCouplingAutoRefCou
  */
 MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol) const
 {
-  if(getFileName2().empty())
+  if(getFileName().empty())
     throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !");
   MEDCouplingAutoRefCountObjectPtr<DataArray> arr;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNull());
@@ -6652,7 +6661,7 @@ MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField ty
  */
 MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const
 {
-  if(getFileName2().empty())
+  if(getFileName().empty())
     throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !");
   MEDCouplingAutoRefCountObjectPtr<DataArray> arr;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNull());
@@ -8181,15 +8190,29 @@ void MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary()
 
 /*!
  * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false.
- * This method does not release arrays set outside the context of a MED file.
+ * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file.
+ * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss instead.
  * 
- * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary
+ * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary, MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss
  */
 void MEDFileAnyTypeFieldMultiTS::unloadArrays()
 {
   contentNotNullBase()->unloadArrays();
 }
 
+/*!
+ * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect.
+ * This method is the symetrical method of MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary.
+ * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database.
+ * 
+ * \sa MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary
+ */
+void MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss()
+{
+  if(!getFileName().empty())
+    contentNotNullBase()->unloadArrays();
+}
+
 std::string MEDFileAnyTypeFieldMultiTS::simpleRepr() const
 {
   std::ostringstream oss;
@@ -9639,9 +9662,10 @@ void MEDFileFields::loadArraysIfNecessary()
 
 /*!
  * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false.
- * This method does not release arrays set outside the context of a MED file.
+ * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file.
+ * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead.
  * 
- * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary
+ * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss
  */
 void MEDFileFields::unloadArrays()
 {
@@ -9653,6 +9677,19 @@ void MEDFileFields::unloadArrays()
     }
 }
 
+/*!
+ * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect.
+ * This method is the symetrical method of MEDFileFields::loadArraysIfNecessary.
+ * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database.
+ * 
+ * \sa MEDFileFields::loadArraysIfNecessary
+ */
+void MEDFileFields::unloadArraysWithoutDataLoss()
+{
+  if(!getFileName().empty())
+    unloadArrays();
+}
+
 std::vector<std::string> MEDFileFields::getPflsReallyUsed() const
 {
   std::vector<std::string> ret;
index 06f929f3b93cc566dd71b1eb4bfdc310734c3c30..c63f95cf85bbaa9c13bac9b135e80805a8d14693 100644 (file)
@@ -334,7 +334,6 @@ namespace ParaMEDMEM
     int getNbOfGaussPtPerCell(int locId) const;
     int getLocalizationId(const std::string& loc) const;
     std::string getFileName() const { return _file_name; }
-    std::string getFileName2() const { return _file_name; }
     const MEDFileFieldLoc& getLocalizationFromId(int locId) const;
     const MEDFileFieldLoc& getLocalization(const std::string& locName) const;
     const DataArrayInt *getProfileFromId(int pflId) const;
@@ -412,7 +411,6 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT int getNbOfGaussPtPerCell(int locId) const;
     MEDLOADER_EXPORT int getLocalizationId(const std::string& loc) const;
     MEDLOADER_EXPORT std::string getFileName() const;
-    MEDLOADER_EXPORT std::string getFileName2() const;
     MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalizationFromId(int locId) const;
     MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalization(const std::string& locName) const;
     MEDLOADER_EXPORT MEDFileFieldLoc& getLocalizationFromId(int locId);
@@ -665,6 +663,7 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT void loadArrays();
     MEDLOADER_EXPORT void loadArraysIfNecessary();
     MEDLOADER_EXPORT void unloadArrays();
+    MEDLOADER_EXPORT void unloadArraysWithoutDataLoss();
     MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitComponents() const;
     MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitDiscretizations() const;
     MEDLOADER_EXPORT MEDFileAnyTypeField1TS *deepCpy() const;
@@ -913,6 +912,7 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT void loadArrays();
     MEDLOADER_EXPORT void loadArraysIfNecessary();
     MEDLOADER_EXPORT void unloadArrays();
+    MEDLOADER_EXPORT void unloadArraysWithoutDataLoss();
     MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const;
     MEDLOADER_EXPORT void writeLL(med_idt fid) const;
     MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
@@ -1085,6 +1085,7 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT void loadArrays();
     MEDLOADER_EXPORT void loadArraysIfNecessary();
     MEDLOADER_EXPORT void unloadArrays();
+    MEDLOADER_EXPORT void unloadArraysWithoutDataLoss();
     MEDLOADER_EXPORT int getNumberOfFields() const;
     MEDLOADER_EXPORT std::vector< std::pair<int,int> > getCommonIterations(bool& areThereSomeForgottenTS) const;
     MEDLOADER_EXPORT std::vector<std::string> getFieldsNames() const;
index 7145ba888fc74d77d5d8645c4539ae48db244b72..63acae414dcfeca2b6017eaa6c84bfbf6a05833c 100644 (file)
@@ -1226,6 +1226,7 @@ namespace ParaMEDMEM
     void loadArrays() throw(INTERP_KERNEL::Exception);
     void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception);
     void unloadArrays() throw(INTERP_KERNEL::Exception);
+    void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception);
     int getDimension() const throw(INTERP_KERNEL::Exception);
     int getIteration() const throw(INTERP_KERNEL::Exception);
     int getOrder() const throw(INTERP_KERNEL::Exception);
@@ -1642,6 +1643,7 @@ namespace ParaMEDMEM
     void loadArrays() throw(INTERP_KERNEL::Exception);
     void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception);
     void unloadArrays() throw(INTERP_KERNEL::Exception);
+    void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception);
     //
     virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception);
     MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception);
@@ -2226,6 +2228,7 @@ namespace ParaMEDMEM
     void loadArrays() throw(INTERP_KERNEL::Exception);
     void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception);
     void unloadArrays() throw(INTERP_KERNEL::Exception);
+    void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception);
     void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception);
     int getNumberOfFields() const;
     std::vector<std::string> getFieldsNames() const throw(INTERP_KERNEL::Exception);
index 6aac69079980b0910af9555344fe75f09939098b..e148051ce18216e5f673e7d11f5a061a725a7e80 100644 (file)
@@ -3583,6 +3583,69 @@ class MEDLoaderTest(unittest.TestCase):
         self.assertEqual(mm.getMeshAtLevel(0).getName(),"abc")
         pass
 
+    def testMEDFileFieldsUnloadArraysWithoutDataLoss1(self):
+        fileName="Pyfile80.med"
+        m=MEDCouplingCMesh() ; m.setName("cmesh")
+        arr=DataArrayDouble(6) ; arr.iota()
+        m.setCoords(arr,arr)
+        nbCells=m.getNumberOfCells()
+        self.assertEqual(25,nbCells)
+        f=MEDCouplingFieldDouble(ON_CELLS)
+        f.setName("FieldOnCell") ; f.setMesh(m)
+        arr=DataArrayDouble(nbCells) ; arr.iota()
+        mm=MEDFileCMesh()
+        mm.setMesh(m)
+        #
+        fmts=MEDFileFieldMultiTS()
+        #
+        for i in xrange(nbCells):
+            t=(float(i)+0.1,i+1,-i-2)
+            f.setTime(*t)
+            arr2=DataArrayDouble(nbCells)
+            perm=DataArrayInt(nbCells) ; perm.iota(i) ; perm%=nbCells
+            arr2[perm]=arr
+            f.setArray(arr2)
+            f1ts=MEDFileField1TS()
+            f1ts.setFieldNoProfileSBT(f)
+            fmts.pushBackTimeStep(f1ts)
+            pass
+        fmts.unloadArraysWithoutDataLoss()
+        self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        fs=MEDFileFields() ; fs.pushField(fmts)
+        self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        fs.unloadArraysWithoutDataLoss()
+        self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        f1ts=fs[0][0]
+        self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        f1ts.unloadArraysWithoutDataLoss()
+        self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        mm.write(fileName,2)
+        fs.write(fileName,0)
+        del m,fmts,mm,f,f1ts
+        ##
+        mm=MEDFileMesh.New(fileName)
+        fmts=MEDFileFieldMultiTS(fileName)
+        self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        fmts.unloadArraysWithoutDataLoss()
+        self.assertTrue(not fmts[0].getUndergroundDataArray().isAllocated())
+        fmts.loadArraysIfNecessary()
+        self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        del mm,fmts
+        fs=MEDFileFields(fileName)
+        self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        fs.unloadArraysWithoutDataLoss()
+        self.assertTrue(not fs[0][0].getUndergroundDataArray().isAllocated())
+        fs.loadArraysIfNecessary()
+        self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        del fs
+        f1ts=MEDFileField1TS(fileName)
+        self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        f1ts.unloadArraysWithoutDataLoss()
+        self.assertTrue(not f1ts.getUndergroundDataArray().isAllocated())
+        f1ts.loadArraysIfNecessary()
+        self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
+        pass
+
     pass
 
 unittest.main()