From: ageay Date: Tue, 17 Sep 2013 08:43:17 +0000 (+0000) Subject: MEDCouplingFieldDouble::nodeToCellDiscretization X-Git-Tag: V7_3_1b1~152 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=267a4b340f2b5b7e5e2c00797486a7611777313a;p=tools%2Fmedcoupling.git MEDCouplingFieldDouble::nodeToCellDiscretization --- diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx index 2931cac0a..a4a0534f6 100644 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -174,10 +174,13 @@ std::vector MEDCouplingField::getDirectChildren() const /*! * Returns a type of \ref MEDCouplingSpatialDisc "spatial discretization" of \a this * field in terms of enum ParaMEDMEM::TypeOfField. - * \return ParaMEDMEM::TypeOfField - the type of \a this field. + * \return ParaMEDMEM::TypeOfField - the type of \a this field. + * \throw If the geometric type is empty. */ TypeOfField MEDCouplingField::getTypeOfField() const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingField::getTypeOfField : spatial discretization is null !"); return _type->getEnum(); } diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index b18199dd6..e721d1423 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -217,6 +217,62 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfT return ret.retn(); } +/*! + * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping ! + * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach + * to each cell the average of values on nodes constituting this cell. + * + * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. + * \throw If \a this spatial discretization is empty or not ON_NODES. + * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). + * + * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization. + * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P1P0" method. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const +{ + checkCoherency(); + TypeOfField tf(getTypeOfField()); + if(tf!=ON_NODES) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !"); + MEDCouplingAutoRefCountObjectPtr ret(clone(false)); + MEDCouplingAutoRefCountObjectPtr nsp(new MEDCouplingFieldDiscretizationP0); + ret->setDiscretization(nsp); + const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call + int nbCells(m->getNumberOfCells()),nbNodes(m->getNumberOfNodes()); + std::vector arrs(getArrays()); + std::size_t sz(arrs.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr > outArrsSafe(sz); std::vector outArrs(sz); + for(std::size_t j=0;jgetNumberOfComponents()); + outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo); + outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); + outArrs[j]=outArrsSafe[j]; + double *pt(outArrsSafe[j]->getPointer()); + const double *srcPt(arrs[j]->begin()); + for(int i=0;i nodeIds; + m->getNodeIdsOfCell(i,nodeIds); + std::fill(pt,pt+nbCompo,0.); + std::size_t nbNodesInCell(nodeIds.size()); + for(std::size_t k=0;k()); + if(nbNodesInCell!=0) + std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies(),1./((double)nbNodesInCell))); + else + { + std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + ret->setArrays(outArrs); + return ret.retn(); +} + /*! * Copies tiny info (component names, name and description) from an \a other field to * \a this one. diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index d0696a804..b64819edc 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -63,6 +63,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingFieldDouble *clone(bool recDeepCpy) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *nodeToCellDiscretization() const; MEDCOUPLING_EXPORT TypeOfTimeDiscretization getTimeDiscretization() const; MEDCOUPLING_EXPORT void checkCoherency() const; MEDCOUPLING_EXPORT void setNature(NatureOfField nat); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 9b2a1527b..b560dbafb 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -13830,6 +13830,27 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(f4.getMesh(),None) pass + # test a simple node to cell convertion of a field + def testSwig2NodeToCellDiscretization1(self): + f=MEDCouplingFieldDouble(ON_NODES) ; f.setTime(1.1,2,3) + a1=DataArrayDouble(4) ; a1.iota() + a2=DataArrayDouble(3) ; a2.iota() + m=MEDCouplingCMesh() ; m.setCoords(a1,a2) + f.setMesh(m) + arr=DataArrayDouble([21.,121.,20.,120.,19.,119.,18.,118.,17.,117.,16.,116.,15.,115.,14.,114.,13.,113.,12.,112.,11.,111.,10.,110.],12,2) ; arr.setInfoOnComponents(["aa [km]","bbb [kJ]"]) + f.setArray(arr) ; f.setName("toto") + # + f2=f.nodeToCellDiscretization() + self.assertEqual(ON_CELLS,f2.getTypeOfField()) + self.assertEqual("toto",f2.getName()) + self.assertEqual([1.1,2,3],f2.getTime()) + self.assertEqual(["aa [km]","bbb [kJ]"],f2.getArray().getInfoOnComponents()) + self.assertEqual(6,f2.getArray().getNumberOfTuples()) + self.assertEqual(f.getMesh().getHiddenCppPointer(),f2.getMesh().getHiddenCppPointer()) + exp=DataArrayDouble([18.5,118.5,17.5,117.5,16.5,116.5,14.5,114.5,13.5,113.5,12.5,112.5],6,2) ; exp.setInfoOnComponents(["aa [km]","bbb [kJ]"]) + self.assertTrue(f2.getArray().isEqual(exp,1e-13)) + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index a511180cd..5f62bec58 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -207,6 +207,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh; %newobject ParaMEDMEM::MEDCouplingFieldDouble::deepCpy; %newobject ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::nodeToCellDiscretization; %newobject ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti; %newobject ParaMEDMEM::MEDCouplingFieldTemplate::New; %newobject ParaMEDMEM::DataArray::deepCpy; @@ -3391,6 +3392,7 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; MEDCouplingFieldDouble *deepCpy() const; MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *nodeToCellDiscretization() const throw(INTERP_KERNEL::Exception); TypeOfTimeDiscretization getTimeDiscretization() const throw(INTERP_KERNEL::Exception); double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); double getIJK(int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception);