From 1755dbe71b2fd46cd796464e8aa410d51e033b0d Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Tue, 25 Apr 2017 08:34:50 +0200 Subject: [PATCH] Some factorization for Field. FieldInt.__getitem__, FieldInt.buildPart, FieldInt.buildPartRange available now --- src/MEDCoupling/MEDCouplingFieldDouble.cxx | 144 ------------------ src/MEDCoupling/MEDCouplingFieldDouble.hxx | 3 - src/MEDCoupling/MEDCouplingFieldT.hxx | 6 + src/MEDCoupling/MEDCouplingFieldT.txx | 163 +++++++++++++++++++++ src/MEDCoupling_Swig/MEDCouplingCommon.i | 137 +++-------------- src/MEDCoupling_Swig/MEDCouplingTypemaps.i | 119 +++++++++++++++ 6 files changed, 310 insertions(+), 262 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 3fef0349a..ef7ead170 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -522,149 +522,6 @@ DataArrayInt *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) c return getArray()->findIdsInRange(vmin,vmax); } -/*! - * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()). - * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done. - * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field. - * Parameter \a part specifies **cell ids whatever the spatial discretization of this** ( - * \ref MEDCoupling::ON_CELLS "ON_CELLS", - * \ref MEDCoupling::ON_NODES "ON_NODES", - * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR"). - * - * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6]. - * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
- * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
- * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
- * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). - * - * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6]. - * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field - * will contain 6 tuples and \a this field will lie on this restricted mesh. - * - * \param [in] part - an array of cell ids to include to the result field. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".
- * \ref py_mcfielddouble_subpart1 "Here is a Python example". - * \endif - * \sa MEDCouplingFieldDouble::buildSubPartRange - */ - -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const -{ - if(part==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); - return buildSubPart(part->begin(),part->end()); -} - -/*! - * Builds a newly created field, that the caller will have the responsability to deal with. - * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkConsistencyLight() returns without any exception thrown), **no check of this will be done**. - * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field. - * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this ( - * \ref MEDCoupling::ON_CELLS "ON_CELLS", - * \ref MEDCoupling::ON_NODES "ON_NODES", - * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR"). - * - * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6]. - * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples. - *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh(). - *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh(). - *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). - * - * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6]. - * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field - * will contain 6 tuples and \a this field will lie on this restricted mesh. - * - * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd ) - * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd ) - * \return a newly allocated field the caller should deal with. - * - * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh(). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
- * \ref py_mcfielddouble_subpart1 "Here a Python example." - * \endif - * \sa MEDCoupling::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const -{ - if(_type.isNull()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; - MCAuto m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect); - MCAuto arrSelect2(arrSelect); - MCAuto ret(clone(false));//quick shallow copy. - const MEDCouplingFieldDiscretization *disc=getDiscretization(); - if(disc) - ret->setDiscretization(MCAuto(disc->clonePart(partBg,partEnd))); - ret->setMesh(m); - std::vector arrays; - timeDiscr()->getArrays(arrays); - std::vector arrs; - std::vector< MCAuto > arrsSafe; - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - DataArrayDouble *arr=0; - if(*iter) - arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - arrs.push_back(arr); arrsSafe.push_back(arr); - } - ret->timeDiscr()->setArrays(arrs,0); - return ret.retn(); -} - -/*! - * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is - * given using a range given \a begin, \a end and \a step to optimize the part computation. - * - * \sa MEDCouplingFieldDouble::buildSubPart - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const -{ - if(_type.isNull()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; - int beginOut,endOut,stepOut; - MCAuto m(_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect)); - MCAuto arrSelect2(arrSelect); - MCAuto ret(clone(false));//quick shallow copy. - const MEDCouplingFieldDiscretization *disc=getDiscretization(); - if(disc) - ret->setDiscretization(MCAuto(disc->clonePartRange(begin,end,step))); - ret->setMesh(m); - std::vector arrays; - timeDiscr()->getArrays(arrays); - std::vector arrs; - std::vector< MCAuto > arrsSafe; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - DataArrayDouble *arr=0; - if(*iter) - { - if(arrSelect) - { - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); - arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - } - else - arr=(*iter)->selectByTupleIdSafeSlice(beginOut,endOut,stepOut); - } - arrs.push_back(arr); arrsSafe.push_back(arr); - } - ret->timeDiscr()->setArrays(arrs,0); - return ret.retn(); -} - MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const { MCAuto tmp(MEDCouplingFieldTemplate::New(*this)); @@ -3291,4 +3148,3 @@ const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !"); return retc; } - diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index d096f9864..a68e907f4 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -46,9 +46,6 @@ namespace MEDCoupling MEDCOUPLING_EXPORT void renumberNodes(const int *old2NewBg, double eps=1e-15); MEDCOUPLING_EXPORT void renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15); MEDCOUPLING_EXPORT DataArrayInt *findIdsInRange(double vmin, double vmax) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *deepCopy() const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *clone(bool recDeepCpy) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const; diff --git a/src/MEDCoupling/MEDCouplingFieldT.hxx b/src/MEDCoupling/MEDCouplingFieldT.hxx index 66f7843e9..dbeaf2c0e 100644 --- a/src/MEDCoupling/MEDCouplingFieldT.hxx +++ b/src/MEDCoupling/MEDCouplingFieldT.hxx @@ -46,6 +46,9 @@ namespace MEDCoupling MEDCOUPLING_EXPORT virtual typename Traits::FieldType *clone(bool recDeepCpy) const = 0; MEDCOUPLING_EXPORT void checkConsistencyLight() const; MEDCOUPLING_EXPORT typename Traits::FieldType *cloneWithMesh(bool recDeepCpy) const; + MEDCOUPLING_EXPORT typename Traits::FieldType *buildSubPart(const DataArrayInt *part) const; + MEDCOUPLING_EXPORT typename Traits::FieldType *buildSubPart(const int *partBg, const int *partEnd) const; + MEDCOUPLING_EXPORT typename Traits::FieldType *buildSubPartRange(int begin, int end, int step) const; MEDCOUPLING_EXPORT void setArray(typename Traits::ArrayType *array) { _time_discr->setArray(array,this); } MEDCOUPLING_EXPORT void setEndArray(typename Traits::ArrayType *array) { _time_discr->setEndArray(array,this); } MEDCOUPLING_EXPORT const typename Traits::ArrayType *getArray() const { return _time_discr->getArray(); } @@ -84,6 +87,9 @@ namespace MEDCoupling MEDCOUPLING_EXPORT bool areCompatibleForDiv(const MEDCouplingField *other) const; MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingFieldT *other); MEDCOUPLING_EXPORT void copyAllTinyAttrFrom(const MEDCouplingFieldT *other); + protected: + const MEDCouplingTimeDiscretizationTemplate *timeDiscrSafe() const; + MEDCouplingTimeDiscretizationTemplate *timeDiscrSafe(); protected: MEDCouplingTimeDiscretizationTemplate *_time_discr; }; diff --git a/src/MEDCoupling/MEDCouplingFieldT.txx b/src/MEDCoupling/MEDCouplingFieldT.txx index 6df99f351..7f6819c18 100644 --- a/src/MEDCoupling/MEDCouplingFieldT.txx +++ b/src/MEDCoupling/MEDCouplingFieldT.txx @@ -367,6 +367,169 @@ namespace MEDCoupling { return _time_discr->getEnum(); } + + /*! + * Builds a newly created field, that the caller will have the responsability to deal with. + * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkConsistencyLight() returns without any exception thrown), **no check of this will be done**. + * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field. + * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this ( + * \ref MEDCoupling::ON_CELLS "ON_CELLS", + * \ref MEDCoupling::ON_NODES "ON_NODES", + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE", + * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR"). + * + * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6]. + * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples. + *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh(). + *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh(). + *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). + * + * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6]. + * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field + * will contain 6 tuples and \a this field will lie on this restricted mesh. + * + * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd ) + * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd ) + * \return a newly allocated field the caller should deal with. + * + * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh(). + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
+ * \ref py_mcfielddouble_subpart1 "Here a Python example." + * \endif + * \sa MEDCoupling::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange + */ + template + typename Traits::FieldType *MEDCouplingFieldT::buildSubPart(const int *partBg, const int *partEnd) const + { + if(_type.isNull()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldT::buildSubPart : Expecting a not NULL spatial discretization !"); + DataArrayInt *arrSelect; + MCAuto m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect); + MCAuto arrSelect2(arrSelect); + MCAuto< typename Traits::FieldType > ret(clone(false));//quick shallow copy. + const MEDCouplingFieldDiscretization *disc=getDiscretization(); + if(disc) + ret->setDiscretization(MCAuto(disc->clonePart(partBg,partEnd))); + ret->setMesh(m); + std::vector::ArrayType *> arrays; + timeDiscrSafe()->getArrays(arrays); + std::vector::ArrayType *> arrs; + std::vector< MCAuto< typename Traits::ArrayType > > arrsSafe; + const int *arrSelBg=arrSelect->begin(); + const int *arrSelEnd=arrSelect->end(); + for(typename std::vector::ArrayType *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + typename Traits::ArrayType *arr(0); + if(*iter) + arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); + arrs.push_back(arr); arrsSafe.push_back(arr); + } + ret->timeDiscrSafe()->setArrays(arrs,0); + return ret.retn(); + } + + /*! + * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()). + * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done. + * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field. + * Parameter \a part specifies **cell ids whatever the spatial discretization of this** ( + * \ref MEDCoupling::ON_CELLS "ON_CELLS", + * \ref MEDCoupling::ON_NODES "ON_NODES", + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE", + * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR"). + * + * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6]. + * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
+ * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
+ * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
+ * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). + * + * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6]. + * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field + * will contain 6 tuples and \a this field will lie on this restricted mesh. + * + * \param [in] part - an array of cell ids to include to the result field. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".
+ * \ref py_mcfielddouble_subpart1 "Here is a Python example". + * \endif + * \sa MEDCouplingFieldDouble::buildSubPartRange + */ + template + typename Traits::FieldType *MEDCouplingFieldT::buildSubPart(const DataArrayInt *part) const + { + if(part==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldT::buildSubPart : not empty array must be passed to this method !"); + return buildSubPart(part->begin(),part->end()); + } + + /*! + * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is + * given using a range given \a begin, \a end and \a step to optimize the part computation. + * + * \sa MEDCouplingFieldDouble::buildSubPart + */ + template + typename Traits::FieldType *MEDCouplingFieldT::buildSubPartRange(int begin, int end, int step) const + { + if(_type.isNull()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); + DataArrayInt *arrSelect; + int beginOut,endOut,stepOut; + MCAuto m(_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect)); + MCAuto arrSelect2(arrSelect); + MCAuto< typename Traits::FieldType > ret(clone(false));//quick shallow copy. + const MEDCouplingFieldDiscretization *disc=getDiscretization(); + if(disc) + ret->setDiscretization(MCAuto(disc->clonePartRange(begin,end,step))); + ret->setMesh(m); + std::vector::ArrayType *> arrays; + timeDiscrSafe()->getArrays(arrays); + std::vector::ArrayType *> arrs; + std::vector< MCAuto< typename Traits::ArrayType > > arrsSafe; + for(typename std::vector::ArrayType *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + typename Traits::ArrayType *arr(0); + if(*iter) + { + if(arrSelect) + { + const int *arrSelBg=arrSelect->begin(); + const int *arrSelEnd=arrSelect->end(); + arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); + } + else + arr=(*iter)->selectByTupleIdSafeSlice(beginOut,endOut,stepOut); + } + arrs.push_back(arr); arrsSafe.push_back(arr); + } + ret->timeDiscrSafe()->setArrays(arrs,0); + return ret.retn(); + } + + template + const MEDCouplingTimeDiscretizationTemplate *MEDCouplingFieldT::timeDiscrSafe() const + { + const MEDCouplingTimeDiscretizationTemplate *ret(_time_discr); + if(!ret) + throw INTERP_KERNEL::Exception("const FieldT : Null type of time discr !"); + return ret; + } + + template + MEDCouplingTimeDiscretizationTemplate *MEDCouplingFieldT::timeDiscrSafe() + { + MEDCouplingTimeDiscretizationTemplate *ret(_time_discr); + if(!ret) + throw INTERP_KERNEL::Exception("const FieldT : Null type of time discr !"); + return ret; + } } #endif diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index fb5745154..b6ceeba3b 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -239,6 +239,9 @@ using namespace INTERP_KERNEL; %newobject MEDCoupling::MEDCouplingFieldInt::deepCopy; %newobject MEDCoupling::MEDCouplingFieldInt::clone; %newobject MEDCoupling::MEDCouplingFieldInt::cloneWithMesh; +%newobject MEDCoupling::MEDCouplingFieldInt::buildSubPart; +%newobject MEDCoupling::MEDCouplingFieldInt::buildSubPartRange; +%newobject MEDCoupling::MEDCouplingFieldInt::__getitem__; %newobject MEDCoupling::MEDCouplingFieldTemplate::New; %newobject MEDCoupling::MEDCouplingMesh::deepCopy; %newobject MEDCoupling::MEDCouplingMesh::clone; @@ -4320,119 +4323,12 @@ namespace MEDCoupling MEDCouplingFieldDouble *buildSubPart(PyObject *li) const throw(INTERP_KERNEL::Exception) { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - MEDCoupling::DataArrayInt *daIntTyypp=0; - const MEDCouplingMesh *mesh=self->getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : field lies on a null mesh !"); - int nbc=mesh->getNumberOfCells(); - convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - return self->buildSubPart(&singleVal,&singleVal+1); - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - return self->buildSubPart(&tmp,&tmp+1); - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - return self->buildSubPart(&multiVal[0],&multiVal[0]+multiVal.size()); - } - case 3: - { - return self->buildSubPartRange(slic.first,slic.second.first,slic.second.second); - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - return self->buildSubPart(daIntTyypp->begin(),daIntTyypp->end()); - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); - } + return fieldT_buildSubPart(self,li); } MEDCouplingFieldDouble *__getitem__(PyObject *li) const throw(INTERP_KERNEL::Exception) { - const char msg[]="MEDCouplingFieldDouble::__getitem__ : invalid call Available API are : \n-myField[dataArrayInt]\n-myField[slice]\n-myField[pythonListOfCellIds]\n-myField[integer]\n-myField[dataArrayInt,1]\n-myField[slice,1]\n-myField[pythonListOfCellIds,1]\n-myField[integer,1]\n"; - if(PyTuple_Check(li)) - { - Py_ssize_t sz=PyTuple_Size(li); - if(sz!=2) - throw INTERP_KERNEL::Exception(msg); - PyObject *elt0=PyTuple_GetItem(li,0),*elt1=PyTuple_GetItem(li,1); - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - MEDCoupling::DataArrayInt *daIntTyypp=0; - if(!self->getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array set on field to deduce number of components !"); - try - { convertObjToPossibleCpp2(elt1,self->getArray()->getNumberOfComponents(),sw,singleVal,multiVal,slic,daIntTyypp); } - catch(INTERP_KERNEL::Exception& e) - { std::ostringstream oss; oss << "MEDCouplingFieldDouble::__getitem__ : invalid type in 2nd parameter (compo) !" << e.what(); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MCAuto ret0=MEDCoupling_MEDCouplingFieldDouble_buildSubPart(self,elt0); - DataArrayDouble *ret0Arr=ret0->getArray(); - if(!ret0Arr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array exists to apply restriction on component on it !"); - switch(sw) - { - case 1: - { - std::vector v2(1,singleVal); - MCAuto aarr(ret0Arr->keepSelectedComponents(v2)); - ret0->setArray(aarr); - return ret0.retn(); - } - case 2: - { - MCAuto aarr(ret0Arr->keepSelectedComponents(multiVal)); - ret0->setArray(aarr); - return ret0.retn(); - } - case 3: - { - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(slic.first,slic.second.first,slic.second.second,"MEDCouplingFieldDouble::__getitem__ : invalid range in 2nd parameter (components) !"); - std::vector v2(nbOfComp); - for(int i=0;i aarr(ret0Arr->keepSelectedComponents(v2)); - ret0->setArray(aarr); - return ret0.retn(); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - - } - else - return MEDCoupling_MEDCouplingFieldDouble_buildSubPart(self,li); + return fieldT__getitem__(self,li); } PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) @@ -5395,6 +5291,7 @@ namespace MEDCoupling MEDCouplingFieldInt *clone(bool recDeepCpy) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldInt *cloneWithMesh(bool recDeepCpy) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *convertToDblField() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldInt *buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception); %extend { MEDCouplingFieldInt(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME) { @@ -5418,13 +5315,23 @@ namespace MEDCoupling return oss.str(); } + MEDCouplingFieldInt *buildSubPart(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + return fieldT_buildSubPart(self,li); + } + + MEDCouplingFieldInt *__getitem__(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + return fieldT__getitem__(self,li); + } + DataArrayInt *getArray() throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getArray(); - if(ret) - ret->incrRef(); - return ret; - } + { + DataArrayInt *ret=self->getArray(); + if(ret) + ret->incrRef(); + return ret; + } PyObject *getTime() throw(INTERP_KERNEL::Exception) { diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i index 6bb7ee801..8aec95be3 100644 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -426,4 +426,123 @@ MEDCoupling::MEDCouplingFieldDouble *MEDCoupling_MEDCouplingFieldDouble___rdiv__ } } +template +typename MEDCoupling::Traits::FieldType *fieldT_buildSubPart(const MEDCoupling::MEDCouplingFieldT *self, PyObject *li) +{ + int sw; + int singleVal; + std::vector multiVal; + std::pair > slic; + MEDCoupling::DataArrayInt *daIntTyypp=0; + const MEDCoupling::MEDCouplingMesh *mesh=self->getMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : field lies on a null mesh !"); + int nbc=mesh->getNumberOfCells(); + convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(singleVal>=0) + return self->buildSubPart(&singleVal,&singleVal+1); + else + { + if(nbc+singleVal>0) + { + int tmp=nbc+singleVal; + return self->buildSubPart(&tmp,&tmp+1); + } + else + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + return self->buildSubPart(&multiVal[0],&multiVal[0]+multiVal.size()); + } + case 3: + { + return self->buildSubPartRange(slic.first,slic.second.first,slic.second.second); + } + case 4: + { + if(!daIntTyypp) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : null instance has been given in input !"); + daIntTyypp->checkAllocated(); + return self->buildSubPart(daIntTyypp->begin(),daIntTyypp->end()); + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); + } +} + +template +typename MEDCoupling::Traits::FieldType *fieldT__getitem__(const MEDCoupling::MEDCouplingFieldT *self, PyObject *li) +{ + const char msg[]="MEDCouplingFieldDouble::__getitem__ : invalid call Available API are : \n-myField[dataArrayInt]\n-myField[slice]\n-myField[pythonListOfCellIds]\n-myField[integer]\n-myField[dataArrayInt,1]\n-myField[slice,1]\n-myField[pythonListOfCellIds,1]\n-myField[integer,1]\n"; + if(PyTuple_Check(li)) + { + Py_ssize_t sz=PyTuple_Size(li); + if(sz!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *elt0=PyTuple_GetItem(li,0),*elt1=PyTuple_GetItem(li,1); + int sw; + int singleVal; + std::vector multiVal; + std::pair > slic; + MEDCoupling::DataArrayInt *daIntTyypp=0; + if(!self->getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array set on field to deduce number of components !"); + try + { convertObjToPossibleCpp2(elt1,self->getArray()->getNumberOfComponents(),sw,singleVal,multiVal,slic,daIntTyypp); } + catch(INTERP_KERNEL::Exception& e) + { std::ostringstream oss; oss << "MEDCouplingFieldDouble::__getitem__ : invalid type in 2nd parameter (compo) !" << e.what(); throw INTERP_KERNEL::Exception(oss.str().c_str()); } + typename MEDCoupling::MCAuto< typename MEDCoupling::Traits::FieldType > ret0(fieldT_buildSubPart(self,elt0)); + typename MEDCoupling::Traits::ArrayType *ret0Arr=ret0->getArray(); + if(!ret0Arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array exists to apply restriction on component on it !"); + switch(sw) + { + case 1: + { + std::vector v2(1,singleVal); + MEDCoupling::MCAuto< typename MEDCoupling::Traits::ArrayType > aarr(ret0Arr->keepSelectedComponents(v2)); + ret0->setArray(aarr); + return ret0.retn(); + } + case 2: + { + MEDCoupling::MCAuto< typename MEDCoupling::Traits::ArrayType > aarr(ret0Arr->keepSelectedComponents(multiVal)); + ret0->setArray(aarr); + return ret0.retn(); + } + case 3: + { + int nbOfComp(MEDCoupling::DataArray::GetNumberOfItemGivenBESRelative(slic.first,slic.second.first,slic.second.second,"MEDCouplingFieldDouble::__getitem__ : invalid range in 2nd parameter (components) !")); + std::vector v2(nbOfComp); + for(int i=0;i::ArrayType > aarr(ret0Arr->keepSelectedComponents(v2)); + ret0->setArray(aarr); + return ret0.retn(); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + else + return fieldT_buildSubPart(self,li); +} + + #endif -- 2.39.2