]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
[EDF28448] : MEDFileUMesh.declarePartsUpdated and MEDFileField1TS context manager... V9_12_0a1 V9_12_0a2
authorAnthony Geay <anthony.geay@edf.fr>
Thu, 17 Aug 2023 13:55:09 +0000 (15:55 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Thu, 17 Aug 2023 13:55:09 +0000 (15:55 +0200)
src/MEDLoader/MEDFileField1TS.cxx
src/MEDLoader/MEDFileField1TS.hxx
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/MEDFileMeshLL.cxx
src/MEDLoader/MEDFileMeshLL.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest4.py

index 735ca45395918446561bb55b5d1089079bfdaa60..9287ec66f338dca5da7d7d8f43062b30b8350564 100644 (file)
@@ -2724,6 +2724,11 @@ try:MEDFileTemplateField1TS<double>(other,shallowCopyOfContent)
 catch(INTERP_KERNEL::Exception& e)
 { throw e; }
 
+MCAuto<MEDFileAnyTypeField1TS> MEDFileField1TS::buildNewEmpty() const
+{
+  return MCAuto<MEDFileAnyTypeField1TS>(MEDFileField1TS::New());
+}
+
 MEDFileField1TS *MEDFileField1TS::shallowCpy() const
 {
   return new MEDFileField1TS(*this);
@@ -2737,6 +2742,11 @@ std::vector< std::vector<DataArrayDouble *> > MEDFileField1TS::getFieldSplitedBy
 
 //= MEDFileInt32Field1TS
 
+MCAuto<MEDFileAnyTypeField1TS> MEDFileInt32Field1TS::buildNewEmpty() const
+{
+  return MCAuto<MEDFileAnyTypeField1TS>(MEDFileInt32Field1TS::New());
+}
+
 MCAuto<MEDCouplingFieldDouble> MEDFileInt32Field1TS::ConvertFieldIntToFieldDouble(const MEDCouplingFieldInt32 *f)
 {
   if(!f)
@@ -2752,6 +2762,11 @@ MCAuto<MEDCouplingFieldDouble> MEDFileInt32Field1TS::ConvertFieldIntToFieldDoubl
 
 //= MEDFileInt64Field1TS
 
+MCAuto<MEDFileAnyTypeField1TS> MEDFileInt64Field1TS::buildNewEmpty() const
+{
+  return MCAuto<MEDFileAnyTypeField1TS>(MEDFileInt64Field1TS::New());
+}
+
 MCAuto<MEDCouplingFieldDouble> MEDFileInt64Field1TS::ConvertFieldIntToFieldDouble(const MEDCouplingFieldInt64 *f)
 {
   if(!f)
@@ -2765,3 +2780,9 @@ MCAuto<MEDCouplingFieldDouble> MEDFileInt64Field1TS::ConvertFieldIntToFieldDoubl
   return ret;
 }
 
+//= MEDFileFloatField1TS
+
+MCAuto<MEDFileAnyTypeField1TS> MEDFileFloatField1TS::buildNewEmpty() const
+{
+  return MCAuto<MEDFileAnyTypeField1TS>(MEDFileFloatField1TS::New());
+}
index 11117d97e76bb2784a63f855e07987338b8c8dd2..223c38f6f22eaa8669aca8b72cb50d5628c85a9a 100644 (file)
@@ -295,6 +295,7 @@ namespace MEDCoupling
     MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *NewAdv(med_idt fid, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileEntities *entities);
     MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *NewAdv(med_idt fid, const std::string& fieldName, int iteration, int order, const MEDFileEntities *entities, const std::vector<mcIdType>& distrib);
 
+    MEDLOADER_EXPORT virtual MCAuto<MEDFileAnyTypeField1TS> buildNewEmpty() const = 0;
     MEDLOADER_EXPORT int getDimension() const;
     MEDLOADER_EXPORT int getIteration() const;
     MEDLOADER_EXPORT int getOrder() const;
@@ -424,6 +425,7 @@ namespace MEDCoupling
     MEDLOADER_EXPORT MEDFileInt32Field1TS *convertToInt(bool isDeepCpyGlobs=true) const;
     MEDLOADER_EXPORT MEDFileInt64Field1TS *convertToInt64(bool isDeepCpyGlobs=true) const;
   public:
+    MEDLOADER_EXPORT MCAuto<MEDFileAnyTypeField1TS> buildNewEmpty() const;
     MEDLOADER_EXPORT MEDFileField1TS *shallowCpy() const;
     MEDLOADER_EXPORT std::vector< std::vector<DataArrayDouble *> > getFieldSplitedByType2(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF,
                                                                                           std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const;
@@ -460,6 +462,7 @@ namespace MEDCoupling
   {
     friend class MEDFileTemplateField1TS<Int32>;
   public:
+    MEDLOADER_EXPORT MCAuto<MEDFileAnyTypeField1TS> buildNewEmpty() const;
     MEDLOADER_EXPORT MEDFileInt32Field1TS *shallowCpy() const { return new MEDFileInt32Field1TS(*this); }
     MEDLOADER_EXPORT std::string getClassName() const override { return std::string("MEDFileInt32Field1TS"); }
   public:
@@ -485,6 +488,7 @@ namespace MEDCoupling
   {
     friend class MEDFileTemplateField1TS<Int64>;
   public:
+    MEDLOADER_EXPORT MCAuto<MEDFileAnyTypeField1TS> buildNewEmpty() const;
     MEDLOADER_EXPORT MEDFileInt64Field1TS *shallowCpy() const { return new MEDFileInt64Field1TS(*this); }
     MEDLOADER_EXPORT std::string getClassName() const override { return std::string("MEDFileInt64Field1TS"); }
   public:
@@ -513,6 +517,7 @@ namespace MEDCoupling
     med_field_type getMEDFileFieldType() const { return MED_FLOAT32; }
     MEDLOADER_EXPORT MEDFileFloatField1TS *shallowCpy() const { return new MEDFileFloatField1TS(*this); }
     MEDLOADER_EXPORT std::string getClassName() const override { return std::string("MEDFileFloatField1TS"); }
+    MEDLOADER_EXPORT MCAuto<MEDFileAnyTypeField1TS> buildNewEmpty() const;
   private:
     ~MEDFileFloatField1TS() { }
     MEDFileFloatField1TS() { }
index 4de31cc17a970646420b1d0edeaff5cf34b6b030..67b4aa6675111d563e851c0e3c4ebb98f13c16f2 100644 (file)
@@ -3904,11 +3904,27 @@ MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
   return getMeshAtLevel(-3,renum);
 }
 
+/*!
+ * This method inform datastructure that vector of MEDCoupling1GTUMesh instances have been touched.
+ * So the version of data to take is vector of MEDCoupling1GTUMesh not MEDCouplingUMesh
+ */
+void MEDFileUMesh::declarePartsUpdated() const
+{
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+    {
+      const MEDFileUMeshSplitL1 *elt(*it);
+      if(elt)
+        elt->declarePartsUpdated();
+    }
+}
+
 /*!
  * This method is for advanced users. There is two storing strategy of mesh in \a this.
  * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
  * When assignment is done the first one is done, which is not optimal in write mode for MED file.
  * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
+ * 
+ * \sa MEDFileUMesh::declarePartsUpdated
  */
 void MEDFileUMesh::forceComputationOfParts() const
 {
index 2cdbaa0f7e6693b6fd52c48ca254622a732aa1aa..4e53ede52f69fd2a5987a02324719149a669a796 100644 (file)
@@ -336,6 +336,7 @@ MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<Data
     MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const;
     MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const;
     MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const;
+    MEDLOADER_EXPORT void declarePartsUpdated() const;
     MEDLOADER_EXPORT void forceComputationOfParts() const;
     MEDLOADER_EXPORT void computeRevNum() const;
     MEDLOADER_EXPORT std::vector<MEDCoupling1GTUMesh *> getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const;
index 030debd0c7196292b97b8fae2736dd858f5d4be5..eec65e3a387ae8e9b8fd82675aee1669e1b14ae4 100644 (file)
@@ -1387,6 +1387,11 @@ void MEDFileUMeshSplitL1::forceComputationOfParts() const
   _m_by_types.forceComputationOfPartsFromUMesh();
 }
 
+void MEDFileUMeshSplitL1::declarePartsUpdated() const
+{
+  _m_by_types.declarePartsUpdated();
+}
+
 void MEDFileUMeshSplitL1::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts)
 {
   _m_by_types.assignParts(mParts);
@@ -1968,6 +1973,12 @@ void MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh() const
   _mp_time=std::max(_mp_time,_m_time);
 }
 
+void MEDFileUMeshAggregateCompute::declarePartsUpdated() const
+{
+  _mp_time=std::max(_mp_time,_m_time) + 1;
+  _m.nullify();
+}
+
 const PartDefinition *MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const
 {
   if(_mp_time<_m_time)
index 737ad23c02860e63a7aa60a66e81d99b058b524f..e33e187351d264fe28371ae5b45422620da22a67 100644 (file)
@@ -249,6 +249,7 @@ MCAuto<DataArrayDouble>& _coords, MCAuto<DataArrayIdType>& _fam_coords, MCAuto<D
     mcIdType getSize() const;
     void setCoords(DataArrayDouble *coords);
     void forceComputationOfPartsFromUMesh() const;
+    void declarePartsUpdated() const;
     const PartDefinition *getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const;
     void serialize(std::vector<mcIdType>& tinyInt, std::vector< MCAuto<DataArrayIdType> >& bigArraysI) const;
     void unserialize(const std::string& name, DataArrayDouble *coo, std::vector<mcIdType>& tinyInt, std::vector< MCAuto<DataArrayIdType> >& bigArraysI);
@@ -287,6 +288,7 @@ MCAuto<DataArrayDouble>& _coords, MCAuto<DataArrayIdType>& _fam_coords, MCAuto<D
     void assignMesh(MEDCouplingUMesh *m, bool newOrOld);
     void assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts);
     void forceComputationOfParts() const;
+    void declarePartsUpdated() const;
     bool empty() const;
     bool presenceOfOneFams(const std::vector<mcIdType>& ids) const;
     int getMeshDimension() const;
index b7c4eb64550cc75f1a497d2de806d5c0867d9b59..bebf5cc0d8d9cadf1e553dcc29ec9fc393e51c09 100644 (file)
@@ -223,6 +223,7 @@ using namespace MEDCoupling;
 %newobject MEDCoupling::MEDFileAnyTypeField1TS::shallowCpy;
 %newobject MEDCoupling::MEDFileAnyTypeField1TS::deepCopy;
 %newobject MEDCoupling::MEDFileAnyTypeField1TS::extractPart;
+%newobject MEDCoupling::MEDFileAnyTypeField1TS::buildNewEmpty;
 %newobject MEDCoupling::MEDFileField1TS::New;
 %newobject MEDCoupling::MEDFileField1TS::field;
 %newobject MEDCoupling::MEDFileField1TS::getFieldAtLevel;
@@ -1453,6 +1454,7 @@ namespace MEDCoupling
     MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const;
     MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const;
     MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const;
+    void declarePartsUpdated() const;
     void forceComputationOfParts() const;
     void computeRevNum() const;
     //
@@ -2212,6 +2214,12 @@ namespace MEDCoupling
         return elt;
       }
 
+      MEDFileAnyTypeField1TS *buildNewEmpty() const
+      {
+        MCAuto<MEDFileAnyTypeField1TS> ret = self->buildNewEmpty();
+        return ret.retn();
+      }
+
       void setProfileNameOnLeaf(INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false)
       {
         self->setProfileNameOnLeaf(0,typ,locId,newPflName,forceRenameOnGlob);
@@ -4405,10 +4413,10 @@ namespace MEDCoupling
 
 %pythoncode %{
 def enter1TS(self):
-    self.loadArrays()
+    self.loadArraysIfNecessary()
     pass
 def exit1TS(self, exctype, exc, tb):
-    self.unloadArrays()
+    self.unloadArraysWithoutDataLoss()
     pass
 MEDFileAnyTypeField1TS.__enter__=enter1TS
 MEDFileAnyTypeField1TS.__exit__=exit1TS
index e75d18a87faebcbf6dc207c687454dc33e4784ac..2bb28a80bd32a758979692f7cd96a6daa3c48b69 100644 (file)
@@ -5716,6 +5716,58 @@ class MEDLoaderTest4(unittest.TestCase):
         m.mergeNodes(1e-5) # coords into m has been modified so coords of mm and m mismatches
         self.assertRaises(InterpKernelException,mm.write,fname,2) # write fails due to mismatch of number of tuples of coords of mm and those of m
 
+    def test47(self):
+        """
+        [EDF28448] : MEDFileUMesh.declarePartsUpdated
+        """
+        m = MEDCouplingUMesh("mesh",2)
+        m.setCoords(DataArrayDouble([(0,0,0)]))
+        m.allocateCells()
+        m.insertNextCell(NORM_QUAD4,[2,3,5,6])
+        mm = MEDFileUMesh()
+        mm[0] = m
+        #
+        mm.forceComputationOfParts()
+        mtest = mm.getDirectUndergroundSingleGeoTypeMeshes(0)[0]
+        self.assertTrue( mtest.getNodalConnectivity().isEqual(DataArrayInt([2,3,5,6])) )
+        # change content of data in parts
+        mtest.getNodalConnectivity()[:] += 1
+        self.assertTrue( mtest.getNodalConnectivity().isEqual(DataArrayInt([3,4,6,7])) )
+        self.assertTrue( mm[0].getNodalConnectivity().isEqual(DataArrayInt([NORM_QUAD4,2,3,5,6])) ) # <- oops UMesh is now not updated !
+        mm.declarePartsUpdated() # invoke declarePartsUpdated to tell mm that something has changed ASTGUMesh vector parts and this is now the correct version
+        self.assertTrue( mm[0].getNodalConnectivity().isEqual(DataArrayInt([NORM_QUAD4,3,4,6,7])) ) # parts and umesh are now synchronized
+
+    @WriteInTmpDir
+    def test48(self):
+        """
+        [EDF28448] : MEDFileField1TS context manager deal with file and not file situation indifferently
+        """
+        fname = "test48.med"
+        m = MEDCouplingUMesh("mesh",2)
+        m.setCoords(DataArrayDouble([(0,0,0)]))
+        m.allocateCells()
+        m.insertNextCell(NORM_QUAD4,[2,3,5,6])
+        mm = MEDFileUMesh()
+        mm[0] = m
+        # now test context manager 
+        fmts = MEDFileFieldMultiTS()
+        f1ts = MEDFileField1TS()
+        f = MEDCouplingFieldDouble(ON_CELLS) ; f.setName("Field") ; f.setMesh(mm[0]) ; f.setArray(DataArrayDouble([0.123]))
+        f1ts.setFieldNoProfileSBT(f)
+        fmts.pushBackTimeStep(f1ts)
+        with f1ts:
+            self.assertEqual( f1ts.getTypesOfFieldAvailable() , [ON_CELLS] )
+            self.assertTrue( f1ts.getUndergroundDataArray().isEqual( DataArrayDouble([0.123]), 1e-12) )
+        self.assertTrue( f1ts.getUndergroundDataArray().isEqual( DataArrayDouble([0.123]), 1e-12) )
+        f1ts.write(fname,2)
+        fs_read = MEDFileFields(fname,False)
+        f1ts_read = fs_read[0][0]
+        self.assertEqual( f1ts_read.getTypesOfFieldAvailable() , [ON_CELLS] )
+        self.assertTrue(not f1ts_read.getUndergroundDataArray().isAllocated())
+        with f1ts_read:
+            self.assertTrue(f1ts_read.getUndergroundDataArray().isAllocated())
+        self.assertTrue(not f1ts_read.getUndergroundDataArray().isAllocated())
+
     pass
 
 if __name__ == "__main__":