From c223741db72e5290f43a42cc2df602456c675652 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 18 Mar 2016 11:36:14 +0100 Subject: [PATCH] Useful extractPart method on MEDFileField series. --- src/MEDLoader/MEDFileField.cxx | 101 ++++++++++++++++++++++++- src/MEDLoader/MEDFileField.hxx | 12 ++- src/MEDLoader/Swig/MEDLoaderCommon.i | 25 ++++++ src/MEDLoader/Swig/MEDLoaderTypemaps.i | 28 +++++++ 4 files changed, 164 insertions(+), 2 deletions(-) diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index c4d25628d..89784e20f 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -6364,6 +6364,53 @@ DataArrayDouble *MEDFileField1TS::ReturnSafelyDataArrayDouble(MCAuto& return arrOutC; } +/*! + * Return an extraction of \a this using \a extractDef map to specify the extraction. + * The keys of \a extractDef is level relative to max ext of \a mm mesh. + * + * \return A new object that the caller is responsible to deallocate. + */ +MEDFileField1TS *MEDFileField1TS::extractPart(const std::map >& extractDef, MEDFileMesh *mm) const +{ + if(!mm) + throw INTERP_KERNEL::Exception("MEDFileField1TS::extractPart : input mesh is NULL !"); + MCAuto ret(MEDFileField1TS::New()); + std::vector tof(getTypesOfFieldAvailable()); + for(std::vector::const_iterator it0=tof.begin();it0!=tof.end();it0++) + { + if((*it0)!=ON_NODES) + { + std::vector levs; + getNonEmptyLevels(mm->getName(),levs); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + std::map >::const_iterator it2(extractDef.find(*lev)); + if(it2!=extractDef.end()) + { + MCAuto t((*it2).second); + MCAuto f(getFieldOnMeshAtLevel(ON_CELLS,(*lev),mm)); + MCAuto fOut(f->buildSubPart(t)); + ret->setFieldNoProfileSBT(fOut); + } + } + } + else + { + std::map >::const_iterator it2(extractDef.find(1)); + if(it2==extractDef.end()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::extractPart : presence of a NODE field and no extract array available for NODE !"); + MCAuto t((*it2).second); + MCAuto f(getFieldOnMeshAtLevel(ON_NODES,0,mm)); + MCAuto fOut(f->deepCopy()); + DataArrayDouble *arr(f->getArray()); + MCAuto newArr(arr->selectByTupleIdSafe(t->begin(),t->end())); + fOut->setArray(newArr); + ret->setFieldNoProfileSBT(fOut); + } + } + return ret.retn(); +} + MEDFileField1TS::MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) { @@ -9035,7 +9082,7 @@ MEDFileIntFieldMultiTS *MEDFileFieldMultiTS::convertToInt(bool isDeepCpyGlobs) c * delete this field using decrRef() as it is no more needed. * \throw If \a pos is not a valid time step id. */ -MEDFileAnyTypeField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const +MEDFileField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const { const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); if(!item) @@ -9342,6 +9389,27 @@ DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArrayExt(int iteration, return static_cast(contentNotNull()->getUndergroundDataArrayExt(iteration,order,entries)); } +/*! + * Return an extraction of \a this using \a extractDef map to specify the extraction. + * The keys of \a extractDef is level relative to max ext of \a mm mesh. + * + * \return A new object that the caller is responsible to deallocate. + */ +MEDFileFieldMultiTS *MEDFileFieldMultiTS::extractPart(const std::map >& extractDef, MEDFileMesh *mm) const +{ + if(!mm) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::extractPart : mesh is null !"); + MCAuto fmtsOut(MEDFileFieldMultiTS::New()); + int nbTS(getNumberOfTS()); + for(int i=0;i f1ts(getTimeStepAtPos(i)); + MCAuto f1tsOut(f1ts->extractPart(extractDef,mm)); + fmtsOut->pushBackTimeStep(f1tsOut); + } + return fmtsOut.retn(); +} + //= MEDFileAnyTypeFieldMultiTSIterator MEDFileAnyTypeFieldMultiTSIterator::MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts):_fmts(fmts),_iter_id(0),_nb_iter(0) @@ -9785,6 +9853,11 @@ DataArrayInt *MEDFileIntFieldMultiTS::getUndergroundDataArray(int iteration, int return static_cast(contentNotNull()->getUndergroundDataArray(iteration,order)); } +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::extractPart(const std::map >& extractDef, MEDFileMesh *mm) const +{ + throw INTERP_KERNEL::Exception("*MEDFileIntFieldMultiTS::extractPart : not implemented yet for int !"); +} + //= MEDFileFields MEDFileFields *MEDFileFields::New() @@ -10275,6 +10348,32 @@ bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, con return ret; } +/*! + * Return an extraction of \a this using \a extractDef map to specify the extraction. + * The keys of \a extractDef is level relative to max ext of \a mm mesh. + * + * \return A new object that the caller is responsible to deallocate. + */ +MEDFileFields *MEDFileFields::extractPart(const std::map >& extractDef, MEDFileMesh *mm) const +{ + if(!mm) + throw INTERP_KERNEL::Exception("MEDFileFields::extractPart : input mesh is NULL !"); + MCAuto fsOut(MEDFileFields::New()); + int nbFields(getNumberOfFields()); + for(int i=0;i fmtsOut(fmts->extractPart(extractDef,mm)); + fsOut->pushField(fmtsOut); + } + return fsOut.retn(); +} + MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const { if(i<0 || i>=(int)_fields.size()) diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index 47c9ebbcd..8b8133866 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -744,6 +744,8 @@ namespace MEDCoupling public: MEDLOADER_EXPORT static void SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MCAuto& arr); MEDLOADER_EXPORT static DataArrayDouble *ReturnSafelyDataArrayDouble(MCAuto& arr); + public: + MEDLOADER_EXPORT MEDFileField1TS *extractPart(const std::map >& extractDef, MEDFileMesh *mm) const; private: med_field_type getMEDFileFieldType() const { return MED_FLOAT64; } const MEDFileField1TSWithoutSDA *contentNotNull() const; @@ -983,6 +985,8 @@ namespace MEDCoupling MEDLOADER_EXPORT std::vector< std::vector > getTypesOfFieldAvailable() const; MEDLOADER_EXPORT std::vector< std::vector< std::pair > > getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; MEDLOADER_EXPORT MCAuto getContent(); + public: + MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *extractPart(const std::map >& extractDef, MEDFileMesh *mm) const = 0; public: MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; @@ -1016,7 +1020,7 @@ namespace MEDCoupling MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; MEDLOADER_EXPORT MEDFileIntFieldMultiTS *convertToInt(bool isDeepCpyGlobs=true) const; // - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; + MEDLOADER_EXPORT MEDFileField1TS *getTimeStepAtPos(int pos) const; MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const; MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const; // @@ -1032,6 +1036,8 @@ namespace MEDCoupling MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArray(int iteration, int order) const; MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const; + public: + MEDLOADER_EXPORT MEDFileFieldMultiTS *extractPart(const std::map >& extractDef, MEDFileMesh *mm) const; private: const MEDFileFieldMultiTSWithoutSDA *contentNotNull() const; MEDFileFieldMultiTSWithoutSDA *contentNotNull(); @@ -1070,6 +1076,8 @@ namespace MEDCoupling MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); // MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArray(int iteration, int order) const; + public: + MEDLOADER_EXPORT MEDFileIntFieldMultiTS *extractPart(const std::map >& extractDef, MEDFileMesh *mm) const; private: const MEDFileIntFieldMultiTSWithoutSDA *contentNotNull() const; MEDFileIntFieldMultiTSWithoutSDA *contentNotNull(); @@ -1140,6 +1148,8 @@ namespace MEDCoupling MEDLOADER_EXPORT void destroyFieldsAtPos2(int bg, int end, int step); MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N); + public: + MEDLOADER_EXPORT MEDFileFields *extractPart(const std::map >& extractDef, MEDFileMesh *mm) const; public: MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index 21dc6559c..a9d85eeb0 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -146,6 +146,7 @@ using namespace MEDCoupling; %newobject MEDCoupling::MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps; %newobject MEDCoupling::MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps; %newobject MEDCoupling::MEDFileFields::__iter__; +%newobject MEDCoupling::MEDFileFields::extractPart; %newobject MEDCoupling::MEDFileAnyTypeFieldMultiTS::New; %newobject MEDCoupling::MEDFileAnyTypeFieldMultiTS::deepCopy; @@ -154,6 +155,7 @@ using namespace MEDCoupling; %newobject MEDCoupling::MEDFileAnyTypeFieldMultiTS::getTimeStep; %newobject MEDCoupling::MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime; %newobject MEDCoupling::MEDFileAnyTypeFieldMultiTS::__iter__; +%newobject MEDCoupling::MEDFileAnyTypeFieldMultiTS::extractPart; %newobject MEDCoupling::MEDFileFieldMultiTS::New; %newobject MEDCoupling::MEDFileFieldMultiTS::LoadSpecificEntities; %newobject MEDCoupling::MEDFileFieldMultiTS::getFieldAtLevel; @@ -177,6 +179,8 @@ using namespace MEDCoupling; %newobject MEDCoupling::MEDFileField1TS::getFieldAtLevelOld; %newobject MEDCoupling::MEDFileField1TS::getUndergroundDataArray; %newobject MEDCoupling::MEDFileField1TS::convertToInt; +%newobject MEDCoupling::MEDFileField1TS::extractPart; + %newobject MEDCoupling::MEDFileIntField1TS::New; %newobject MEDCoupling::MEDFileIntField1TS::getUndergroundDataArray; %newobject MEDCoupling::MEDFileIntField1TS::convertToDouble; @@ -2102,6 +2106,13 @@ namespace MEDCoupling PyTuple_SetItem(ret,1,elt); return ret; } + + MEDFileField1TS *extractPart(PyObject *extractDef, MEDFileMesh *mm) const + { + std::map > extractDefCpp; + convertToMapIntDataArrayInt(extractDef,extractDefCpp); + return self->extractPart(extractDefCpp,mm); + } } }; @@ -2548,6 +2559,13 @@ namespace MEDCoupling } } + MEDFileAnyTypeFieldMultiTS *extractPart(PyObject *extractDef, MEDFileMesh *mm) const + { + std::map > extractDefCpp; + convertToMapIntDataArrayInt(extractDef,extractDefCpp); + return self->extractPart(extractDefCpp,mm); + } + static PyObject *MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(PyObject *li) throw(INTERP_KERNEL::Exception) { std::vector vectFMTS; @@ -3054,6 +3072,13 @@ namespace MEDCoupling self->destroyFieldsAtPos(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); } } + + MEDFileFields *extractPart(PyObject *extractDef, MEDFileMesh *mm) const throw(INTERP_KERNEL::Exception) + { + std::map > extractDefCpp; + convertToMapIntDataArrayInt(extractDef,extractDefCpp); + return self->extractPart(extractDefCpp,mm); + } } }; diff --git a/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/src/MEDLoader/Swig/MEDLoaderTypemaps.i index be6d74b2d..9e49e474f 100644 --- a/src/MEDLoader/Swig/MEDLoaderTypemaps.i +++ b/src/MEDLoader/Swig/MEDLoaderTypemaps.i @@ -356,3 +356,31 @@ int MEDFileFieldsgetitemSingleTS__(const MEDFileFields *self, PyObject *obj) thr else throw INTERP_KERNEL::Exception("MEDFileFields::__getitem__ : only integer or string with fieldname supported !"); } + +void convertToMapIntDataArrayInt(PyObject *pyMap, std::map >& cppMap) +{ + if(!PyDict_Check(pyMap)) + throw INTERP_KERNEL::Exception("convertToMapIntDataArrayInt : input is not a python map !"); + PyObject *key, *value; + Py_ssize_t pos(0); + cppMap.clear(); + while (PyDict_Next(pyMap,&pos,&key,&value)) + { + if(!PyInt_Check(key)) + throw INTERP_KERNEL::Exception("convertToMapIntDataArrayInt : keys in map must be PyInt !"); + long k(PyInt_AS_LONG(key)); + void *argp(0); + int status(SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_MEDCoupling__DataArrayInt,0|0)); + if(!SWIG_IsOK(status)) + { + std::ostringstream oss; oss << "convertToMapIntDataArrayInt : values in map must be DataArrayInt !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + DataArrayInt *arg(reinterpret_cast(argp)); + MCAuto arg2(arg); + if(arg) + arg->incrRef(); + cppMap[k]=arg2; + } +} + -- 2.39.2