From d002061cf33d5731aa8cc02415ceacffc580b1ad Mon Sep 17 00:00:00 2001 From: ageay Date: Thu, 11 Apr 2013 13:26:29 +0000 Subject: [PATCH] MEDCouplingFieldDouble::buildSubPartRange --- src/MEDCoupling/MEDCouplingField.cxx | 21 +- src/MEDCoupling/MEDCouplingField.hxx | 1 + .../MEDCouplingFieldDiscretization.cxx | 209 ++++++++++++++++-- .../MEDCouplingFieldDiscretization.hxx | 9 + src/MEDCoupling/MEDCouplingFieldDouble.cxx | 53 ++++- src/MEDCoupling/MEDCouplingFieldDouble.hxx | 1 + src/MEDCoupling/MEDCouplingMemArray.cxx | 8 +- src/MEDCoupling/MEDCouplingMemArrayChar.cxx | 2 +- src/MEDCoupling/MEDCouplingMesh.cxx | 22 ++ src/MEDCoupling/MEDCouplingMesh.hxx | 2 + src/MEDCoupling/MEDCouplingPointSet.cxx | 29 ++- src/MEDCoupling/MEDCouplingPointSet.hxx | 2 + 12 files changed, 325 insertions(+), 34 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx index 4f3fc3e56..967caf414 100644 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -394,7 +394,9 @@ MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy) /*! * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). - * @param di is an array returned that specifies entity ids (nodes, cells ids...) in mesh 'mesh' of entity in returned submesh. + * @param di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array. + * + * \sa MEDCouplingField::buildSubMeshDataRange */ MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const { @@ -403,6 +405,23 @@ MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int return _type->buildSubMeshData(_mesh,start,end,di); } +/*! + * This method returns a submesh of 'mesh' instance constituting cell ids defined by a range given by the 3 following inputs \a begin, \a end and \a step. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingField::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingField::buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshDataRange method !"); + return _type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,di); +} + /*! * This method returns tuples ids implied by the mesh selection of the cell ids contained in array defined as an interval [start;end). * \return a newly allocated DataArrayInt instance containing tuples ids. diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx index 1df5494c2..ed37178f7 100644 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -63,6 +63,7 @@ namespace ParaMEDMEM DataArrayDouble *getLocalizationOfDiscr() const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const; const MEDCouplingFieldDiscretization *getDiscretization() const { return _type; } MEDCouplingFieldDiscretization *getDiscretization() { return _type; } diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index f9e201fac..4cedfe1a0 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -164,6 +164,14 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePart(const return clone(); } +/*! + * For all field discretization excepted GaussPts the slice( \a beginCellId, \a endCellIds, \a stepCellId ) has no impact on the cloned instance. + */ +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const +{ + return clone(); +} + /*! * Excepted for MEDCouplingFieldDiscretizationPerCell no underlying TimeLabel object : nothing to do in generally. */ @@ -256,6 +264,22 @@ void MEDCouplingFieldDiscretization::integral(const MEDCouplingMesh *mesh, const } } +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretization::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretization::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretization::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + MEDCouplingAutoRefCountObjectPtr da=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); + return buildSubMeshData(mesh,da->begin(),da->end(),di); +} + void MEDCouplingFieldDiscretization::getSerializationIntArray(DataArrayInt *& arr) const { arr=0; @@ -619,17 +643,38 @@ DataArrayInt *MEDCouplingFieldDiscretizationP0::computeTupleIdsToSelectFromCellI * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). * @param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh. * Example : The first cell id of returned mesh has the (*di)[0] id in 'mesh' + * + * \sa MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange */ MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const { if(!mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::buildSubMeshData : NULL input mesh !"); - MEDCouplingMesh *ret=mesh->buildPart(start,end); - di=DataArrayInt::New(); - di->alloc((int)std::distance(start,end),1); - int *pt=di->getPointer(); - std::copy(start,end,pt); - return ret; + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); + MEDCouplingAutoRefCountObjectPtr diSafe=DataArrayInt::New(); + diSafe->alloc((int)std::distance(start,end),1); + std::copy(start,end,diSafe->getPointer()); + di=diSafe.retn(); + return ret.retn(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationP0::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationP0::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); + di=0; beginOut=beginCellIds; endOut=endCellIds; stepOut=stepCellIds; + return ret.retn(); } int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) @@ -709,11 +754,34 @@ MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData(const M { if(!mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::buildSubMeshData : NULL input mesh !"); - MEDCouplingMesh *ret=mesh->buildPartAndReduceNodes(start,end,di); - DataArrayInt *di2=di->invertArrayO2N2N2O(ret->getNumberOfNodes()); - di->decrRef(); - di=di2; - return ret; + DataArrayInt *diTmp=0; + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartAndReduceNodes(start,end,diTmp); + MEDCouplingAutoRefCountObjectPtr diTmpSafe(diTmp); + MEDCouplingAutoRefCountObjectPtr di2=diTmpSafe->invertArrayO2N2N2O(ret->getNumberOfNodes()); + di=di2.retn(); + return ret.retn(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationNodes::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationNodes::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::buildSubMeshDataRange : NULL input mesh !"); + DataArrayInt *diTmp=0; + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRangeAndReduceNodes(beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,diTmp); + MEDCouplingAutoRefCountObjectPtr diTmpSafe(diTmp); + MEDCouplingAutoRefCountObjectPtr di2=diTmpSafe->invertArrayO2N2N2O(ret->getNumberOfNodes()); + di=di2.retn(); + return ret.retn(); } /*! @@ -911,6 +979,15 @@ MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(con } } +MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, int beginCellIds, int endCellIds, int stepCellIds):_discr_per_cell(0) +{ + DataArrayInt *arr=other._discr_per_cell; + if(arr) + { + _discr_per_cell=arr->selectByTupleId2(beginCellIds,endCellIds,stepCellIds); + } +} + void MEDCouplingFieldDiscretizationPerCell::updateTime() const { if(_discr_per_cell) @@ -1056,6 +1133,10 @@ MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const M { } +MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, int beginCellIds, int endCellIds, int stepCellIds):MEDCouplingFieldDiscretizationPerCell(other,beginCellIds,endCellIds,stepCellIds),_loc(other._loc) +{ +} + TypeOfField MEDCouplingFieldDiscretizationGauss::getEnum() const { return TYPE; @@ -1123,6 +1204,11 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePart(c return new MEDCouplingFieldDiscretizationGauss(*this,startCellIds,endCellIds); } +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const +{ + return new MEDCouplingFieldDiscretizationGauss(*this,beginCellIds,endCellIds,stepCellIds); +} + std::string MEDCouplingFieldDiscretizationGauss::getStringRepr() const { std::ostringstream oss; oss << REPR << "." << std::endl; @@ -1476,8 +1562,56 @@ MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshData(const MED { if(!mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshData : NULL input mesh !"); - di=computeTupleIdsToSelectFromCellIds(mesh,start,end); - return mesh->buildPart(start,end); + MEDCouplingAutoRefCountObjectPtr diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); + di=diSafe.retn(); + return ret.retn(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationGauss::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationGauss::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(stepCellIds!=1)//even for stepCellIds==-1 the output will not be a range + return MEDCouplingFieldDiscretization::buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,di); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : NULL input mesh !"); + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : no discretization array set !"); + di=0; beginOut=0; endOut=0; stepOut=stepCellIds; + const char msg[]="MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : cell #"; + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + const int *w=_discr_per_cell->begin(); + int nbMaxOfLocId=(int)_loc.size(); + for(int i=0;i=0 && *w=endCellIds) + break; + } + else + { std::ostringstream oss; oss << msg << i << " has invalid id (" << *w << ") ! Should be in [0," << nbMaxOfLocId << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + } + else + { std::ostringstream oss; oss << msg << i << " is detected as orphan !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + } + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); + return ret.retn(); } /*! @@ -1613,7 +1747,7 @@ int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cel { if(!_discr_per_cell) throw INTERP_KERNEL::Exception("No Gauss localization still set !"); - int locId=_discr_per_cell->getConstPointer()[cellId]; + int locId=_discr_per_cell->begin()[cellId]; if(locId<0) throw INTERP_KERNEL::Exception("No Gauss localization set for the specified cell !"); return locId; @@ -1685,7 +1819,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellFie throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : no discretization array set !"); int nbOfTuples=_discr_per_cell->getNumberOfTuples(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - const int *w=_discr_per_cell->getConstPointer(); + const int *w=_discr_per_cell->begin(); ret->alloc(nbOfTuples,1); int *valsToFill=ret->getPointer(); int nbMaxOfLocId=(int)_loc.size(); @@ -1720,7 +1854,7 @@ void MEDCouplingFieldDiscretizationGauss::reprQuickOverview(std::ostream& stream */ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations() { - const int *start=_discr_per_cell->getConstPointer(); + const int *start=_discr_per_cell->begin(); int nbOfTuples=_discr_per_cell->getNumberOfTuples(); INTERP_KERNEL::AutoPtr tmp=new int[_loc.size()]; std::fill((int *)tmp,(int *)tmp+_loc.size(),-2); @@ -2136,10 +2270,49 @@ MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData(const M { if(!mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData : NULL input mesh !"); - di=computeTupleIdsToSelectFromCellIds(mesh,start,end); - return mesh->buildPart(start,end); + MEDCouplingAutoRefCountObjectPtr diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); + di=diSafe.retn(); + return ret.retn(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationGauss::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationGauss::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(stepCellIds!=1)//even for stepCellIds==-1 the output will not be a range + return MEDCouplingFieldDiscretization::buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,di); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange : NULL input mesh !"); + int nbOfCells=mesh->getNumberOfCells(); + di=0; beginOut=0; endOut=0; stepOut=stepCellIds; + const char msg[]="MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange : cell #"; + for(int i=0;igetTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isDynamic()) + { std::ostringstream oss; oss << msg << i << " presence of dynamic cell (polygons and polyedrons) ! Not implemented !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + int delta=cm.getNumberOfNodes(); + if(i=endCellIds) + break; + } + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); + return ret.retn(); } + /*! * This method returns a tuple ids selection from cell ids selection [start;end). * This method is called by MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData to return parameter \b di. diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx index 96da042d0..22e40cea7 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -55,6 +55,7 @@ namespace ParaMEDMEM virtual MEDCouplingFieldDiscretization *deepCpy() const; virtual MEDCouplingFieldDiscretization *clone() const = 0; virtual MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; + virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; virtual std::string getStringRepr() const = 0; virtual const char *getRepr() const = 0; virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) = 0; @@ -78,6 +79,7 @@ namespace ParaMEDMEM virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const = 0; virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const = 0; virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0; + virtual MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; virtual void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const = 0; virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const = 0; virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const = 0; @@ -135,6 +137,7 @@ namespace ParaMEDMEM void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); public: @@ -155,6 +158,7 @@ namespace ParaMEDMEM DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception); void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; @@ -197,6 +201,7 @@ namespace ParaMEDMEM protected: MEDCouplingFieldDiscretizationPerCell(); MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds); + MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, int beginCellIds, int endCellIds, int stepCellIds); ~MEDCouplingFieldDiscretizationPerCell(); void updateTime() const; std::size_t getHeapMemorySize() const; @@ -220,6 +225,7 @@ namespace ParaMEDMEM bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; MEDCouplingFieldDiscretization *clone() const; MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; + MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; std::string getStringRepr() const; const char *getRepr() const; std::size_t getHeapMemorySize() const; @@ -244,6 +250,7 @@ namespace ParaMEDMEM void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; @@ -266,6 +273,7 @@ namespace ParaMEDMEM void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); protected: MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds=0, const int *endCellIds=0); + MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, int beginCellIds, int endCellIds, int stepCellIds); void zipGaussLocalizations(); int getOffsetOfCell(int cellId) const throw(INTERP_KERNEL::Exception); void checkLocalizationId(int locId) const throw(INTERP_KERNEL::Exception); @@ -305,6 +313,7 @@ namespace ParaMEDMEM void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 52e53a9c3..81e9dc6f3 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -496,15 +496,15 @@ DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) co * * If \a this is field on node lying on a mesh that have 10 cells and 11 nodes for example. If part contains following cellIds [3,7,6]. * \a this is currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field, - * will contain 6 tuples and this field will lie on this restricted mesh. + * will contain 6 tuples and this field will lie on this restricted mesh. + * + * \sa MEDCouplingFieldDouble::buildSubPartRange */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception) { if(part==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); - const int *start=part->getConstPointer(); - const int *end=start+part->getNbOfElems(); - return buildSubPart(start,end); + return buildSubPart(part->begin(),part->end()); } /*! @@ -535,7 +535,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt * \ref cpp_mcfielddouble_subpart1 "Here a C++ example." * * \ref py_mcfielddouble_subpart1 "Here a Python example." - * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const + * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception) { @@ -566,6 +566,49 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, 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 throw(INTERP_KERNEL::Exception) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); + DataArrayInt *arrSelect; + int beginOut,endOut,stepOut; + MEDCouplingAutoRefCountObjectPtr m=_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect); + MEDCouplingAutoRefCountObjectPtr arrSelect2(arrSelect); + MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. + const MEDCouplingFieldDiscretization *disc=getDiscretization(); + if(disc) + ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr(disc->clonePartRange(begin,end,step))); + ret->setMesh(m); + std::vector arrays; + _time_discr->getArrays(arrays); + std::vector arrs; + std::vector< MEDCouplingAutoRefCountObjectPtr > 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)->selectByTupleId2(beginOut,endOut,stepOut); + } + arrs.push_back(arr); arrsSafe.push_back(arr); + } + ret->_time_discr->setArrays(arrs,0); + return ret.retn(); +} + TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const { return _time_discr->getEnum(); diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index 5eb82cf67..6e3c3282f 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -58,6 +58,7 @@ namespace ParaMEDMEM DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *deepCpy() const; MEDCouplingFieldDouble *clone(bool recDeepCpy) const; MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 07d0c484f..9ad55aaef 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -1435,7 +1435,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons if(*w>=0 && *wgetNumberOfTuples) !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !"); ret->copyStringInfoFrom(*this); return ret.retn(); } @@ -1453,7 +1453,6 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons * \param [in] step - index increment to get index of the next tuple to copy. * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller * is to delete using decrRef() as it is no more needed. - * \throw If (\a end2 < \a bg) or (\a step <= 0). * \sa DataArrayDouble::substr. */ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception) @@ -1461,7 +1460,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) c checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayDouble::selectByTupleId2 : "); + int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : "); ret->alloc(newNbOfTuples,nbComp); double *pt=ret->getPointer(); const double *srcPt=getConstPointer()+bg*nbComp; @@ -6416,7 +6415,6 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int * \param [in] step - index increment to get index of the next tuple to copy. * \return DataArrayInt * - the new instance of DataArrayInt that the caller * is to delete using decrRef() as it is no more needed. - * \throw If (\a end2 < \a bg) or (\a step <= 0). * \sa DataArrayInt::substr. */ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception) @@ -6424,7 +6422,7 @@ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const t checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); + int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); ret->alloc(newNbOfTuples,nbComp); int *pt=ret->getPointer(); const int *srcPt=getConstPointer()+bg*nbComp; diff --git a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx index f38bd25c9..0906a91ad 100644 --- a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx +++ b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx @@ -580,7 +580,7 @@ DataArrayChar *DataArrayChar::selectByTupleId2(int bg, int end2, int step) const checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); + int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); ret->alloc(newNbOfTuples,nbComp); char *pt=ret->getPointer(); const char *srcPt=getConstPointer()+bg*nbComp; diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index 726785406..1e1f6d278 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -231,6 +231,28 @@ bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const return true; } +/*! + * This method is equivalent to MEDCouplingMesh::buildPart method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds. + * + * \sa MEDCouplingMesh::buildPart + */ +MEDCouplingMesh *MEDCouplingMesh::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); + return buildPart(cellIds->begin(),cellIds->end()); +} + +/*! + * This method is equivalent to MEDCouplingMesh::buildPartAndReduceNodes method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds. + * + * \sa MEDCouplingMesh::buildPartAndReduceNodes + */ +MEDCouplingMesh *MEDCouplingMesh::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); + return buildPartAndReduceNodes(cellIds->begin(),cellIds->end(),arr); +} + /*! * This method builds a field lying on 'this' with 'nbOfComp' components. * 'func' is a pointer that points to a function that takes 2 arrays in parameter and returns a boolean. diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 83210b6e9..ff714a769 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -117,6 +117,8 @@ namespace ParaMEDMEM virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0; virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; + virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception); virtual MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception) = 0; virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception) = 0; virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 32c1efa3c..38e9f1f0b 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -259,11 +259,11 @@ DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision, DataArrayInt *comm,*commI; findCommonNodes(precision,limitNodeId,comm,commI); int oldNbOfNodes=getNumberOfNodes(); - DataArrayInt *ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); + MEDCouplingAutoRefCountObjectPtr ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); areNodesMerged=(oldNbOfNodes!=newNbOfNodes); comm->decrRef(); commI->decrRef(); - return ret; + return ret.retn(); } /*! @@ -1044,11 +1044,32 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end */ MEDCouplingMesh *MEDCouplingPointSet::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const { - MEDCouplingPointSet *ret=buildPartOfMySelf(start,end,true); + MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelf(start,end,true); arr=ret->zipCoordsTraducer(); - return ret; + return ret.retn(); +} + +/*! + * This method specialized the MEDCouplingMesh::buildPartRange + * + * \sa MEDCouplingUMesh::buildPartOfMySelf2 + */ +MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception) +{ + return buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true); } +/*! + * This method specialized the MEDCouplingMesh::buildPartRangeAndReduceNodes + * + * \sa MEDCouplingUMesh::buildPartOfMySelf2 + */ +MEDCouplingMesh *MEDCouplingPointSet::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true); + arr=ret->zipCoordsTraducer(); + return ret.retn(); +} /*! * 'This' is expected to be of spaceDim==2. Idem for 'center' and 'vect' diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index 908ef71e5..e0ef76118 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -94,6 +94,8 @@ namespace ParaMEDMEM static void Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords); MEDCouplingMesh *buildPart(const int *start, const int *end) const; MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; + MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); + MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception); virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const = 0; virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) = 0; virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; -- 2.39.2