From dbb24ef3f833b10c186ddff3f5a890f3ba2f3310 Mon Sep 17 00:00:00 2001 From: ageay Date: Tue, 2 Jul 2013 09:04:04 +0000 Subject: [PATCH] splitDiscretizations on MEDFileField* classes --- src/MEDLoader/MEDFileField.cxx | 194 +++++++++++++++++++++++++++ src/MEDLoader/MEDFileField.hxx | 9 ++ src/MEDLoader/Swig/MEDLoaderCommon.i | 20 +++ 3 files changed, 223 insertions(+) diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index 02dc4c7f1..52b6b0657 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -1417,6 +1417,30 @@ void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRef (*it)->setFather(this); } +/*! + * \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::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) throw(INTERP_KERNEL::Exception) +{ + 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) + { + newPmPtPd.push_back(*it); + std::pair bgEnd; bgEnd.first=(*it)->getStart(); bgEnd.second=(*it)->getEnd(); + (*it)->setNewStart(globalNum); + globalNum=(*it)->getEnd(); + its.push_back(bgEnd); + ret=true; + } + if(ret) + _field_pm_pt_pd=newPmPtPd; + return ret; +} + MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception):_father(fath),_geo_type(geoType) { } @@ -1932,6 +1956,25 @@ bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const char *meshName, cons return true; } +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + */ +void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) throw(INTERP_KERNEL::Exception) +{ + 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)->keepOnlySpatialDiscretization(tof,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) throw(INTERP_KERNEL::Exception) { std::map > > types; @@ -4001,6 +4044,66 @@ bool MEDFileAnyTypeField1TSWithoutSDA::renumberEntitiesLyingOnMesh(const char *m return ret; } +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations() const throw(INTERP_KERNEL::Exception) +{ + 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; + 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++) + allEnt.insert(*it2); + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(allEnt.size()); + std::set::const_iterator it3(allEnt.begin()); + for(std::size_t i=0;i > its; + ret[i]=shallowCpy(); + int newLgth=ret[i]->keepOnlySpatialDiscretization(*it3,its); + ret[i]->updateData(newLgth,its); + } + return ret; +} + +int MEDFileAnyTypeField1TSWithoutSDA::keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its) throw(INTERP_KERNEL::Exception) +{ + 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; +} + +void MEDFileAnyTypeField1TSWithoutSDA::updateData(int newLgth, const std::vector< std::pair >& oldStartStops) throw(INTERP_KERNEL::Exception) +{ + if(_nb_of_tuples_to_be_allocated>=0) + { + _nb_of_tuples_to_be_allocated=newLgth; + return ; + } + if(_nb_of_tuples_to_be_allocated==-1) + return ; + if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) + { + const DataArray *oldArr=getUndergroundDataArray(); + if(!oldArr || !oldArr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 1 !"); + MEDCouplingAutoRefCountObjectPtr newArr=createNewEmptyDataArrayInstance(); + newArr->alloc(newLgth,getNumberOfComponents()); + int pos=0; + for(std::vector< std::pair >::const_iterator it=oldStartStops.begin();it!=oldStartStops.end();it++) + { + if((*it).second<(*it).first) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : the range in the leaves was invalid !"); + newArr->setContigPartOfSelectedValues2(pos,oldArr,(*it).first,(*it).second,1); + pos+=(*it).second-(*it).first; + } + setArray(newArr); + return ; + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 2 !"); +} + void MEDFileAnyTypeField1TSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const throw(INTERP_KERNEL::Exception) { if(_field_per_mesh.empty()) @@ -5662,6 +5765,26 @@ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFil return ret; } +/*! + * 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. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitDiscretizations() const throw(INTERP_KERNEL::Exception) +{ + 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::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; + } + return ret; +} + MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::deepCpy() const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); @@ -7189,6 +7312,57 @@ std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations() const throw(INTERP_KERNEL::Exception) +{ + std::size_t sz(_time_steps.size()); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); + for(std::size_t i=0;isplitDiscretizations(); + } + // + std::vector< MEDCouplingAutoRefCountObjectPtr > ret; + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > ret2; + std::vector< TypeOfField > types; + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + { + std::vector ts=(*it1)->getTypesOfFieldAvailable(); + if(ts.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations : it appears that the splitting of MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations has returned invalid result !"); + std::vector< TypeOfField >::iterator it2=std::find(types.begin(),types.end(),ts[0]); + if(it2==types.end()) + types.push_back(ts[0]); + } + ret.resize(types.size()); ret2.resize(types.size()); + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + { + TypeOfField typ=(*it1)->getTypesOfFieldAvailable()[0]; + std::size_t pos=std::distance(types.begin(),std::find(types.begin(),types.end(),typ)); + ret2[pos].push_back(*it1); + } + for(std::size_t i=0;i 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; + elt->MEDFileFieldNameScope::operator=(*this); + } + return ret; +} + void MEDFileAnyTypeFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) throw(INTERP_KERNEL::Exception) { _name=field->getName(); @@ -7942,6 +8116,26 @@ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ME return ret; } +/*! + * 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. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitDiscretizations() const throw(INTERP_KERNEL::Exception) +{ + 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::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; + } + return ret; +} + MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index 86a104dad..aae7740b7 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -120,6 +120,7 @@ namespace ParaMEDMEM int getNumberOfComponents() const; int getNumberOfTuples() const; int getStart() const { return _start; } + int getEnd() const { return _end; } DataArray *getOrCreateAndGetArray(); const DataArray *getOrCreateAndGetArray() const; const std::vector& getInfo() const; @@ -205,6 +206,7 @@ namespace ParaMEDMEM void getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, std::vector& geoTypes) const; void fillValues(int& startEntryId, std::vector< std::pair,std::pair > >& entries) const; void setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) throw(INTERP_KERNEL::Exception); + bool keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) throw(INTERP_KERNEL::Exception); 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) throw(INTERP_KERNEL::Exception); @@ -254,6 +256,7 @@ namespace ParaMEDMEM std::vector getLocsReallyUsedMulti() const; bool changeMeshNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception); bool renumberEntitiesLyingOnMesh(const char *meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); + void keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) throw(INTERP_KERNEL::Exception); void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception); void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const throw(INTERP_KERNEL::Exception); @@ -501,6 +504,8 @@ namespace ParaMEDMEM DataArray *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const throw(INTERP_KERNEL::Exception); public: bool renumberEntitiesLyingOnMesh(const char *meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); + std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const throw(INTERP_KERNEL::Exception); + int keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its) throw(INTERP_KERNEL::Exception); public: void allocNotFromFile(int newNbOfTuples) throw(INTERP_KERNEL::Exception); bool allocIfNecessaryTheArrayToReceiveDataFromFile() throw(INTERP_KERNEL::Exception); @@ -513,6 +518,7 @@ namespace ParaMEDMEM protected: int getMeshIdFromMeshName(const char *mName) const throw(INTERP_KERNEL::Exception); int addNewEntryIfNecessary(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + void updateData(int newLgth, const std::vector< std::pair >& oldStartStops) throw(INTERP_KERNEL::Exception); protected: std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > > _field_per_mesh; int _iteration; @@ -650,6 +656,7 @@ namespace ParaMEDMEM void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); void releaseArrays() throw(INTERP_KERNEL::Exception); std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitComponents() const throw(INTERP_KERNEL::Exception); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitDiscretizations() const throw(INTERP_KERNEL::Exception); MEDFileAnyTypeField1TS *deepCpy() const throw(INTERP_KERNEL::Exception); int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) throw(INTERP_KERNEL::Exception); virtual MEDFileAnyTypeField1TS *shallowCpy() const throw(INTERP_KERNEL::Exception) = 0; @@ -769,6 +776,7 @@ namespace ParaMEDMEM std::size_t getHeapMemorySize() const; virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *deepCpy() const throw(INTERP_KERNEL::Exception); virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitComponents() const throw(INTERP_KERNEL::Exception); + virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const throw(INTERP_KERNEL::Exception); virtual const char *getTypeStr() const throw(INTERP_KERNEL::Exception) = 0; virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const throw(INTERP_KERNEL::Exception) = 0; virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const throw(INTERP_KERNEL::Exception) = 0; @@ -898,6 +906,7 @@ namespace ParaMEDMEM std::size_t getHeapMemorySize() const; virtual MEDFileAnyTypeFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitComponents() const throw(INTERP_KERNEL::Exception); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitDiscretizations() const throw(INTERP_KERNEL::Exception); virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const throw(INTERP_KERNEL::Exception) = 0; virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const throw(INTERP_KERNEL::Exception) = 0; // diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index ab758d651..a35f7f1c9 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -1253,6 +1253,16 @@ namespace ParaMEDMEM PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); return retPy; } + + PyObject *splitDiscretizations() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitDiscretizations(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i > ret=self->splitDiscretizations(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i tmp; -- 2.39.2