From e103384d7fe69e78616ae26038a33a175596b7c1 Mon Sep 17 00:00:00 2001 From: Anida Khizar Date: Thu, 16 Mar 2023 10:59:41 +0100 Subject: [PATCH] [Partial load] Allowing partial load of meshes with multiple geometrical types --- src/MEDLoader/MEDFileMesh.cxx | 8 ++-- src/MEDLoader/MEDFileMesh.hxx | 4 +- src/MEDLoader/MEDFileMeshLL.cxx | 43 ++++++++++--------- src/MEDLoader/MEDFileMeshLL.hxx | 4 +- src/ParaMEDLoader/ParaMEDFileMesh.cxx | 27 ++++++------ src/ParaMEDLoader/ParaMEDFileMesh.hxx | 6 ++- .../ParaMEDMEMTest_MEDLoader.cxx | 7 ++- 7 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index d6c47707f..2da4f8c74 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -2515,10 +2515,10 @@ MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, co * \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. */ -MEDFileUMesh *MEDFileUMesh::LoadPartOfFromUserDistrib(med_idt fid, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileUMesh *MEDFileUMesh::LoadPartOfFromUserDistrib(med_idt fid, const std::string& mName, const std::map>& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) { MCAuto ret(MEDFileUMesh::New()); - ret->loadPartUMeshFromFileFromUserDistrib(fid,mName,type,distrib,dt,it,mrs); + ret->loadPartUMeshFromFileFromUserDistrib(fid,mName,distrib,dt,it,mrs); return ret.retn(); } @@ -2915,7 +2915,7 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, * * \sa loadLL */ -void MEDFileUMesh::loadPartUMeshFromFileFromUserDistrib(med_idt fid, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileUMesh::loadPartUMeshFromFileFromUserDistrib(med_idt fid, const std::string& mName, const std::map>& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUMeshL2 loaderl2; MEDCoupling::MEDCouplingMeshType meshType; @@ -2928,7 +2928,7 @@ void MEDFileUMesh::loadPartUMeshFromFileFromUserDistrib(med_idt fid, const std:: std::ostringstream oss; oss << "loadPartUMeshFromFileFromUserDistrib : Trying to load as unstructured an existing mesh with name '" << mName << "' !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - loaderl2.loadPartFromUserDistrib(fid,mid,mName,type,distrib,dt,it,mrs); + loaderl2.loadPartFromUserDistrib(fid,mid,mName,distrib,dt,it,mrs); dispatchLoadedPart(fid,loaderl2,mName,mrs); } diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index 9b8820f5f..24b3e0459 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -271,7 +271,7 @@ namespace MEDCoupling 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 MEDFileUMesh *LoadPartOfFromUserDistrib(med_idt fid, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOfFromUserDistrib(med_idt fid, const std::string& mName, const std::map>& distrib, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); 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; } @@ -383,7 +383,7 @@ MCAuto& coords, MCAuto& partCoords, MCAuto& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - void loadPartUMeshFromFileFromUserDistrib(med_idt fid, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + void loadPartUMeshFromFileFromUserDistrib(med_idt fid, const std::string& mName, const std::map>& distrib, 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 3bc9116a8..b2ea8df34 100644 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ b/src/MEDLoader/MEDFileMeshLL.cxx @@ -588,7 +588,7 @@ void MEDFileUMeshL2::loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const * First, we load the connectivity of nodes. Second, we load coordinates of nodes lying in the specified cells. * \throw exception if multiple load sessions are requested */ -void MEDFileUMeshL2::loadPartFromUserDistrib(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileUMeshL2::loadPartFromUserDistrib(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::map>& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) { int Mdim; std::vector infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim)); @@ -596,36 +596,32 @@ void MEDFileUMeshL2::loadPartFromUserDistrib(med_idt fid, const MeshOrStructMesh return ; /* First step : loading connectivity of nodes, ie building a new mesh of one geometrical type with only the specified cells in distrib */ - loadPartOfConnectivityFromUserDistrib(fid,Mdim,mName,type,distrib,dt,it,mrs); + loadPartOfConnectivityFromUserDistrib(fid,Mdim,mName,distrib,dt,it,mrs); /* Second step : loading nodes */ 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); - MEDCoupling1GTUMesh *mesh = _per_type_mesh[0][0/*only one type in our case*/]->getMesh(); - // for each node in the original mesh, which ones are laying on the partial mesh defined above - mesh->computeNodeIdsAlg(fetchedNodeIds); + for(std::vector< std::vector< MCAuto > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) + for(std::vector< MCAuto >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds); // for each node in the original mesh, which ones are laying on the current single geometrical type partial mesh if(!mrs || mrs->getNumberOfCoordsLoadSessions()==1) { - std::vector distribNodes; - for(mcIdType i=0; i > o2n(MapKeyVal::New()); - std::map& mapO2N(o2n->data()); - for(mcIdType node=0; noderenumberNodesInConn(mapO2N); + MCAuto fni(DataArrayIdType::BuildListOfSwitchedOn(fetchedNodeIds)); + MCAuto< MapKeyVal > o2n(fni->invertArrayN2O2O2NOptimized()); + for(std::vector< std::vector< MCAuto > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) + for(std::vector< MCAuto >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + (*it1)->getMesh()->renumberNodesInConn(o2n->data()); + // loading coordinates of fetched nodes + std::vector distribNodes; + for(std::map::const_iterator mapIter = o2n->data().begin(); mapIter != o2n->data().end(); ++mapIter) + distribNodes.push_back(mapIter->first); this->loadPartCoords(fid,infosOnComp,mName,dt,it,distribNodes); } else @@ -668,12 +664,17 @@ void MEDFileUMeshL2::loadPartOfConnectivity(med_idt fid, int mdim, const std::st * This method builds a new mesh of single geometrical type based on the partition of cells \a distrib, from mesh \a mName in file \a fid. * This distribution is not necessarily a slice. */ -void MEDFileUMeshL2::loadPartOfConnectivityFromUserDistrib(med_idt fid, int mdim, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileUMeshL2::loadPartOfConnectivityFromUserDistrib(med_idt fid, int mdim, const std::string& mName, const std::map>& distrib, int dt, int it, MEDFileMeshReadSelector *mrs) { _per_type_mesh.resize(1); _per_type_mesh[0].clear(); - MCAuto tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,type,distrib,mrs)); - _per_type_mesh[0].push_back(tmp); + std::map>::const_iterator iter; + for (iter = distrib.begin(); iter != distrib.end(); iter++) + { + MCAuto tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,iter->first/*type*/,iter->second/*distrib over the current type*/,mrs)); + _per_type_mesh[0].push_back(tmp); + } + sortTypes(); } void MEDFileUMeshL2::loadCoords(med_idt fid, const std::vector& infosOnComp, const std::string& mName, int dt, int it) diff --git a/src/MEDLoader/MEDFileMeshLL.hxx b/src/MEDLoader/MEDFileMeshLL.hxx index 9efa9f3b5..95246ff2d 100644 --- a/src/MEDLoader/MEDFileMeshLL.hxx +++ b/src/MEDLoader/MEDFileMeshLL.hxx @@ -121,11 +121,11 @@ 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 loadPartFromUserDistrib(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadPartFromUserDistrib(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::map>& distrib, int dt, int it, MEDFileMeshReadSelector *mrs); 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 loadPartOfConnectivityFromUserDistrib(med_idt fid, int mdim, const std::string& mName, INTERP_KERNEL::NormalizedCellType type, const std::vector& distrib, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadPartOfConnectivityFromUserDistrib(med_idt fid, int mdim, const std::string& mName, const std::map>& distrib, int dt, int it, MEDFileMeshReadSelector *mrs); void loadCoords(med_idt fid, const std::vector& infosOnComp, const std::string& mName, int dt, int it); void loadPartCoords(med_idt fid, const std::vector& infosOnComp, const std::string& mName, int dt, int it, mcIdType nMin, mcIdType nMax); diff --git a/src/ParaMEDLoader/ParaMEDFileMesh.cxx b/src/ParaMEDLoader/ParaMEDFileMesh.cxx index 7ff676952..91972cccd 100644 --- a/src/ParaMEDLoader/ParaMEDFileMesh.cxx +++ b/src/ParaMEDLoader/ParaMEDFileMesh.cxx @@ -132,7 +132,7 @@ MEDFileUMesh *ParaMEDFileUMesh::New(int iPart, int nbOfParts, const std::string& * \throw exception if the mesh contains multiple types of cells * \throw exception if the partition of the mesh cells defined by \a distrib does not cover the whole mesh */ -MEDFileUMesh *ParaMEDFileUMesh::ParaNew(const std::vector& distrib, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileUMesh *ParaMEDFileUMesh::ParaNew(const std::map> &distrib, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUtilities::CheckFileForRead(fileName); #ifdef HDF5_IS_PARALLEL @@ -176,16 +176,17 @@ MEDFileUMesh *ParaMEDFileUMesh::ParaNew(int iPart, int nbOfParts, const MPI_Comm * Loads mesh \a mName in parallel using a custom partition of the mesh cells among the processes. * See ParaMEDFileUMesh::ParaNew for detailed description. */ -MEDFileUMesh *ParaMEDFileUMesh::NewPrivate(med_idt fid, const MPI_Comm& com, const std::vector& distrib, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileUMesh *ParaMEDFileUMesh::NewPrivate(med_idt fid, const MPI_Comm& com, const std::map>& distrib, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MCAuto ret; - INTERP_KERNEL::NormalizedCellType geoType; - getSingleGeometricType(fileName,mName,geoType); - med_geometry_type geoMedType(typmai3[geoType]); - med_bool changement,transformation; - med_int totalNumberOfElements(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); - checkDistribution(com,totalNumberOfElements,distrib); - ret=MEDFileUMesh::LoadPartOfFromUserDistrib(fid,mName,geoType,distrib,dt,it,mrs); + for(std::map>::const_iterator iter=distrib.begin(); iter!= distrib.end(); iter++) + { + med_geometry_type geoMedType(typmai3[iter->first /*current geometric type*/]); + med_bool changement,transformation; + med_int totalNumberOfElements(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); + checkDistribution(com,totalNumberOfElements,iter->second /*distrib over this geometric type*/); + } + ret=MEDFileUMesh::LoadPartOfFromUserDistrib(fid,mName,distrib,dt,it,mrs); return ret.retn(); } @@ -250,12 +251,12 @@ MEDFileField1TS *ParaMEDFileField1TS::NewPrivate(med_idt fid, const MPI_Comm& co { INTERP_KERNEL::NormalizedCellType geoType; getSingleGeometricType(MEDFileWritable::FileNameFromFID(fid),mName,geoType); - med_geometry_type geoMedType(typmai3[geoType]); - med_bool changement,transformation; if(loc==ON_CELLS) //if distribution is on nodes, no fast way to check it (as a node can be shared by multiple processors) { - med_int totalNumberOfElements(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,geoMedType,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)); - checkDistribution(com,totalNumberOfElements,distrib); + med_geometry_type geoMedType(typmai3[geoType]); + med_bool changement,transformation; + med_int totalNumberOfElements(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoMedType,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)); + checkDistribution(com,totalNumberOfElements,distrib); } std::vector> tmp={ {loc, geoType} }; INTERP_KERNEL::AutoCppPtr entities(MEDFileEntities::BuildFrom(&tmp)); diff --git a/src/ParaMEDLoader/ParaMEDFileMesh.hxx b/src/ParaMEDLoader/ParaMEDFileMesh.hxx index 8c3d83974..18a3dc861 100644 --- a/src/ParaMEDLoader/ParaMEDFileMesh.hxx +++ b/src/ParaMEDLoader/ParaMEDFileMesh.hxx @@ -27,8 +27,10 @@ #include #include +#include #include "MCIdType.hxx" #include "MEDCouplingRefCountObject.hxx" +#include "NormalizedGeometricTypes" namespace MEDCoupling { @@ -50,11 +52,11 @@ namespace MEDCoupling public: static MEDFileUMesh *New(int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); static MEDFileUMesh *ParaNew(int iPart, int nbOfParts, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - static MEDFileUMesh *ParaNew(const std::vector& distrib, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + static MEDFileUMesh *ParaNew(const std::map>&, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); private: static MEDFileUMesh *NewPrivate(med_idt fid, int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - static MEDFileUMesh *NewPrivate(med_idt fid, const MPI_Comm& com, const std::vector& distrib, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + static MEDFileUMesh *NewPrivate(med_idt fid, const MPI_Comm& com, const std::map>&, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); }; diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx index bb779bdcb..2420a4fa0 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx @@ -96,18 +96,17 @@ void ParaMEDMEMTest::testParallelLoad1() if(size!=2) return ; - std::vector distrib; + std::map> distrib; if (rank == 0) - distrib = {0,1,4,5}; //c++ type of indexing: index starts from zero! + distrib = { {INTERP_KERNEL::NORM_QUAD4,{0,1,4,5}/*c++ type of indexing: index starts from zero!*/} }; else - distrib = {2,3,6,7}; + distrib = { {INTERP_KERNEL::NORM_QUAD4,{2,3,6,7}} }; std::string filename=INTERP_TEST::getResourceFile("SimpleTest2D.med"); MCAuto mu = ParaMEDFileUMesh::ParaNew(distrib, MPI_COMM_WORLD, MPI_INFO_NULL, filename, "mesh"); MCAuto meshRef = genLocMesh(rank); CPPUNIT_ASSERT(mu->getMeshAtLevel(0)->isEqual(meshRef,1e-12)); MPI_Barrier(MPI_COMM_WORLD); - } -- 2.39.2