From: Anthony Geay Date: Thu, 29 Sep 2016 15:07:42 +0000 (+0200) Subject: On the road X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1966df2ca4bd227e5da06703f227a82379ec4da4;p=tools%2Fmedcoupling.git On the road --- diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 2ba9ee4e1..a3bbcc180 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -7963,7 +7963,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, * \throw If \a a[ *i* ]->getMeshDimension() < 0. * \throw If the meshes in \a a are of different dimension (getMeshDimension()). */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector& a) +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const std::vector& a) { std::size_t sz=a.size(); if(sz==0) @@ -7996,7 +7996,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector& a) +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(const std::vector& a) { if(a.empty()) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !"); diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 68093553c..9a8fc33c2 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -232,7 +232,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0); MEDCOUPLING_EXPORT static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da); MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(std::vector& a); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(const std::vector& a); MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const std::vector& meshes); MEDCOUPLING_EXPORT static MEDCouplingUMesh *FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); @@ -311,7 +311,7 @@ namespace MEDCoupling void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, double eps, MCAuto& elts, MCAuto& eltsIndex) const; /// @cond INTERNAL - static MEDCouplingUMesh *MergeUMeshesLL(std::vector& a); + static MEDCouplingUMesh *MergeUMeshesLL(const std::vector& a); typedef int (*DimM1DescNbrer)(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2); template MEDCouplingUMesh *buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const; diff --git a/src/MEDLoader/MEDFileData.cxx b/src/MEDLoader/MEDFileData.cxx index 96e77a72c..d6288a523 100644 --- a/src/MEDLoader/MEDFileData.cxx +++ b/src/MEDLoader/MEDFileData.cxx @@ -219,6 +219,73 @@ bool MEDFileData::unPolyzeMeshes() return !meshesImpacted.empty(); } +/*! + * Precondition : all instances in \a mfds should have a single mesh with fields on it. If there is an instance with not exactly one mesh an exception will be thrown. + * You can invoke MEDFileFields::partOfThisLyingOnSpecifiedMeshName method to make it work. + */ +MCAuto MEDFileData::Aggregate(const std::vector& mfds) +{ + if(mfds.empty()) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : empty vector !"); + std::size_t sz(mfds.size()),i(0); + MCAuto ret(MEDFileData::New()); + std::vector ms(sz); + std::vector< std::vector< std::pair > > dts(sz); + for(std::vector::const_iterator it=mfds.begin();it!=mfds.end();it++,i++) + { + const MEDFileData *elt(*it); + if(!elt) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : presence of NULL pointer !"); + const MEDFileMeshes *meshes(elt->getMeshes()); + if(!meshes) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : presence of an instance with no meshes attached on it !"); + if(meshes->getNumberOfMeshes()!=1) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : all instances in input vector must lie on exactly one mesh ! To have it you can invoke partOfThisLyingOnSpecifiedMeshName method."); + const MEDFileMesh *mesh(meshes->getMeshAtPos(0)); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : presence of null mesh in a MEDFileData instance among input vector !"); + const MEDFileUMesh *umesh(dynamic_cast(mesh)); + if(!umesh) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : works only for unstructured meshes !"); + ms[i]=umesh; + dts[i]=umesh->getAllDistributionOfTypes(); + } + MCAuto agg_m(MEDFileUMesh::Aggregate(ms)); + MCAuto mss(MEDFileMeshes::New()); mss->pushMesh(agg_m); + ret->setMeshes(mss); + // fields + std::vector fieldNames(mfds[0]->getFields()->getFieldsNames()); + std::set fieldNamess(fieldNames.begin(),fieldNames.end()); + if(fieldNames.size()!=fieldNamess.size()) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : field names must be different each other !"); + std::vector< std::vector > vectOfFields(fieldNames.size()); + MCAuto fss(MEDFileFields::New()); + for(std::vector::const_iterator it=mfds.begin();it!=mfds.end();it++) + { + std::vector fieldNames0((*it)->getFields()->getFieldsNames()); + std::set fieldNamess0(fieldNames0.begin(),fieldNames0.end()); + if(fieldNamess!=fieldNamess0) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : field names must be the same for all input instances !"); + i=0; + for(std::vector::const_iterator it1=fieldNames.begin();it1!=fieldNames.end();it1++,i++) + { + const MEDFileAnyTypeFieldMultiTS *fmts((*it)->getFields()->getFieldWithName(*it1)); + if(!fmts) + throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : internal error 1 !"); + vectOfFields[i].push_back(fmts); + } + } + i=0; + for(std::vector::const_iterator it1=fieldNames.begin();it1!=fieldNames.end();it1++,i++) + { + MCAuto fmts(MEDFileAnyTypeFieldMultiTS::Aggregate(vectOfFields[i],dts)); + fmts->setMeshName(agg_m->getName()); + fss->pushField(fmts); + } + ret->setFields(fss); + return ret; +} + MEDFileData::MEDFileData() { } diff --git a/src/MEDLoader/MEDFileData.hxx b/src/MEDLoader/MEDFileData.hxx index d09cfd33e..bdb21eb97 100644 --- a/src/MEDLoader/MEDFileData.hxx +++ b/src/MEDLoader/MEDFileData.hxx @@ -53,6 +53,7 @@ namespace MEDCoupling MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); MEDLOADER_EXPORT bool changeMeshName(const std::string& oldMeshName, const std::string& newMeshName); MEDLOADER_EXPORT bool unPolyzeMeshes(); + MEDLOADER_EXPORT static MCAuto Aggregate(const std::vector& mfds); // MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; private: diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index 612cb82d9..d3c7904a3 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -21,6 +21,7 @@ #include "MEDFileField.hxx" #include "MEDFileMesh.hxx" #include "MEDLoaderBase.hxx" +#include "MEDLoaderTraits.hxx" #include "MEDFileUtilities.hxx" #include "MEDFileSafeCaller.txx" #include "MEDFileFieldOverView.hxx" @@ -1579,10 +1580,6 @@ bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDis return true; } -MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType):_father(fath),_geo_type(geoType) -{ -} - MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd):_father(fath),_geo_type(geoType) { INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); @@ -2341,6 +2338,63 @@ const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAn throw INTERP_KERNEL::Exception(oss.str()); } +/*! + * dts = level 1 meshes to aggregate. Level 2 all geo type. Level 3 pair specifying geo type and number of elem in geotype. + */ +MCAuto MEDFileFieldPerMeshPerTypePerDisc::Aggregate(int &start, const std::vector< std::pair >& pms, const std::vector< std::vector< std::pair > >& dts, TypeOfField tof, MEDFileFieldPerMeshPerType *father, std::vector > >& extractInfo) +{ + MCAuto ret(new MEDFileFieldPerMeshPerTypePerDisc(father,tof)); + for(std::vector >::const_iterator it=pms.begin();it!=pms.end();it++) + { + if(!(*it).second->getProfile().empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for profiles !"); + if(!(*it).second->getLocalization().empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for gauss pts !"); + //getNumberOfTuples + } + return ret; +} + +MCAuto MEDFileFieldPerMeshPerType::Aggregate(int &start, const std::vector >& pms, const std::vector< std::vector< std::pair > >& dts, INTERP_KERNEL::NormalizedCellType gt, MEDFileFieldPerMesh *father, std::vector > >& extractInfo) +{ + MCAuto ret(new MEDFileFieldPerMeshPerType(father,gt)); + std::map > > m; + for(std::vector >::const_iterator it=pms.begin();it!=pms.end();it++) + { + for(std::vector< MCAuto >::const_iterator it2=(*it).second->_field_pm_pt_pd.begin();it2!=(*it).second->_field_pm_pt_pd.end();it2++) + m[(*it2)->getType()].push_back(std::pair((*it).first,*it2)); + } + for(std::map > >::const_iterator it=m.begin();it!=m.end();it++) + { + MCAuto agg(MEDFileFieldPerMeshPerTypePerDisc::Aggregate(start,(*it).second,dts,(*it).first,ret,extractInfo)); + ret->_field_pm_pt_pd.push_back(agg); + } + return ret; +} + +MCAuto MEDFileFieldPerMesh::Aggregate(const std::vector& pms, const std::vector< std::vector< std::pair > >& dts, MEDFileAnyTypeField1TSWithoutSDA *father, std::vector > >& extractInfo) +{ + MCAuto ret(new MEDFileFieldPerMesh(father,pms[0]->getMeshName(),pms[0]->getMeshIteration(),pms[0]->getMeshOrder())); + std::map > > m; + std::size_t i(0); + for(std::vector::const_iterator it=pms.begin();it!=pms.end();it++,i++) + { + const std::vector< MCAuto< MEDFileFieldPerMeshPerType > >& v((*it)->_field_pm_pt); + for(std::vector< MCAuto< MEDFileFieldPerMeshPerType > >::const_iterator it2=v.begin();it2!=v.end();it2++) + { + INTERP_KERNEL::NormalizedCellType gt((*it2)->getGeoType()); + m[gt].push_back(std::pair(i,*it2)); + } + } + int start(0); + for(std::map > >::const_iterator it=m.begin();it!=m.end();it++) + { + MCAuto agg(MEDFileFieldPerMeshPerType::Aggregate(start,(*it).second,dts,(*it).first,ret,extractInfo)); + ret->_field_pm_pt.push_back(agg); + } + return ret; +} + int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type) { int i=0; @@ -5149,6 +5203,28 @@ MEDFileIntField1TSWithoutSDA *MEDFileField1TSWithoutSDA::convertToInt() const return ret.retn(); } +void MEDFileField1TSWithoutSDA::aggregate(const std::vector& f1tss, const std::vector< std::vector< std::pair > >& dts) +{ + if(f1tss.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::aggregate : empty vector !"); + std::vector pms; + for(std::vector::const_iterator it=f1tss.begin();it!=f1tss.end();it++) + { + if(!*it) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::aggregate : presence of null pointer in input vector !"); + if((*it)->_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::aggregate : no info !"); + pms.push_back((*it)->_field_per_mesh[0]); + } + std::vector > > extractInfo; + MCAuto fpm(MEDFileFieldPerMesh::Aggregate(pms,dts,this,extractInfo)); + _field_per_mesh.push_back(fpm); + int iteration,order; + double tv(f1tss[0]->getTime(iteration,order)); + _iteration=iteration; _order=order; _dt=tv; + +} + /*! * Returns a pointer to the underground DataArrayDouble instance. So the * caller should not decrRef() it. This method allows for a direct access to the field @@ -9094,6 +9170,96 @@ MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::extractPart(const std::m return fmtsOut.retn(); } +template +MCAuto AggregateHelperF1TS(const std::vector< typename MLFieldTraits::F1TSType const *>& f1tss, const std::vector< std::vector< std::pair > >& dts) +{ + MCAuto< typename MLFieldTraits::F1TSType > ret(MLFieldTraits::F1TSType::New()); + if(f1tss.empty()) + throw INTERP_KERNEL::Exception("AggregateHelperF1TS : empty vector !"); + std::size_t sz(f1tss.size()),i(0); + std::vector< typename MLFieldTraits::F1TSWSDAType const *> f1tsw(sz); + for(typename std::vector< typename MLFieldTraits::F1TSType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++,i++) + { + typename MLFieldTraits::F1TSType const *elt(*it); + if(!elt) + throw INTERP_KERNEL::Exception("AggregateHelperF1TS : presence of a null pointer !"); + f1tsw[i]=dynamic_cast::F1TSWSDAType const *>(elt->contentNotNullBase()); + } + typename MLFieldTraits::F1TSWSDAType *retc(dynamic_cast::F1TSWSDAType *>(ret->contentNotNullBase())); + if(!retc) + throw INTERP_KERNEL::Exception("AggregateHelperF1TS : internal error 1 !"); + retc->aggregate(f1tsw,dts); + return DynamicCast::F1TSType , MEDFileAnyTypeField1TS>(ret); +} + +template +MCAuto< MEDFileAnyTypeFieldMultiTS > AggregateHelperFMTS(const std::vector< typename MLFieldTraits::FMTSType const *>& fmtss, const std::vector< std::vector< std::pair > >& dts) +{ + MCAuto< typename MLFieldTraits::FMTSType > ret(MLFieldTraits::FMTSType::New()); + if(fmtss.empty()) + throw INTERP_KERNEL::Exception("AggregateHelperFMTS : empty vector !"); + std::size_t sz(fmtss.size()); + for(typename std::vector< typename MLFieldTraits::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++) + { + typename MLFieldTraits::FMTSType const *elt(*it); + if(!elt) + throw INTERP_KERNEL::Exception("AggregateHelperFMTS : presence of null pointer !"); + } + int nbTS(fmtss[0]->getNumberOfTS()); + for(typename std::vector< typename MLFieldTraits::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++) + if((*it)->getNumberOfTS()!=nbTS) + throw INTERP_KERNEL::Exception("AggregateHelperFMTS : all fields must have the same number of TS !"); + for(int iterTS=0;iterTS::F1TSType const *> f1tss(sz); + for(typename std::vector< typename MLFieldTraits::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++,i++) + { + f1tss[i]=(*it)->getTimeStepAtPos(i); + } + MCAuto f1ts(AggregateHelperF1TS(f1tss,dts)); + ret->pushBackTimeStep(f1ts); + } + return DynamicCast::FMTSType , MEDFileAnyTypeFieldMultiTS>(ret); +} + +/*! + * \a dts and \a ftmss are expected to have same size. + */ +MCAuto MEDFileAnyTypeFieldMultiTS::Aggregate(const std::vector& fmtss, const std::vector< std::vector< std::pair > >& dts) +{ + if(fmtss.empty()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : input vector is empty !"); + std::size_t sz(fmtss.size()); + std::vector fmtss1; + std::vector fmtss2; + for(std::vector::const_iterator it=fmtss.begin();it!=fmtss.end();it++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : presence of null instance in input vector !"); + const MEDFileFieldMultiTS *elt1(dynamic_cast(*it)); + if(elt1) + { + fmtss1.push_back(elt1); + continue; + } + const MEDFileIntFieldMultiTS *elt2(dynamic_cast(*it)); + if(elt2) + { + fmtss2.push_back(elt2); + continue; + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : not recognized type !"); + } + if(fmtss1.size()!=sz && fmtss2.size()!=sz) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : type of data is not homogeneous !"); + if(fmtss1.size()==sz) + return AggregateHelperFMTS(fmtss1,dts); + if(fmtss2.size()!=sz) + return AggregateHelperFMTS(fmtss2,dts); + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : not implemented yet !"); +} + MEDFileAnyTypeFieldMultiTSIterator *MEDFileAnyTypeFieldMultiTS::iterator() { return new MEDFileAnyTypeFieldMultiTSIterator(this); @@ -9899,7 +10065,7 @@ DataArrayInt *MEDFileIntFieldMultiTS::getFieldWithProfile(TypeOfField type, int * delete this field using decrRef() as it is no more needed. * \throw If \a pos is not a valid time step id. */ -MEDFileAnyTypeField1TS *MEDFileIntFieldMultiTS::getTimeStepAtPos(int pos) const +MEDFileIntField1TS *MEDFileIntFieldMultiTS::getTimeStepAtPos(int pos) const { const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); if(!item) diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index a748d0b09..1e8bde153 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -127,6 +127,7 @@ namespace MEDCoupling int getNumberOfTuples() const; int getStart() const { return _start; } int getEnd() const { return _end; } + int getNumberOfVals() const { return _nval; } DataArray *getOrCreateAndGetArray(); const DataArray *getOrCreateAndGetArray() const; const std::vector& getInfo() const; @@ -152,6 +153,8 @@ namespace MEDCoupling static MEDFileFieldPerMeshPerTypePerDisc *NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt, bool isPfl, int nbi, int offset, std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, MEDFileFieldGlobsReal& glob, bool ¬InExisting); + static MCAuto Aggregate(int &start, const std::vector >& pms, const std::vector< std::vector< std::pair > >& dts, TypeOfField tof, MEDFileFieldPerMeshPerType *father, std::vector > >& extractInfo); + MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type):_type(type),_father(fath),_start(-1),_end(-1),_nval(-1),_loc_id(-5),_profile_it(-1) { } private: MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd); MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const std::string& dummy); @@ -216,19 +219,21 @@ namespace MEDCoupling void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId); const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId) const; + int getNumberOfLoc() const { return _field_pm_pt_pd.size(); } 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< MCAuto< 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); + static MCAuto Aggregate(int &start, const std::vector< std::pair >& pms, const std::vector< std::vector< std::pair > >& dts, INTERP_KERNEL::NormalizedCellType gt, MEDFileFieldPerMesh *father, std::vector > >& extractInfo); + MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *father, INTERP_KERNEL::NormalizedCellType gt):_father(father),_geo_type(gt) { } private: std::vector addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); std::vector addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); std::vector addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); std::vector addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd); - MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType); private: MEDFileFieldPerMesh *_father; std::vector< MCAuto > _field_pm_pt_pd; @@ -284,6 +289,7 @@ namespace MEDCoupling void getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId); const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const; + static MCAuto Aggregate(const std::vector& pms, const std::vector< std::vector< std::pair > >& dts, MEDFileAnyTypeField1TSWithoutSDA *father, std::vector > >& extractInfo); private: int addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type); MEDCouplingFieldDouble *finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, @@ -303,6 +309,7 @@ namespace MEDCoupling static int ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& locs); MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities); MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); + MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const std::string& meshName, int meshIt, int meshOrd):_father(fath),_mesh_name(meshName),_mesh_iteration(meshIt),_mesh_order(meshOrd) { } private: std::string _mesh_name; int _mesh_iteration; @@ -589,6 +596,7 @@ namespace MEDCoupling MEDLOADER_EXPORT DataArrayDouble *getOrCreateAndGetArrayDouble(); MEDLOADER_EXPORT const DataArrayDouble *getOrCreateAndGetArrayDouble() const; MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA *convertToInt() const; + MEDLOADER_EXPORT void aggregate(const std::vector& f1tss, const std::vector< std::vector< std::pair > >& dts); protected: MCAuto< DataArrayDouble > _arr; public: @@ -617,6 +625,7 @@ namespace MEDCoupling MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayInt() const; MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayIntExt(std::vector< std::pair,std::pair > >& entries) const; MEDLOADER_EXPORT MEDFileField1TSWithoutSDA *convertToDouble() const; + MEDLOADER_EXPORT void aggregate(const std::vector& f1tss, const std::vector< std::vector< std::pair > >& dts); protected: MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); protected: @@ -1000,6 +1009,7 @@ namespace MEDCoupling public: MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *buildNewEmpty() const = 0; MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *extractPart(const std::map >& extractDef, MEDFileMesh *mm) const; + MEDLOADER_EXPORT static MCAuto Aggregate(const std::vector& fmtss, const std::vector< std::vector< std::pair > >& dts); public: MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; @@ -1076,7 +1086,7 @@ namespace MEDCoupling MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll=true); MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *shallowCpy() const; MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; + MEDLOADER_EXPORT MEDFileIntField1TS *getTimeStepAtPos(int pos) const; MEDLOADER_EXPORT MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const; // MEDLOADER_EXPORT MEDCouplingFieldInt *field(int iteration, int order, const MEDFileMesh *mesh) const; diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 9f956cb65..62f59518f 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -2090,6 +2090,9 @@ std::vector MEDFileMesh::getAllGeoTypes() con return ret; } +/*! + * \sa getAllDistributionOfTypes + */ std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const { MCAuto mLev(getMeshAtLevel(meshDimRelToMax)); @@ -3588,6 +3591,30 @@ MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_ return sp->getDirectUndergroundSingleGeoTypeMesh(gt); } +/*! + * This method returns for each geo types in \a this number of cells with this geo type. + * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated. + * This method also returns the number of nodes of \a this (key associated is NORM_ERROR) + * + * \sa getDistributionOfTypes + */ +std::vector< std::pair > MEDFileUMesh::getAllDistributionOfTypes() const +{ + std::vector< std::pair > ret; + std::vector nel(getNonEmptyLevels()); + for(std::vector::reverse_iterator it=nel.rbegin();it!=nel.rend();it++) + { + std::vector gt(getGeoTypesAtLevel(*it)); + for(std::vector::const_iterator it1=gt.begin();it1!=gt.end();it1++) + { + int nbCells(getNumberOfCellsWithType(*it1)); + ret.push_back(std::pair(*it1,nbCells)); + } + } + ret.push_back(std::pair(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes())); + return ret; +} + /*! * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this. * \throw if the reqsuested \a meshDimRelToMax does not exist. @@ -4499,6 +4526,102 @@ MCAuto MEDFileUMesh::symmetry3DPlane(const double point[3], const return ret; } +MCAuto MEDFileUMesh::Aggregate(const std::vector& meshes) +{ + if(meshes.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !"); + std::size_t sz(meshes.size()),i(0); + std::vector coos(sz); + std::vector fam_coos(sz),num_coos(sz); + for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++,i++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !"); + coos[i]=(*it)->getCoords(); + fam_coos[i]=(*it)->getFamilyFieldAtLevel(1); + num_coos[i]=(*it)->getNumberFieldAtLevel(1); + } + const MEDFileUMesh *ref(meshes[0]); + int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension()); + std::vector levs(ref->getNonEmptyLevels()); + std::map > m_fam,m_renum; + std::map > m_mesh; + std::map map1; + std::map > map2; + for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++,i++) + { + if((*it)->getSpaceDimension()!=spaceDim) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !"); + if((*it)->getMeshDimension()!=meshDim) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !"); + if((*it)->getNonEmptyLevels()!=levs) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !"); + for(std::vector::const_iterator it2=levs.begin();it2!=levs.end();it2++) + { + m_mesh[*it2].push_back((*it)->getMeshAtLevel(*it2)); + m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2)); + m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2)); + } + const std::map& locMap1((*it)->getFamilyInfo()); + for(std::map::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++) + map1[(*it3).first]=(*it3).second; + const std::map >& locMap2((*it)->getGroupInfo()); + for(std::map >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++) + map2[(*it4).first]=(*it4).second; + } + // Easy part : nodes + MCAuto ret(MEDFileUMesh::New()); + MCAuto coo(DataArrayDouble::Aggregate(coos)); + ret->setCoords(coo); + if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end()) + { + MCAuto fam_coo(DataArrayInt::Aggregate(fam_coos)); + ret->setFamilyFieldArr(1,fam_coo); + } + if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end()) + { + MCAuto num_coo(DataArrayInt::Aggregate(num_coos)); + ret->setRenumFieldArr(1,num_coo); + } + // cells + for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) + { + std::map >::const_iterator it2(m_mesh.find(*it)); + if(it2==m_mesh.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !"); + MCAuto mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second)); + mesh->setCoords(coo); mesh->setName(ref->getName()); + ret->setMeshAtLevel(*it,mesh); + MCAuto renum(mesh->sortCellsInMEDFileFrmt()); + std::map >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it)); + if(it3!=m_fam.end()) + { + const std::vector& fams((*it3).second); + if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end()) + { + MCAuto famm(DataArrayInt::Aggregate(fams)); + famm->renumberInPlace(renum->begin()); + ret->setFamilyFieldArr(*it,famm); + } + } + if(it4!=m_renum.end()) + { + const std::vector& renums((*it4).second); + if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end()) + { + MCAuto renumm(DataArrayInt::Aggregate(renums)); + renumm->renumberInPlace(renum->begin()); + ret->setRenumFieldArr(1,renumm); + } + } + } + // + ret->setFamilyInfo(map1); + ret->setGroupInfo(map2); + ret->setName(ref->getName()); + return ret; +} + void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MCAuto >& bigArraysI, MCAuto& bigArrayD) { clearNonDiscrAttributes(); diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index d47a334b5..1e0f48bb2 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -299,6 +299,7 @@ namespace MEDCoupling MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; MEDLOADER_EXPORT MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMax, bool renum=false) const; MEDLOADER_EXPORT std::vector getDistributionOfTypes(int meshDimRelToMax) const; + MEDLOADER_EXPORT std::vector< std::pair > getAllDistributionOfTypes() const; MEDLOADER_EXPORT MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const; MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const; MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const; @@ -336,6 +337,7 @@ namespace MEDCoupling MEDLOADER_EXPORT MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const; MEDLOADER_EXPORT MEDFileUMesh *quadraticToLinear(double eps=1e-12) const; MEDLOADER_EXPORT MCAuto symmetry3DPlane(const double point[3], const double normalVector[3]) const; + MEDLOADER_EXPORT static MCAuto Aggregate(const std::vector& meshes); // serialization MEDLOADER_EXPORT void serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MCAuto >& bigArraysI, MCAuto& bigArrayD); diff --git a/src/MEDLoader/MEDLoaderTraits.hxx b/src/MEDLoader/MEDLoaderTraits.hxx new file mode 100644 index 000000000..25cdfb3ee --- /dev/null +++ b/src/MEDLoader/MEDLoaderTraits.hxx @@ -0,0 +1,58 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __MEDLOADERTRAITS_HXX__ +#define __MEDLOADERTRAITS_HXX__ + +#include "MEDLoaderDefines.hxx" + +namespace MEDCoupling +{ + template + struct MEDLOADER_EXPORT MLFieldTraits + { + typedef T EltType; + }; + + class MEDFileFieldMultiTS; + class MEDFileField1TS; + class MEDFileIntFieldMultiTS; + class MEDFileIntField1TS; + class MEDFileField1TSWithoutSDA; + class MEDFileIntField1TSWithoutSDA; + + template<> + struct MEDLOADER_EXPORT MLFieldTraits + { + typedef MEDFileFieldMultiTS FMTSType; + typedef MEDFileField1TS F1TSType; + typedef MEDFileField1TSWithoutSDA F1TSWSDAType; + }; + + template<> + struct MEDLOADER_EXPORT MLFieldTraits + { + typedef MEDFileIntFieldMultiTS FMTSType; + typedef MEDFileIntField1TS F1TSType; + typedef MEDFileIntField1TSWithoutSDA F1TSWSDAType; + }; +} + +#endif