From 2832aba2a52c176771e4b400008a395e0ca43cf2 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 1 Oct 2014 08:49:34 +0200 Subject: [PATCH] Part definition class to prepare implementation of functionalities in MEDLoader for ParaMEDReader. --- src/MEDCoupling/CMakeLists.txt | 1 + src/MEDCoupling/MEDCouplingPartDefinition.cxx | 227 ++++++++++++++++++ src/MEDCoupling/MEDCouplingPartDefinition.hxx | 92 +++++++ src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 38 +++ src/MEDCoupling_Swig/MEDCouplingCommon.i | 95 ++++++++ src/MEDCoupling_Swig/MEDCouplingTypemaps.i | 15 ++ 6 files changed, 468 insertions(+) create mode 100644 src/MEDCoupling/MEDCouplingPartDefinition.cxx create mode 100644 src/MEDCoupling/MEDCouplingPartDefinition.hxx diff --git a/src/MEDCoupling/CMakeLists.txt b/src/MEDCoupling/CMakeLists.txt index 5c462b1e4..785a37d38 100644 --- a/src/MEDCoupling/CMakeLists.txt +++ b/src/MEDCoupling/CMakeLists.txt @@ -58,6 +58,7 @@ SET(medcoupling_SOURCES MEDCouplingCartesianAMRMesh.cxx MEDCouplingAMRAttribute.cxx MEDCouplingMatrix.cxx + MEDCouplingPartDefinition.cxx ) SET(medcouplingremapper_SOURCES diff --git a/src/MEDCoupling/MEDCouplingPartDefinition.cxx b/src/MEDCoupling/MEDCouplingPartDefinition.cxx new file mode 100644 index 000000000..08c1d2282 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingPartDefinition.cxx @@ -0,0 +1,227 @@ +// Copyright (C) 2007-2014 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) + +#include "MEDCouplingPartDefinition.hxx" + +using namespace ParaMEDMEM; + +PartDefinition *PartDefinition::New(int start, int stop, int step) +{ + return SlicePartDefinition::New(start,stop,step); +} + +PartDefinition *PartDefinition::New(DataArrayInt *listOfIds) +{ + return DataArrayPartDefinition::New(listOfIds); +} + +PartDefinition::~PartDefinition() +{ +} + +DataArrayPartDefinition *DataArrayPartDefinition::New(DataArrayInt *listOfIds) +{ + return new DataArrayPartDefinition(listOfIds); +} + +int DataArrayPartDefinition::getNumberOfElems() const +{ + checkInternalArrayOK(); + return _arr->getNumberOfTuples(); +} + +PartDefinition *DataArrayPartDefinition::operator+(const PartDefinition& other) const +{ + const PartDefinition *otherPt(&other); + if(!otherPt) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); + const DataArrayPartDefinition *other1(dynamic_cast(otherPt)); + if(other1) + return add1(other1); + const SlicePartDefinition *other2(dynamic_cast(otherPt)); + if(other2) + return add2(other2); + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : unrecognized type in input !"); +} + +std::string DataArrayPartDefinition::getRepr() const +{ + std::ostringstream oss; oss << "DataArray Part : "; + const DataArrayInt *arr(_arr); + if(arr) + arr->reprQuickOverview(oss); + else + oss << "No Data !"; + return oss.str(); +} + +DataArrayInt *DataArrayPartDefinition::toDAI() const +{ + checkInternalArrayOK(); + const DataArrayInt *arr(_arr); + DataArrayInt *arr2(const_cast(arr)); + arr2->incrRef(); + return arr2; +} + +DataArrayPartDefinition::DataArrayPartDefinition(DataArrayInt *listOfIds) +{ + CheckInternalArrayOK(listOfIds); + _arr=listOfIds; + _arr->incrRef(); +} + +void DataArrayPartDefinition::checkInternalArrayOK() const +{ + CheckInternalArrayOK(_arr); +} + +void DataArrayPartDefinition::CheckInternalArrayOK(const DataArrayInt *listOfIds) +{ + if(!listOfIds || !listOfIds->isAllocated() || listOfIds->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::CheckInternalArrayOK : Input list must be not null allocated and with one components !"); +} + +void DataArrayPartDefinition::updateTime() const +{ + if((const DataArrayInt *)_arr) + updateTimeWith(*_arr); +} + +std::size_t DataArrayPartDefinition::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(DataArrayPartDefinition); +} + +std::vector DataArrayPartDefinition::getDirectChildrenWithNull() const +{ + std::vector ret(1,(const DataArrayInt *)_arr); + return ret; +} + +DataArrayPartDefinition *DataArrayPartDefinition::add1(const DataArrayPartDefinition *other) const +{ + MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); +} + +DataArrayPartDefinition *DataArrayPartDefinition::add2(const SlicePartDefinition *other) const +{ + MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); +} + +DataArrayPartDefinition::~DataArrayPartDefinition() +{ +} + +SlicePartDefinition *SlicePartDefinition::New(int start, int stop, int step) +{ + return new SlicePartDefinition(start,stop,step); +} + +DataArrayInt *SlicePartDefinition::toDAI() const +{ + return DataArrayInt::Range(_start,_stop,_step); +} + +int SlicePartDefinition::getNumberOfElems() const +{ + return DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getNumberOfElems"); +} + +PartDefinition *SlicePartDefinition::operator+(const PartDefinition& other) const +{ + const PartDefinition *otherPt(&other); + if(!otherPt) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); + const DataArrayPartDefinition *other1(dynamic_cast(otherPt)); + if(other1) + return add1(other1); + const SlicePartDefinition *other2(dynamic_cast(otherPt)); + if(other2) + return add2(other2); + throw INTERP_KERNEL::Exception("SlicePartDefinition::operator+ : unrecognized type in input !"); +} + +std::string SlicePartDefinition::getRepr() const +{ + std::ostringstream oss; + oss << "Slice is defined with : start=" << _start << " stop=" << _stop << " step=" << _step; + return oss.str(); +} + +int SlicePartDefinition::getEffectiveStop() const +{ + int nbElems(DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getEffectiveStop")); + return _start+nbElems*_step; +} + +SlicePartDefinition::SlicePartDefinition(int start, int stop, int step):_start(start),_stop(stop),_step(step) +{ +} + +/*! + * No child ! It is the leaf ! So no implementation. + */ +void SlicePartDefinition::updateTime() const +{ +} + +std::size_t SlicePartDefinition::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(SlicePartDefinition); +} + +std::vector SlicePartDefinition::getDirectChildrenWithNull() const +{ + return std::vector(); +} + +DataArrayPartDefinition *SlicePartDefinition::add1(const DataArrayPartDefinition *other) const +{ + MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); +} + +PartDefinition *SlicePartDefinition::add2(const SlicePartDefinition *other) const +{ + if(_step==other->_step && getEffectiveStop()==other->_start) + { + return SlicePartDefinition::New(_start,other->_stop,_step); + } + else + { + MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); + } +} + +SlicePartDefinition::~SlicePartDefinition() +{ +} diff --git a/src/MEDCoupling/MEDCouplingPartDefinition.hxx b/src/MEDCoupling/MEDCouplingPartDefinition.hxx new file mode 100644 index 000000000..a64ca77c1 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingPartDefinition.hxx @@ -0,0 +1,92 @@ +// Copyright (C) 2007-2014 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 __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +namespace ParaMEDMEM +{ + class PartDefinition : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT static PartDefinition *New(int start, int stop, int step); + MEDCOUPLING_EXPORT static PartDefinition *New(DataArrayInt *listOfIds); + MEDCOUPLING_EXPORT virtual DataArrayInt *toDAI() const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfElems() const = 0; + MEDCOUPLING_EXPORT virtual PartDefinition *operator+(const PartDefinition& other) const = 0; + MEDCOUPLING_EXPORT virtual std::string getRepr() const = 0; + protected: + virtual ~PartDefinition(); + }; + + class SlicePartDefinition; + + class DataArrayPartDefinition : public PartDefinition + { + public: + MEDCOUPLING_EXPORT static DataArrayPartDefinition *New(DataArrayInt *listOfIds); + MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; + MEDCOUPLING_EXPORT int getNumberOfElems() const; + MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; + MEDCOUPLING_EXPORT std::string getRepr() const; + private: + DataArrayPartDefinition(DataArrayInt *listOfIds); + void checkInternalArrayOK() const; + static void CheckInternalArrayOK(const DataArrayInt *listOfIds); + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; + DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; + DataArrayPartDefinition *add2(const SlicePartDefinition *other) const; + virtual ~DataArrayPartDefinition(); + private: + MEDCouplingAutoRefCountObjectPtr _arr; + }; + + class SlicePartDefinition : public PartDefinition + { + public: + MEDCOUPLING_EXPORT static SlicePartDefinition *New(int start, int stop, int step); + MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; + MEDCOUPLING_EXPORT int getNumberOfElems() const; + MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; + MEDCOUPLING_EXPORT std::string getRepr() const; + //specific method + MEDCOUPLING_EXPORT int getEffectiveStop() const; + private: + SlicePartDefinition(int start, int stop, int step); + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; + DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; + PartDefinition *add2(const SlicePartDefinition *other) const; + virtual ~SlicePartDefinition(); + private: + int _start; + int _stop; + int _step; + }; +} + +#endif diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 0587b0f97..6d3fa8e9f 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -15919,6 +15919,44 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertTrue(MEDCoupling1DGTUMesh(m0).computeFetchedNodeIds().isEqual(ref)) pass + def testSwig2PartDefinition1(self): + pd=PartDefinition.New(5,22,3) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) + self.assertEqual(pd.getNumberOfElems(),6) + self.assertEqual(pd.getEffectiveStop(),23) + pd=PartDefinition.New(5,23,3) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) + self.assertEqual(pd.getNumberOfElems(),6) + self.assertEqual(pd.getEffectiveStop(),23) + pd=PartDefinition.New(5,22,1) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) + self.assertEqual(pd.getNumberOfElems(),17) + self.assertEqual(pd.getEffectiveStop(),22) + pd=PartDefinition.New(5,23,3)+PartDefinition.New(23,27,3) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertEqual(pd.getNumberOfElems(),8) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20,23,26]))) + self.assertEqual(pd.getEffectiveStop(),29) + pd=SlicePartDefinition(5,22,1) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) + self.assertEqual(pd.getNumberOfElems(),17) + self.assertEqual(pd.getEffectiveStop(),22) + d=DataArrayInt([2,4,5,6,10]) + pd=PartDefinition.New(d) + self.assertTrue(isinstance(pd,DataArrayPartDefinition)) + self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) + pd=DataArrayPartDefinition(d) + self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) + pd=DataArrayPartDefinition(d)+DataArrayPartDefinition(DataArrayInt([12,14,20])) + self.assertTrue(isinstance(pd,DataArrayPartDefinition)) + self.assertEqual(pd.getNumberOfElems(),8) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([2,4,5,6,10,12,14,20]))) + pass + pass if __name__ == '__main__': diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index e4ddc68ec..c5820aef9 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -43,6 +43,7 @@ #include "MEDCouplingCartesianAMRMesh.hxx" #include "MEDCouplingAMRAttribute.hxx" #include "MEDCouplingMatrix.hxx" +#include "MEDCouplingPartDefinition.hxx" #include "MEDCouplingTypemaps.i" #include "InterpKernelAutoPtr.hxx" @@ -150,6 +151,18 @@ using namespace INTERP_KERNEL; } //$$$$$$$$$$$$$$$$$$ +//////////////////// +%typemap(out) ParaMEDMEM::PartDefinition* +{ + $result=convertPartDefinition($1,$owner); +} + +%typemap(out) PartDefinition* +{ + $result=convertPartDefinition($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + #ifdef WITH_NUMPY %init %{ import_array(); %} #endif @@ -374,6 +387,11 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DenseMatrix::__add__; %newobject ParaMEDMEM::DenseMatrix::__sub__; %newobject ParaMEDMEM::DenseMatrix::__mul__; +%newobject ParaMEDMEM::PartDefinition::New; +%newobject ParaMEDMEM::PartDefinition::toDAI; +%newobject ParaMEDMEM::PartDefinition::__add__; +%newobject ParaMEDMEM::DataArrayPartDefinition::New; +%newobject ParaMEDMEM::SlicePartDefinition::New; %feature("unref") MEDCouplingPointSet "$this->decrRef();" %feature("unref") MEDCouplingMesh "$this->decrRef();" @@ -404,6 +422,9 @@ using namespace INTERP_KERNEL; %feature("unref") MEDCouplingDataForGodFather "$this->decrRef();" %feature("unref") MEDCouplingAMRAttribute "$this->decrRef();" %feature("unref") DenseMatrix "$this->decrRef();" +%feature("unref") PartDefinition "$this->decrRef();" +%feature("unref") DataArrayPartDefinition "$this->decrRef();" +%feature("unref") SlicePartDefinition "$this->decrRef();" %rename(assign) *::operator=; %ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo; @@ -5387,6 +5408,80 @@ namespace ParaMEDMEM #endif } }; + + class PartDefinition : public RefCountObject, public TimeLabel + { + public: + static PartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); + static PartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *toDAI() const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfElems() const throw(INTERP_KERNEL::Exception); + virtual std::string getRepr() const throw(INTERP_KERNEL::Exception); + %extend + { + virtual PartDefinition *__add__(const PartDefinition& other) const throw(INTERP_KERNEL::Exception) + { + return (*self)+other; + } + } + protected: + virtual ~PartDefinition(); + }; + + class DataArrayPartDefinition : public PartDefinition + { + public: + static DataArrayPartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); + %extend + { + DataArrayPartDefinition(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception) + { + return DataArrayPartDefinition::New(listOfIds); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->getRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; oss << "DataArrayPartDefinition C++ instance at " << self << "." << std::endl; + oss << self->getRepr(); + return oss.str(); + } + } + protected: + virtual ~DataArrayPartDefinition(); + }; + + class SlicePartDefinition : public PartDefinition + { + public: + static SlicePartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); + int getEffectiveStop() const throw(INTERP_KERNEL::Exception); + %extend + { + SlicePartDefinition(int start, int stop, int step) throw(INTERP_KERNEL::Exception) + { + return SlicePartDefinition::New(start,stop,step); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->getRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; oss << "SlicePartDefinition C++ instance at " << self << "." << std::endl; + oss << self->getRepr(); + return oss.str(); + } + } + protected: + virtual ~SlicePartDefinition(); + }; } %pythoncode %{ diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i index edae65742..5880fc975 100644 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -85,6 +85,21 @@ static PyObject* convertMultiFields(ParaMEDMEM::MEDCouplingMultiFields *mfs, int return ret; } +static PyObject *convertPartDefinition(ParaMEDMEM::PartDefinition *pd, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!pd) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast(pd)) + ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__DataArrayPartDefinition,owner); + else + ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__SlicePartDefinition,owner); + return ret; +} + static PyObject *convertCartesianAMRMesh(ParaMEDMEM::MEDCouplingCartesianAMRMeshGen *mesh, int owner) throw(INTERP_KERNEL::Exception) { if(!mesh) -- 2.39.2