From: ageay Date: Tue, 17 Jan 2012 15:35:41 +0000 (+0000) Subject: Addition of DataArrayDouble::getDifferentValues X-Git-Tag: V6_main_FINAL~911 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4fb7c714de98338d291af891f0730bba5efeb9f9;p=tools%2Fmedcoupling.git Addition of DataArrayDouble::getDifferentValues --- diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index cd29db529..d7355cd9c 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -357,9 +357,20 @@ DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) co } /*! - * Builds a newly created field, that the caller will have the responsability. + * 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 'this' so that only tuples id specified in 'part' will be contained in returned field. + * This method returns a restriction of 'this' so that only tuples id specified in 'part' will be contained in returned field. + * Parameter 'part' specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of 'this' (ON_CELLS, ON_NODES, ON_GAUSS_PT, ON_GAUSS_NE) + * + * If 'this' is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6]. + * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples. + * Tuple#0 of return field will refer to the cell#0 of returned mesh. The cell #0 of returned mesh will be equal to the cell#3 of 'this->getMesh()' + * Tuple#1 of return field will refer to the cell#1 of returned mesh. The cell #1 of returned mesh will be equal to the cell#7 of 'this->getMesh()' + * Tuple#2 of return field will refer to the cell#2 of returned mesh. The cell #2 of returned mesh will be equal to the cell#6 of 'this->getMesh()' + * + * If '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]. + * '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. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception) { @@ -371,9 +382,20 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt } /*! - * Builds a newly created field, that the caller will have the responsability. + * 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 'this' so that only tuples id specified in ['partBg';'partEnd') will be contained in returned field. + * Parameter ['partBg','partEnd') specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of 'this' (ON_CELLS, ON_NODES, ON_GAUSS_PT, ON_GAUSS_NE) + * + * If 'this' is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6]. + * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples. + * Tuple#0 of return field will refer to the cell#0 of returned mesh. The cell #0 of returned mesh will be equal to the cell#3 of 'this->getMesh()' + * Tuple#1 of return field will refer to the cell#1 of returned mesh. The cell #1 of returned mesh will be equal to the cell#7 of 'this->getMesh()' + * Tuple#2 of return field will refer to the cell#2 of returned mesh. The cell #2 of returned mesh will be equal to the cell#6 of 'this->getMesh()' + * + * If '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]. + * '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. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception) { diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index eb7c5662b..a99f19069 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -419,6 +419,14 @@ void DataArrayDouble::sort() throw(INTERP_KERNEL::Exception) _mem.sort(); } +void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::reverse : only supported with 'this' array with ONE component !"); + _mem.reverse(); +} + void DataArrayDouble::checkMonotonic(double eps) const throw(INTERP_KERNEL::Exception) { if(!isMonotonic(eps)) @@ -582,7 +590,7 @@ void DataArrayDouble::renumberInPlaceR(const int *new2Old) /*! * This method does \b not change the number of tuples after this call. - * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used. + * Only a permutation is done. If a permutation reduction is needed renumberAndReduce. */ DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const { @@ -601,7 +609,7 @@ DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const /*! * This method does \b not change the number of tuples after this call. - * Only a permutation is done. + * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used. */ DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const { @@ -845,11 +853,17 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL * comm and commIndex. The distance is computed using norm2. This method expects that 'this' is allocated and that the number of components is in [1,2,3]. * If not an exception will be thrown. * This method is typically used by MEDCouplingPointSet::findCommonNodes and MEDCouplingUMesh::mergeNodes. - * @param limitNodeId is the limit node id. All nodes which id is strictly lower than 'limitNodeId' will not be merged each other. - * @param comm out parameter (not inout) - * @param commIndex out parameter (not inout) + * In case of success, commIndex->getNumberOfTuples()-1 gives the number of tuples groupes that are within distance 'prec'. + * comm->getNumberOfTuples()==commIndex->back() + * The returned pair of DataArrayInt instances ('comm','commIndex') is called Surjectived Format 2 \sa DataArrayInt::BuildNew2OldArrayFromSurjectiveFormat2. + * This format is more compact in surjective format because only all tuple ids not in 'comm' are remain unchanged. + * + * @param prec is an absolute precision. + * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other. + * @param comm out parameter (not inout). Number of components is equal to 1. + * @param commIndex out parameter (not inout). Number of components is equal to 1. */ -void DataArrayDouble::findCommonTuples(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception) +void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception) { comm=DataArrayInt::New(); commIndex=DataArrayInt::New(); @@ -872,13 +886,13 @@ void DataArrayDouble::findCommonTuples(double prec, int limitNodeId, DataArrayIn switch(nbOfCompo) { case 3: - findCommonTuplesAlg<3>(bbox,nbOfTuples,limitNodeId,prec,c,cI); + findCommonTuplesAlg<3>(bbox,nbOfTuples,limitTupleId,prec,c,cI); break; case 2: - findCommonTuplesAlg<2>(bbox,nbOfTuples,limitNodeId,prec,c,cI); + findCommonTuplesAlg<2>(bbox,nbOfTuples,limitTupleId,prec,c,cI); break; case 1: - findCommonTuplesAlg<1>(bbox,nbOfTuples,limitNodeId,prec,c,cI); + findCommonTuplesAlg<1>(bbox,nbOfTuples,limitTupleId,prec,c,cI); break; default: throw INTERP_KERNEL::Exception("Unexpected spacedim of coords. Must be 1, 2 or 3."); @@ -889,6 +903,25 @@ void DataArrayDouble::findCommonTuples(double prec, int limitNodeId, DataArrayIn std::copy(c.begin(),c.end(),comm->getPointer()); } +/*! + * This method returns a newly allocated object the user should deal with. + * This method works for arrays which have number of components into [1,2,3]. If not an exception will be thrown. + * This method returns the different values in 'this' using 'prec'. The different values are kept in the same + * order than 'this'. That is to say that returned DataArrayDouble instance is not systematically sorted. + * + * @param prec is an absolute precision. + * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other. + */ +DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception) +{ + DataArrayInt *c0=0,*cI0=0; + findCommonTuples(prec,limitTupleId,c0,cI0); + MEDCouplingAutoRefCountObjectPtr c(c0),cI(cI0); + int newNbOfTuples=-1; + MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples); + return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); +} + void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) { copyPartOfStringInfoFrom2(compoIds,*a); @@ -1087,6 +1120,22 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr } } +/*! + * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated. + * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown. + * And to finish this method works for arrays that have number of tuples >= 1. + */ +double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !"); + return *(getConstPointer()+nbOfTuples-1); +} + void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet) { if(newArray!=arrayToSet) @@ -2594,6 +2643,14 @@ void DataArrayInt::sort() throw(INTERP_KERNEL::Exception) _mem.sort(); } +void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::reverse : only supported with 'this' array with ONE component !"); + _mem.reverse(); +} + /*! * This method expects that 'this' and 'other' have the same number of tuples and exactly one component both. If not an exception will be thrown. * This method retrieves a newly created array with same number of tuples than 'this' and 'other' with one component. @@ -2879,6 +2936,48 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data arrI=retI; } +/*! + * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayDouble::findCommonTuples for example) + * The retrieved array minimizes the permutation. + * Let's take an example : + * If 'nbOfOldTuples'==10 and 'arr'==[0,3, 5,7,9] and 'arrI'==[0,2,5] it returns the following array [0,1,2,0,3,4,5,4,6,4] and newNbOfTuples==7. + * + * @param nbOfOldTuples is the number of tuples in initial array. + * @param arr is the list of tuples ids grouped by 'arrI' array + * @param arrI is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple. + * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application + */ +DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) +{ + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfOldTuples,1); + int *pt=ret->getPointer(); + std::fill(pt,pt+nbOfOldTuples,-1); + int nbOfGrps=arrI->getNumberOfTuples()-1; + const int *cIPtr=arrI->getConstPointer(); + const int *cPtr=arr->getConstPointer(); + for(int i=0;igetNumberOfTuples()' tuples and 1 component. @@ -3307,6 +3406,22 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt } } +/*! + * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated. + * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown. + * And to finish this method works for arrays that have number of tuples >= 1. + */ +int DataArrayInt::back() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !"); + return *(getConstPointer()+nbOfTuples-1); +} + void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet) { if(newArray!=arrayToSet) diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index cc5eb0196..754d5ad08 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -69,6 +69,7 @@ namespace ParaMEDMEM T *fromNoInterlace(int nbOfComp) const; T *toNoInterlace(int nbOfComp) const; void sort(); + void reverse(); void alloc(int nbOfElements); void reAlloc(int newNbOfElements); void useArray(const T *array, bool ownership, DeallocType type, int nbOfElem); @@ -144,6 +145,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void iota(double init=0.) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isUniform(double val, double eps) const; MEDCOUPLING_EXPORT void sort() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkMonotonic(double eps) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isMonotonic(double eps) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string repr() const; @@ -173,7 +175,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); @@ -184,6 +187,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } + MEDCOUPLING_EXPORT double back() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); } @@ -310,6 +314,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void sort() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithZero(); MEDCOUPLING_EXPORT void fillWithValue(int val); MEDCOUPLING_EXPORT void iota(int init=0) throw(INTERP_KERNEL::Exception); @@ -341,6 +346,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId2(int bg, int end, int step) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isIdentity() const; MEDCOUPLING_EXPORT bool isUniform(int val) const; @@ -359,6 +365,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } + MEDCOUPLING_EXPORT int back() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); } diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 2868a0867..32f66aad0 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -216,6 +216,13 @@ namespace ParaMEDMEM std::sort(pt,pt+_nb_of_elem); } + template + void MemArray::reverse() + { + T *pt=_pointer.getPointer(); + std::reverse(pt,pt+_nb_of_elem); + } + template void MemArray::alloc(int nbOfElements) { diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index cac488467..ffc3c2a6a 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -18,6 +18,7 @@ // #include "MEDCouplingPointSet.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" #include "MEDCouplingUMesh.hxx" #include "MEDCouplingUMeshDesc.hxx" #include "MEDCouplingMemArray.hxx" @@ -242,34 +243,9 @@ void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfNodes, DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, int& newNbOfNodes) const { - DataArrayInt *ret=DataArrayInt::New(); - int nbNodesOld=getNumberOfNodes(); - ret->alloc(nbNodesOld,1); - int *pt=ret->getPointer(); - std::fill(pt,pt+nbNodesOld,-1); - int nbOfGrps=commIndex->getNumberOfTuples()-1; - const int *cIPtr=commIndex->getConstPointer(); - const int *cPtr=comm->getConstPointer(); - for(int i=0;ialloc(newNbOfNodes,spaceDim); - newCoords->copyStringInfoFrom(*_coords); - int oldNbOfNodes=getNumberOfNodes(); - double *ptToFill=newCoords->getPointer(); - const double *oldCoordsPtr=_coords->getConstPointer(); - for(int i=0;i newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes); setCoords(newCoords); - newCoords->decrRef(); } /* diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx index 5830f62e3..f65d6f564 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx @@ -1805,5 +1805,119 @@ void MEDCouplingBasicsTest4::testDADFindCommonTuples1() c->decrRef(); cI->decrRef(); // + const double array11[6]={2.3,1.2,1.3,2.4,2.5,0.8}; + da->alloc(6,1); + std::copy(array11,array11+6,da->getPointer()); + // nbOftuples=1, no common groups + da->findCommonTuples(1e-2,-1,c,cI); + CPPUNIT_ASSERT_EQUAL(0,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(1,cI->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); + c->decrRef(); + cI->decrRef(); + // + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testDABack1() +{ + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,1); + const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; + std::copy(array1,array1+6,da->getPointer()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.8,da->back(),1e-14); + da->rearrange(2); + CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); + da->alloc(0,1); + CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); da->decrRef(); + // + DataArrayInt *da2=DataArrayInt::New(); + da2->alloc(4,1); + const int array2[4]={4,7,8,2}; + std::copy(array2,array2+4,da2->getPointer()); + CPPUNIT_ASSERT_EQUAL(2,da2->back()); + da2->rearrange(2); + CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); + da2->alloc(0,1); + CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); + da2->decrRef(); +} + +void MEDCouplingBasicsTest4::testDADGetDifferentValues1() +{ + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,1); + const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; + std::copy(array1,array1+6,da->getPointer()); + // + const double expected1[4]={2.301,1.2,1.3,0.8}; + DataArrayDouble *dv=da->getDifferentValues(1e-2); + CPPUNIT_ASSERT_EQUAL(4,dv->getNbOfElems()); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],dv->getIJ(i,0),1e-14); + dv->decrRef(); + // + dv=da->getDifferentValues(2e-1); + const double expected2[3]={2.301,1.3,0.8}; + CPPUNIT_ASSERT_EQUAL(3,dv->getNbOfElems()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],dv->getIJ(i,0),1e-14); + dv->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIBuildOld2NewArrayFromSurjectiveFormat2() +{ + const int arr[5]={0,3, 5,7,9}; + const int arrI[3]={0,2,5}; + DataArrayInt *a=DataArrayInt::New(); + a->alloc(5,1); + std::copy(arr,arr+5,a->getPointer()); + DataArrayInt *b=DataArrayInt::New(); + b->alloc(3,1); + std::copy(arrI,arrI+3,b->getPointer()); + int newNbTuple=-1; + DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a,b,newNbTuple); + const int expected[10]={0,1,2,0,3,4,5,4,6,4}; + CPPUNIT_ASSERT_EQUAL(10,ret->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(7,newNbTuple); + CPPUNIT_ASSERT_EQUAL(1,ret->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected,expected+10,ret->getConstPointer())); + ret->decrRef(); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest4::testDADIReverse1() +{ + const int arr[6]={0,3,5,7,9,2}; + DataArrayInt *a=DataArrayInt::New(); + a->alloc(6,1); + std::copy(arr,arr+6,a->getPointer()); + CPPUNIT_ASSERT_EQUAL(2,a->back()); + a->reverse(); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(arr[5-i],a->getIJ(i,0)); + a->alloc(5,1); + std::copy(arr,arr+5,a->getPointer()); + a->reverse(); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_EQUAL(arr[4-i],a->getIJ(i,0)); + a->decrRef(); + // + const double arr2[6]={0.,3.,5.,7.,9.,2.}; + DataArrayDouble *b=DataArrayDouble::New(); + b->alloc(6,1); + std::copy(arr2,arr2+6,b->getPointer()); + b->reverse(); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[5-i],b->getIJ(i,0),1e-14); + b->alloc(5,1); + std::copy(arr,arr+5,b->getPointer()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.,b->back(),1e-14); + b->reverse(); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[4-i],b->getIJ(i,0),1e-14); + b->decrRef(); } diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx index 4e4d2ee9c..c88dfd400 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx @@ -82,6 +82,10 @@ namespace ParaMEDMEM CPPUNIT_TEST( testUMeshBuildSetInstanceFromThis1 ); CPPUNIT_TEST( testUMeshMergeMeshesCVW1 ); CPPUNIT_TEST( testDADFindCommonTuples1 ); + CPPUNIT_TEST( testDABack1 ); + CPPUNIT_TEST( testDADGetDifferentValues1 ); + CPPUNIT_TEST( testDAIBuildOld2NewArrayFromSurjectiveFormat2 ); + CPPUNIT_TEST( testDADIReverse1 ); CPPUNIT_TEST_SUITE_END(); public: void testDescriptionInMeshTimeUnit1(); @@ -133,6 +137,10 @@ namespace ParaMEDMEM void testUMeshMergeMeshesCVW1(); void testChangeUnderlyingMeshWithCMesh1(); void testDADFindCommonTuples1(); + void testDABack1(); + void testDADGetDifferentValues1(); + void testDAIBuildOld2NewArrayFromSurjectiveFormat2(); + void testDADIReverse1(); }; } diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i index 51a097a27..95413f688 100644 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ b/src/MEDCoupling_Swig/MEDCoupling.i @@ -205,6 +205,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayDouble::fromPolarToCart; %newobject ParaMEDMEM::DataArrayDouble::fromCylToCart; %newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart; +%newobject ParaMEDMEM::DataArrayDouble::getDifferentValues; %newobject ParaMEDMEM::DataArrayDouble::__getitem__; %newobject ParaMEDMEM::DataArrayDouble::__add__; %newobject ParaMEDMEM::DataArrayDouble::__radd__; @@ -690,10 +691,10 @@ namespace ParaMEDMEM return res; } - PyObject *findCommonNodes(double prec, int limitNodeId=-1) const throw(INTERP_KERNEL::Exception) + PyObject *findCommonNodes(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception) { DataArrayInt *comm, *commIndex; - self->findCommonNodes(prec,limitNodeId,comm,commIndex); + self->findCommonNodes(prec,limitTupleId,comm,commIndex); PyObject *res = PyList_New(2); PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); @@ -3046,6 +3047,16 @@ namespace ParaMEDMEM return convertIntArrToPyList3(ret); } + static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI) throw(INTERP_KERNEL::Exception) + { + int newNbOfTuples=-1; + DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arr,arrI,newNbOfTuples); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(newNbOfTuples)); + return ret; + } + void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple) throw(INTERP_KERNEL::Exception) { int *tmp=new int[nbOfTuples*nbOfElsPerTuple]; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 1fd2f66df..ea61321fa 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -7957,6 +7957,98 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(3,cI.getNbOfElems()); self.assertEqual(expected3,c.getValues()) self.assertEqual(expected4,cI.getValues()) + # nbOftuples=1, no common groups + array11=[2.3,1.2,1.3,2.4,2.5,0.8] + da.setValues(array11,6,1) + c,cI=da.findCommonTuples(1e-2); + self.assertEqual(0,c.getNbOfElems()); + self.assertEqual(1,cI.getNbOfElems()); + self.assertEqual([0],cI.getValues()) + pass + + def testDABack1(self): + da=DataArrayDouble.New(); + array1=[2.3,1.2,1.3,2.3,2.301,0.8] + da.setValues(array1,6,1); + self.assertAlmostEqual(0.8,da.back(),14); + da.rearrange(2); + self.assertRaises(InterpKernelException,da.back); + da.alloc(0,1); + self.assertRaises(InterpKernelException,da.back); + # + da=DataArrayInt.New(); + array2=[4,7,8,2] + da.setValues(array2,4,1); + self.assertEqual(2,da.back()); + da.rearrange(2); + self.assertRaises(InterpKernelException,da.back); + da.alloc(0,1); + self.assertRaises(InterpKernelException,da.back); + pass + + def testDADGetDifferentValues1(self): + da=DataArrayDouble.New(); + array1=[2.3,1.2,1.3,2.3,2.301,0.8] + da.setValues(array1,6,1) + # + expected1=[2.301,1.2,1.3,0.8] + dv=da.getDifferentValues(1e-2); + self.assertEqual(4,dv.getNbOfElems()); + for i in xrange(4): + self.assertAlmostEqual(expected1[i],dv.getIJ(i,0),14); + pass + # + dv=da.getDifferentValues(2e-1); + expected2=[2.301,1.3,0.8] + self.assertEqual(3,dv.getNbOfElems()); + for i in xrange(3): + self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14); + pass + pass + + def testDAIBuildOld2NewArrayFromSurjectiveFormat2(self): + arr=[0,3, 5,7,9] + arrI=[0,2,5] + a=DataArrayInt.New(); + a.setValues(arr,5,1); + b=DataArrayInt.New(); + b.setValues(arrI,3,1); + ret,newNbTuple=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(10,a,b); + expected=[0,1,2,0,3,4,5,4,6,4] + self.assertEqual(10,ret.getNbOfElems()); + self.assertEqual(7,newNbTuple); + self.assertEqual(1,ret.getNumberOfComponents()); + self.assertTrue(expected,ret.getValues()); + pass + + def testDADIReverse1(self): + arr=[0,3,5,7,9,2] + a=DataArrayInt.New(); + a.setValues(arr,6,1); + self.assertEqual(2,a.back()); + a.reverse(); + for i in xrange(6): + self.assertEqual(arr[5-i],a.getIJ(i,0)); + pass + a.setValues(arr,5,1); + a.reverse(); + for i in xrange(5): + self.assertEqual(arr[4-i],a.getIJ(i,0)); + pass + # + arr2=[0.,3.,5.,7.,9.,2.] + b=DataArrayDouble.New(); + b.setValues(arr2,6,1); + b.reverse(); + for i in xrange(6): + self.assertAlmostEqual(arr2[5-i],b.getIJ(i,0),14); + pass + b.setValues(arr2,5,1); + self.assertAlmostEqual(9.,b.back(),14) + b.reverse(); + for i in xrange(5): + self.assertAlmostEqual(arr2[4-i],b.getIJ(i,0),14); + pass pass def setUp(self):