]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
[EDF27364] : Partial connectivity only extraction of cells of a mesh (MEDFileUMesh...
authorAnthony Geay <anthony.geay@edf.fr>
Wed, 15 Mar 2023 09:52:41 +0000 (10:52 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Wed, 15 Mar 2023 14:39:49 +0000 (15:39 +0100)
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/MEDFileMeshLL.cxx
src/MEDLoader/MEDFileMeshLL.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py

index 8bed8693955aff1625fc29849116cf1f26c2c437..4f2bab9370c331390cde18b77e6113756aea68fc 100644 (file)
@@ -2468,6 +2468,41 @@ MEDFileUMesh *MEDFileUMesh::New()
   return new MEDFileUMesh;
 }
 
+/*!
+ * Please refer to the other MEDFileUMesh::LoadConnectivityOnlyPartOf method that has the same semantic and the same parameter (excepted the first).
+ * This method is \b NOT wrapped into python.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::LoadConnectivityOnlyPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,[](MEDFileUMeshL2& loader,med_idt fid, MeshOrStructMeshCls *mid,const std::string& mName,const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>&slicPerTyp,int dt,int it,MEDFileMeshReadSelector *mrs){ int Mdim; loader.loadPartConnectivityOnly(fid,mid,mName,types,slicPerTyp,dt,it,mrs,Mdim); },dt,it,mrs);
+  return ret;
+}
+
+/*!
+ * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
+ * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
+ * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
+ * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
+ * at most the memory consumtion. Contrary to MEDFileUMesh::LoadPart this method does not load coordinates but only connectivities
+ *
+ * \param [in] fileName - the name of the file.
+ * \param [in] mName - the name of the mesh to be read.
+ * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
+ * \param [in] slicPerTyp - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
+ * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
+ * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
+ * \param [in] mrs - the request for what to be loaded.
+ * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
+ * \sa MEDFileUMesh::LoadPartOf
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::LoadConnectivityOnlyPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
+  return MEDFileUMesh::LoadConnectivityOnlyPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
+}
+
 /*!
  * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
  * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
@@ -2483,6 +2518,7 @@ MEDFileUMesh *MEDFileUMesh::New()
  * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
  * \param [in] mrs - the request for what to be loaded.
  * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
+ * \sa MEDFileUMesh::LoadConnectivityOnlyPartOf
  */
 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
@@ -2498,7 +2534,7 @@ MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::s
 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
-  ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
+  ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,[](MEDFileUMeshL2& loader,med_idt fid, MeshOrStructMeshCls *mid,const std::string& mName,const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>&slicPerTyp,int dt,int it,MEDFileMeshReadSelector *mrs){ loader.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); },dt,it,mrs);
   return ret.retn();
 }
 
@@ -2872,7 +2908,8 @@ catch(INTERP_KERNEL::Exception& e)
  *
  * \sa loadLL
  */
-void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp,
+std::function<void(MEDFileUMeshL2&,med_idt fid, MeshOrStructMeshCls *,const std::string&, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>&,int,int,MEDFileMeshReadSelector *)> functorOnUMeshL2, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUMeshL2 loaderl2;
   MEDCoupling::MEDCouplingMeshType meshType;
@@ -2885,7 +2922,7 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName,
       std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
+  functorOnUMeshL2(loaderl2,fid,mid,mName,types,slicPerTyp,dt,it,mrs);
   dispatchLoadedPart(fid,loaderl2,mName,mrs);
 }
 
index 171f6aab2024e1630059d6312d47c181e3e14fb9..69e02e815b4b7dc9ee6f567f30bc40ef43b4f71b 100644 (file)
@@ -269,8 +269,10 @@ namespace MEDCoupling
     MEDLOADER_EXPORT static MEDFileUMesh *New(const MEDCouplingMappedExtrudedMesh *mem);
     MEDLOADER_EXPORT static MEDFileUMesh *New();
     MEDLOADER_EXPORT std::string getClassName() const override { return std::string("MEDFileUMesh"); }
-    MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
-    MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
+    MEDLOADER_EXPORT static MCAuto<MEDFileUMesh> LoadConnectivityOnlyPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=nullptr);
+    MEDLOADER_EXPORT static MCAuto<MEDFileUMesh> LoadConnectivityOnlyPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=nullptr);
+    MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=nullptr);
+    MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=nullptr);
     MEDLOADER_EXPORT static void LoadPartCoords(const std::string& fileName, const std::string& mName, int dt, int it, const std::vector<std::string>& infosOnComp, mcIdType startNodeId, mcIdType stopNodeId,
 MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<DataArrayIdType>& famCoords, MCAuto<DataArrayIdType>& numCoords, MCAuto<DataArrayAsciiChar>& nameCoords);
     MEDLOADER_EXPORT static const char *GetSpeStr4ExtMesh() { return SPE_FAM_STR_EXTRUDED_MESH; }
@@ -381,7 +383,7 @@ MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<Data
     void writeMeshLL(med_idt fid) const;
     MEDFileUMesh();
     MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
-    void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
+    void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, std::function<void(MEDFileUMeshL2&,med_idt fid, MeshOrStructMeshCls*,const std::string&,const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>&,int,int,MEDFileMeshReadSelector *)> functorOnUMeshL2, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
     void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
     void dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs);
     const MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) const;
index 656955a1c153ef01249fc0824ef4918bbfd33550..18d3e5931cfc2212971485ad67ffdb7f9b02a48c 100644 (file)
@@ -547,13 +547,14 @@ void MEDFileUMeshL2::loadAll(med_idt fid, const MeshOrStructMeshCls *mId, const
   loadCoords(fid,infosOnComp,mName,dt,it);
 }
 
-void MEDFileUMeshL2::loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+/*!
+ * This method is expected to be invoked after the load of connectivity.
+ * This method is in charge of :
+ *  - dealing with optimized load of coordinates (loading only points fetched by the already loaded cells)
+ *  - update the connectivity in \a this to fit the coordinates loaded just above
+ */
+void MEDFileUMeshL2::dealWithCoordsInLoadPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<std::string>& infosOnComp, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  int Mdim;
-  std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
-  if(Mdim==-4)
-    return ;
-  loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs);
   med_bool changement,transformation;
   mcIdType nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
   std::vector<bool> fetchedNodeIds(nCoords,false);
@@ -582,6 +583,25 @@ void MEDFileUMeshL2::loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const
   }
 }
 
+std::vector<std::string> MEDFileUMeshL2::loadPartConnectivityOnly(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs, int& Mdim)
+{
+  std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
+  if(Mdim==-4)
+    return infosOnComp;
+  loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs);
+  return infosOnComp;
+}
+
+void MEDFileUMeshL2::loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  int Mdim;
+  std::vector<std::string> infosOnComp(loadPartConnectivityOnly(fid,mId,mName,types,slicPerTyp,dt,it,mrs,Mdim));
+  if(Mdim==-4)
+    return ;
+  loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs);
+  dealWithCoordsInLoadPart(fid,mId,mName,infosOnComp,types,slicPerTyp,dt,it,mrs);
+}
+
 void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   _per_type_mesh.resize(1);
index c79c371c8cc9c015e34b26557d2b0496db81bb01..94a34a2d1b0f10acce750f9422efbdacc24bcde8 100644 (file)
@@ -121,6 +121,8 @@ namespace MEDCoupling
     std::vector<std::string> loadCommonPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, int dt, int it, int& Mdim);
     void loadAll(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
     void loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs);
+    void dealWithCoordsInLoadPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<std::string>& infosOnComp, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs);
+    std::vector<std::string> loadPartConnectivityOnly(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs, int& Mdim);
     void loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
     void loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs);
     void loadCoords(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it);
index 9bfac569fb47570dc47f0f33c6ca4cc8ba532486..abf4561ea124665a7bff746cbd9c27cc8c2fc485 100644 (file)
@@ -108,6 +108,7 @@ using namespace MEDCoupling;
 %newobject MEDCoupling::MEDFileData::getJoints;
 %newobject MEDCoupling::MEDFileStructuredMesh::getImplicitFaceMesh;
 %newobject MEDCoupling::MEDFileUMesh::New;
+%newobject MEDCoupling::MEDFileUMesh::LoadConnectivityOnlyPartOf;
 %newobject MEDCoupling::MEDFileUMesh::LoadPartOf;
 %newobject MEDCoupling::MEDFileUMesh::getCoords;
 %newobject MEDCoupling::MEDFileUMesh::getPartDefAtLevel;
@@ -1497,6 +1498,17 @@ namespace MEDCoupling
          {
            return MEDFileUMesh::New();
          }
+         
+         static MEDFileUMesh *LoadConnectivityOnlyPartOf(const std::string& fileName, const std::string& mName, PyObject *types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0)
+         {
+           std::vector<int> typesCpp1;
+           convertPyToNewIntArr3(types,typesCpp1);
+           std::size_t sz(typesCpp1.size());
+           std::vector<INTERP_KERNEL::NormalizedCellType> typesCpp2(sz);
+           for(std::size_t ii=0;ii<sz;ii++)
+             typesCpp2[ii]=(INTERP_KERNEL::NormalizedCellType)typesCpp1[ii];
+           return MEDFileUMesh::LoadConnectivityOnlyPartOf(fileName,mName,typesCpp2,slicPerTyp,dt,it,mrs).retn();
+         }
 
          static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, PyObject *types, const std::vector<mcIdType>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0)
          {
index c0556b16b5a6213218b780aec41b3affb93cde35..ad0f08eab0cbcf3230e010a4632d9d08eb4aa972 100644 (file)
@@ -4333,6 +4333,23 @@ class MEDLoaderTest3(unittest.TestCase):
         arr = DataArrayDouble(21, 2) ; arr[:, 0] = list(range(203, 224)) ; arr[:, 1] = list(range(303, 324))
         arr.setInfoOnComponents(compos)
         self.assertTrue(fs[1][0].getUndergroundDataArray().isEqual(arr,1e-12))
+        # [EDF27364] : test of LoadConnectivityOnlyPartOf
+        mm3=MEDFileUMesh.LoadConnectivityOnlyPartOf(fileName,meshName,[NORM_QUAD4],[0,6,1])
+        mm3.forceComputationOfParts()
+        m3s = mm3.getDirectUndergroundSingleGeoTypeMeshes(0)
+        self.assertEqual( len(m3s), 1 )
+        m3s = m3s[0]
+        self.assertTrue( m3s.getCoords() is None )
+        self.assertEqual( m3s.getCellModelEnum() , NORM_QUAD4 )
+        self.assertTrue( m3s.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13])) )
+        mm4 = MEDFileUMesh.LoadConnectivityOnlyPartOf(fileName,meshName,[NORM_QUAD4],[3,15,1])
+        mm4.forceComputationOfParts()
+        m4s = mm4.getDirectUndergroundSingleGeoTypeMeshes(0)
+        self.assertEqual( len(m4s), 1 )
+        m4s = m4s[0]
+        self.assertTrue( m4s.getCoords() is None )
+        self.assertEqual( m4s.getCellModelEnum() , NORM_QUAD4 )
+        self.assertTrue( m4s.getNodalConnectivity().isEqual(DataArrayInt([4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17,13,12,18,19,14,13,19,20,15,14,20,21,16,15,21,22,17,16,22,23])) )
         pass
 
     @WriteInTmpDir