Salome HOME
Generalization of unstructured grid supported by the remapper.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
index eb91aa22ce5e1567af0ef80998d72ce7b9dd1da9..adc2f0b1c71587f8f95a602d4745d155b940e6ee 100644 (file)
@@ -247,6 +247,42 @@ void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(
   _info_on_compo=info;
 }
 
+/*!
+ * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
+ * type of \a this and \a aBase.
+ *
+ * \throw If \a aBase and \a this do not have the same type.
+ *
+ * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
+ */
+void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
+{
+  if(!aBase)
+    throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
+  DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
+  DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
+  DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
+  const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
+  const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
+  const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
+  if(this1 && a1)
+    {
+      this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
+      return ;
+    }
+  if(this2 && a2)
+    {
+      this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
+      return ;
+    }
+  if(this3 && a3)
+    {
+      this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
+      return ;
+    }
+  throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
+}
+
 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
 {
   int nbOfCompo=(int)_info_on_compo.size();
@@ -2631,7 +2667,7 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr
 }
 
 /*!
- * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
+ * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
  * of \a this array. Textual data is not copied. Both arrays must have equal number of
  * components.
  * The tuples to assign to are defined by index of the first tuple, and
@@ -2640,18 +2676,18 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr
  * All components of selected tuples are copied.
  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
  *              values to.
- *  \param [in] a - the array to copy values from.
+ *  \param [in] aBase - the array to copy values from.
  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
  *  \throw If \a this is not allocated.
- *  \throw If \a a is NULL.
- *  \throw If \a a is not allocated.
+ *  \throw If \a aBase is NULL.
+ *  \throw If \a aBase is not allocated.
  *  \throw If \a tuplesSelec is NULL.
  *  \throw If \a tuplesSelec is not allocated.
- *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
+ *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
- *         \a a array.
+ *         \a aBase array.
  */
 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
 {
@@ -2691,7 +2727,7 @@ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const Data
 }
 
 /*!
- * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
+ * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
  * of \a this array. Textual data is not copied. Both arrays must have equal number of
  * components.
  * The tuples to copy are defined by three values similar to parameters of
@@ -2701,19 +2737,19 @@ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const Data
  * All components of selected tuples are copied.
  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
  *              values to.
- *  \param [in] a - the array to copy values from.
- *  \param [in] bg - index of the first tuple to copy of the array \a a.
- *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
+ *  \param [in] aBase - the array to copy values from.
+ *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
+ *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
  *              are located.
  *  \param [in] step - index increment to get index of the next tuple to copy.
  *  \throw If \a this is not allocated.
- *  \throw If \a a is NULL.
- *  \throw If \a a is not allocated.
- *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
+ *  \throw If \a aBase is NULL.
+ *  \throw If \a aBase is not allocated.
+ *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
  *  \throw If parameters specifying tuples to copy, do not give a
  *            non-empty range of increasing indices or indices are out of a valid range
- *            for the array \a a.
+ *            for the array \a aBase.
  */
 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
 {
@@ -6149,7 +6185,16 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
   std::fill(pt,pt+oldNbOfElem,-1);
   int nbOfNewElems=getNumberOfTuples();
   for(int i=0;i<nbOfNewElems;i++)
-    pt[new2Old[i]]=i;
+    {
+      int v(new2Old[i]);
+      if(v>=0 && v<oldNbOfElem)
+         pt[v]=i;
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
   return ret.retn();
 }
 
@@ -6245,7 +6290,8 @@ bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_
                       throw INTERP_KERNEL::Exception(oss.str().c_str());
                     }
                 }
-              return false;
+              else
+                return false;
             }
           else
             return false;
@@ -6883,7 +6929,7 @@ DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
   p1->sort(true); p2->sort(true);
   if(!p1->isEqualWithoutConsideringStr(*p2))
-    throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation betwenn the 2 arrays !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
   p1=ids1->checkAndPreparePermutation();
   p2=ids2->checkAndPreparePermutation();
   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
@@ -7874,7 +7920,7 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt
 }
 
 /*!
- * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
+ * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
  * of \a this array. Textual data is not copied. Both arrays must have equal number of
  * components.
  * The tuples to assign to are defined by index of the first tuple, and
@@ -7883,18 +7929,18 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt
  * All components of selected tuples are copied.
  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
  *              values to.
- *  \param [in] a - the array to copy values from.
- *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
+ *  \param [in] aBase - the array to copy values from.
+ *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
  *  \throw If \a this is not allocated.
- *  \throw If \a a is NULL.
- *  \throw If \a a is not allocated.
+ *  \throw If \a aBase is NULL.
+ *  \throw If \a aBase is not allocated.
  *  \throw If \a tuplesSelec is NULL.
  *  \throw If \a tuplesSelec is not allocated.
  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
- *         \a a array.
+ *         \a aBase array.
  */
 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
 {
@@ -7934,7 +7980,7 @@ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArr
 }
 
 /*!
- * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
+ * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
  * of \a this array. Textual data is not copied. Both arrays must have equal number of
  * components.
  * The tuples to copy are defined by three values similar to parameters of
@@ -7944,19 +7990,19 @@ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArr
  * All components of selected tuples are copied.
  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
  *              values to.
- *  \param [in] a - the array to copy values from.
- *  \param [in] bg - index of the first tuple to copy of the array \a a.
- *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
+ *  \param [in] aBase - the array to copy values from.
+ *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
+ *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
  *              are located.
  *  \param [in] step - index increment to get index of the next tuple to copy.
  *  \throw If \a this is not allocated.
- *  \throw If \a a is NULL.
- *  \throw If \a a is not allocated.
- *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
+ *  \throw If \a aBase is NULL.
+ *  \throw If \a aBase is not allocated.
+ *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
  *  \throw If parameters specifying tuples to copy, do not give a
  *            non-empty range of increasing indices or indices are out of a valid range
- *            for the array \a a.
+ *            for the array \a aBase.
  */
 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
 {
@@ -9559,6 +9605,67 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets
   return ret.retn();
 }
 
+/*!
+ * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
+ * scaled array (monotonically increasing).
+from that of \a this and \a
+ * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
+ * "index" array of a "iota" array, thus, whose each element gives an index of a group
+ * beginning within the "iota" array. And \a this is a one-dimensional array
+ * considered as a selector of groups described by \a offsets to include into the result array.
+ *  \throw If \a  is NULL.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *  \throw If \a this->getNumberOfTuples() == 0.
+ *  \throw If \a this is not monotonically increasing.
+ *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
+ *
+ *  \b Example: <br>
+ *          - \a bg , \a end and \a step : (0,5,2)
+ *          - \a this: [0,3,6,10,14,20]
+ *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
+ */
+DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const throw(INTERP_KERNEL::Exception)
+{
+  if(!isAllocated())
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
+  int nbOfTuples(getNumberOfTuples());
+  if(nbOfTuples==0)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
+  const int *ids(begin());
+  int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
+  for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
+    {
+      if(pos>=0 && pos<nbOfTuples-1)
+        {
+          int delta(ids[pos+1]-ids[pos]);
+          sz+=delta;
+          if(delta<0)
+            {
+              std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }          
+        }
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
+  int *retPtr(ret->getPointer());
+  pos=bg;
+  for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
+    {
+      int delta(ids[pos+1]-ids[pos]);
+      for(int j=0;j<delta;j++,retPtr++)
+        *retPtr=pos;
+    }
+  return ret.retn();
+}
+
 /*!
  * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
  * For each tuple at place **i** in \a this it tells which is the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result