From: Anthony Geay Date: Wed, 15 Mar 2023 09:52:41 +0000 (+0100) Subject: [EDF27364] : Partial connectivity only extraction of cells of a mesh (MEDFileUMesh... X-Git-Tag: V9_11_0a1~7 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=06f4a5b378e649182161d639b3a05ead43eba660;p=tools%2Fmedcoupling.git [EDF27364] : Partial connectivity only extraction of cells of a mesh (MEDFileUMesh.LoadConnectivityOnlyPartOf) --- diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 8bed86939..4f2bab937 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -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::LoadConnectivityOnlyPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MCAuto ret(MEDFileUMesh::New()); + ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,[](MEDFileUMeshL2& loader,med_idt fid, MeshOrStructMeshCls *mid,const std::string& mName,const std::vector& types, const std::vector&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::LoadConnectivityOnlyPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& 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& types, const std::vector& 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& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) { MCAuto 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& types, const std::vector&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& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, +std::function& types, const std::vector&,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); } diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index 171f6aab2..69e02e815 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -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& types, const std::vector& 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& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MCAuto LoadConnectivityOnlyPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=nullptr); + MEDLOADER_EXPORT static MCAuto LoadConnectivityOnlyPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& 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& types, const std::vector& 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& types, const std::vector& 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& infosOnComp, mcIdType startNodeId, mcIdType stopNodeId, MCAuto& coords, MCAuto& partCoords, MCAuto& famCoords, MCAuto& numCoords, MCAuto& nameCoords); MEDLOADER_EXPORT static const char *GetSpeStr4ExtMesh() { return SPE_FAM_STR_EXTRUDED_MESH; } @@ -381,7 +383,7 @@ MCAuto& coords, MCAuto& partCoords, MCAuto& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, std::function& types, const std::vector&,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; diff --git a/src/MEDLoader/MEDFileMeshLL.cxx b/src/MEDLoader/MEDFileMeshLL.cxx index 656955a1c..18d3e5931 100644 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ b/src/MEDLoader/MEDFileMeshLL.cxx @@ -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& types, const std::vector& 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& infosOnComp, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) { - int Mdim; - std::vector 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 fetchedNodeIds(nCoords,false); @@ -582,6 +583,25 @@ void MEDFileUMeshL2::loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const } } +std::vector MEDFileUMeshL2::loadPartConnectivityOnly(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs, int& Mdim) +{ + std::vector 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& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + int Mdim; + std::vector 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); diff --git a/src/MEDLoader/MEDFileMeshLL.hxx b/src/MEDLoader/MEDFileMeshLL.hxx index c79c371c8..94a34a2d1 100644 --- a/src/MEDLoader/MEDFileMeshLL.hxx +++ b/src/MEDLoader/MEDFileMeshLL.hxx @@ -121,6 +121,8 @@ namespace MEDCoupling std::vector 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& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); + void dealWithCoordsInLoadPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector& infosOnComp, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); + std::vector loadPartConnectivityOnly(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector& types, const std::vector& 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& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); void loadCoords(med_idt fid, const std::vector& infosOnComp, const std::string& mName, int dt, int it); diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index 9bfac569f..abf4561ea 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -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& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) + { + std::vector typesCpp1; + convertPyToNewIntArr3(types,typesCpp1); + std::size_t sz(typesCpp1.size()); + std::vector typesCpp2(sz); + for(std::size_t ii=0;ii& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) { diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index c0556b16b..ad0f08eab 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -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