Salome HOME
OK thanks to INV !
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
index abfc07b2365c1f85bc1e857e8ce9c2fb2647e4dc..b5dd7300f7f12119403989e236734f7e6bbe0449 100644 (file)
@@ -399,6 +399,33 @@ void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL:
     }
 }
 
+/*!
+ * Sets information on all components. This method can change number of components
+ * at certain conditions; if the conditions are not respected, an exception is thrown.
+ * The number of components can be changed in \a this only if \a this is not allocated.
+ * The condition of number of components must not be changed.
+ *
+ * To know more on format of the component information see
+ * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
+ *  \param [in] info - a vector of component infos.
+ *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
+ */
+void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()!=(int)info.size())
+    {
+      if(!isAllocated())
+        _info_on_compo=info;
+      else
+        {
+          std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  else
+    _info_on_compo=info;
+}
+
 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
 {
   if(getNumberOfTuples()!=nbOfTuples)
@@ -488,6 +515,45 @@ void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) thro
     }
 }
 
+/*!
+ * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, 
+ * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
+ *
+ * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
+ *
+ * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
+ * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
+ * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
+ * \param [in] sliceId - the slice id considered
+ * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
+ * \param [out] startSlice - the start of the slice considered
+ * \param [out] stopSlice - the stop of the slice consided
+ * 
+ * \throw If \a step == 0
+ * \throw If \a nbOfSlices not > 0
+ * \throw If \a sliceId not in [0,nbOfSlices)
+ */
+void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
+{
+  if(nbOfSlices<=0)
+    {
+      std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(sliceId<0 || sliceId>=nbOfSlices)
+    {
+      std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
+  int minNbOfElemsPerSlice=nbElems/nbOfSlices;
+  startSlice=start+minNbOfElemsPerSlice*step*sliceId;
+  if(sliceId<nbOfSlices-1)
+    stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
+  else
+    stopSlice=stop;
+}
+
 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
 {
   if(end<begin)
@@ -587,6 +653,16 @@ void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
 }
 
+/*!
+ * This method desallocated \a this without modification of informations relative to the components.
+ * After call of this method, DataArrayDouble::isAllocated will return false.
+ * If \a this is already not allocated, \a this is let unchanged.
+ */
+void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
+{
+  _mem.destroy();
+}
+
 std::size_t DataArrayDouble::getHeapMemorySize() const
 {
   std::size_t sz=_mem.getNbOfElemAllocated();
@@ -594,32 +670,6 @@ std::size_t DataArrayDouble::getHeapMemorySize() const
   return DataArray::getHeapMemorySize()+sz;
 }
 
-/*!
- * Sets information on all components. This method can change number of components
- * at certain conditions; if the conditions are not respected, an exception is thrown.
- * The number of components can be changed provided that \a this is not allocated.
- *
- * To know more on format of the component information see
- * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
- *  \param [in] info - a vector of component infos.
- *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
- */
-void DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
-{
-  if(getNumberOfComponents()!=(int)info.size())
-    {
-      if(!isAllocated())
-        _info_on_compo=info;
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayDouble::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  else
-    _info_on_compo=info;
-}
-
 /*!
  * Returns the only one value in \a this, if and only if number of elements
  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
@@ -1170,9 +1220,12 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other,
  * than the current number the array is truncated, otherwise the array is extended.
  *  \param [in] nbOfTuples - new number of tuples. 
  *  \throw If \a this is not allocated.
+ *  \throw If \a nbOfTuples is negative.
  */
 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
 {
+  if(nbOfTuples<0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
   checkAllocated();
   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
   declareAsNew();
@@ -1211,7 +1264,7 @@ DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::E
     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
   DataArrayDouble *ret=DataArrayDouble::New();
-  ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
   return ret;
 }
 
@@ -1231,7 +1284,7 @@ DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exc
     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
   double *tab=_mem.toNoInterlace(getNumberOfComponents());
   DataArrayDouble *ret=DataArrayDouble::New();
-  ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
   return ret;
 }
 
@@ -1252,7 +1305,16 @@ void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::E
   double *tmp=new double[nbTuples*nbOfCompo];
   const double *iptr=getConstPointer();
   for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
+    {
+      int v=old2New[i];
+      if(v>=0 && v<nbTuples)
+        std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
   delete [] tmp;
   declareAsNew();
@@ -1276,7 +1338,16 @@ void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::
   double *tmp=new double[nbTuples*nbOfCompo];
   const double *iptr=getConstPointer();
   for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
+    {
+      int v=new2Old[i];
+      if(v>=0 && v<nbTuples)
+        std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
   delete [] tmp;
   declareAsNew();
@@ -1482,7 +1553,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) c
  *  \throw If \a end > \a this->getNumberOfTuples().
  *  \throw If \a this is not allocated.
  */
-DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
+DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   int nbOfComp=getNumberOfComponents();
@@ -1667,9 +1738,9 @@ void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
  *  \throw If a component index (\a i) is not valid: 
  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
  *
- *  \ref cpp_mcdataarraydouble_keepselectedcomponents "Here is a Python example".
+ *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
  */
-DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
+DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
@@ -1713,7 +1784,7 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL
     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
   int nbOfComp1=getNumberOfComponents();
   int nbOfComp2=other->getNumberOfComponents();
-  double *newArr=new double[nbOfTuples*(nbOfComp1+nbOfComp2)];
+  double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
   double *w=newArr;
   const double *inp1=getConstPointer();
   const double *inp2=other->getConstPointer();
@@ -1722,17 +1793,44 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL
       w=std::copy(inp1,inp1+nbOfComp1,w);
       w=std::copy(inp2,inp2+nbOfComp2,w);
     }
-  useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
+  useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
   std::vector<int> compIds(nbOfComp2);
   for(int i=0;i<nbOfComp2;i++)
     compIds[i]=nbOfComp1+i;
   copyPartOfStringInfoFrom2(compIds,*other);
 }
 
+/*!
+ * This method checks that all tuples in \a other are in \a this.
+ * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
+ * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this.
+ *
+ * \param [in] other - the array having the same number of components than \a this.
+ * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
+ * \sa DataArrayDouble::findCommonTuples
+ */
+bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
+{
+  if(!other)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
+  checkAllocated(); other->checkAllocated();
+  if(getNumberOfComponents()!=other->getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
+  DataArrayInt *c=0,*ci=0;
+  a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
+  int newNbOfTuples=-1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
+  tupleIds=ret1.retn();
+  return newNbOfTuples==getNumberOfTuples();
+}
+
 /*!
  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
- * distance is computed using norm2.
+ * distance separating two points is computed with the infinite norm.
  *
  * Indices of coincident tuples are stored in output arrays.
  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
@@ -1758,7 +1856,7 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL
  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
  *
  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
- *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
+ *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
  */
 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
 {
@@ -1919,7 +2017,7 @@ DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other)
  *  \throw If \a this is not allocated.
  *  \throw If the number of components is not in [1,2,3].
  *
- *  \ref cpp_mcdataarraydouble_getdifferentvalues "Here is a Python example".
+ *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
  */
 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
 {
@@ -1934,7 +2032,6 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple
 
 /*!
  * Copy all components in a specified order from another DataArrayDouble.
- * The specified components become the first ones in \a this array.
  * Both numerical and textual data is copied. The number of tuples in \a this and
  * the other array can be different.
  *  \param [in] a - the array to copy data from.
@@ -1944,7 +2041,7 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple
  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
  *
- *  \ref cpp_mcdataarraydouble_setselectedcomponents "Here is a Python example".
+ *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
  */
 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
 {
@@ -1994,7 +2091,7 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std:
  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
  *
- *  \ref cpp_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
+ *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
  */
 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
 {
@@ -2057,7 +2154,7 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
- *  \ref cpp_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
+ *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
  */
 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
 {
@@ -2111,7 +2208,7 @@ void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTupl
  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
  *
- *  \ref cpp_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
+ *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
  */
 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
 {
@@ -2182,7 +2279,7 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu
  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
  *         out of a valid range for \a this array.
  *
- *  \ref cpp_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
+ *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
  */
 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
 {
@@ -2242,7 +2339,7 @@ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, cons
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
- *  \ref cpp_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
+ *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
  */
 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
 {
@@ -2314,7 +2411,7 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
- *  \ref cpp_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
+ *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
  */
 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
 {
@@ -2509,10 +2606,13 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr
  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
  *         \a a array.
  */
-void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
+void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
 {
-  if(!a || !tuplesSelec)
+  if(!aBase || !tuplesSelec)
     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
+  const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
+  if(!a)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
   checkAllocated();
   a->checkAllocated();
   tuplesSelec->checkAllocated();
@@ -2568,10 +2668,13 @@ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const Data
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for the array \a a.
  */
-void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
+void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
 {
+  if(!aBase)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
+  const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
   if(!a)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArrayDouble is NULL !");
+    throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
   checkAllocated();
   a->checkAllocated();
   int nbOfComp=getNumberOfComponents();
@@ -2621,6 +2724,24 @@ double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_K
   return _mem[tupleId*_info_on_compo.size()+compoId];
 }
 
+/*!
+ * Returns the first value of \a this. 
+ *  \return double - the last value of \a this array.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *  \throw If \a this->getNumberOfTuples() < 1.
+ */
+double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples<1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
+  return *(getConstPointer());
+}
+
 /*!
  * Returns the last value of \a this. 
  *  \return double - the last value of \a this array.
@@ -2942,6 +3063,29 @@ double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP
   return ret;
 }
 
+/*!
+ * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value.
+ * This method only works for single component array.
+ *
+ * \return a value in [ 0, \c this->getNumberOfTuples() )
+ *
+ * \throw If \a this is not allocated
+ *
+ */
+int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
+{
+  int ret=0;
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
+  const double *vals=begin();
+  int nbOfTuples=getNumberOfTuples();
+  for(int i=0;i<nbOfTuples;i++,vals++)
+    if(fabs(*vals-value)<=eps)
+      ret++;
+  return ret;
+}
+
 /*!
  * Returns the average value of \a this one-dimensional array.
  *  \return double - the average value over all values of \a this array.
@@ -3077,6 +3221,66 @@ double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Except
   return ret;
 }
 
+/*!
+ * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
+ * The returned array will have same number of components than \a this and number of tuples equal to
+ * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
+ *
+ * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
+ * This method is quite useful for users that need to put a field on cells to field on nodes on the same mesh without a need of conservation.
+ *
+ * \param [in] bgOfIndex - begin (included) of the input index array.
+ * \param [in] endOfIndex - end (excluded) of the input index array.
+ * \return DataArrayDouble * - the new instance having the same number of components than \a this.
+ * 
+ * \throw If bgOfIndex or end is NULL.
+ * \throw If input index array is not ascendingly sorted.
+ * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
+ * \throw If std::distance(bgOfIndex,endOfIndex)==0.
+ */
+DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
+{
+  if(!bgOfIndex || !endOfIndex)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
+  checkAllocated();
+  int nbCompo=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  int sz=(int)std::distance(bgOfIndex,endOfIndex);
+  if(sz<1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
+  sz--;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
+  const int *w=bgOfIndex;
+  if(*w<0 || *w>=nbOfTuples)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
+  const double *srcPt=begin()+(*w)*nbCompo;
+  double *tmp=ret->getPointer();
+  for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
+    {
+      std::fill(tmp,tmp+nbCompo,0.);
+      if(w[1]>=w[0])
+        {
+          for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
+            {
+              if(j>=0 && j<nbOfTuples)
+                std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
+              else
+                {
+                  std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  ret->copyStringInfoFrom(*this);
+  return ret.retn();
+}
+
 /*!
  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
  * Cartesian coordinate system. The two components of the tuple of \a this array are 
@@ -3450,19 +3654,53 @@ DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Excepti
  *          The caller is to delete this result array using decrRef() as it is no more
  *          needed.
  *  \throw If \a this is not allocated.
+ *  \sa DataArrayDouble::maxPerTupleWithCompoId
  */
 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   int nbOfComp=getNumberOfComponents();
-  DataArrayDouble *ret=DataArrayDouble::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
   int nbOfTuple=getNumberOfTuples();
   ret->alloc(nbOfTuple,1);
   const double *src=getConstPointer();
   double *dest=ret->getPointer();
   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
     *dest=*std::max_element(src,src+nbOfComp);
-  return ret;
+  return ret.retn();
+}
+
+/*!
+ * Computes the maximal value within every tuple of \a this array and it returns the first component
+ * id for each tuple that corresponds to the maximal value within the tuple.
+ * 
+ *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
+ *          same number of tuples and only one component.
+ *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
+ *          same number of tuples as \a this array and one component.
+ *          The caller is to delete this result array using decrRef() as it is no more
+ *          needed.
+ *  \throw If \a this is not allocated.
+ *  \sa DataArrayDouble::maxPerTuple
+ */
+DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  int nbOfComp=getNumberOfComponents();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
+  int nbOfTuple=getNumberOfTuples();
+  ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
+  const double *src=getConstPointer();
+  double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
+  for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
+    {
+      const double *loc=std::max_element(src,src+nbOfComp);
+      *dest=*loc;
+      *dest1=(int)std::distance(src,loc);
+    }
+  compoIdOfMaxPerTuple=ret1.retn();
+  return ret0.retn();
 }
 
 /*!
@@ -4031,8 +4269,8 @@ DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Except
 /*!
  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
  * array whose values are within a given range. Textual data is not copied.
- *  \param [in] vmin - a lowest acceptable value.
- *  \param [in] vmax - a greatest acceptable value.
+ *  \param [in] vmin - a lowest acceptable value (included).
+ *  \param [in] vmax - a greatest acceptable value (included).
  *  \return DataArrayInt * - the new instance of DataArrayInt.
  *          The caller is to delete this result array using decrRef() as it is no more
  *          needed.
@@ -4655,7 +4893,7 @@ void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_
  * valid cases.
  * 1.  The arrays have same number of tuples and components. Then each value of
  *   the result array (_a_) is a product of the corresponding values of \a a1 and
- *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
+ *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
  *   component. Then
  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
@@ -4749,12 +4987,12 @@ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const Data
  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
  * valid cases.
  * 1.  The arrays have same number of tuples and components. Then each value of
- *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
- *   _a_ [ i, j ] *= _other_ [ i, j ].
+ *   \a other array is multiplied to the corresponding value of \a this array, i.e.
+ *   _this_ [ i, j ] *= _other_ [ i, j ].
  * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] *= _other_ [ i, 0 ].
+ *   _this_ [ i, j ] *= _other_ [ i, 0 ].
  * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] *= _a2_ [ 0, j ].
+ *   _this_ [ i, j ] *= _a2_ [ 0, j ].
  *
  *  \param [in] other - an array to multiply to \a this one.
  *  \throw If \a other is NULL.
@@ -5204,6 +5442,16 @@ void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
 }
 
+/*!
+ * This method desallocated \a this without modification of informations relative to the components.
+ * After call of this method, DataArrayInt::isAllocated will return false.
+ * If \a this is already not allocated, \a this is let unchanged.
+ */
+void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
+{
+  _mem.destroy();
+}
+
 std::size_t DataArrayInt::getHeapMemorySize() const
 {
   std::size_t sz=_mem.getNbOfElemAllocated();
@@ -5211,32 +5459,6 @@ std::size_t DataArrayInt::getHeapMemorySize() const
   return DataArray::getHeapMemorySize()+sz;
 }
 
-/*!
- * Sets information on all components. This method can change number of components
- * at certain conditions; if the conditions are not respected, an exception is thrown.
- * The number of components can be changed provided that \a this is not allocated.
- *
- * To know more on format of the component information see
- * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
- *  \param [in] info - a vector of component infos.
- *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
- */
-void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
-{
-  if(getNumberOfComponents()!=(int)info.size())
-    {
-      if(!isAllocated())
-        _info_on_compo=info;
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  else
-    _info_on_compo=info;
-}
-
 /*!
  * Returns the only one value in \a this, if and only if number of elements
  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
@@ -5663,7 +5885,7 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd
         *pt=indArrBg[*pt];
       else
         {
-          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
+          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
@@ -5752,7 +5974,7 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
         }
       else
         {
-          std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
+          std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
@@ -6169,7 +6391,7 @@ DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Excepti
     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
   DataArrayInt *ret=DataArrayInt::New();
-  ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
   return ret;
 }
 
@@ -6190,7 +6412,7 @@ DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception
     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
   int *tab=_mem.toNoInterlace(getNumberOfComponents());
   DataArrayInt *ret=DataArrayInt::New();
-  ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
   return ret;
 }
 
@@ -6211,7 +6433,16 @@ void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exce
   int *tmp=new int[nbTuples*nbOfCompo];
   const int *iptr=getConstPointer();
   for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
+    {
+      int v=old2New[i];
+      if(v>=0 && v<nbTuples)
+        std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
   delete [] tmp;
   declareAsNew();
@@ -6235,7 +6466,16 @@ void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exc
   int *tmp=new int[nbTuples*nbOfCompo];
   const int *iptr=getConstPointer();
   for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
+    {
+      int v=new2Old[i];
+      if(v>=0 && v<nbTuples)
+        std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
   delete [] tmp;
   declareAsNew();
@@ -6441,7 +6681,7 @@ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const t
  *  \throw If \a end > \a this->getNumberOfTuples().
  *  \throw If \a this is not allocated.
  */
-DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
+DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   int nbOfComp=getNumberOfComponents();
@@ -6516,7 +6756,7 @@ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERN
   const int *pt=getConstPointer();
   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
   DataArrayInt *ret=DataArrayInt::New();
-  ret->useArray(pt2,true,CPP_DEALLOC,nbTuples,1);
+  ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
   return ret;
 }
 
@@ -6895,9 +7135,12 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue)
  * than the current number the array is truncated, otherwise the array is extended.
  *  \param [in] nbOfTuples - new number of tuples. 
  *  \throw If \a this is not allocated.
+ *  \throw If \a nbOfTuples is negative.
  */
 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
 {
+  if(nbOfTuples<0)
+    throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
   checkAllocated();
   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
   declareAsNew();
@@ -6917,9 +7160,9 @@ void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
  *  \throw If a component index (\a i) is not valid: 
  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
  *
- *  \ref cpp_mcdataarrayint_keepselectedcomponents "Here is a Python example".
+ *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
  */
-DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
+DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
@@ -6961,7 +7204,7 @@ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exce
     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
   int nbOfComp1=getNumberOfComponents();
   int nbOfComp2=other->getNumberOfComponents();
-  int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)];
+  int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
   int *w=newArr;
   const int *inp1=getConstPointer();
   const int *inp2=other->getConstPointer();
@@ -6970,7 +7213,7 @@ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exce
       w=std::copy(inp1,inp1+nbOfComp1,w);
       w=std::copy(inp2,inp2+nbOfComp2,w);
     }
-  useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
+  useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
   std::vector<int> compIds(nbOfComp2);
   for(int i=0;i<nbOfComp2;i++)
     compIds[i]=nbOfComp1+i;
@@ -6989,7 +7232,7 @@ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exce
  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
  *
- *  \ref cpp_mcdataarrayint_setselectedcomponents "Here is a Python example".
+ *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
  */
 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
 {
@@ -7040,7 +7283,7 @@ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vecto
  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
  *
- *  \ref cpp_mcdataarrayint_setpartofvalues1 "Here is a Python example".
+ *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
  */
 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
 {
@@ -7103,7 +7346,7 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
- *  \ref cpp_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
+ *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
  */
 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
 {
@@ -7158,7 +7401,7 @@ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, in
  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
  *
- *  \ref cpp_mcdataarrayint_setpartofvalues2 "Here is a Python example".
+ *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
  */
 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
 {
@@ -7229,7 +7472,7 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples,
  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
  *         out of a valid range for \a this array.
  *
- *  \ref cpp_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
+ *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
  */
 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
 {
@@ -7289,7 +7532,7 @@ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
- *  \ref cpp_mcdataarrayint_setpartofvalues3 "Here is a Python example".
+ *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
  */
 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
 {
@@ -7361,7 +7604,7 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples,
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
- *  \ref cpp_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
+ *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
  */
 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
 {
@@ -7522,8 +7765,13 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt
  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
  *         \a a array.
  */
-void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
+void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
 {
+  if(!aBase || !tuplesSelec)
+    throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
+  const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
+  if(!a)
+    throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
   checkAllocated();
   a->checkAllocated();
   tuplesSelec->checkAllocated();
@@ -7579,8 +7827,13 @@ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArr
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for the array \a a.
  */
-void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
+void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
 {
+  if(!aBase)
+    throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
+  const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
+  if(!a)
+    throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
   checkAllocated();
   a->checkAllocated();
   int nbOfComp=getNumberOfComponents();
@@ -7630,9 +7883,27 @@ int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL:
   return _mem[tupleId*_info_on_compo.size()+compoId];
 }
 
+/*!
+ * Returns the first value of \a this. 
+ *  \return int - the last value of \a this array.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *  \throw If \a this->getNumberOfTuples() < 1.
+ */
+int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples<1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
+  return *(getConstPointer());
+}
+
 /*!
  * Returns the last value of \a this. 
- *  \return double - the last value of \a this array.
+ *  \return int - the last value of \a this array.
  *  \throw If \a this is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1.
  *  \throw If \a this->getNumberOfTuples() < 1.
@@ -7894,6 +8165,29 @@ int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_K
   return -1;
 }
 
+/*!
+ * This method returns the number of values in \a this that are equals to input parameter \a value.
+ * This method only works for single component array.
+ *
+ * \return a value in [ 0, \c this->getNumberOfTuples() )
+ *
+ * \throw If \a this is not allocated
+ *
+ */
+int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
+{
+  int ret=0;
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
+  const int *vals=begin();
+  int nbOfTuples=getNumberOfTuples();
+  for(int i=0;i<nbOfTuples;i++,vals++)
+    if(*vals==value)
+      ret++;
+  return ret;
+}
+
 /*!
  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
@@ -7964,6 +8258,65 @@ int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
   return ret;
 }
 
+/*!
+ * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
+ * The returned array will have same number of components than \a this and number of tuples equal to
+ * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
+ *
+ * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
+ *
+ * \param [in] bgOfIndex - begin (included) of the input index array.
+ * \param [in] endOfIndex - end (excluded) of the input index array.
+ * \return DataArrayInt * - the new instance having the same number of components than \a this.
+ * 
+ * \throw If bgOfIndex or end is NULL.
+ * \throw If input index array is not ascendingly sorted.
+ * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
+ * \throw If std::distance(bgOfIndex,endOfIndex)==0.
+ */
+DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
+{
+  if(!bgOfIndex || !endOfIndex)
+    throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
+  checkAllocated();
+  int nbCompo=getNumberOfComponents();
+  int nbOfTuples=getNumberOfTuples();
+  int sz=(int)std::distance(bgOfIndex,endOfIndex);
+  if(sz<1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
+  sz--;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
+  const int *w=bgOfIndex;
+  if(*w<0 || *w>=nbOfTuples)
+    throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
+  const int *srcPt=begin()+(*w)*nbCompo;
+  int *tmp=ret->getPointer();
+  for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
+    {
+      std::fill(tmp,tmp+nbCompo,0.);
+      if(w[1]>=w[0])
+        {
+          for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
+            {
+              if(j>=0 && j<nbOfTuples)
+                std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
+              else
+                {
+                  std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  ret->copyStringInfoFrom(*this);
+  return ret.retn();
+}
+
 /*!
  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
@@ -8037,10 +8390,61 @@ DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& a
   return ret.retn();
 }
 
+/*!
+ * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
+ * A packed index array is an allocated array with one component, and at least one tuple. The first element
+ * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
+ * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes.
+ * 
+ * \return DataArrayInt * - a new object to be managed by the caller.
+ */
+DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
+{
+  int retSz=1;
+  for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
+    {
+      if(*it4)
+        {
+          (*it4)->checkAllocated();
+          if((*it4)->getNumberOfComponents()!=1)
+            {
+              std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          int nbTupl=(*it4)->getNumberOfTuples();
+          if(nbTupl<1)
+            {
+              std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          if((*it4)->front()!=0)
+            {
+              std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          retSz+=nbTupl-1;
+        }
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  if(arrs.empty())
+    throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(retSz,1);
+  int *pt=ret->getPointer(); *pt++=0;
+  for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
+    pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
+  ret->copyStringInfoFrom(*(arrs[0]));
+  return ret.retn();
+}
+
 /*!
  * Returns the maximal value and its location within \a this one-dimensional array.
  *  \param [out] tupleId - index of the tuple holding the maximal value.
- *  \return double - the maximal value among all values of \a this array.
+ *  \return int - the maximal value among all values of \a this array.
  *  \throw If \a this->getNumberOfComponents() != 1
  *  \throw If \a this->getNumberOfTuples() < 1
  */
@@ -8247,8 +8651,8 @@ void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
  * this[*id] in [\b vmin,\b vmax)
  * 
- * \param [in] vmin begin of range. This value is included in range.
- * \param [out] vmax end of range. This value is \b not included in range.
+ * \param [in] vmin begin of range. This value is included in range (included).
+ * \param [in] vmax end of range. This value is \b not included in range (excluded).
  * \return a newly allocated data array that the caller should deal with.
  */
 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
@@ -8265,6 +8669,35 @@ DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP
   return ret.retn();
 }
 
+/*!
+ * This method works only on data array with one component.
+ * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown.
+ * 
+ * \param [in] vmin begin of range. This value is included in range (included).
+ * \param [in] vmax end of range. This value is \b not included in range (excluded).
+ * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
+ */
+bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
+  int nbOfTuples=getNumberOfTuples();
+  bool ret=true;
+  const int *cptr=getConstPointer();
+  for(int i=0;i<nbOfTuples;i++,cptr++)
+    {
+      if(*cptr>=vmin && *cptr<vmax)
+        { ret=ret && *cptr==i; }
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  return ret;
+}
+
 /*!
  * Modify all elements of \a this array, so that
  * an element _x_ becomes <em> val % x </em>.
@@ -8519,14 +8952,13 @@ DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *
 
 /*!
  * Returns a new DataArrayInt which contains all elements of given one-dimensional
- * not negative arrays. The result array does not contain any duplicates and its values
+ * arrays. The result array does not contain any duplicates and its values
  * are sorted in ascending order.
  *  \param [in] arr - sequence of DataArrayInt's to unite.
  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
  *         array using decrRef() as it is no more needed.
  *  \throw If any \a arr[i] is not allocated.
  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
- *  \throw If any value of \a arr[i] is negative.
  */
 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
 {
@@ -8534,17 +8966,12 @@ DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>&
   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
     if(*it4)
       a.push_back(*it4);
-  int valm=std::numeric_limits<int>::max();
   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
     {
       (*it)->checkAllocated();
       if((*it)->getNumberOfComponents()!=1)
         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
-      int tmp1;
-      valm=std::min((*it)->getMinValue(tmp1),valm);
     }
-  if(valm<0)
-    throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
   //
   std::set<int> r;
   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
@@ -8561,14 +8988,13 @@ DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>&
 
 /*!
  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
- * not negative arrays. The result array does not contain any duplicates and its values
+ * arrays. The result array does not contain any duplicates and its values
  * are sorted in ascending order.
  *  \param [in] arr - sequence of DataArrayInt's to intersect.
  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
  *         array using decrRef() as it is no more needed.
  *  \throw If any \a arr[i] is not allocated.
  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
- *  \throw If any value of \a arr[i] < 0.
  */
 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
 {
@@ -8576,17 +9002,12 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayI
   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
     if(*it4)
       a.push_back(*it4);
-  int valm=std::numeric_limits<int>::max();
   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
     {
       (*it)->checkAllocated();
       if((*it)->getNumberOfComponents()!=1)
         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
-      int tmp1;
-      valm=std::min((*it)->getMinValue(tmp1),valm);
     }
-  if(valm<0)
-    throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : a negative value has been detected !");
   //
   std::set<int> r;
   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
@@ -8712,7 +9133,7 @@ DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other
 
 /*!
  * Returns a new DataArrayInt which contains all elements of \a this and a given
- * one-dimensional not negative arrays. The result array does not contain any duplicates
+ * one-dimensional arrays. The result array does not contain any duplicates
  * and its values are sorted in ascending order.
  *  \param [in] other - an array to unite with \a this one.
  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
@@ -8720,7 +9141,6 @@ DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other
  *  \throw If \a this or \a other is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1.
  *  \throw If \a other->getNumberOfComponents() != 1.
- *  \throw If any value of \a this or \a other is negative.
  */
 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
 {
@@ -8732,7 +9152,7 @@ DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(IN
 
 /*!
  * Returns a new DataArrayInt which contains elements present in both \a this and a given
- * one-dimensional not negative arrays. The result array does not contain any duplicates
+ * one-dimensional arrays. The result array does not contain any duplicates
  * and its values are sorted in ascending order.
  *  \param [in] other - an array to intersect with \a this one.
  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
@@ -8740,7 +9160,6 @@ DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(IN
  *  \throw If \a this or \a other is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1.
  *  \throw If \a other->getNumberOfComponents() != 1.
- *  \throw If any value of \a this or \a other is negative.
  */
 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
 {
@@ -8779,6 +9198,7 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
  * "MEDCouplingUMesh::buildDescendingConnectivity" and
  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
+ * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
  *          The caller is to delete this array using decrRef() as it is no more needed. 
@@ -8790,6 +9210,8 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
  *         - this contains [1,3,6,7,7,9,15]
  *         - result array contains [2,3,1,0,2,6],
  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
+ *
+ * \sa DataArrayInt::computeOffsets2
  */
 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
 {
@@ -8852,12 +9274,14 @@ void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
  * components remains the same and number of tuples is inceamented by one.<br>
  * This method is useful for allToAllV in MPI with contiguous policy. This method
  * differs from computeOffsets() in that the number of tuples is changed by this one.
+ * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
  *  \throw If \a this is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1.
  *
  *  \b Example: <br>
  *          - Before \a this contains [3,5,1,2,0,8]
  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
+ * \sa DataArrayInt::deltaShiftIndex
  */
 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
 {
@@ -8865,14 +9289,14 @@ void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
   int nbOfTuples=getNumberOfTuples();
-  int *ret=new int[nbOfTuples+1];
+  int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
   if(nbOfTuples==0)
     return ;
   const int *work=getConstPointer();
   ret[0]=0;
   for(int i=0;i<nbOfTuples;i++)
     ret[i+1]=work[i]+ret[i];
-  useArray(ret,true,CPP_DEALLOC,nbOfTuples+1,1);
+  useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
   declareAsNew();
 }
 
@@ -10017,19 +10441,22 @@ void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exce
 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
 {
   std::size_t sz=std::distance(start,end);
-  int *ret=new int[sz];
+  int *ret=(int *)malloc(sz*sizeof(int));
   int *work=new int[sz];
   std::copy(start,end,work);
   std::sort(work,work+sz);
   if(std::unique(work,work+sz)!=work+sz)
     {
       delete [] work;
-      delete [] ret;
+      free(ret);
       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
     }
+  std::map<int,int> m;
+  for(int *workPt=work;workPt!=work+sz;workPt++)
+    m[*workPt]=(int)std::distance(work,workPt);
   int *iter2=ret;
   for(const int *iter=start;iter!=end;iter++,iter2++)
-    *iter2=(int)std::distance(work,std::find(work,work+sz,*iter));
+    *iter2=m[*iter];
   delete [] work;
   return ret;
 }