]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
MergeNodes method on PointSet classes.
authorageay <ageay>
Wed, 6 Jan 2010 11:11:22 +0000 (11:11 +0000)
committerageay <ageay>
Wed, 6 Jan 2010 11:11:22 +0000 (11:11 +0000)
14 files changed:
src/INTERP_KERNEL/BBTree.txx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingPointSet.txx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingTimeLabel.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMeshDesc.cxx
src/MEDCoupling/MEDCouplingUMeshDesc.hxx
src/MEDCoupling/Makefile.am
src/MEDCoupling/Test/MEDCouplingBasicsTest.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx

index 04ee29b328173fc36a8573d4dbb4f6201765bcca..76ac351eb2e27d4a47804aec47cc1b843071d1a3 100644 (file)
@@ -156,7 +156,7 @@ public:
             bool intersects = true;
             for (int idim=0; idim<dim; idim++)
               {
-                if (bb_ptr[idim*2]-bb[idim*2+1]>-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon)
+                if (bb_ptr[idim*2]-bb[idim*2+1]>_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<-_epsilon)
                   intersects=false;
               }
             if (intersects)
index b907df1f8f02ffd7772f2cbb3e24a3843dacc8f2..29615cc4f03385e40db4fa462083e66b2d39f2c8 100644 (file)
@@ -25,6 +25,14 @@ void DataArray::setName(const char *name)
   _name=name;
 }
 
+void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
+{
+  if(_info_on_compo.size()!=other._info_on_compo.size())
+    throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
+  _name=other._name;
+  _info_on_compo=other._info_on_compo;
+}
+
 bool DataArray::areInfoEquals(const DataArray& other) const
 {
   if(_nb_of_tuples!=other._nb_of_tuples)
index 1865161d6af696dcdfadd4c5f967d3d165dc391c..c875fd2816845aa64a79e8beaa630911248261ba 100644 (file)
@@ -79,6 +79,7 @@ namespace ParaMEDMEM
   {
   public:
     void setName(const char *name);
+    void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception);
     bool areInfoEquals(const DataArray& other) const;
     std::string getName() const { return _name; }
     std::string getInfoOnComponent(int i) const { return _info_on_compo[i]; }
index 06b06de8668cae200f89a506786f0d8e263aa94d..28cc7759000e5d9f0953c9df44dd6481fbb3e90c 100644 (file)
@@ -20,6 +20,7 @@
 #include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingUMeshDesc.hxx"
 #include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingPointSet.txx"
 
 #include <cmath>
 #include <limits>
@@ -96,6 +97,107 @@ bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, doubl
   return _coords->isEqual(*other._coords,prec);
 }
 
+/*!
+ * @param comm out parameter (not inout)
+ * @param commIndex out parameter (not inout)
+ */
+void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const
+{
+  comm=DataArrayInt::New();
+  commIndex=DataArrayInt::New();
+  //
+  int nbNodesOld=getNumberOfNodes();
+  int spaceDim=getSpaceDimension();
+  std::vector<double> bbox(2*nbNodesOld*spaceDim);
+  const double *coordsPtr=_coords->getConstPointer();
+  for(int i=0;i<nbNodesOld;i++)
+    {
+      for(int j=0;j<spaceDim;j++)
+        {
+          bbox[2*spaceDim*i+2*j]=coordsPtr[spaceDim*i+j];
+          bbox[2*spaceDim*i+2*j+1]=coordsPtr[spaceDim*i+j];
+        }
+    }
+  //
+  std::vector<int> c,cI(1);
+  switch(spaceDim)
+    {
+    case 3:
+      findCommonNodesAlg<3>(bbox,nbNodesOld,prec,c,cI);
+      break;
+    case 2:
+      findCommonNodesAlg<2>(bbox,nbNodesOld,prec,c,cI);
+      break;
+    case 1:
+      findCommonNodesAlg<1>(bbox,nbNodesOld,prec,c,cI);
+      break;
+    default:
+      throw INTERP_KERNEL::Exception("Unexpected spacedim of coords. Must be 1,2 or 3.");
+    }
+  commIndex->alloc(cI.size(),1);
+  std::copy(cI.begin(),cI.end(),commIndex->getPointer());
+  comm->alloc(cI.back(),1);
+  std::copy(c.begin(),c.end(),comm->getPointer());
+}
+
+/*!
+ * @param comm in param in the same format than one returned by findCommonNodes method.
+ * @param commI in param in the same format than one returned by findCommonNodes method.
+ * @return the old to new correspondance array.
+ */
+DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommNodesFrmt(const DataArrayInt *comm, const DataArrayInt *commIndex,
+                                                                      int& newNbOfNodes) const
+{
+  DataArrayInt *ret=DataArrayInt::New();
+  int nbNodesOld=getNumberOfNodes();
+  ret->alloc(nbNodesOld,1);
+  std::fill(ret->getPointer(),ret->getPointer()+nbNodesOld,-1);
+  int *retPtr=ret->getPointer();
+  std::vector<int> commRemain(comm->getConstPointer(),comm->getConstPointer()+comm->getNumberOfTuples());
+  std::vector<int> commIRemain(commIndex->getConstPointer(),commIndex->getConstPointer()+commIndex->getNumberOfTuples());
+  int newNb=0;
+  for(int iNode=0;iNode<nbNodesOld;iNode++)
+    {
+      if(retPtr[iNode]!=-1)
+        continue;
+      if(commRemain.empty())
+        {
+          retPtr[iNode]=newNb++;
+          continue;
+        }
+      if(commRemain[0]!=iNode)
+        retPtr[iNode]=newNb;
+      else
+        {
+          for(std::vector<int>::const_iterator iNode2=commRemain.begin();
+              iNode2!=commRemain.begin()+commIRemain[1];iNode2++)
+            retPtr[*iNode2]=newNb;
+          int delta=commIRemain[1];
+          commRemain.erase(commRemain.begin(),commRemain.begin()+commIRemain[1]);
+          commIRemain.erase(commIRemain.begin());
+          std::transform(commIRemain.begin(),commIRemain.end(),commIRemain.begin(),std::bind2nd(std::minus<int>(),delta));
+        }
+      newNb++;
+    }
+  newNbOfNodes=newNb;
+  return ret;
+}
+
+void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
+{
+  DataArrayDouble *newCoords=DataArrayDouble::New();
+  int spaceDim=getSpaceDimension();
+  newCoords->alloc(newNbOfNodes,spaceDim);
+  newCoords->copyStringInfoFrom(*_coords);
+  int oldNbOfNodes=getNumberOfNodes();
+  double *ptToFill=newCoords->getPointer();
+  const double *oldCoordsPtr=_coords->getConstPointer();
+  for(int i=0;i<oldNbOfNodes;i++)
+    std::copy(oldCoordsPtr+i*spaceDim,oldCoordsPtr+(i+1)*spaceDim,ptToFill+newNodeNumbers[i]*spaceDim);
+  setCoords(newCoords);
+  newCoords->decrRef();
+}
+
 void MEDCouplingPointSet::getBoundingBox(double *bbox) const
 {
   int dim=getSpaceDimension();
index 7308d40f32655e6226303d1b8c8d4b96b6833cfc..84d6a122d0557579313f90f77eace3137a92519e 100644 (file)
@@ -43,6 +43,10 @@ namespace ParaMEDMEM
     void setCoords(DataArrayDouble *coords);
     DataArrayDouble *getCoords() const { return _coords; }
     bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const;
+    virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged) = 0;
+    void findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const;
+    DataArrayInt *buildNewNumberingFromCommNodesFrmt(const DataArrayInt *comm, const DataArrayInt *commIndex,
+                                                     int& newNbOfNodes) const;
     void getBoundingBox(double *bbox) const;
     void zipCoords();
     void rotate(const double *center, const double *vector, double angle);
@@ -53,7 +57,7 @@ namespace ParaMEDMEM
     virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
     virtual void findBoundaryNodes(std::vector<int>& nodes) const = 0;
     virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0;
-    virtual void renumberConnectivity(const int *newNodeNumbers) = 0;
+    virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     //! size of returned tinyInfo must be always the same.
     virtual void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
     virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings);
@@ -67,6 +71,9 @@ namespace ParaMEDMEM
     static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps);
     void rotate2D(const double *center, double angle);
     void rotate3D(const double *center, const double *vect, double angle);
+    template<int SPACEDIM>
+    void findCommonNodesAlg(std::vector<double>& bbox,
+                            int nbNodes, double prec, std::vector<int>& c, std::vector<int>& cI) const;
   protected:
     DataArrayDouble *_coords;
   };
diff --git a/src/MEDCoupling/MEDCouplingPointSet.txx b/src/MEDCoupling/MEDCouplingPointSet.txx
new file mode 100644 (file)
index 0000000..c02c608
--- /dev/null
@@ -0,0 +1,68 @@
+//  Copyright (C) 2007-2008  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __PARAMEDMEM_MEDCOUPLINGPOINTSET_TXX__
+#define __PARAMEDMEM_MEDCOUPLINGPOINTSET_TXX__
+
+#include "MEDCouplingPointSet.txx"
+#include "InterpolationUtils.hxx"
+#include "BBTree.txx"
+
+#include <vector>
+
+namespace ParaMEDMEM
+{
+  template<int SPACEDIM>
+  void MEDCouplingPointSet::findCommonNodesAlg(std::vector<double>& bbox,
+                                               int nbNodes, double prec,
+                                               std::vector<int>& c, std::vector<int>& cI) const
+  {
+    const double *coordsPtr=_coords->getConstPointer();
+    BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbNodes,prec);
+    double bb[2*SPACEDIM];
+    double prec2=prec*prec;
+    for(int i=0;i<nbNodes;i++)
+      {
+        if(std::find(c.begin(),c.end(),i)!=c.end())
+          continue;
+        for(int j=0;j<SPACEDIM;j++)
+          {
+            bb[2*j]=coordsPtr[SPACEDIM*i+j];
+            bb[2*j+1]=coordsPtr[SPACEDIM*i+j];
+          }
+        std::vector<int> intersectingElems;
+        myTree.getIntersectingElems(bb,intersectingElems);
+        if(intersectingElems.size()>1)
+          {
+            std::vector<int> commonNodes;
+            for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
+              if(*it!=i)
+                if(INTERP_KERNEL::distance2<SPACEDIM>(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))<prec2)
+                  commonNodes.push_back(*it);
+            if(!commonNodes.empty())
+              {
+                cI.push_back(cI.back()+commonNodes.size()+1);
+                c.push_back(i);
+                c.insert(c.end(),commonNodes.begin(),commonNodes.end());
+              }
+          }
+      }
+  }
+}
+
+#endif
index ae26d09d4398dd7622b322bd2cececd92fc1810c..24849f263ed775c1c1ff3bb62a4cb01dc0c76e02 100644 (file)
@@ -35,11 +35,11 @@ namespace ParaMEDMEM
     void declareAsNew();
     //! This method should be called on high level classes as Field or Mesh to take into acount modifications done in aggragates objects.
     virtual void updateTime() = 0;
+    unsigned int getTimeOfThis() const { return _time; }
   protected:
     TimeLabel();
     virtual ~TimeLabel();
     void updateTimeWith(const TimeLabel& other);
-    unsigned int getTimeOfThis() const { return _time; }
   private:
     static unsigned int GLOBAL_TIME;
     unsigned int _time;
index 155d469bc6deeb77c453bc20ce5631565af87c3f..9303c2d47e139e0c8c0b49bbc1e289ccc5806a41 100644 (file)
@@ -412,6 +412,25 @@ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer()
   return ret;
 }
 
+/*!
+ * @param areNodesMerged if at least two nodes have been merged.
+ * @return old to new node correspondance.
+ */
+DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged)
+{
+  DataArrayInt *comm,*commI;
+  findCommonNodes(comm,commI,precision);
+  int newNbOfNodes;
+  int oldNbOfNodes=getNumberOfNodes();
+  DataArrayInt *ret=buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
+  areNodesMerged=(oldNbOfNodes!=newNbOfNodes);
+  comm->decrRef();
+  commI->decrRef();
+  if(areNodesMerged)
+    renumberNodes(ret->getConstPointer(),newNbOfNodes);
+  return ret;
+}
+
 MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const
 {
   MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(start,end);
@@ -500,8 +519,9 @@ void MEDCouplingUMesh::findBoundaryNodes(std::vector<int>& nodes) const
   meshDM1->decrRef();
 }
 
-void MEDCouplingUMesh::renumberConnectivity(const int *newNodeNumbers)
+void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
 {
+  MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes);
   int *conn=getNodalConnectivity()->getPointer();
   const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
   int nbOfCells=getNumberOfCells();
@@ -586,6 +606,7 @@ void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connInd
   DataArrayInt::setArrayIn(connIndex,_nodal_connec_index);
   if(isComputingTypes)
     computeTypes();
+  declareAsNew();
 }
 
 MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCpy):MEDCouplingPointSet(other,deepCpy),_iterator(-1),_mesh_dim(other._mesh_dim),
index 66000673d762b3b1f83759143d40d213bbebeb49..56b804eb15552d6b564d996eb2b622bb1d4d2605 100644 (file)
@@ -61,11 +61,12 @@ namespace ParaMEDMEM
     DataArrayInt *zipCoordsTraducer();
     void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
     MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
+    DataArrayInt *mergeNodes(double precision, bool& areNodesMerged);
     MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
     MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
     void findBoundaryNodes(std::vector<int>& nodes) const;
     MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const;
-    void renumberConnectivity(const int *newNodeNumbers);
+    void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
   private:
index fc20b2747aafe1d8eaba3f36dc2788ba9b1a50dd..f89e91c3cce5594f074c0e59142363194a3af238 100644 (file)
@@ -215,6 +215,13 @@ void MEDCouplingUMeshDesc::giveElemsInBoundingBox(const double *bbox, double eps
   delete [] elem_bb;
 }
 
+DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged)
+{
+  //not implemented yet.
+  areNodesMerged=false;
+  return 0;
+}
+
 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const
 {
   //not implemented yet.
@@ -238,8 +245,10 @@ MEDCouplingPointSet *MEDCouplingUMeshDesc::buildBoundaryMesh(bool keepCoords) co
   return 0;
 }
 
-void MEDCouplingUMeshDesc::renumberConnectivity(const int *newNodeNumbers)
+void MEDCouplingUMeshDesc::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
 {
+  MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes);
+  //not implemented yet
 }
 
 MEDCouplingFieldDouble *MEDCouplingUMeshDesc::getMeasureField(bool isAbs) const
index ca3c9b6d4087ebcba7c2ba33ec8fbdb484cd6433..c44288ba2cf12d31f86534529a2e998de3d4d64b 100644 (file)
@@ -48,11 +48,12 @@ namespace ParaMEDMEM
     void unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2,
                          const std::vector<std::string>& littleStrings);
     void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
+    DataArrayInt *mergeNodes(double precision, bool& areNodesMerged);
     MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
     MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
     void findBoundaryNodes(std::vector<int>& nodes) const;
     MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const;
-    void renumberConnectivity(const int *newNodeNumbers);
+    void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
     DataArrayInt *zipCoordsTraducer();
   private:
index f77485572e307afe2740b55b5c62c63621a4111d..d9a827d4e0b6b43d5f26cb000b0e25a0497868db 100644 (file)
@@ -32,7 +32,7 @@ MEDCouplingFieldDouble.hxx  MEDCouplingMesh.hxx MEDCouplingUMesh.hxx MEDCoupling
 MEDCouplingField.hxx MEDCouplingNormalizedUnstructuredMesh.hxx MEDCouplingMemArray.hxx            \
 MEDCouplingNormalizedUnstructuredMesh.txx  MEDCouplingMemArray.txx MEDCouplingRefCountObject.hxx  \
 MEDCouplingCMesh.hxx MEDCouplingTimeDiscretization.hxx                                            \
-MEDCouplingFieldDiscretization.hxx MEDCouplingPointSet.hxx                                        \
+MEDCouplingFieldDiscretization.hxx MEDCouplingPointSet.hxx MEDCouplingPointSet.txx                \
 MEDCouplingUMeshDesc.hxx MEDCouplingNatureOfField.hxx                                             \
 MEDCouplingNormalizedCartesianMesh.hxx MEDCouplingNormalizedCartesianMesh.txx                     \
 MEDCouplingRemapper.hxx MEDCouplingExtrudedMesh.hxx
@@ -86,6 +86,7 @@ EXTRA_DIST += \
        MEDCouplingMemArray.txx                   \
        MEDCouplingRefCountObject.hxx             \
        MEDCouplingPointSet.hxx                   \
+       MEDCouplingPointSet.txx                   \
        MEDCouplingUMeshDesc.hxx                  \
        MEDCouplingNatureOfField.hxx              \
        MEDCouplingRemapper.hxx
index 8a5d4b9260e56e933af0ad3fa5b9da884ad18f26..0b7a5c0c056b545e7d8f4e49246395901916b7b8 100644 (file)
@@ -887,6 +887,102 @@ void MEDCouplingBasicsTest::testExtrudedMesh1()
   mesh2D->decrRef();
 }
 
+void MEDCouplingBasicsTest::testFindCommonNodes()
+{
+  DataArrayInt *comm,*commI;
+  MEDCouplingUMesh *targetMesh=build3DTargetMesh_1();
+  targetMesh->findCommonNodes(comm,commI,1e-10);
+  CPPUNIT_ASSERT_EQUAL(1,commI->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(0,comm->getNumberOfTuples());
+  int newNbOfNodes;
+  DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
+  CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes);
+  CPPUNIT_ASSERT_EQUAL(27,o2n->getNumberOfTuples());
+  const int o2nExp1[27]=
+    {
+      0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
+      21,22,23,24,25,26
+    };
+  CPPUNIT_ASSERT(std::equal(o2nExp1,o2nExp1+27,o2n->getConstPointer()));
+  o2n->decrRef();
+  comm->decrRef();
+  commI->decrRef();
+  targetMesh->decrRef();
+  //
+  targetMesh=build3DTargetMeshMergeNode_1();
+  CPPUNIT_ASSERT_EQUAL(31,targetMesh->getNumberOfNodes());
+  targetMesh->findCommonNodes(comm,commI,1e-10);
+  CPPUNIT_ASSERT_EQUAL(3,commI->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(6,comm->getNumberOfTuples());
+  const int commExpected[6]={1,27,28,29,23,30};
+  const int commIExpected[3]={0,4,6};
+  CPPUNIT_ASSERT(std::equal(commExpected,commExpected+6,comm->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(commIExpected,commIExpected+3,commI->getConstPointer()));
+  o2n=targetMesh->buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
+  CPPUNIT_ASSERT_EQUAL(31,o2n->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes);
+  const int o2nExp2[31]=
+    {
+      0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
+      21,22,23,24,25,26,1,1,1,23
+    };
+  CPPUNIT_ASSERT(std::equal(o2nExp2,o2nExp2+31,o2n->getConstPointer()));
+  o2n->decrRef();
+  comm->decrRef();
+  commI->decrRef();
+  targetMesh->decrRef();
+  //
+  targetMesh=build3DTargetMesh_1();
+  bool areNodesMerged;
+  unsigned int time=targetMesh->getTimeOfThis();
+  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged);
+  targetMesh->updateTime();
+  CPPUNIT_ASSERT(time==targetMesh->getTimeOfThis());
+  CPPUNIT_ASSERT(!areNodesMerged);
+  targetMesh->decrRef();
+  o2n->decrRef();
+  //
+  targetMesh=build3DTargetMeshMergeNode_1();
+  time=targetMesh->getTimeOfThis();
+  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged);
+  targetMesh->updateTime();
+  CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis());
+  CPPUNIT_ASSERT(areNodesMerged);
+  int connExp[72]={18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15,
+                   18,4,5,8,7,13,14,17,16,
+                   18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24,
+                   18,13,14,17,16,22,23,26,25};
+  CPPUNIT_ASSERT_EQUAL(72,targetMesh->getNodalConnectivity()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(connExp,connExp+72,targetMesh->getNodalConnectivity()->getConstPointer()));
+  CPPUNIT_ASSERT_EQUAL(27,targetMesh->getCoords()->getNumberOfTuples());
+  double coordsExp[81]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0.  , 0., 50., 0., 50., 50., 0. ,
+                         200., 50., 0.,   0., 200., 0., 50., 200., 0. , 200., 200., 0. ,
+                         0., 0., 50., 50., 0., 50. , 200., 0., 50.  , 0., 50., 50., 50.,
+                         50., 50. , 200., 50., 50.,   0., 200., 50., 50., 200., 50. ,
+                         200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200.  
+                         , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 
+                         0., 200., 200., 50., 200., 200. , 200., 200., 200. };
+  CPPUNIT_ASSERT(std::equal(coordsExp,coordsExp+81,targetMesh->getCoords()->getConstPointer()));
+  targetMesh->decrRef();
+  o2n->decrRef();
+  //2D
+  targetMesh=build2DTargetMeshMergeNode_1();
+  CPPUNIT_ASSERT_EQUAL(18,targetMesh->getNumberOfNodes());
+  time=targetMesh->getTimeOfThis();
+  o2n=targetMesh->mergeNodes(1e-10,areNodesMerged);
+  CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis());
+  CPPUNIT_ASSERT(areNodesMerged);
+  CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes());
+  int connExp2[23]={4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3};
+  CPPUNIT_ASSERT_EQUAL(23,targetMesh->getNodalConnectivity()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(connExp2,connExp2+23,targetMesh->getNodalConnectivity()->getConstPointer()));
+  double coordsExp2[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7};
+  CPPUNIT_ASSERT_EQUAL(9,targetMesh->getCoords()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(coordsExp2,coordsExp2+18,targetMesh->getCoords()->getConstPointer()));
+  targetMesh->decrRef();
+  o2n->decrRef();
+}
+
 void MEDCouplingBasicsTest::test2DInterpP0P0_1()
 {
   MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1();
@@ -3241,6 +3337,48 @@ MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_1()
   return targetMesh;
 }
 
+MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshMergeNode_1()
+{
+  double targetCoords[36]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 };
+  int targetConn[18]={0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6};
+  MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
+  targetMesh->setMeshDimension(2);
+  targetMesh->allocateCells(5);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10);
+  targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14);
+  targetMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(18,2);
+  std::copy(targetCoords,targetCoords+36,myCoords->getPointer());
+  targetMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return targetMesh;
+}
+
+MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMeshMergeNode_1()
+{
+  double targetCoords[93]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0.  , 0., 50., 0., 50., 50., 0. , 200., 50., 0.,   0., 200., 0., 50., 200., 0. , 200., 200., 0. ,
+                            0., 0., 50., 50., 0., 50. , 200., 0., 50.  , 0., 50., 50., 50., 50., 50. , 200., 50., 50.,   0., 200., 50., 50., 200., 50. , 200., 200., 50. ,
+                            0., 0., 200., 50., 0., 200. , 200., 0., 200.  , 0., 50., 200., 50., 50., 200. , 200., 50., 200.,   0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0.,  200., 50., 200.};
+  int targetConn[64]={0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16,
+                      9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25};
+  MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
+  targetMesh->setMeshDimension(3);
+  targetMesh->allocateCells(12);
+  for(int i=0;i<8;i++)
+    targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn+8*i);
+  targetMesh->finishInsertingCells();
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(31,3);
+  std::copy(targetCoords,targetCoords+93,myCoords->getPointer());
+  targetMesh->setCoords(myCoords);
+  myCoords->decrRef();
+  return targetMesh;
+}
+
 MEDCouplingUMesh *MEDCouplingBasicsTest::build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D)
 {
   double coords[180]={
index e99db013c90b2d59afd37bd75b7b5ab29f3d8b71..adcb3b70562215ebc1dd6f0ec310ca4be4a0549d 100644 (file)
@@ -50,6 +50,7 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testNatureChecking );
     CPPUNIT_TEST( testBuildSubMeshData );
     CPPUNIT_TEST( testExtrudedMesh1 );
+    CPPUNIT_TEST( testFindCommonNodes );
     CPPUNIT_TEST( test2DInterpP0P0_1 );
     CPPUNIT_TEST( test2DInterpP0P0PL_1 );
     CPPUNIT_TEST( test2DInterpP0P0PL_2 );
@@ -119,6 +120,7 @@ namespace ParaMEDMEM
     void testNatureChecking();
     void testBuildSubMeshData();
     void testExtrudedMesh1();
+    void testFindCommonNodes();
     void test2DInterpP0P0_1();
     void test2DInterpP0P0PL_1();
     void test2DInterpP0P0PL_2();
@@ -185,6 +187,8 @@ namespace ParaMEDMEM
     MEDCouplingUMesh *build3DSurfTargetMesh_2();
     MEDCouplingUMesh *build3DSourceMesh_1();
     MEDCouplingUMesh *build3DTargetMesh_1();
+    MEDCouplingUMesh *build2DTargetMeshMergeNode_1();
+    MEDCouplingUMesh *build3DTargetMeshMergeNode_1();
     MEDCouplingUMesh *build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D);
     double sumAll(const std::vector< std::map<int,double> >& matrix);
   };