]> SALOME platform Git repositories - tools/medcoupling.git/blobdiff - src/MEDCoupling/MEDCouplingMemArray.cxx
Salome HOME
Doc
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
old mode 100644 (file)
new mode 100755 (executable)
index aa04149..6092bcd
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2020  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-// Author : Anthony Geay (CEA/DEN)
+// Author : Anthony Geay (EDF R&D)
 
 #include "MEDCouplingMemArray.txx"
-#include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
+#include "BBTree.txx"
 #include "GenMathFormulae.hxx"
+#include "InterpKernelAutoPtr.hxx"
 #include "InterpKernelExprParser.hxx"
 
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DNode.hxx"
+#include "InterpKernelGeo2DEdgeLin.hxx"
+
 #include <set>
 #include <cmath>
 #include <limits>
 
 typedef double (*MYFUNCPTR)(double);
 
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
+
+template class MEDCOUPLING_EXPORT MEDCoupling::MemArray<mcIdType>;
+template class MEDCOUPLING_EXPORT MEDCoupling::MemArray<double>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTemplate<mcIdType>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTemplate<double>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTemplateClassic<Int32>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTemplateClassic<Int64>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTemplateClassic<double>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTemplateFP<double>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayIterator<double>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayIterator<mcIdType>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayDiscrete<Int32>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayDiscreteSigned<Int32>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayDiscrete<Int64>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayDiscreteSigned<Int64>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTuple<mcIdType>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTuple<double>;
+template class MEDCOUPLING_EXPORT MEDCoupling::DataArrayTuple<float>;
+
+void MEDCoupling::DACheckNbOfTuplesAndComp(const DataArray *da, mcIdType nbOfTuples, std::size_t nbOfCompo, const std::string& msg)
+{
+  if(!da)
+    throw INTERP_KERNEL::Exception("DACheckNbOfTuplesAndComp : null input object !");
+  da->checkNbOfTuplesAndComp(nbOfTuples,nbOfCompo,msg);
+}
 
 template<int SPACEDIM>
-void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
+void DataArrayDouble::findCommonTuplesAlg(const double *bbox, mcIdType nbNodes, mcIdType limitNodeId, double prec, DataArrayIdType *c, DataArrayIdType *cI) const
 {
   const double *coordsPtr=getConstPointer();
-  BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
+  BBTreePts<SPACEDIM,mcIdType> myTree(bbox,0,0,nbNodes,prec);
   std::vector<bool> isDone(nbNodes);
-  for(int i=0;i<nbNodes;i++)
+  for(mcIdType i=0;i<nbNodes;i++)
     {
       if(!isDone[i])
         {
-          std::vector<int> intersectingElems;
+          std::vector<mcIdType> intersectingElems;
           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
           if(intersectingElems.size()>1)
             {
-              std::vector<int> commonNodes;
-              for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
+              std::vector<mcIdType> commonNodes;
+              for(std::vector<mcIdType>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
                 if(*it!=i)
                   if(*it>=limitNodeId)
                     {
@@ -59,7 +91,7 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l
                     }
               if(!commonNodes.empty())
                 {
-                  cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
+                  cI->pushBackSilent(cI->back()+ToIdType(commonNodes.size())+1);
                   c->pushBackSilent(i);
                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
                 }
@@ -69,32 +101,32 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l
 }
 
 template<int SPACEDIM>
-void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
-                                                DataArrayInt *c, DataArrayInt *cI)
+void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,mcIdType>& myTree, const double *pos, mcIdType nbOfTuples, double eps,
+                                                DataArrayIdType *c, DataArrayIdType *cI)
 {
-  for(int i=0;i<nbOfTuples;i++)
+  for(mcIdType i=0;i<nbOfTuples;i++)
     {
-      std::vector<int> intersectingElems;
+      std::vector<mcIdType> intersectingElems;
       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
-      std::vector<int> commonNodes;
-      for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
+      std::vector<mcIdType> commonNodes;
+      for(std::vector<mcIdType>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
         commonNodes.push_back(*it);
-      cI->pushBackSilent(cI->back()+(int)commonNodes.size());
+      cI->pushBackSilent(cI->back()+ToIdType(commonNodes.size()));
       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
     }
 }
 
 template<int SPACEDIM>
-void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
+void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,mcIdType>& myTree, double dist, const double *pos, mcIdType nbOfTuples, const double *thisPt, mcIdType thisNbOfTuples, mcIdType *res)
 {
-  double distOpt(dist);
+  double distOpt = std::max(dist, std::numeric_limits<double>::epsilon());
   const double *p(pos);
-  int *r(res);
-  for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
+  mcIdType *r(res);
+  for(mcIdType i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
     {
       while(true)
         {
-          int elem=-1;
+          mcIdType elem=-1;
           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
           if(ret!=std::numeric_limits<double>::max())
             {
@@ -108,7 +140,23 @@ void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTre
     }
 }
 
-std::size_t DataArray::getHeapMemorySize() const
+mcIdType DataArray::EffectiveCircPerm(mcIdType nbOfShift, mcIdType nbOfTuples)
+{
+  if(nbOfTuples<=0)
+    throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
+  if(nbOfShift>=0)
+    {
+      return nbOfShift%nbOfTuples;
+    }
+  else
+    {
+      mcIdType tmp(-nbOfShift);
+      tmp=tmp%nbOfTuples;
+      return nbOfTuples-tmp;
+    }
+}
+
+std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t sz1=_name.capacity();
   std::size_t sz2=_info_on_compo.capacity();
@@ -118,12 +166,17 @@ std::size_t DataArray::getHeapMemorySize() const
   return sz1+sz2+sz3;
 }
 
+std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
+{
+  return std::vector<const BigMemoryObject *>();
+}
+
 /*!
  * Sets the attribute \a _name of \a this array.
  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
  *  \param [in] name - new array name
  */
-void DataArray::setName(const char *name)
+void DataArray::setName(const std::string& name)
 {
   _name=name;
 }
@@ -138,7 +191,7 @@ void DataArray::setName(const char *name)
  *  \param [in] other - another instance of DataArray to copy the textual data from.
  *  \throw If number of components of \a this array differs from that of the \a other.
  */
-void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
+void DataArray::copyStringInfoFrom(const DataArray& other)
 {
   if(_info_on_compo.size()!=other._info_on_compo.size())
     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
@@ -146,37 +199,37 @@ void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::
   _info_on_compo=other._info_on_compo;
 }
 
-void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
+void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<std::size_t>& compoIds)
 {
-  int nbOfCompoOth=other.getNumberOfComponents();
+  std::size_t nbOfCompoOth=other.getNumberOfComponents();
   std::size_t newNbOfCompo=compoIds.size();
   for(std::size_t i=0;i<newNbOfCompo;i++)
-    if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
+    if(compoIds[i]>=nbOfCompoOth)
       {
         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   for(std::size_t i=0;i<newNbOfCompo;i++)
-    setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
+    setInfoOnComponent(i,other.getInfoOnComponent(compoIds[i]));
 }
 
-void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
+void DataArray::copyPartOfStringInfoFrom2(const std::vector<std::size_t>& compoIds, const DataArray& other)
 {
-  int nbOfCompo=getNumberOfComponents();
-  std::size_t partOfCompoToSet=compoIds.size();
-  if((int)partOfCompoToSet!=other.getNumberOfComponents())
+  if(compoIds.size()!=other.getNumberOfComponents())
     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
+  std::size_t partOfCompoToSet=compoIds.size();
+  std::size_t nbOfCompo=getNumberOfComponents();
   for(std::size_t i=0;i<partOfCompoToSet;i++)
-    if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
+    if(compoIds[i]>=nbOfCompo)
       {
         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   for(std::size_t i=0;i<partOfCompoToSet;i++)
-    setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
+    setInfoOnComponent(compoIds[i],other.getInfoOnComponent(i));
 }
 
-bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
+bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
 {
   std::ostringstream oss;
   if(_name!=other._name)
@@ -209,13 +262,13 @@ bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reaso
  *  \param [in] other - another instance of DataArray to compare the textual data of.
  *  \return bool - \a true if the textual information is same, \a false else.
  */
-bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
+bool DataArray::areInfoEquals(const DataArray& other) const
 {
   std::string tmp;
   return areInfoEqualsIfNotWhy(other,tmp);
 }
 
-void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
+void DataArray::reprWithoutNameStream(std::ostream& stream) const
 {
   stream << "Number of components : "<< getNumberOfComponents() << "\n";
   stream << "Info of these components : ";
@@ -224,7 +277,7 @@ void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_K
   stream << "\n";
 }
 
-std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
+std::string DataArray::cppRepr(const std::string& varName) const
 {
   std::ostringstream ret;
   reprCppStream(varName,ret);
@@ -237,9 +290,9 @@ std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::E
  *  \param [in] info - a vector of strings.
  *  \throw If size of \a info differs from the number of components of \a this.
  */
-void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
+void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
 {
-  if(getNumberOfComponents()!=(int)info.size())
+  if(getNumberOfComponents()!=info.size())
     {
       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -247,20 +300,56 @@ void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(
   _info_on_compo=info;
 }
 
-std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
+/*!
+ * 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 mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
+{
+  if(!aBase)
+    throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
+  DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
+  DataArrayIdType *this2(dynamic_cast<DataArrayIdType *>(this));
+  DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
+  const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
+  const DataArrayIdType *a2(dynamic_cast<const DataArrayIdType *>(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
 {
-  int nbOfCompo=(int)_info_on_compo.size();
+  std::size_t nbOfCompo=_info_on_compo.size();
   std::vector<std::string> ret(nbOfCompo);
-  for(int i=0;i<nbOfCompo;i++)
+  for(std::size_t i=0;i<nbOfCompo;i++)
     ret[i]=getVarOnComponent(i);
   return ret;
 }
 
-std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
+std::vector<std::string> DataArray::getUnitsOnComponent() const
 {
-  int nbOfCompo=(int)_info_on_compo.size();
+  std::size_t nbOfCompo=_info_on_compo.size();
   std::vector<std::string> ret(nbOfCompo);
-  for(int i=0;i<nbOfCompo;i++)
+  for(std::size_t i=0;i<nbOfCompo;i++)
     ret[i]=getUnitOnComponent(i);
   return ret;
 }
@@ -273,13 +362,13 @@ std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KER
  *  \return std::string - a string containing the information on \a i-th component.
  *  \throw If \a i is not a valid component index.
  */
-std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
+std::string DataArray::getInfoOnComponent(std::size_t i) const
 {
-  if(i<(int)_info_on_compo.size() && i>=0)
+  if(i<_info_on_compo.size())
     return _info_on_compo[i];
   else
     {
-      std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
+      std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << _info_on_compo.size();
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
@@ -296,15 +385,15 @@ std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exce
  *  \return std::string - a string containing the var information, or the full info.
  *  \throw If \a i is not a valid component index.
  */
-std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
+std::string DataArray::getVarOnComponent(std::size_t i) const
 {
-  if(i<(int)_info_on_compo.size() && i>=0)
+  if(i<_info_on_compo.size())
     {
       return GetVarNameFromInfo(_info_on_compo[i]);
     }
   else
     {
-      std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
+      std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << _info_on_compo.size();
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
@@ -321,15 +410,15 @@ std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Excep
  *  \return std::string - a string containing the unit information, if any, or "".
  *  \throw If \a i is not a valid component index.
  */
-std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
+std::string DataArray::getUnitOnComponent(std::size_t i) const
 {
-  if(i<(int)_info_on_compo.size() && i>=0)
+  if(i<_info_on_compo.size())
     {
       return GetUnitFromInfo(_info_on_compo[i]);
     }
   else
     {
-      std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
+      std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << _info_on_compo.size();
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
@@ -344,7 +433,7 @@ std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exce
  *  \param [in] info - the full component information.
  *  \return std::string - a string containing only var information, or the \a info.
  */
-std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
+std::string DataArray::GetVarNameFromInfo(const std::string& info)
 {
   std::size_t p1=info.find_last_of('[');
   std::size_t p2=info.find_last_of(']');
@@ -368,7 +457,7 @@ std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_
  *  \param [in] info - the full component information.
  *  \return std::string - a string containing only unit information, if any, or "".
  */
-std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
+std::string DataArray::GetUnitFromInfo(const std::string& info)
 {
   std::size_t p1=info.find_last_of('[');
   std::size_t p2=info.find_last_of(']');
@@ -379,6 +468,80 @@ std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KER
   return info.substr(p1+1,p2-p1-1);
 }
 
+/*!
+ * This method put in info format the result of the merge of \a var and \a unit.
+ * The standard format for that is "var [unit]".
+ * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
+ */
+std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
+{
+  std::ostringstream oss;
+  oss << var << " [" << unit << "]";
+  return oss.str();
+}
+
+std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
+{
+  switch(at)
+    {
+    case AX_CART:
+      return std::string("AX_CART");
+    case AX_CYL:
+      return std::string("AX_CYL");
+    case AX_SPHER:
+      return std::string("AX_SPHER");
+    default:
+      throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
+    }
+}
+
+/*!
+ * Returns a new DataArray by concatenating all given arrays, so that (1) the number
+ * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
+ * the number of component in the result array is same as that of each of given arrays.
+ * Info on components is copied from the first of the given arrays. Number of components
+ * in the given arrays must be  the same.
+ *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
+ *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
+ *          The caller is to delete this result array using decrRef() as it is no more
+ *          needed.
+ *  \throw If all arrays within \a arrs are NULL.
+ *  \throw If all not null arrays in \a arrs have not the same type.
+ *  \throw If getNumberOfComponents() of arrays within \a arrs.
+ */
+DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
+{
+  std::vector<const DataArray *> arr2;
+  for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
+    if(*it)
+      arr2.push_back(*it);
+  if(arr2.empty())
+    throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
+  std::vector<const DataArrayDouble *> arrd;
+  std::vector<const DataArrayIdType *> arri;
+  std::vector<const DataArrayChar *> arrc;
+  for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
+    {
+      const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
+      if(a)
+        { arrd.push_back(a); continue; }
+      const DataArrayIdType *b=dynamic_cast<const DataArrayIdType *>(*it);
+      if(b)
+        { arri.push_back(b); continue; }
+      const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
+      if(c)
+        { arrc.push_back(c); continue; }
+      throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
+    }
+  if(arr2.size()==arrd.size())
+    return DataArrayDouble::Aggregate(arrd);
+  if(arr2.size()==arri.size())
+    return DataArrayIdType::Aggregate(arri);
+  if(arr2.size()==arrc.size())
+    return DataArrayChar::Aggregate(arrc);
+  throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
+}
+
 /*!
  * Sets information on a component specified by an index.
  * To know more on format of this information
@@ -388,13 +551,13 @@ std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KER
  *  \param [in] info - the string containing the information.
  *  \throw If \a i is not a valid component index.
  */
-void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
+void DataArray::setInfoOnComponent(std::size_t i, const std::string& info)
 {
-  if(i<(int)_info_on_compo.size() && i>=0)
+  if(i<_info_on_compo.size())
     _info_on_compo[i]=info;
   else
     {
-      std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
+      std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << _info_on_compo.size();
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
@@ -402,16 +565,17 @@ 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 provided that \a this is not allocated.
+ * 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)
+void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
 {
-  if(getNumberOfComponents()!=(int)info.size())
+  if(getNumberOfComponents()!=info.size())
     {
       if(!isAllocated())
         _info_on_compo=info;
@@ -425,7 +589,7 @@ void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
     _info_on_compo=info;
 }
 
-void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
+void DataArray::checkNbOfTuples(mcIdType nbOfTuples, const std::string& msg) const
 {
   if(getNumberOfTuples()!=nbOfTuples)
     {
@@ -434,16 +598,16 @@ void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INT
     }
 }
 
-void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
+void DataArray::checkNbOfComps(std::size_t nbOfCompo, const std::string& msg) const
 {
-  if(getNumberOfComponents()!=nbOfCompo)
+  if (getNumberOfComponents()!=nbOfCompo)
     {
       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
 
-void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
+void DataArray::checkNbOfElems(mcIdType nbOfElems, const std::string& msg) const
 {
   if(getNbOfElems()!=nbOfElems)
     {
@@ -452,9 +616,9 @@ void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const thr
     }
 }
 
-void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
+void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
 {
-   if(getNumberOfTuples()!=other.getNumberOfTuples())
+  if(getNumberOfTuples()!=other.getNumberOfTuples())
     {
       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -466,7 +630,7 @@ void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg)
     }
 }
 
-void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
+void DataArray::checkNbOfTuplesAndComp(mcIdType nbOfTuples, std::size_t nbOfCompo, const std::string& msg) const
 {
   checkNbOfTuples(nbOfTuples,msg);
   checkNbOfComps(nbOfCompo,msg);
@@