From 2f9cac3385a4fc9b8f46dedc3462aec0127ae325 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 17 Oct 2014 10:42:32 +0200 Subject: [PATCH] Multi discr per geo type management. --- src/MEDLoader/MEDFileField.cxx | 187 +++++++++++++++++++++++++-- src/MEDLoader/MEDFileField.hxx | 7 + src/MEDLoader/Swig/MEDLoaderCommon.i | 20 +++ 3 files changed, 205 insertions(+), 9 deletions(-) diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index 14f49546b..4e461f329 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -1505,7 +1505,7 @@ void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRef */ bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) { - bool ret=false; + bool ret(false); std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) if((*it)->getType()==tof) @@ -1522,6 +1522,24 @@ bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof, return ret; } +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + * \return bool - false if the type of field \a tof is not contained in \a this. + */ +bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) +{ + if(_field_pm_pt_pd.size()<=idOfDisc) + return false; + MEDCouplingAutoRefCountObjectPtr elt(_field_pm_pt_pd[idOfDisc]); + std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd(1,elt); + std::pair bgEnd; bgEnd.first=_field_pm_pt_pd[idOfDisc]->getStart(); bgEnd.second=_field_pm_pt_pd[idOfDisc]->getEnd(); + elt->setNewStart(globalNum); + globalNum=elt->getEnd(); + its.push_back(bgEnd); + return true; +} + MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType):_father(fath),_geo_type(geoType) { } @@ -2073,6 +2091,25 @@ void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &gl _field_pm_pt=ret; } +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + */ +void MEDFileFieldPerMesh::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector< std::pair > its2; + if((*it)->keepOnlyGaussDiscretization(idOfDisc,globalNum,its2)) + { + ret.push_back(*it); + its.insert(its.end(),its2.begin(),its2.end()); + } + } + _field_pm_pt=ret; +} + void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) { std::map > > types; @@ -4152,12 +4189,18 @@ bool MEDFileAnyTypeField1TSWithoutSDA::renumberEntitiesLyingOnMesh(const std::st return ret; } +/*! + * This method splits \a this into several sub-parts so that each sub parts have exactly one spatial discretization. This method implements the minimal + * splitting that leads to single spatial discretization of this. + * + * \sa splitMultiDiscrPerGeoTypes + */ std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations() const { std::vector types; std::vector< std::vector > typesF; std::vector< std::vector > pfls,locs; - std::vector< std::vector > > bgEnd=getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs); + std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); std::set allEnt; for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++) for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) @@ -4168,7 +4211,48 @@ std::vector< MEDCouplingAutoRefCountObjectPtr { std::vector< std::pair > its; ret[i]=shallowCpy(); - int newLgth=ret[i]->keepOnlySpatialDiscretization(*it3,its); + int newLgth(ret[i]->keepOnlySpatialDiscretization(*it3,its)); + ret[i]->updateData(newLgth,its); + } + return ret; +} + +/*! + * This method performs a sub splitting as splitDiscretizations does but finer. This is the finest spliting level that can be done. + * This method implements the minimal splitting so that each returned elements are mono Gauss discretization per geometric type. + * + * \sa splitDiscretizations + */ +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes() const +{ + std::vector types; + std::vector< std::vector > typesF; + std::vector< std::vector > pfls,locs; + std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); + std::set allEnt; + std::size_t nbOfMDPGT(0),ii(0); + for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++,ii++) + { + nbOfMDPGT=std::max(nbOfMDPGT,locs[ii].size()); + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + allEnt.insert(*it2); + } + if(allEnt.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !"); + if(nbOfMDPGT==0) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); + if(nbOfMDPGT==1) + { + std::vector< MEDCouplingAutoRefCountObjectPtr > ret0(1); + ret0[0]=const_cast(this); this->incrRef(); + return ret0; + } + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(nbOfMDPGT); + for(std::size_t i=0;i > its; + ret[i]=shallowCpy(); + int newLgth(ret[i]->keepOnlyGaussDiscretization(i,its)); ret[i]->updateData(newLgth,its); } return ret; @@ -4176,12 +4260,20 @@ std::vector< MEDCouplingAutoRefCountObjectPtr int MEDFileAnyTypeField1TSWithoutSDA::keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its) { - int globalCounter=0; + int globalCounter(0); for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) (*it)->keepOnlySpatialDiscretization(tof,globalCounter,its); return globalCounter; } +int MEDFileAnyTypeField1TSWithoutSDA::keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair >& its) +{ + int globalCounter(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->keepOnlyGaussDiscretization(idOfDisc,globalCounter,its); + return globalCounter; +} + void MEDFileAnyTypeField1TSWithoutSDA::updateData(int newLgth, const std::vector< std::pair >& oldStartStops) { if(_nb_of_tuples_to_be_allocated>=0) @@ -5956,14 +6048,34 @@ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFil /*! * This method returns as MEDFileAnyTypeField1TS new instances as number of spatial discretizations in \a this. - * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. + * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. */ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitDiscretizations() const { const MEDFileAnyTypeField1TSWithoutSDA *content(_content); if(!content) throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitDiscretizations : no content in this ! Unable to split discretization !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitDiscretizations(); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeField1TS new instances as number of maximal number of discretization in \a this. + * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretization !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); std::size_t sz(contentsSplit.size()); std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); for(std::size_t i=0;i elt=createNew(); + MEDCouplingAutoRefCountObjectPtr elt(createNew()); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=ret2[i].begin();it1!=ret2[i].end();it1++) elt->pushBackTimeStep(*it1);//also updates infos in elt ret[i]=elt; @@ -7572,6 +7684,43 @@ std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes() const +{ + std::size_t sz(_time_steps.size()); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); + std::size_t szOut(std::numeric_limits::max()); + for(std::size_t i=0;isplitMultiDiscrPerGeoTypes(); + if(szOut==std::numeric_limits::max()) + szOut=items[i].size(); + else + if(items[i].size()!=szOut) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : The splitting per discretization is expected to be same among time steps !"); + } + if(szOut==std::numeric_limits::max()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(szOut); + for(std::size_t i=0;i elt(createNew()); + for(std::size_t j=0;jpushBackTimeStep(items[i][j]); + ret[i]=elt; + elt->MEDFileFieldNameScope::operator=(*this); + } + return ret; +} + void MEDFileAnyTypeFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) { _name=field->getName(); @@ -8355,14 +8504,34 @@ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ME /*! * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of discretizations over time steps in \a this. - * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. + * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. */ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitDiscretizations() const { const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); if(!content) throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitDiscretizations : no content in this ! Unable to split discretizations !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitDiscretizations(); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of sub-discretizations over time steps in \a this. + * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretizations !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); std::size_t sz(contentsSplit.size()); std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); for(std::size_t i=0;i,std::pair > >& entries) const; void setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves); bool keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its); + bool keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its); static med_entity_type ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType); private: std::vector addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); @@ -272,6 +273,7 @@ namespace ParaMEDMEM bool changeMeshNames(const std::vector< std::pair >& modifTab); bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); void keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its); + void keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its); void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; @@ -523,7 +525,9 @@ namespace ParaMEDMEM public: MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr > splitMultiDiscrPerGeoTypes() const; MEDLOADER_EXPORT int keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its); + MEDLOADER_EXPORT int keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair >& its); public: MEDLOADER_EXPORT void allocNotFromFile(int newNbOfTuples); MEDLOADER_EXPORT bool allocIfNecessaryTheArrayToReceiveDataFromFile(); @@ -677,6 +681,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitComponents() const; MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitDiscretizations() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitMultiDiscrPerGeoTypes() const; MEDLOADER_EXPORT MEDFileAnyTypeField1TS *deepCpy() const; MEDLOADER_EXPORT int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TS *shallowCpy() const = 0; @@ -799,6 +804,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *deepCpy() const; MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitComponents() const; MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const; + MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitMultiDiscrPerGeoTypes() const; MEDLOADER_EXPORT virtual const char *getTypeStr() const = 0; MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const = 0; MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const = 0; @@ -932,6 +938,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *deepCpy() const; MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitComponents() const; MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitDiscretizations() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitMultiDiscrPerGeoTypes() const; MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const = 0; MEDLOADER_EXPORT virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const = 0; // diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index a9bf3b350..85eba32d2 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -1395,6 +1395,16 @@ namespace ParaMEDMEM PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); return retPy; } + + PyObject *splitMultiDiscrPerGeoTypes() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitMultiDiscrPerGeoTypes(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i > ret=self->splitMultiDiscrPerGeoTypes(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i tmp; -- 2.39.2