From: ageay Date: Fri, 24 Feb 2012 11:31:45 +0000 (+0000) Subject: MEDfileMesh::getNonEmptyLevels() X-Git-Tag: V6_main_FINAL~823 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=918308d83e8a66962c3d4f418d9f0e1f02582e8a;p=tools%2Fmedcoupling.git MEDfileMesh::getNonEmptyLevels() --- diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index d48dc5a17..134f13694 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -2104,6 +2104,63 @@ std::vector& MEDFileField1TSWithoutDAS::getInfo() return arr->getInfoOnComponents(); } +/*! + * This method has one input 'mname'. It can be null if the user is the general case where there is only one meshName lying on 'this' + * This method returns two things. + * - The absolute dimension of 'this' in first parameter. + * - The available ext levels relative to the absolute dimension returned in first parameter. These relative levels are relative + * to the first output parameter. The values in 'levs' will be returned in decreasing order. + * + * This method is designed for MEDFileField1TS instances that have a discritization ON_CELLS, ON_GAUSS_NE and ON_GAUSS. + * Only these 3 discretizations will be taken into account here. + * + * If 'this' is empty this method will throw an INTERP_KERNEL::Exception. + * If there is \b only node fields defined in 'this' -1 is returned and 'levs' output parameter will be empty. In this + * case the caller has to know the underlying mesh it refers to. By defaut it is the level 0 of the corresponding mesh. + * + * This method is usefull to make the link between meshDimension of the underlying mesh in 'this' and the levels on 'this'. + * It is possible (even if it is not common) that the highest level in 'this' were not equal to the meshDimension of the underlying mesh in 'this'. + * + * Let's consider the typical following case : + * - a mesh 'm1' has a meshDimension 3 and has the following non empty levels + * [0,-1,-2] for example 'm1' lies on TETRA4, HEXA8 TRI3 and SEG2 + * - 'f1' lies on 'm1' and is defined on 3D and 1D cells for example + * TETRA4 and SEG2 + * - 'f2' lies on 'm1' too and is defined on 2D and 1D cells for example TRI3 and SEG2 + * + * In this case f1->getNonEmptyLevelsExt will return (3,[0,-2]) and f2->getNonEmptyLevelsExt will return (2,[0,-1]) + * + * To retrieve the highest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+(-2));//absDim-meshDim+relativeLev + * To retrieve the highest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+(-1));//absDim-meshDim+relativeLev + */ +int MEDFileField1TSWithoutDAS::getNonEmptyLevels(const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception) +{ + levs.clear(); + int meshId=getMeshIdFromMeshName(mname); + std::vector types; + std::vector< std::vector > typesF; + std::vector< std::vector > pfls, locs; + _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); + if(types.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutDAS::getNonEmptyLevels : 'this' is empty !"); + std::set st(types.begin(),types.end()); + if(st.size()==1 && (*st.begin())==INTERP_KERNEL::NORM_ERROR) + return -1; + st.erase(INTERP_KERNEL::NORM_ERROR); + std::set ret1; + for(std::set::const_iterator it=st.begin();it!=st.end();it++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*it); + ret1.insert((int)cm.getDimension()); + } + int ret=*std::max_element(ret1.begin(),ret1.end()); + std::copy(ret1.rbegin(),ret1.rend(),std::back_insert_iterator >(levs)); + std::transform(levs.begin(),levs.end(),levs.begin(),std::bind2nd(std::plus(),-ret)); + return ret; +} + std::vector MEDFileField1TSWithoutDAS::getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) { std::vector ret; @@ -2445,6 +2502,8 @@ int MEDFileField1TSWithoutDAS::getMeshIdFromMeshName(const char *mName) const th { if(_field_per_mesh.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutDAS::getMeshIdFromMeshName : No field set !"); + if(mName==0) + return 0; std::string mName2(mName); int ret=0; std::vector msg; @@ -2867,6 +2926,42 @@ std::vector< std::pair > MEDFileFieldMultiTSWithoutDAS::getIterations() return ret; } +/*! + * This method has 3 inputs 'iteration' 'order' 'mname'. 'mname' can be null if the user is the general case where there is only one meshName lying on 'this' + * This method returns two things. + * - The absolute dimension of 'this' in first parameter. + * - The available ext levels relative to the absolute dimension returned in first parameter. These relative levels are relative + * to the first output parameter. The values in 'levs' will be returned in decreasing order. + * + * This method is designed for MEDFileFieldMultiTS instances that have a discritization ON_CELLS, ON_GAUSS_NE and ON_GAUSS. + * Only these 3 discretizations will be taken into account here. + * + * If 'this' is empty this method will throw an INTERP_KERNEL::Exception. + * If there is \b only node fields defined in 'this' -1 is returned and 'levs' output parameter will be empty. In this + * case the caller has to know the underlying mesh it refers to. By defaut it is the level 0 of the corresponding mesh. + * + * This method is usefull to make the link between meshDimension of the underlying mesh in 'this' and the levels on 'this'. + * It is possible (even if it is not common) that the highest level in 'this' were not equal to the meshDimension of the underlying mesh in 'this'. + * + * Let's consider the typical following case : + * - a mesh 'm1' has a meshDimension 3 and has the following non empty levels + * [0,-1,-2] for example 'm1' lies on TETRA4, HEXA8 TRI3 and SEG2 + * - 'f1' lies on 'm1' and is defined on 3D and 1D cells for example + * TETRA4 and SEG2 + * - 'f2' lies on 'm1' too and is defined on 2D and 1D cells for example TRI3 and SEG2 + * + * In this case f1->getNonEmptyLevelsExt will return (3,[0,-2]) and f2->getNonEmptyLevelsExt will return (2,[0,-1]) + * + * To retrieve the highest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+(-2));//absDim-meshDim+relativeLev + * To retrieve the highest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+(-1));//absDim-meshDim+relativeLev + */ +int MEDFileFieldMultiTSWithoutDAS::getNonEmptyLevels(int iteration, int order, const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception) +{ + return getTimeStepEntry(iteration,order).getNonEmptyLevels(mname,levs); +} + std::vector< std::vector > MEDFileFieldMultiTSWithoutDAS::getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) { int lgth=_time_steps.size(); diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index 4bbc0570b..e31abf114 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -350,6 +350,7 @@ namespace ParaMEDMEM void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, MEDFieldFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFieldFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); public: + int getNonEmptyLevels(const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception); std::vector getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception); std::vector< std::vector > > getFieldSplitedByType(const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception); std::vector< std::vector > getFieldSplitedByType2(const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception); @@ -413,6 +414,7 @@ namespace ParaMEDMEM static MEDFileFieldMultiTSWithoutDAS *New(med_idt fid, const char *fieldName, int id, int ft, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception); int getNumberOfTS() const; std::vector< std::pair > getIterations() const; + int getNonEmptyLevels(int iteration, int order, const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception); std::vector< std::vector > getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception); std::vector< std::vector< std::pair > > getFieldSplitedByType(int iteration, int order, const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception); std::vector< std::vector > getFieldSplitedByType2(int iteration, int order, const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/Swig/MEDLoader.i b/src/MEDLoader/Swig/MEDLoader.i index b83fbfeb9..893661373 100644 --- a/src/MEDLoader/Swig/MEDLoader.i +++ b/src/MEDLoader/Swig/MEDLoader.i @@ -701,6 +701,16 @@ namespace ParaMEDMEM return ret2; } + PyObject *getNonEmptyLevels(const char *mname=0) const throw(INTERP_KERNEL::Exception) + { + std::vector ret1; + int ret0=self->getNonEmptyLevels(mname,ret1); + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); + PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); + return elt; + } + PyObject *getFieldSplitedByType(const char *mname=0) const throw(INTERP_KERNEL::Exception) { std::vector types; @@ -891,6 +901,16 @@ namespace ParaMEDMEM return ret2; } + PyObject *getNonEmptyLevels(int iteration, int order, const char *mname=0) const throw(INTERP_KERNEL::Exception) + { + std::vector ret1; + int ret0=self->getNonEmptyLevels(iteration,order,mname,ret1); + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); + PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); + return elt; + } + PyObject *getFieldSplitedByType(int iteration, int order, const char *mname=0) const throw(INTERP_KERNEL::Exception) { std::vector types; diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 79e6a639e..08b84a70b 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -659,6 +659,7 @@ class MEDLoaderTest(unittest.TestCase): da=DataArrayInt.New(); da.setValues([1,2,4,5,7,8],6,1) ; da.setName("sup1Node") # ff1.setFieldProfile(f1,mm1,0,da) + self.assertEqual(ff1.getNonEmptyLevels(),(-1, [])) ff1.write(fname,0) # vals,pfl=ff1.getFieldWithProfile(ON_NODES,0,mm1) ; vals.setName("") @@ -972,6 +973,76 @@ class MEDLoaderTest(unittest.TestCase): f4=MEDLoader.ReadFieldCell(fname,"3DSurfMesh_2",0,"VectorFieldOnCells2",0,1) self.assertTrue(f4.isEqual(f2,1e-12,1e-12)) pass + + def testMEDLoaderMultiLevelCellField1(self): + fname="Pyfile42.med" + m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() + m=MEDFileUMesh.New() + m.setCoords(m2.getCoords()) + m.setMeshAtLevel(0,m2) + m.setMeshAtLevel(-1,m1) + m.setMeshAtLevel(-2,m0) + m.write(fname,2) + # + FieldName1="Field1" + compNames1=["comp1","comp2","comp3"] + ff1=MEDFileField1TS.New() + da2=DataArrayDouble.New() + da2.alloc(m2.getNumberOfCells()*len(compNames1),1) + da2.iota(7.) + da2.rearrange(len(compNames1)) + da2.setInfoOnComponents(compNames1) + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f2.setName(FieldName1) ; f2.setArray(da2) ; f2.setMesh(m2) ; f2.checkCoherency() + ff1.setFieldNoProfileSBT(f2) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0])) + da0=DataArrayDouble.New() + da0.alloc(m0.getNumberOfCells()*len(compNames1),1) + da0.iota(190.) + da0.rearrange(len(compNames1)) + da0.setInfoOnComponents(compNames1) + f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName1) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() + ff1.setFieldNoProfileSBT(f0) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-2])) + da1=DataArrayDouble.New() + da1.alloc(m1.getNumberOfCells()*len(compNames1),1) + da1.iota(90.) + da1.rearrange(len(compNames1)) + da1.setInfoOnComponents(compNames1) + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName1) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() + ff1.setFieldNoProfileSBT(f1) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) + # + ff1.write(fname,0) + # + FieldName2="Field2" + compNames2=["comp11","comp22"] + ff2=MEDFileField1TS.New() + da0=DataArrayDouble.New() + da0.alloc(m0.getNumberOfCells()*2,1) + da0.iota(-190.) + da0.rearrange(2) + da0.setInfoOnComponents(compNames2) + f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName2) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() + ff2.setFieldNoProfileSBT(f0) + self.assertEqual(ff2.getNonEmptyLevels(),(0, [0])) + da1=DataArrayDouble.New() + da1.alloc(m1.getNumberOfCells()*len(compNames2),1) + da1.iota(-90.) + da1.rearrange(len(compNames2)) + da1.setInfoOnComponents(compNames2) + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName2) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() + ff2.setFieldNoProfileSBT(f1) + self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) + # + ff2.write(fname,0) + # + ff1=MEDFileField1TS.New(fname,FieldName1,-1,-1) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) + self.assertEqual(ff1.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')]), (3, [(0, (84, 148), '', '')]), (4, [(0, (148, 212), '', '')])]) + ff2=MEDFileField1TS.New(fname,FieldName2,-1,-1) + self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) + self.assertEqual(ff2.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')])]) + pass pass unittest.main()