X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingFieldT.txx;h=23807ce9708c00ae1a8fd52141d4f6c866ec8f58;hb=b8616069f6667dcec3f90574a05bfc9e66d87fa5;hp=61e2aa1bf8ffd1fecb0775650d7eb00cafb4dca2;hpb=c5f9a2bb5f775564b5bd81de58dfa708bcef020d;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingFieldT.txx b/src/MEDCoupling/MEDCouplingFieldT.txx index 61e2aa1bf..23807ce97 100644 --- a/src/MEDCoupling/MEDCouplingFieldT.txx +++ b/src/MEDCoupling/MEDCouplingFieldT.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2016 CEA/DEN, EDF R&D +// Copyright (C) 2016-2021 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 @@ -117,21 +117,22 @@ namespace MEDCoupling } return ret.retn(); } + + template + bool MEDCouplingFieldT::isEqual(const MEDCouplingFieldT *other, double meshPrec, T valsPrec) const + { + std::string tmp; + return isEqualIfNotWhy(other,meshPrec,valsPrec,tmp); + } template - bool MEDCouplingFieldT::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const + bool MEDCouplingFieldT::isEqualIfNotWhy(const MEDCouplingFieldT *other, double meshPrec, T valsPrec, std::string& reason) const { if(!other) throw INTERP_KERNEL::Exception("MEDCouplingFieldT::isEqualIfNotWhy : other instance is NULL !"); - const MEDCouplingFieldT *otherC(dynamic_cast *>(other)); - if(!otherC) - { - reason="field given in input is not castable in MEDCouplingFieldT !"; - return false; - } - if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason)) + if(!isEqualIfNotWhyProtected(other,meshPrec,reason)) return false; - if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,T(valsPrec),reason)) + if(!_time_discr->isEqualIfNotWhy(other->_time_discr,T(valsPrec),reason)) { reason.insert(0,"In FieldT time discretizations differ :"); return false; @@ -150,14 +151,13 @@ namespace MEDCoupling * \throw If the spatial discretization of \a this field is NULL. */ template - bool MEDCouplingFieldT::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const + bool MEDCouplingFieldT::isEqualWithoutConsideringStr(const MEDCouplingFieldT *other, double meshPrec, T valsPrec) const { - const MEDCouplingFieldT *otherC(dynamic_cast *>(other)); - if(!otherC) + if(!other) return false; - if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) + if(!isEqualWithoutConsideringStrProtected(other,meshPrec)) return false; - if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,T(valsPrec))) + if(!_time_discr->isEqualWithoutConsideringStr(other->_time_discr,valsPrec)) return false; return true; } @@ -203,6 +203,78 @@ namespace MEDCoupling copyTinyAttrFrom(other); } + /*! + * Permutes values of \a this field according to a given permutation array for cells + * renumbering. The underlying mesh is deeply copied and its cells are also permuted. + * The number of cells remains the same; for that the permutation array \a old2NewBg + * should not contain equal ids. + * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **. + * + * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is + * to be equal to \a this->getMesh()->getNumberOfCells(). + * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation + * array, so that its maximal cell id to correspond to (be less than) the number + * of cells in mesh. This new array is then used for the renumbering. If \a + * check == \c false, \a old2NewBg is used as is, that is less secure as validity + * of ids in \a old2NewBg is not checked. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a check == \c true and \a old2NewBg contains equal ids. + * \throw If mesh nature does not allow renumbering (e.g. structured mesh). + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".
+ * \ref py_mcfielddouble_renumberCells "Here is a Python example". + * \endif + */ + template + void MEDCouplingFieldT::renumberCells(const mcIdType *old2NewBg, bool check) + { + renumberCellsWithoutMesh(old2NewBg,check); + MCAuto m(_mesh->deepCopy()); + m->renumberCells(old2NewBg,check); + setMesh(m); + updateTime(); + } + + /*! + * Permutes values of \a this field according to a given permutation array for cells + * renumbering. The underlying mesh is \b not permuted. + * The number of cells remains the same; for that the permutation array \a old2NewBg + * should not contain equal ids. + * This method performs a part of job of renumberCells(). The reasonable use of this + * method is only for multi-field instances lying on the same mesh to avoid a + * systematic duplication and renumbering of _mesh attribute. + * \warning Use this method with a lot of care! + * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is + * to be equal to \a this->getMesh()->getNumberOfCells(). + * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation + * array, so that its maximal cell id to correspond to (be less than) the number + * of cells in mesh. This new array is then used for the renumbering. If \a + * check == \c false, \a old2NewBg is used as is, that is less secure as validity + * of ids in \a old2NewBg is not checked. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a check == \c true and \a old2NewBg contains equal ids. + * \throw If mesh nature does not allow renumbering (e.g. structured mesh). + */ + template + void MEDCouplingFieldT::renumberCellsWithoutMesh(const mcIdType *old2NewBg, bool check) + { + if(!_mesh) + throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !"); + if(_type.isNull()) + throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); + // + _type->renumberCells(old2NewBg,check); + std::vector< typename MEDCoupling::Traits::ArrayType *> arrays; + timeDiscrSafe()->getArrays(arrays); + std::vector arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin()); + _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check); + // + updateTime(); + } + /*! * This method is more strict than MEDCouplingField::areCompatibleForMerge method. * This method is used for operation on fields to operate a first check before attempting operation. @@ -296,10 +368,10 @@ namespace MEDCoupling { if(getArray()->isAllocated()) { - int nbOfCompo=getArray()->getNumberOfComponents(); + std::size_t nbOfCompo=getArray()->getNumberOfComponents(); ret << Traits::FieldTypeName << " default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; ret << Traits::FieldTypeName << " default array has following info on components : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; ret << "\n"; } @@ -325,7 +397,7 @@ namespace MEDCoupling nat=MEDCouplingNatureOfField::GetRepr(_nature); stream << "Nature of field : " << nat << ".\n"; } - catch(INTERP_KERNEL::Exception& e) + catch(INTERP_KERNEL::Exception&) { } const MEDCouplingFieldDiscretization *fd(_type); if(!fd) @@ -369,7 +441,7 @@ namespace MEDCoupling } /*! - * Builds a newly created field, that the caller will have the responsability to deal with. + * Builds a newly created field, that the caller will have the responsibility 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 ( @@ -402,13 +474,13 @@ namespace MEDCoupling * \sa MEDCoupling::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange */ template - typename Traits::FieldType *MEDCouplingFieldT::buildSubPart(const int *partBg, const int *partEnd) const + typename Traits::FieldType *MEDCouplingFieldT::buildSubPart(const mcIdType *partBg, const mcIdType *partEnd) const { if(_type.isNull()) throw INTERP_KERNEL::Exception("MEDCouplingFieldT::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; + DataArrayIdType *arrSelect; MCAuto m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect); - MCAuto arrSelect2(arrSelect); + MCAuto arrSelect2(arrSelect); MCAuto< typename Traits::FieldType > ret(clone(false));//quick shallow copy. const MEDCouplingFieldDiscretization *disc=getDiscretization(); if(disc) @@ -418,8 +490,8 @@ namespace MEDCoupling timeDiscrSafe()->getArrays(arrays); std::vector::ArrayType *> arrs; std::vector< MCAuto< typename Traits::ArrayType > > arrsSafe; - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); + const mcIdType *arrSelBg=arrSelect->begin(); + const mcIdType *arrSelEnd=arrSelect->end(); for(typename std::vector::ArrayType *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) { typename Traits::ArrayType *arr(0); @@ -432,7 +504,7 @@ namespace MEDCoupling } /*! - * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()). + * Builds a newly created field, that the caller will have the responsibility 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** ( @@ -462,7 +534,7 @@ namespace MEDCoupling * \sa MEDCouplingFieldDouble::buildSubPartRange */ template - typename Traits::FieldType *MEDCouplingFieldT::buildSubPart(const DataArrayInt *part) const + typename Traits::FieldType *MEDCouplingFieldT::buildSubPart(const DataArrayIdType *part) const { if(part==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldT::buildSubPart : not empty array must be passed to this method !"); @@ -476,14 +548,14 @@ namespace MEDCoupling * \sa MEDCouplingFieldDouble::buildSubPart */ template - typename Traits::FieldType *MEDCouplingFieldT::buildSubPartRange(int begin, int end, int step) const + typename Traits::FieldType *MEDCouplingFieldT::buildSubPartRange(mcIdType begin, mcIdType end, mcIdType step) const { if(_type.isNull()) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; - int beginOut,endOut,stepOut; + DataArrayIdType *arrSelect; + mcIdType beginOut,endOut,stepOut; MCAuto m(_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect)); - MCAuto arrSelect2(arrSelect); + MCAuto arrSelect2(arrSelect); MCAuto< typename Traits::FieldType > ret(clone(false));//quick shallow copy. const MEDCouplingFieldDiscretization *disc=getDiscretization(); if(disc) @@ -500,8 +572,8 @@ namespace MEDCoupling { if(arrSelect) { - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); + const mcIdType *arrSelBg=arrSelect->begin(); + const mcIdType *arrSelEnd=arrSelect->end(); arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); } else @@ -547,19 +619,19 @@ namespace MEDCoupling * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. */ template - void MEDCouplingFieldT::getTinySerializationIntInformation(std::vector& tinyInfo) const + void MEDCouplingFieldT::getTinySerializationIntInformation(std::vector& tinyInfo) const { if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !"); tinyInfo.clear(); - tinyInfo.push_back((int)_type->getEnum()); - tinyInfo.push_back((int)timeDiscrSafe()->getEnum()); - tinyInfo.push_back((int)_nature); + tinyInfo.push_back(ToIdType(_type->getEnum())); + tinyInfo.push_back(ToIdType(timeDiscrSafe()->getEnum())); + tinyInfo.push_back(ToIdType(_nature)); timeDiscrSafe()->getTinySerializationIntInformation(tinyInfo); - std::vector tinyInfo2; + std::vector tinyInfo2; _type->getTinySerializationIntInformation(tinyInfo2); tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size()); + tinyInfo.push_back(ToIdType(tinyInfo2.size())); } /*! @@ -588,18 +660,18 @@ namespace MEDCoupling * \sa checkForUnserialization */ template - void MEDCouplingFieldT::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector::ArrayType *>& arrays) + void MEDCouplingFieldT::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayIdType *&dataInt, std::vector::ArrayType *>& arrays) { if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); dataInt=0; - std::vector tinyInfoITmp(tinyInfoI); - int sz=tinyInfoITmp.back(); + std::vector tinyInfoITmp(tinyInfoI); + mcIdType sz=tinyInfoITmp.back(); tinyInfoITmp.pop_back(); - std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); - std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); + std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); + std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); timeDiscrSafe()->resizeForUnserialization(tinyInfoI2,arrays); - std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); + std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); _type->resizeForUnserialization(tinyInfoITmp3,dataInt); } @@ -609,29 +681,29 @@ namespace MEDCoupling * \sa resizeForUnserialization */ template - void MEDCouplingFieldT::checkForUnserialization(const std::vector& tinyInfoI, const DataArrayInt *dataInt, const std::vector::ArrayType *>& arrays) + void MEDCouplingFieldT::checkForUnserialization(const std::vector& tinyInfoI, const DataArrayIdType *dataInt, const std::vector::ArrayType *>& arrays) { if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); - std::vector tinyInfoITmp(tinyInfoI); - int sz=tinyInfoITmp.back(); + std::vector tinyInfoITmp(tinyInfoI); + mcIdType sz=tinyInfoITmp.back(); tinyInfoITmp.pop_back(); - std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); - std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); + std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); + std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); timeDiscrSafe()->checkForUnserialization(tinyInfoI2,arrays); - std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); + std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); _type->checkForUnserialization(tinyInfoITmp3,dataInt); } template - void MEDCouplingFieldT::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) + void MEDCouplingFieldT::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) { if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !"); - std::vector tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); + std::vector tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); // std::vector tmp(tinyInfoD); - int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it + mcIdType sz=ToIdType(tinyInfoD.back());//very bad, lack of time to improve it tmp.pop_back(); std::vector tmp1(tmp.begin(),tmp.end()-sz); std::vector tmp2(tmp.end()-sz,tmp.end()); @@ -639,18 +711,18 @@ namespace MEDCoupling timeDiscrSafe()->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS); _nature=(NatureOfField)tinyInfoI[2]; _type->finishUnserialization(tmp2); - int nbOfElemS=(int)tinyInfoS.size(); + std::size_t nbOfElemS=tinyInfoS.size(); _name=tinyInfoS[nbOfElemS-3]; _desc=tinyInfoS[nbOfElemS-2]; setTimeUnit(tinyInfoS[nbOfElemS-1]); } /*! - * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller. + * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsibilities of the caller. * The values returned must be consulted only in readonly mode. */ template - void MEDCouplingFieldT::serialize(DataArrayInt *&dataInt, std::vector::ArrayType *>& arrays) const + void MEDCouplingFieldT::serialize(DataArrayIdType *&dataInt, std::vector::ArrayType *>& arrays) const { if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform serialize !");