From 78455b75596e9968005fe3496f312b2376427541 Mon Sep 17 00:00:00 2001 From: Anida Khizar Date: Tue, 14 Mar 2023 15:14:50 +0100 Subject: [PATCH] [Partial load] Partial loading for field located on nodes --- src/MEDLoader/MEDFileFieldInternal.cxx | 11 ++++++++--- src/MEDLoader/MEDFileMeshLL.cxx | 1 - src/ParaMEDLoader/ParaMEDFileMesh.cxx | 19 +++++++++++-------- src/ParaMEDLoader/ParaMEDFileMesh.hxx | 5 +++-- .../ParaMEDMEMTest_MEDLoader.cxx | 6 ++---- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/MEDLoader/MEDFileFieldInternal.cxx b/src/MEDLoader/MEDFileFieldInternal.cxx index 9113a7810..3dcb92993 100644 --- a/src/MEDLoader/MEDFileFieldInternal.cxx +++ b/src/MEDLoader/MEDFileFieldInternal.cxx @@ -3201,7 +3201,7 @@ MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWith } } -MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const PartDefinition *pdCells, const MEDFileEntities *entities):_mesh_iteration(meshIteration),_mesh_order(meshOrder), +MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const PartDefinition *pd, const MEDFileEntities *entities):_mesh_iteration(meshIteration),_mesh_order(meshOrder), _father(fath) { INTERP_KERNEL::AutoPtr meshName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); @@ -3216,7 +3216,7 @@ MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWith std::string name1(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); if(nbProfile>0 || nbProfile2>0) { - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,pdCells)); + _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,pd)); if(nbProfile>0) setMeshName(name0); else @@ -3226,7 +3226,12 @@ MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWith if(MFFPMIter::IsPresenceOfNode(entities)) { - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::MEDFileFieldPerMesh : nodes profile not handled yet !"); + med_int nbProfile(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE,MED_NONE,meshCsit+1,meshName,pflName,locName)); + if(nbProfile>0) + { + _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_NODES,INTERP_KERNEL::NORM_ERROR,nasc,pd)); + setMeshName(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE)); + } } } diff --git a/src/MEDLoader/MEDFileMeshLL.cxx b/src/MEDLoader/MEDFileMeshLL.cxx index 5c7c907af..3bc9116a8 100644 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ b/src/MEDLoader/MEDFileMeshLL.cxx @@ -603,7 +603,6 @@ void MEDFileUMeshL2::loadPartFromUserDistrib(med_idt fid, const MeshOrStructMesh 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); diff --git a/src/ParaMEDLoader/ParaMEDFileMesh.cxx b/src/ParaMEDLoader/ParaMEDFileMesh.cxx index 243e35b9a..7ff676952 100644 --- a/src/ParaMEDLoader/ParaMEDFileMesh.cxx +++ b/src/ParaMEDLoader/ParaMEDFileMesh.cxx @@ -40,8 +40,8 @@ void getSingleGeometricType(const std::string& fileName, const std::string& mNam int meshDim, spaceDim; mcIdType numberOfNodes; std::vector< std::vector< std::pair > > typesDistrib(GetUMeshGlobalInfo(fileName,mName,meshDim,spaceDim,numberOfNodes)); - std::size_t numberOfTypes = typesDistrib.size(); - if(numberOfTypes != 1) + std::size_t numberOfTypesMaxDimension = typesDistrib[0].size(); + if(numberOfTypesMaxDimension != 1) throw INTERP_KERNEL::Exception("ParaMEDFileMesh : only mesh with single geometrical type are supported with given distribution !"); geoType = typesDistrib[0][0].first; } @@ -231,7 +231,7 @@ MEDFileUMesh *ParaMEDFileUMesh::NewPrivate(med_idt fid, int iPart, int nbOfParts * \throw exception if the mesh contains more than one geometric type * \throw exception if the given distribution does not cover the entire mesh on which the field is defined */ -MEDFileField1TS *ParaMEDFileField1TS::ParaNew(const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& fName, const std::string& mName, const std::vector& distrib, int dt, int it) +MEDFileField1TS *ParaMEDFileField1TS::ParaNew(const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& fName, const std::string& mName, const std::vector& distrib, TypeOfField loc, int dt, int it) { MEDFileUtilities::CheckFileForRead(fileName); #ifdef HDF5_IS_PARALLEL @@ -239,22 +239,25 @@ MEDFileField1TS *ParaMEDFileField1TS::ParaNew(const MPI_Comm& com, const MPI_Inf #else MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); #endif - return ParaMEDFileField1TS::NewPrivate(fid,com,fName,mName,distrib,dt,it); + return ParaMEDFileField1TS::NewPrivate(fid,com,fName,mName,distrib,loc,dt,it); } /*! * Loads field \a fName in parallel using a custom partition of the mesh cells on which the field is defined among the processes. * See ParaMEDFileField1TS::ParaNew for detailed description. */ -MEDFileField1TS *ParaMEDFileField1TS::NewPrivate(med_idt fid, const MPI_Comm& com, const std::string& fName, const std::string& mName, const std::vector& distrib, int dt, int it) +MEDFileField1TS *ParaMEDFileField1TS::NewPrivate(med_idt fid, const MPI_Comm& com, const std::string& fName, const std::string& mName, const std::vector& distrib, TypeOfField loc, int dt, int it) { INTERP_KERNEL::NormalizedCellType geoType; getSingleGeometricType(MEDFileWritable::FileNameFromFID(fid),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); - std::vector> tmp={ {ON_CELLS, geoType} }; + 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); + } + std::vector> tmp={ {loc, geoType} }; INTERP_KERNEL::AutoCppPtr entities(MEDFileEntities::BuildFrom(&tmp)); MCAuto partFile(MEDFileAnyTypeField1TS::NewAdv(fid,fName,dt,it,entities,distrib)); diff --git a/src/ParaMEDLoader/ParaMEDFileMesh.hxx b/src/ParaMEDLoader/ParaMEDFileMesh.hxx index d886e5844..8c3d83974 100644 --- a/src/ParaMEDLoader/ParaMEDFileMesh.hxx +++ b/src/ParaMEDLoader/ParaMEDFileMesh.hxx @@ -28,6 +28,7 @@ #include #include #include "MCIdType.hxx" +#include "MEDCouplingRefCountObject.hxx" namespace MEDCoupling { @@ -67,9 +68,9 @@ namespace MEDCoupling class ParaMEDFileField1TS { public: - static MEDFileField1TS *ParaNew(const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& fName, const std::string& mName, const std::vector& distrib, int dt=-1, int it=-1); + static MEDFileField1TS *ParaNew(const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& fName, const std::string& mName, const std::vector& distrib, TypeOfField loc, int dt=-1, int it=-1); private: - static MEDFileField1TS *NewPrivate(med_idt fid, const MPI_Comm& com, const std::string& fName, const std::string& mName, const std::vector& distrib, int dt, int it); + static MEDFileField1TS *NewPrivate(med_idt fid, const MPI_Comm& com, const std::string& fName, const std::string& mName, const std::vector& distrib, TypeOfField loc, int dt, int it); }; diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx index dcf0140f9..bb779bdcb 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx @@ -128,11 +128,9 @@ void ParaMEDMEMTest::testParallelLoad2() distrib = {2,3,6,7}; std::string filename=INTERP_TEST::getResourceFile("SimpleTest2D.med"); - MCAuto f1TS = ParaMEDFileField1TS::ParaNew(MPI_COMM_WORLD, MPI_INFO_NULL,filename,"field","mesh",distrib); - MCAuto partField = f1TS->getFieldAtTopLevel(ON_CELLS); + MCAuto f1TS = ParaMEDFileField1TS::ParaNew(MPI_COMM_WORLD, MPI_INFO_NULL,filename,"field","mesh",distrib,ON_CELLS); MCAuto fieldRef = genLocField(rank); -// CPPUNIT_ASSERT_EQUAL(4,(int)partField->getNumberOfTuples()); // NOT TRUE ANYMORE! Number of tuples of partField is the number of tuples of global field - CPPUNIT_ASSERT(partField->getArray()->isEqual(*fieldRef->getArray(),1e-12)); + CPPUNIT_ASSERT(f1TS->getUndergroundDataArray()->isEqual(*fieldRef->getArray(),1e-12)); MPI_Barrier(MPI_COMM_WORLD); } -- 2.39.2