]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
*** empty log message ***
authorageay <ageay>
Mon, 6 Dec 2010 16:22:13 +0000 (16:22 +0000)
committerageay <ageay>
Mon, 6 Dec 2010 16:22:13 +0000 (16:22 +0000)
18 files changed:
src/MEDCoupling/MEDCouplingCMesh.cxx
src/MEDCoupling/MEDCouplingCMesh.hxx
src/MEDCoupling/MEDCouplingExtrudedMesh.cxx
src/MEDCoupling/MEDCouplingExtrudedMesh.hxx
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingFieldDouble.hxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMesh.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingTimeDiscretization.cxx
src/MEDCoupling/MEDCouplingTimeDiscretization.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMeshDesc.cxx
src/MEDCoupling/MEDCouplingUMeshDesc.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx

index 4c49d3b93d482b8e50a29f01f60023c2a312c735..7b3141077e42dd0bb4dc494924cf7b042051156d 100644 (file)
@@ -436,7 +436,7 @@ void MEDCouplingCMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coor
   declareAsNew();
 }
 
-MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const
+MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
 {
   int spaceDim=getSpaceDimension();
   MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim);
index c7d9e879255b8c37815e9200f1e1750c135a004a..3d047a6eb974ac6fd4fcabcf92eac71f2c2f4a13 100644 (file)
@@ -63,7 +63,7 @@ namespace ParaMEDMEM
                    DataArrayDouble *coordsY=0,
                    DataArrayDouble *coordsZ=0);
     // tools
-    MEDCouplingUMesh *buildUnstructured() const;
+    MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
     MEDCouplingMesh *buildPart(const int *start, const int *end) const;
     MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
     DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception);
index 84a9d451c383b10dfc61be6933bd7a58676ac77a..385977e011b9381da31dbc6eb4a114e7599609a6 100644 (file)
@@ -330,6 +330,11 @@ MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const
   return ret;
 }
 
+MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
+{
+  return build3DUnstructuredMesh();
+}
+
 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
 {
   std::string name="MeasureOfMesh_";
index 36317241094095a07590764e652b78401c4a31ad..d5025341eb453753d820839a7456ace144acf892 100644 (file)
@@ -65,6 +65,7 @@ namespace ParaMEDMEM
     MEDCouplingUMesh *getMesh1D() const { return _mesh1D; }
     DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; }
     MEDCouplingUMesh *build3DUnstructuredMesh() const;
+    MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *getMeasureField(bool) const;
     MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const;
     MEDCouplingFieldDouble *buildOrthogonalField() const;
index 60b5caab8a255079a3e5b76d3596c12789e0a79c..f530f2141c36ee73a0ba4ba89928cc848661c4b4 100644 (file)
@@ -52,6 +52,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) c
   return ret;
 }
 
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const
+{
+  return cloneWithMesh(true);
+}
+
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const
 {
   MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(_time_discr,td,deepCpy);
@@ -221,6 +226,21 @@ bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other)
   return true;
 }
 
+/*!
+ * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
+ * except that 'this' and other can have different number of components.
+ */
+bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
+{
+  if(!MEDCouplingField::areStrictlyCompatible(other))
+    return false;
+  if(_nature!=other->_nature)
+    return false;
+  if(!_time_discr->areCompatibleForMeld(other->_time_discr))
+    return false;
+  return true;
+}
+
 /*!
  * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same.
  * The values of field are impacted in consequence to have the same geometrical field.
@@ -1033,6 +1053,29 @@ bool MEDCouplingFieldDouble::mergeNodes(double eps) throw(INTERP_KERNEL::Excepti
   return true;
 }
 
+/*!
+ * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
+ */
+bool MEDCouplingFieldDouble::mergeNodes2(double eps) throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
+  if(!meshC)
+    throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
+  bool ret;
+  int ret2;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes2(eps,ret,ret2);
+  if(!ret)//no nodes have been merged.
+    return ret;
+  std::vector<DataArrayDouble *> arrays;
+  _time_discr->getArrays(arrays);
+  for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
+    if(*iter)
+      _type->renumberValuesOnNodes(arr->getConstPointer(),*iter);
+  setMesh(meshC2);
+  return true;
+}
+
 /*!
  * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet.
  * If some nodes have disappeared true is returned.
@@ -1221,7 +1264,7 @@ void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Excepti
   _time_discr->sortPerTuple(asc);
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areCompatibleForMerge(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply mergeFields on them !");
@@ -1229,6 +1272,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFie
   const MEDCouplingMesh *m2=f2->getMesh();
   MEDCouplingMesh *m=m1->mergeMyselfWith(m2);
   MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
   ret->setMesh(m);
   m->decrRef();
@@ -1237,7 +1281,48 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFie
   return ret;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) throw(INTERP_KERNEL::Exception)
+{
+  if(a.size()<=1)
+    throw INTERP_KERNEL::Exception("FieldDouble::mergeFields : size of array must be > 1 !");
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms(a.size());
+  std::vector< const MEDCouplingUMesh *> ms2(a.size());
+  std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
+  std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
+  const MEDCouplingFieldDouble *ref=(*it++);
+  for(;it!=a.end();it++)
+    if(!ref->areCompatibleForMerge(*it))
+      throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply mergeFields on them !");
+  for(int i=0;i<(int)a.size();i++)
+    {
+      if(!a[i]->getMesh())
+        throw INTERP_KERNEL::Exception("mergeFields : A field as no underlying mesh !");
+      ms[i]=a[i]->getMesh()->buildUnstructured();
+      ms2[i]=ms[i];
+      tds[i]=a[i]->_time_discr;
+    }
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::mergeUMeshes(ms2);
+  MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds);
+  td->copyTinyAttrFrom(*(a[0]->_time_discr));
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone());
+  ret->setMesh(m);
+  ret->setName(a[0]->getName());
+  ret->setDescription(a[0]->getDescription());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::meldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
+{
+  if(!f1->areCompatibleForMeld(f2))
+    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply meldFields on them !");
+  MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  ret->setMesh(f1->getMesh());
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply dotFields on them !");
@@ -1248,7 +1333,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingField
   return ret;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply crossProductFields on them !");
@@ -1259,7 +1344,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCoup
   return ret;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply maxFields on them !");
@@ -1270,7 +1355,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingField
   return ret;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply minFields on them !");
@@ -1281,7 +1366,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingField
   return ret;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply addFields on them !");
@@ -1292,7 +1377,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingField
   return ret;
 }
 
-const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
 {
   if(!areStrictlyCompatible(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
@@ -1300,7 +1385,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCoupli
   return *this;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply substractFields on them !");
@@ -1311,7 +1396,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplin
   return ret;
 }
 
-const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
 {
   if(!areStrictlyCompatible(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !");
@@ -1319,7 +1404,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCoupli
   return *this;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areCompatibleForMul(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply multiplyFields on them !");
@@ -1330,7 +1415,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCoupling
   return ret;
 }
 
-const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
 {
   if(!areCompatibleForMul(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
@@ -1338,7 +1423,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCoupli
   return *this;
 }
 
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
 {
   if(!f1->areStrictlyCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply divideFields on them !");
@@ -1349,7 +1434,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFi
   return ret;
 }
 
-const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
+const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
 {
   if(!areStrictlyCompatible(&other))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
index 19f804c3183559b5259860e8876c53eefa9d4a4a..c319fae10585242cb8570a81892af9267746ca6d 100644 (file)
@@ -41,6 +41,7 @@ namespace ParaMEDMEM
     bool areCompatibleForMerge(const MEDCouplingField *other) const;
     bool areStrictlyCompatible(const MEDCouplingField *other) const;
     bool areCompatibleForMul(const MEDCouplingField *other) const;
+    bool areCompatibleForMeld(const MEDCouplingFieldDouble *other) const;
     void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     void renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     void renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception);
@@ -48,6 +49,7 @@ namespace ParaMEDMEM
     DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *deepCpy() const;
     MEDCouplingFieldDouble *clone(bool recDeepCpy) const;
     MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const;
     MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const;
@@ -112,6 +114,7 @@ namespace ParaMEDMEM
     void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception);
     void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception);
     bool mergeNodes(double eps) throw(INTERP_KERNEL::Exception);
+    bool mergeNodes2(double eps) throw(INTERP_KERNEL::Exception);
     bool zipCoords() throw(INTERP_KERNEL::Exception);
     bool zipConnectivity(int compType) throw(INTERP_KERNEL::Exception);
     bool simplexize(int policy) throw(INTERP_KERNEL::Exception);
@@ -128,27 +131,29 @@ namespace ParaMEDMEM
     MEDCouplingFieldDouble *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
     void setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
     void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception);
-    static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const { return dotFields(this,&other); }
-    static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const { return crossProductFields(this,&other); }
-    static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const { return maxFields(this,&other); }
-    static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const { return minFields(this,&other); }
-    MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const { return addFields(this,&other); }
-    const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other);
-    static MEDCouplingFieldDouble *addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const { return substractFields(this,&other); }
-    const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other);
-    static MEDCouplingFieldDouble *substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const { return multiplyFields(this,&other); }
-    const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other);
-    static MEDCouplingFieldDouble *multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
-    MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const { return divideFields(this,&other); }
-    const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other);
-    static MEDCouplingFieldDouble *divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2);
+    static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *mergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *meldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return dotFields(this,&other); }
+    static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return crossProductFields(this,&other); }
+    static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return maxFields(this,&other); }
+    static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return minFields(this,&other); }
+    MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return addFields(this,&other); }
+    const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return substractFields(this,&other); }
+    const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return multiplyFields(this,&other); }
+    const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
+    MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return divideFields(this,&other); }
+    const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception);
+    static MEDCouplingFieldDouble *divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception);
   private:
     MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td);
     MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy);
index 1b4a20b49b0745204d143bc040715c75e2019b31..3d916ed2ec17d48b38fc1a43c0d673097982dd5a 100644 (file)
@@ -136,6 +136,11 @@ DataArrayDouble *DataArrayDouble::deepCopy() const
   return new DataArrayDouble(*this);
 }
 
+DataArrayDouble *DataArrayDouble::deepCpy() const
+{
+  return new DataArrayDouble(*this);
+}
+
 DataArrayDouble *DataArrayDouble::performCpy(bool deepCpy) const
 {
   if(deepCpy)
@@ -479,6 +484,37 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>&
   return ret;
 }
 
+/*!
+ * This method melds the components of 'this' with components of 'other'.
+ * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this'
+ * before the call and the number of components of 'other'.
+ * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown.
+ */
+void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  other->checkAllocated();
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples!=other->getNumberOfTuples())
+    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 *w=newArr;
+  const double *inp1=getConstPointer();
+  const double *inp2=other->getConstPointer();
+  for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
+    {
+      w=std::copy(inp1,inp1+nbOfComp1,w);
+      w=std::copy(inp2,inp2+nbOfComp2,w);
+    }
+  useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
+  std::vector<int> compIds(nbOfComp2);
+  for(int i=0;i<nbOfComp2;i++)
+    compIds[i]=nbOfComp1+i;
+  copyPartOfStringInfoFrom2(compIds,*other);
+}
+
 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
 {
   copyPartOfStringInfoFrom2(compoIds,*a);
@@ -1035,16 +1071,74 @@ DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const thr
 
 DataArrayDouble *DataArrayDouble::aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
 {
-  int nbOfComp=a1->getNumberOfComponents();
-  if(nbOfComp!=a2->getNumberOfComponents())
-    throw INTERP_KERNEL::Exception("Nb of components mismatch for array aggregation !");
-  int nbOfTuple1=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
+  std::vector<const DataArrayDouble *> tmp(2);
+  tmp[0]=a1; tmp[1]=a2;
+  return aggregate(tmp);
+}
+
+DataArrayDouble *DataArrayDouble::aggregate(const std::vector<const DataArrayDouble *>& a) throw(INTERP_KERNEL::Exception)
+{
+  if(a.empty())
+    throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : input list must be NON EMPTY !");
+  std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
+  int nbOfComp=(*it)->getNumberOfComponents();
+  int nbt=(*it++)->getNumberOfTuples();
+  for(int i=1;it!=a.end();it++,i++)
+    {
+      if((*it)->getNumberOfComponents()!=nbOfComp)
+        throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : Nb of components mismatch for array aggregation !");
+      nbt+=(*it)->getNumberOfTuples();
+    }
   DataArrayDouble *ret=DataArrayDouble::New();
-  ret->alloc(nbOfTuple1+nbOfTuple2,nbOfComp);
-  double *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
-  std::copy(a2->getConstPointer(),a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
-  ret->copyStringInfoFrom(*a1);
+  ret->alloc(nbt,nbOfComp);
+  double *pt=ret->getPointer();
+  for(it=a.begin();it!=a.end();it++)
+    pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
+  ret->copyStringInfoFrom(*(a[0]));
+  return ret;
+}
+
+DataArrayDouble *DataArrayDouble::meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<const DataArrayDouble *> arr(2);
+  arr[0]=a1; arr[1]=a2;
+  return meld(arr);
+}
+
+DataArrayDouble *DataArrayDouble::meld(const std::vector<const DataArrayDouble *>& a) throw(INTERP_KERNEL::Exception)
+{
+  if(a.empty())
+    throw INTERP_KERNEL::Exception("DataArrayDouble::meld : array must be NON empty !");
+  std::vector<const DataArrayDouble *>::const_iterator it;
+  for(it=a.begin();it!=a.end();it++)
+    (*it)->checkAllocated();
+  it=a.begin();
+  int nbOfTuples=(*it)->getNumberOfTuples();
+  std::vector<int> nbc(a.size());
+  std::vector<const double *> pts(a.size());
+  nbc[0]=(*it)->getNumberOfComponents();
+  pts[0]=(*it++)->getConstPointer();
+  for(int i=1;it!=a.end();it++,i++)
+    {
+      if(nbOfTuples!=(*it)->getNumberOfTuples())
+        throw INTERP_KERNEL::Exception("DataArrayDouble::meld : mismatch of number of tuples !");
+      nbc[i]=(*it)->getNumberOfComponents();
+      pts[i]=(*it)->getConstPointer();
+    }
+  int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
+  DataArrayDouble *ret=DataArrayDouble::New();
+  ret->alloc(nbOfTuples,totalNbOfComp);
+  double *retPtr=ret->getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    for(int j=0;j<(int)a.size();j++)
+      {
+        retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
+        pts[j]+=nbc[j];
+      }
+  int k=0;
+  for(int i=0;i<(int)a.size();i++)
+    for(int j=0;j<nbc[i];j++,k++)
+      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
   return ret;
 }
 
@@ -1316,6 +1410,11 @@ DataArrayInt *DataArrayInt::deepCopy() const
   return new DataArrayInt(*this);
 }
 
+DataArrayInt *DataArrayInt::deepCpy() const
+{
+  return new DataArrayInt(*this);
+}
+
 DataArrayInt *DataArrayInt::performCpy(bool deepCpy) const
 {
   if(deepCpy)
@@ -1705,6 +1804,37 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compo
   return ret;
 }
 
+/*!
+ * This method melds the components of 'this' with components of 'other'.
+ * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this'
+ * before the call and the number of components of 'other'.
+ * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown.
+ */
+void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  other->checkAllocated();
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples!=other->getNumberOfTuples())
+    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 *w=newArr;
+  const int *inp1=getConstPointer();
+  const int *inp2=other->getConstPointer();
+  for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
+    {
+      w=std::copy(inp1,inp1+nbOfComp1,w);
+      w=std::copy(inp2,inp2+nbOfComp2,w);
+    }
+  useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
+  std::vector<int> compIds(nbOfComp2);
+  for(int i=0;i<nbOfComp2;i++)
+    compIds[i]=nbOfComp1+i;
+  copyPartOfStringInfoFrom2(compIds,*other);
+}
+
 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
 {
   copyPartOfStringInfoFrom2(compoIds,*a);
@@ -1778,6 +1908,50 @@ DataArrayInt *DataArrayInt::aggregate(const DataArrayInt *a1, const DataArrayInt
   return ret;
 }
 
+DataArrayInt *DataArrayInt::meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<const DataArrayInt *> arr(2);
+  arr[0]=a1; arr[1]=a2;
+  return meld(arr);
+}
+
+DataArrayInt *DataArrayInt::meld(const std::vector<const DataArrayInt *>& a) throw(INTERP_KERNEL::Exception)
+{
+  if(a.empty())
+    throw INTERP_KERNEL::Exception("DataArrayInt::meld : array must be NON empty !");
+  std::vector<const DataArrayInt *>::const_iterator it;
+  for(it=a.begin();it!=a.end();it++)
+    (*it)->checkAllocated();
+  it=a.begin();
+  int nbOfTuples=(*it)->getNumberOfTuples();
+  std::vector<int> nbc(a.size());
+  std::vector<const int *> pts(a.size());
+  nbc[0]=(*it)->getNumberOfComponents();
+  pts[0]=(*it++)->getConstPointer();
+  for(int i=1;it!=a.end();it++,i++)
+    {
+      if(nbOfTuples!=(*it)->getNumberOfTuples())
+        throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
+      nbc[i]=(*it)->getNumberOfComponents();
+      pts[i]=(*it)->getConstPointer();
+    }
+  int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfTuples,totalNbOfComp);
+  int *retPtr=ret->getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    for(int j=0;j<(int)a.size();j++)
+      {
+        retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
+        pts[j]+=nbc[j];
+      }
+  int k=0;
+  for(int i=0;i<(int)a.size();i++)
+    for(int j=0;j<nbc[i];j++,k++)
+      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
+  return ret;
+}
+
 /*!
  * This method create a minimal partition of groups 'groups' the std::iota array of size 'newNb'.
  * This method returns an array of size 'newNb' that specifies for each item at which familyId it owns to, and this method returns
index 57d7d8a0a26154d791f07c855744513ee0f8d4e2..75d1feef24a0526ec363ca318a69fd192cff4d4a 100644 (file)
@@ -119,6 +119,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool isAllocated() const;
     MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *deepCopy() const;
+    MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const;
     MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception);
@@ -147,6 +148,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
     MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
@@ -185,6 +187,9 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayDouble *aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *aggregate(const std::vector<const DataArrayDouble *>& a) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayDouble *meld(const std::vector<const DataArrayDouble *>& a) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayDouble *dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayDouble *crossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayDouble *max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception);
@@ -212,6 +217,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool isAllocated() const;
     MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *deepCopy() const;
+    MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const;
     MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const;
@@ -244,6 +250,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
     MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
@@ -254,6 +261,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(int val) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualList(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayInt *aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2);
+    MEDCOUPLING_EXPORT static DataArrayInt *meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayInt *meld(const std::vector<const DataArrayInt *>& a) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayInt *makePartition(const std::vector<DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups);
     MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); }
index 75ed3f30927e46264b30d70f77b2bdf8776c661d..d5b8286764fd127ec3b068a19c4ed59f83bea609 100644 (file)
@@ -40,6 +40,7 @@ namespace ParaMEDMEM
 
   class DataArrayInt;
   class DataArrayDouble;
+  class MEDCouplingUMesh;
   class MEDCouplingFieldDouble;
 
   class MEDCOUPLING_EXPORT MEDCouplingMesh : public RefCountObject, public TimeLabel
@@ -91,6 +92,7 @@ namespace ParaMEDMEM
     virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0;
     virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0;
     virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0;
+    virtual MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception) = 0;
     virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception) = 0;
     virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const;
     static MEDCouplingMesh *mergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2);
index e587b297892922b0055e8192947ba52c141c6915..d4812d83a36a31c1bbd707d70cfbd4b8a24c58b1 100644 (file)
@@ -326,6 +326,38 @@ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNo
   newCoords->decrRef();
 }
 
+/*
+ * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes.
+ * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes())
+ * This value is asked because often known by the caller of this method.
+ * Contrary to ParaMEDMEM::MEDCouplingPointSet::renumberNodes method for merged nodes the barycenter of them is computed here.
+ *
+ * @param newNodeNumbers array specifying the new numbering.
+ * @param newNbOfNodes the new number of nodes.
+ */
+void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes)
+{
+  DataArrayDouble *newCoords=DataArrayDouble::New();
+  std::vector<int> div(newNbOfNodes);
+  int spaceDim=getSpaceDimension();
+  newCoords->alloc(newNbOfNodes,spaceDim);
+  newCoords->copyStringInfoFrom(*_coords);
+  newCoords->fillWithZero();
+  int oldNbOfNodes=getNumberOfNodes();
+  double *ptToFill=newCoords->getPointer();
+  const double *oldCoordsPtr=_coords->getConstPointer();
+  for(int i=0;i<oldNbOfNodes;i++)
+    {
+      std::transform(oldCoordsPtr+i*spaceDim,oldCoordsPtr+(i+1)*spaceDim,ptToFill+newNodeNumbers[i]*spaceDim,
+                     ptToFill+newNodeNumbers[i]*spaceDim,std::plus<double>());
+      div[newNodeNumbers[i]]++;
+    }
+  for(int i=0;i<newNbOfNodes;i++)
+    ptToFill=std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)div[i]));
+  setCoords(newCoords);
+  newCoords->decrRef();
+}
+
 /*!
  * This method fills bbox params like that : bbox[0]=XMin, bbox[1]=XMax, bbox[2]=YMin...
  * The returned bounding box is arranged along trihedron.
@@ -513,7 +545,7 @@ void MEDCouplingPointSet::findNodesOnPlane(const double *pt, const double *vec,
 /*!
  * merge _coords arrays of m1 and m2 and returns the union. The returned instance is newly created with ref count == 1.
  */
-DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2)
+DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception)
 {
   int spaceDim=m1->getSpaceDimension();
   if(spaceDim!=m2->getSpaceDimension())
@@ -521,6 +553,30 @@ DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const MEDCouplingPointSet
   return DataArrayDouble::aggregate(m1->getCoords(),m2->getCoords());
 }
 
+DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const std::vector<const MEDCouplingPointSet *>& ms) throw(INTERP_KERNEL::Exception)
+{
+  if(ms.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::mergeNodesArray : input array must be NON EMPTY !");
+  std::vector<const MEDCouplingPointSet *>::const_iterator it=ms.begin();
+  std::vector<const DataArrayDouble *> coo(ms.size());
+  int spaceDim=(*it)->getSpaceDimension();
+  coo[0]=(*it++)->getCoords();
+  for(int i=1;it!=ms.end();it++,i++)
+    {
+      const DataArrayDouble *tmp=(*it)->getCoords();
+      if(tmp)
+        {
+          if((*it)->getSpaceDimension()==spaceDim)
+            coo[i]=tmp;
+          else
+            throw INTERP_KERNEL::Exception("Mismatch in SpaceDim during call of mergeNodesArray !");
+        }
+      else
+        throw INTERP_KERNEL::Exception("Empty coords detected during call of mergeNodesArray !");
+    }
+  return DataArrayDouble::aggregate(coo);
+}
+
 /*!
  * Factory to build new instance of instanciable subclasses of MEDCouplingPointSet.
  * This method is used during unserialization process.
index 21cb749b4b2c70c151222a364dc0cba207ccda7b..4a51adf5bb35bc9adccb6b15a2fa07e9c3cf43be 100644 (file)
@@ -54,6 +54,7 @@ namespace ParaMEDMEM
     bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const;
     bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const;
     virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0;
+    virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0;
     DataArrayInt *buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const;
     std::vector<int> getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception);
     void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception);
@@ -70,7 +71,8 @@ namespace ParaMEDMEM
     void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
     virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0;
     void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector<int>& nodes) const throw(INTERP_KERNEL::Exception);
-    static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2);
+    static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception);
+    static DataArrayDouble *mergeNodesArray(const std::vector<const MEDCouplingPointSet *>& ms) throw(INTERP_KERNEL::Exception);
     static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type);
     static void rotate2DAlg(const double *center, double angle, int nbNodes, double *coords);
     static void rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords);
@@ -82,6 +84,7 @@ namespace ParaMEDMEM
     virtual void findBoundaryNodes(std::vector<int>& nodes) const = 0;
     virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0;
     virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
+    virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes);
     virtual bool isEmptyMesh(const std::vector<int>& tinyInfo) const = 0;
     //! size of returned tinyInfo must be always the same.
     void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
index a150a9cd4e15c2585651a1bc16986efa76c3fccf..8e43c0e60e4492f2443fabc2e05be1c769a75033 100644 (file)
@@ -115,6 +115,19 @@ bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeD
   return true;
 }
 
+bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const
+{
+  if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
+    return false;
+  if(_array==0 && other->_array==0)
+    return true;
+  if(_array==0 || other->_array==0)
+    return false;
+  if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples())
+    return false;
+  return true;
+}
+
 bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
 {
   if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
@@ -708,6 +721,14 @@ bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDi
   return otherC!=0;
 }
 
+bool MEDCouplingNoTimeLabel::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other))
+    return false;
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  return otherC!=0;
+}
+
 bool MEDCouplingNoTimeLabel::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
 {
   const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
@@ -731,6 +752,36 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCoupli
     throw INTERP_KERNEL::Exception("NoTimeLabel::aggregation on mismatched time discretization !");
   DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const
+{
+  std::vector<const DataArrayDouble *> a(other.size());
+  int i=0;
+  for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++)
+    {
+      const MEDCouplingNoTimeLabel *itC=dynamic_cast<const MEDCouplingNoTimeLabel *>(*it);
+      if(!itC)
+        throw INTERP_KERNEL::Exception("NoTimeLabel::aggregate on mismatched time discretization !");
+      a[i]=itC->getArray();
+    }
+  DataArrayDouble *arr=DataArrayDouble::aggregate(a);
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("NoTimeLabel::meld on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::meld(getArray(),other->getArray());
+  MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel;
   ret->setTimeTolerance(getTimeTolerance());
   ret->setArray(arr,0);
   arr->decrRef();
@@ -986,6 +1037,14 @@ bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeD
   return otherC!=0;
 }
 
+bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other))
+    return false;
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  return otherC!=0;
+}
+
 bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
 {
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
@@ -1030,12 +1089,38 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCoupl
     throw INTERP_KERNEL::Exception("WithTimeStep::aggregation on mismatched time discretization !");
   DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
-  ret->setTimeTolerance(getTimeTolerance());
   ret->setArray(arr,0);
   arr->decrRef();
-  int tmp1,tmp2;
-  double tmp3=getStartTime(tmp1,tmp2);
-  ret->setStartTime(tmp3,tmp1,tmp2);
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const
+{
+  std::vector<const DataArrayDouble *> a(other.size());
+  int i=0;
+  for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++)
+    {
+      const MEDCouplingWithTimeStep *itC=dynamic_cast<const MEDCouplingWithTimeStep *>(*it);
+      if(!itC)
+        throw INTERP_KERNEL::Exception("WithTimeStep::aggregate on mismatched time discretization !");
+      a[i]=itC->getArray();
+    }
+  DataArrayDouble *arr=DataArrayDouble::aggregate(a);
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("WithTimeStep::meld on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::meld(getArray(),other->getArray());
+  MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep;
+  ret->setArray(arr,0);
+  arr->decrRef();
   return ret;
 }
 
@@ -1341,6 +1426,14 @@ bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCoupli
   return otherC!=0;
 }
 
+bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other))
+    return false;
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  return otherC!=0;
+}
+
 bool MEDCouplingConstOnTimeInterval::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
 {
   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
@@ -1421,19 +1514,44 @@ void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const throw(
 
 MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const MEDCouplingTimeDiscretization *other) const
 {
-   const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregation on mismatched time discretization !");
   DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray());
   MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const
+{
+  std::vector<const DataArrayDouble *> a(other.size());
+  int i=0;
+  for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++)
+    {
+      const MEDCouplingConstOnTimeInterval *itC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(*it);
+      if(!itC)
+        throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregate on mismatched time discretization !");
+      a[i]=itC->getArray();
+    }
+  DataArrayDouble *arr=DataArrayDouble::aggregate(a);
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("ConstOnTimeInterval::meld on mismatched time discretization !");
+  DataArrayDouble *arr=DataArrayDouble::meld(getArray(),other->getArray());
+  MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval;
   ret->setTimeTolerance(getTimeTolerance());
   ret->setArray(arr,0);
   arr->decrRef();
-  int tmp1,tmp2;
-  double tmp3=getStartTime(tmp1,tmp2);
-  ret->setStartTime(tmp3,tmp1,tmp2);
-  tmp3=getEndTime(tmp1,tmp2);
-  ret->setEndTime(tmp3,tmp1,tmp2);
   return ret;
 }
 
@@ -1878,6 +1996,14 @@ bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDis
   return otherC!=0;
 }
 
+bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other))
+    return false;
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  return otherC!=0;
+}
+
 /*!
  * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples()
  */
@@ -1938,6 +2064,44 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplin
   DataArrayDouble *arr1=DataArrayDouble::aggregate(getArray(),other->getArray());
   DataArrayDouble *arr2=DataArrayDouble::aggregate(getEndArray(),other->getEndArray());
   MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const
+{
+  std::vector<const DataArrayDouble *> a(other.size());
+  std::vector<const DataArrayDouble *> b(other.size());
+  int i=0;
+  for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++)
+    {
+      const MEDCouplingLinearTime *itC=dynamic_cast<const MEDCouplingLinearTime *>(*it);
+      if(!itC)
+        throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::aggregate on mismatched time discretization !");
+      a[i]=itC->getArray();
+      b[i]=itC->getEndArray();
+    }
+  DataArrayDouble *arr=DataArrayDouble::aggregate(a);
+  DataArrayDouble *arr2=DataArrayDouble::aggregate(b);
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setArray(arr,0);
+  arr->decrRef();
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::meld on mismatched time discretization !");
+  DataArrayDouble *arr1=DataArrayDouble::meld(getArray(),other->getArray());
+  DataArrayDouble *arr2=DataArrayDouble::meld(getEndArray(),other->getEndArray());
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
   ret->setTimeTolerance(getTimeTolerance());
   ret->setArray(arr1,0);
   arr1->decrRef();
index e826e12ced90714acd1fe1f42f579d4ce4080243..45f8518ba083278f8f3e2d76c95fae7caa1a90b4 100644 (file)
@@ -46,6 +46,7 @@ namespace ParaMEDMEM
     virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
     virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
     virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const;
     virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
     virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const;
     virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(const MEDCouplingTimeDiscretization *other,
@@ -53,6 +54,8 @@ namespace ParaMEDMEM
     virtual std::string getStringRepr() const = 0;
     virtual TypeOfTimeDiscretization getEnum() const = 0;
     virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0;
+    virtual MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const = 0;
+    virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0;
     virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0;
     virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0;
     virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0;
@@ -133,6 +136,8 @@ namespace ParaMEDMEM
     std::string getStringRepr() const;
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const;
+    MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
@@ -150,6 +155,7 @@ namespace ParaMEDMEM
     bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const;
     void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) { }
     void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception);
@@ -180,6 +186,8 @@ namespace ParaMEDMEM
     void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const;
+    MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
@@ -197,6 +205,7 @@ namespace ParaMEDMEM
     bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const;
     void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
     void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
     void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
@@ -236,6 +245,7 @@ namespace ParaMEDMEM
     bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const;
     bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
     bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const;
     std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception);
@@ -245,6 +255,8 @@ namespace ParaMEDMEM
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
     std::string getStringRepr() const;
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const;
+    MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
@@ -331,10 +343,13 @@ namespace ParaMEDMEM
     bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
     bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const;
     void getValueForTime(double time, const std::vector<double>& vals, double *res) const;
     void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception);
     void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception);
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const;
+    MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const;
index 2fb724a8db49575e0e7df044268363889431164c..b4b80c5e5c4c855ad733ee6f78ac7e4033f95b8c 100644 (file)
@@ -907,6 +907,17 @@ DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerge
   return ret;
 }
 
+/*!
+ * Idem ParaMEDMEM::MEDCouplingUMesh::mergeNodes method except that the merged nodes are meld into the barycenter of them.
+ */
+DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
+{
+  DataArrayInt *ret=buildPermArrayForMergeNode(-1,precision,areNodesMerged,newNbOfNodes);
+  if(areNodesMerged)
+    renumberNodes2(ret->getConstPointer(),newNbOfNodes);
+  return ret;
+}
+
 /*!
  * This method tries to use 'other' coords and use it for 'this'. If no exception was thrown after the call of this method :
  * this->_coords==other->_coords. If not a exception is thrown this remains unchanged.
@@ -1101,6 +1112,12 @@ void MEDCouplingUMesh::findBoundaryNodes(std::vector<int>& nodes) const
   meshDM1->decrRef();
 }
 
+MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
+{
+  incrRef();
+  return const_cast<MEDCouplingUMesh *>(this);
+}
+
 /*
  * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes.
  * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes())
@@ -1116,6 +1133,22 @@ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes
   renumberNodesInConn(newNodeNumbers);
 }
 
+/*
+ * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes.
+ * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes())
+ * This value is asked because often known by the caller of this method.
+ * This method, contrary to MEDCouplingMesh::renumberCells does NOT conserve the number of nodes before and after.
+ * The difference with ParaMEDMEM::MEDCouplingUMesh::renumberNodes method is in the fact that the barycenter of merged nodes is computed here.
+ *
+ * @param newNodeNumbers array specifying the new numbering.
+ * @param newNbOfNodes the new number of nodes.
+ */
+void MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes)
+{
+  MEDCouplingPointSet::renumberNodes2(newNodeNumbers,newNbOfNodes);
+  renumberNodesInConn(newNodeNumbers);
+}
+
 /*!
  * This method renumbers nodes in connectivity only without any reference with coords.
  * Use it with care !
@@ -3215,41 +3248,69 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const
  * Returns a newly created mesh (with ref count ==1) that contains merge of 'mesh1' and 'other'.
  * The coords of 'mesh2' are added at the end of coords of 'mesh1'.
  */
-MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2)
+MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception)
 {
-  MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
-  ret->setName("merge");
-  DataArrayDouble *pts=mergeNodesArray(mesh1,mesh2);
+  std::vector<const MEDCouplingUMesh *> tmp(2);
+  tmp[0]=mesh1; tmp[1]=mesh2;
+  return mergeUMeshes(tmp);
+}
+
+MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(std::vector<const MEDCouplingUMesh *>& a) throw(INTERP_KERNEL::Exception)
+{
+  if(a.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeUMeshes : input array must be NON EMPTY !");
+  std::vector<const MEDCouplingUMesh *>::const_iterator it=a.begin();
+  int meshDim=(*it)->getMeshDimension();
+  int nbOfCells=(*it)->getNumberOfCells();
+  int meshLgth=(*it++)->getMeshLength();
+  for(;it!=a.end();it++)
+    {
+      if(meshDim!=(*it)->getMeshDimension())
+        throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, mergeMeshes impossible !");
+      nbOfCells+=(*it)->getNumberOfCells();
+      meshLgth+=(*it)->getMeshLength();
+    }
+  std::vector<const MEDCouplingPointSet *> aps(a.size());
+  std::copy(a.begin(),a.end(),aps.begin());
+  DataArrayDouble *pts=mergeNodesArray(aps);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("merge",meshDim);
   ret->setCoords(pts);
   pts->decrRef();
-  int meshDim=mesh1->getMeshDimension();
-  if(meshDim!=mesh2->getMeshDimension())
-    throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, mergeMeshes impossible !");
-  ret->setMeshDimension(meshDim);
-  int delta=mesh1->getMeshLength();
-  int pos=mesh1->getNumberOfCells();
-  int nbOfCells2=mesh2->getNumberOfCells();
-  int end=mesh1->getNumberOfCells()+nbOfCells2+1;
-  DataArrayInt *nodalIndex=DataArrayInt::aggregate(mesh1->getNodalConnectivityIndex(),
-                                                   mesh2->getNodalConnectivityIndex(),1);
-  std::transform(nodalIndex->getConstPointer()+pos+1,nodalIndex->getConstPointer()+end,
-                 nodalIndex->getPointer()+pos+1,std::bind2nd(std::plus<int>(),delta));
-  DataArrayInt *newNodal2=mesh2->getNodalConnectivity()->deepCopy();
-  delta=mesh1->getNumberOfNodes();
-  const int *nI2=mesh2->getNodalConnectivityIndex()->getConstPointer();
-  int *pt=newNodal2->getPointer();
-  for(int i=0;i<nbOfCells2;i++)
-    {
-      pt++;
-      for(int j=0;j<nI2[i+1]-nI2[i]-1;j++,pt++)
-        if(*pt!=-1)
-          *pt+=delta;
-    }
-  DataArrayInt *nodal=DataArrayInt::aggregate(mesh1->getNodalConnectivity(),newNodal2,0);
-  newNodal2->decrRef();
-  ret->setConnectivity(nodal,nodalIndex,true);
-  nodalIndex->decrRef();
-  nodal->decrRef();
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(meshLgth,1);
+  int *cPtr=c->getPointer();
+  DataArrayInt *cI=DataArrayInt::New();
+  cI->alloc(nbOfCells+1,1);
+  int *cIPtr=cI->getPointer();
+  *cIPtr++=0;
+  int offset=0;
+  int offset2=0;
+  for(it=a.begin();it!=a.end();it++)
+    {
+      int curNbOfCell=(*it)->getNumberOfCells();
+      const int *curCI=(*it)->_nodal_connec_index->getConstPointer();
+      const int *curC=(*it)->_nodal_connec->getConstPointer();
+      cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus<int>(),offset));
+      for(int j=0;j<curNbOfCell;j++)
+        {
+          const int *src=curC+curCI[j];
+          *cPtr++=*src++;
+          for(;src!=curC+curCI[j+1];src++,cPtr++)
+            {
+              if(*src!=-1)
+                *cPtr=*src+offset2;
+              else
+                *cPtr=-1;
+            }
+        }
+      offset=curCI[curNbOfCell];
+      offset2+=(*it)->getNumberOfNodes();
+    }
+  //
+  ret->setConnectivity(c,cI,true);
+  c->decrRef();
+  cI->decrRef();
+  ret->incrRef();
   return ret;
 }
 
index df4ddd292337228ebca3c69c4d310bba73d4a18c..0fe13c9fcaf3f3c69ec33a83a4e412dc4f6b3b91 100644 (file)
@@ -85,13 +85,16 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
+    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
+    MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector<int>& nodes) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const;
     MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
+    MEDCOUPLING_EXPORT void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes);
     MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems);
@@ -134,7 +137,8 @@ namespace ParaMEDMEM
     //
     MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
     MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const;
-    MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2);
+    MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(std::vector<const MEDCouplingUMesh *>& a) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes);
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *fuseUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr);
     MEDCOUPLING_EXPORT static bool isPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords);
index e8629b7b81ada122576ad10d38751fa74e4a0b6b..e0cff180d7e7b5181af696beb7c6ada9b510b36f 100644 (file)
@@ -338,6 +338,13 @@ DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesM
   return 0;
 }
 
+DataArrayInt *MEDCouplingUMeshDesc::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
+{
+  //not implemented yet.
+  areNodesMerged=false;
+  return 0;
+}
+
 void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception("Not implemented yet !");
@@ -377,6 +384,11 @@ MEDCouplingPointSet *MEDCouplingUMeshDesc::buildBoundaryMesh(bool keepCoords) co
   return 0;
 }
 
+MEDCouplingUMesh *MEDCouplingUMeshDesc::buildUnstructured() const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::buildUnstructured : not implemented yet !");
+}
+
 void MEDCouplingUMeshDesc::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception("Available for UMesh desc but not implemented yet !");
index f11fe94a40ebbb15eba3b5a8190cba413709923c..1924108e9fd04af15754e32cb3b02251d6860122 100644 (file)
@@ -62,6 +62,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector<int>& elems);
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
+    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
@@ -69,6 +70,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector<int>& nodes) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const;
+    MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
index 2b2f4de2a7e13aab51094892ceaee1f36077e765..8e1e4fb01d878d33055ba726ad9ab6a1f54acd1a 100644 (file)
@@ -3618,3 +3618,207 @@ void MEDCouplingBasicsTest::testSimplexize2()
   f1->decrRef();
   m->decrRef();
 }
+
+void MEDCouplingBasicsTest::testDAMeld1()
+{
+  DataArrayDouble *da1=DataArrayDouble::New();
+  da1->alloc(7,2);
+  DataArrayDouble *da2=DataArrayDouble::New();
+  da2->alloc(7,1);
+  //
+  da1->fillWithValue(7.);
+  da2->iota(0.);
+  DataArrayDouble *da3=da2->applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec");
+  //
+  da1->setInfoOnComponent(0,"c0da1");
+  da1->setInfoOnComponent(1,"c1da1");
+  da3->setInfoOnComponent(0,"c0da3");
+  da3->setInfoOnComponent(1,"c1da3");
+  da3->setInfoOnComponent(2,"c2da3");
+  //
+  DataArrayDouble *da1C=da1->deepCpy();
+  da1->meldWith(da3);
+  CPPUNIT_ASSERT_EQUAL(5,da1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(7,da1->getNumberOfTuples());
+  CPPUNIT_ASSERT(da1->getInfoOnComponent(0)=="c0da1");
+  CPPUNIT_ASSERT(da1->getInfoOnComponent(1)=="c1da1");
+  CPPUNIT_ASSERT(da1->getInfoOnComponent(2)=="c0da3");
+  CPPUNIT_ASSERT(da1->getInfoOnComponent(3)=="c1da3");
+  CPPUNIT_ASSERT(da1->getInfoOnComponent(4)=="c2da3");
+  //
+  const double expected1[35]={7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.};
+  for(int i=0;i<35;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-10);
+  //
+  DataArrayInt *dai1=da1C->convertToIntArr();
+  DataArrayInt *dai3=da3->convertToIntArr();
+  dai1->meldWith(dai3);
+  CPPUNIT_ASSERT_EQUAL(5,dai1->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(7,dai1->getNumberOfTuples());
+  CPPUNIT_ASSERT(dai1->getInfoOnComponent(0)=="c0da1");
+  CPPUNIT_ASSERT(dai1->getInfoOnComponent(1)=="c1da1");
+  CPPUNIT_ASSERT(dai1->getInfoOnComponent(2)=="c0da3");
+  CPPUNIT_ASSERT(dai1->getInfoOnComponent(3)=="c1da3");
+  CPPUNIT_ASSERT(dai1->getInfoOnComponent(4)=="c2da3");
+  for(int i=0;i<35;i++)
+    CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai1->getIJ(0,i));
+  // test of static method DataArrayDouble::meld
+  DataArrayDouble *da4=DataArrayDouble::meld(da1C,da3);
+  CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(7,da4->getNumberOfTuples());
+  CPPUNIT_ASSERT(da4->getInfoOnComponent(0)=="c0da1");
+  CPPUNIT_ASSERT(da4->getInfoOnComponent(1)=="c1da1");
+  CPPUNIT_ASSERT(da4->getInfoOnComponent(2)=="c0da3");
+  CPPUNIT_ASSERT(da4->getInfoOnComponent(3)=="c1da3");
+  CPPUNIT_ASSERT(da4->getInfoOnComponent(4)=="c2da3");
+  for(int i=0;i<35;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da4->getIJ(0,i),1e-10);
+  // test of static method DataArrayInt::meld
+  dai1->decrRef();
+  dai1=da1C->convertToIntArr();
+  DataArrayInt *dai4=DataArrayInt::meld(dai1,dai3);
+  CPPUNIT_ASSERT_EQUAL(5,dai4->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(7,dai4->getNumberOfTuples());
+  CPPUNIT_ASSERT(dai4->getInfoOnComponent(0)=="c0da1");
+  CPPUNIT_ASSERT(dai4->getInfoOnComponent(1)=="c1da1");
+  CPPUNIT_ASSERT(dai4->getInfoOnComponent(2)=="c0da3");
+  CPPUNIT_ASSERT(dai4->getInfoOnComponent(3)=="c1da3");
+  CPPUNIT_ASSERT(dai4->getInfoOnComponent(4)=="c2da3");
+  for(int i=0;i<35;i++)
+    CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai4->getIJ(0,i));
+  //
+  dai4->decrRef();
+  da4->decrRef();
+  dai3->decrRef();
+  dai1->decrRef();
+  da1C->decrRef();
+  da1->decrRef();
+  da2->decrRef();
+  da3->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFieldMeld1()
+{
+  MEDCouplingUMesh *m=build3DSurfTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setMesh(m);
+  DataArrayDouble *da1=DataArrayDouble::New();
+  const double arr1[5]={12.,23.,34.,45.,56.};
+  da1->alloc(5,1);
+  std::copy(arr1,arr1+5,da1->getPointer());
+  da1->setInfoOnComponent(0,"aaa");
+  f1->setArray(da1);
+  f1->setTime(3.4,2,1);
+  f1->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f2=f1->deepCpy();
+  f2->setMesh(f1->getMesh());
+  f2->checkCoherency();
+  f2->changeNbOfComponents(2,5.);
+  (*f2)=5.;
+  f2->getArray()->setInfoOnComponent(0,"bbb");
+  f2->getArray()->setInfoOnComponent(1,"ccc");
+  f2->checkCoherency();
+  //
+  MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::meldFields(f2,f1);
+  f3->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(5,f3->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,f3->getNumberOfComponents());
+  CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(0)=="bbb");
+  CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(1)=="ccc");
+  CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(2)=="aaa");
+  const double expected1[15]={5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.};
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-12);
+  int dt,it;
+  double time=f3->getTime(dt,it);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,time,1e-14);
+  CPPUNIT_ASSERT_EQUAL(2,dt);
+  CPPUNIT_ASSERT_EQUAL(1,it);
+  //
+  MEDCouplingFieldDouble *f4=f2->buildNewTimeReprFromThis(NO_TIME,false);
+  MEDCouplingFieldDouble *f5=f1->buildNewTimeReprFromThis(NO_TIME,false);
+  MEDCouplingFieldDouble *f6=MEDCouplingFieldDouble::meldFields(f4,f5);
+  f6->checkCoherency();
+  CPPUNIT_ASSERT_EQUAL(5,f6->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,f6->getNumberOfComponents());
+  CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(0)=="bbb");
+  CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(1)=="ccc");
+  CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(2)=="aaa");
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f6->getIJ(0,i),1e-12);
+  //
+  f6->decrRef();
+  f4->decrRef();
+  f5->decrRef();
+  f3->decrRef();
+  da1->decrRef();
+  f2->decrRef();
+  f1->decrRef();
+  m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testMergeNodes2()
+{
+  MEDCouplingUMesh *m1=build2DTargetMesh_1();
+  MEDCouplingUMesh *m2=build2DTargetMesh_1();
+  const double vec[2]={0.002,0.};
+  m2->translate(vec);
+  //
+  std::vector<const MEDCouplingUMesh *> tmp(2);
+  tmp[0]=m1;
+  tmp[1]=m2;
+  MEDCouplingUMesh *m3=MEDCouplingUMesh::mergeUMeshes(tmp);
+  bool b;
+  int newNbOfNodes;
+  DataArrayInt *da=m3->mergeNodes2(0.01,b,newNbOfNodes);
+  CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfNodes());
+  const double expected1[18]={-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7};
+  for(int i=0;i<18;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],m3->getCoords()->getIJ(0,i),1e-13);
+  //
+  da->decrRef();
+  m3->decrRef();
+  m1->decrRef();
+  m2->decrRef();
+}
+
+void MEDCouplingBasicsTest::testMergeField2()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f1->setMesh(m);
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(5,2);
+  arr->fillWithValue(2.);
+  f1->setArray(arr);
+  arr->decrRef();
+  MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f2->setMesh(m);
+  arr=DataArrayDouble::New();
+  arr->alloc(5,2);
+  arr->fillWithValue(5.);
+  f2->setArray(arr);
+  arr->decrRef();
+  MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+  f3->setMesh(m);
+  arr=DataArrayDouble::New();
+  arr->alloc(5,2);
+  arr->fillWithValue(7.);
+  f3->setArray(arr);
+  arr->decrRef();
+  //
+  std::vector<const MEDCouplingFieldDouble *> tmp(3);
+  tmp[0]=f1; tmp[1]=f2; tmp[2]=f3;
+  MEDCouplingFieldDouble *f4=MEDCouplingFieldDouble::mergeFields(tmp);
+  CPPUNIT_ASSERT_EQUAL(15,f4->getMesh()->getNumberOfCells());
+  const double expected1[30]={2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.};
+  for(int i=0;i<30;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f4->getIJ(0,i),1.e-13);
+  //
+  f4->decrRef();
+  f1->decrRef();
+  f2->decrRef();
+  f3->decrRef();
+  m->decrRef();
+}