]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Addition of DataArrayDouble::getDifferentValues
authorageay <ageay>
Tue, 17 Jan 2012 15:35:41 +0000 (15:35 +0000)
committerageay <ageay>
Tue, 17 Jan 2012 15:35:41 +0000 (15:35 +0000)
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMemArray.txx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx
src/MEDCoupling_Swig/MEDCoupling.i
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py

index cd29db5292878f37b5898f21ff9f58138a85bab8..d7355cd9c0bf2c792efb8fe7e02366205b3edc7b 100644 (file)
@@ -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)
 {
index eb7c5662bf44f7f8735c8064b7a7aeeba3c3aa93..a99f1906997cc82af346f0c99a06ca321661994d 100644 (file)
@@ -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<DataArrayInt> c(c0),cI(cI0);
+  int newNbOfTuples=-1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples);
+  return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
+}
+
 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& 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;i<nbOfGrps;i++)
+    pt[cPtr[cIPtr[i]]]=-(i+2);
+  int newNb=0;
+  for(int iNode=0;iNode<nbOfOldTuples;iNode++)
+    {
+      if(pt[iNode]<0)
+        {
+          if(pt[iNode]==-1)
+            pt[iNode]=newNb++;
+          else
+            {
+              int grpId=-(pt[iNode]+2);
+              for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
+                pt[cPtr[j]]=newNb;
+              newNb++;
+            }
+        }
+    }
+  newNbOfTuples=newNb;
+  return ret;
+}
+
 /*!
  * This method expects that 'this' is allocated and with only one component. If not an exception will be thrown.
  * This method returns a newly created array with 'this->getNumberOfTuples()' 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)
index cc5eb01962ac7162580d31ce690d21b335afd672..754d5ad08a493ab460c69b0657df51c7f274a1ae 100644 (file)
@@ -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<int>& 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<int>& 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(); }
index 2868a086736b36a6919e6bb9a3f8a9113295da0a..32f66aad0350436f6e2bdc8a758af18fc50e16f9 100644 (file)
@@ -216,6 +216,13 @@ namespace ParaMEDMEM
     std::sort(pt,pt+_nb_of_elem);
   }
 
+  template<class T>
+  void MemArray<T>::reverse()
+  {
+    T *pt=_pointer.getPointer();
+    std::reverse(pt,pt+_nb_of_elem);
+  }
+
   template<class T>
   void MemArray<T>::alloc(int nbOfElements)
   {
index cac4884674e6aac9731915f98afecb93fbe31066..ffc3c2a6a4dcc4b3fd9ae6e3c183a44aa109323a 100644 (file)
@@ -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;i<nbOfGrps;i++)
-    pt[cPtr[cIPtr[i]]]=-(i+2);
-  int newNb=0;
-  for(int iNode=0;iNode<nbNodesOld;iNode++)
-    {
-      if(pt[iNode]<0)
-        {
-          if(pt[iNode]==-1)
-            pt[iNode]=newNb++;
-          else
-            {
-              int grpId=-(pt[iNode]+2);
-              for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
-                pt[cPtr[j]]=newNb;
-              newNb++;
-            }
-        }
-    }
-  newNbOfNodes=newNb;
-  return ret;
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !");
+  return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm,commIndex,newNbOfNodes);
 }
 
 /*
@@ -281,17 +257,10 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const
  */
 void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
 {
-  DataArrayDouble *newCoords=DataArrayDouble::New();
-  int spaceDim=getSpaceDimension();
-  newCoords->alloc(newNbOfNodes,spaceDim);
-  newCoords->copyStringInfoFrom(*_coords);
-  int oldNbOfNodes=getNumberOfNodes();
-  double *ptToFill=newCoords->getPointer();
-  const double *oldCoordsPtr=_coords->getConstPointer();
-  for(int i=0;i<oldNbOfNodes;i++)
-    std::copy(oldCoordsPtr+i*spaceDim,oldCoordsPtr+(i+1)*spaceDim,ptToFill+newNodeNumbers[i]*spaceDim);
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::renumberNodes : no coords specified !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes);
   setCoords(newCoords);
-  newCoords->decrRef();
 }
 
 /*
index 5830f62e38f31aee2ea8c73acb5f6ff87f40f5ab..f65d6f5641a78627d08594a92d514209c2e114cd 100644 (file)
@@ -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();
 }
index 4e4d2ee9c482eb631cbbb69a1848f3288755ec4f..c88dfd4005232d38be94f5f792a23f1bbf741615 100644 (file)
@@ -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();
   };
 }
 
index 51a097a2702094a515153c5b6d27185246953c06..95413f688553c6c44a92b1d33d2e8e765bc7fb06 100644 (file)
@@ -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];
index 1fd2f66df90b0c39495bee24d32ab51f9564049d..ea61321faf3cf092de0a0979234d616fa1977e70 100644 (file)
@@ -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):