]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
*** empty log message ***
authorageay <ageay>
Mon, 12 Jul 2010 06:31:02 +0000 (06:31 +0000)
committerageay <ageay>
Mon, 12 Jul 2010 06:31:02 +0000 (06:31 +0000)
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx

index 0c0ce18879bbcfe90a320f561d39cd326ab02a3e..74ed28ba8ea354d957fae6febbc4d94833f76c7d 100644 (file)
@@ -272,6 +272,25 @@ void MEDCouplingPointSet::zipCoords()
   traducer->decrRef();
 }
 
+struct MEDCouplingCompAbs
+{
+  bool operator()(double x, double y) { return std::abs(x)<std::abs(y);}
+};
+
+/*!
+ * This method expects that _coords attribute is set.
+ * @return the carateristic dimension of point set. This caracteristic dimension is the max of difference 
+ * @exception If _coords attribute not set.
+ */
+double MEDCouplingPointSet::getCaracteristicDimension() const
+{
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCaracteristicDimension : Coordinates not set !");
+  const double *coords=_coords->getConstPointer();
+  int nbOfValues=_coords->getNbOfElems();
+  return std::abs(*std::max_element(coords,coords+nbOfValues,MEDCouplingCompAbs()));
+}
+
 /*!
  * Non const method that operates a rotation of 'this'.
  * If spaceDim==2 'vector' parameter is ignored (and could be 0) and the rotation is done around 'center' with angle specified by 'angle'.
index 601777efc1a6338045e4f41b0808e692605244d4..ab1004c80f0b1a2b73110a59c424344bc116be6b 100644 (file)
@@ -57,6 +57,7 @@ namespace ParaMEDMEM
                                                      int& newNbOfNodes) const;
     void getBoundingBox(double *bbox) const;
     void zipCoords();
+    double getCaracteristicDimension() const;
     void rotate(const double *center, const double *vector, double angle);
     void translate(const double *vector);
     void scale(const double *point, double factor);
index 823d992435837993094009e68db3cf77cee94933..760ef3282c81f37c1531c96a02129e5c1b753964 100644 (file)
@@ -506,7 +506,12 @@ bool MEDCouplingUMesh::areCellsEqualsInPool(const std::vector<int>& candidates,
 }
 
 /*!
- * 
+ * This method common cells base regarding 'compType' comparison policy described in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for details.
+ * This method returns 2 values 'res' and 'resI'.
+ * If 'res' and 'resI' are not empty before calling this method they will be cleared before set.
+ * The format of 'res' and 'resI' is as explained here.
+ * resI.size()-1 is the number of set of cells equal.
+ * The nth set is [res.begin()+resI[n];res.begin()+resI[n+1]) with 0<=n<resI.size()-1 
  */
 template<int SPACEDIM>
 void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector<int>& res, std::vector<int>& resI) const
@@ -517,7 +522,9 @@ void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector<int>& res,
   int nbOfCells=getNumberOfCells();
   getBoundingBoxForBBTree(bbox);
   double bb[2*SPACEDIM];
-  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,1e-12);
+  double eps=getCaracteristicDimension();
+  eps*=1.e-12;
+  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,eps);
   const int *conn=getNodalConnectivity()->getConstPointer();
   const int *connI=getNodalConnectivityIndex()->getConstPointer();
   const double *coords=getCoords()->getConstPointer();
@@ -539,10 +546,13 @@ void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector<int>& res,
               }
           std::vector<int> candidates;
           myTree.getIntersectingElems(bb,candidates);
+          std::vector<int>::iterator it=std::find(candidates.begin(),candidates.end(),k);
+          candidates.erase(candidates.begin(),it);
           if(areCellsEqualsInPool(candidates,compType,res))
             {
+              int pos=resI.back();
               resI.push_back(res.size());
-              for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+              for(std::vector<int>::const_iterator it=res.begin()+pos;it!=res.end();it++)
                 isFetched[*it]=true;
             }
         }
@@ -1587,6 +1597,10 @@ namespace ParaMEDMEMImpl
   };
 }
 
+/*!
+ * This methods checks that cells are sorted by their types.
+ * This method makes asumption (no check) that connectivity is correctly set before calling.
+ */
 bool MEDCouplingUMesh::checkConsecutiveCellTypes() const
 {
   const int *conn=_nodal_connec->getConstPointer();
@@ -1604,6 +1618,34 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const
   return true;
 }
 
+/*!
+ * This methods split this into as mush as untructured meshes that consecutive set of same type cells.
+ * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense.
+ * This method makes asumption (no check) that connectivity is correctly set before calling.
+ */
+std::vector<MEDCouplingUMesh *> MEDCouplingUMesh::splitByType() const
+{
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<MEDCouplingUMesh *> ret;
+  for(const int *i=connI;i!=connI+nbOfCells;)
+    {
+      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+      int startCellId=std::distance(connI,i);
+      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+      int endCellId=std::distance(connI,i);
+      int sz=endCellId-startCellId;
+      int *cells=new int[sz];
+      for(int j=0;j<sz;j++)
+        cells[j]=startCellId+j;
+      MEDCouplingUMesh *m=(MEDCouplingUMesh *)buildPartOfMySelf(cells,cells+sz,true);
+      delete [] cells;
+      ret.push_back(m);
+    }
+  return ret;
+}
+
 /*!
  * Returns a newly created mesh (with ref count ==1) that contains merge of 'this' and 'other'.
  */
index c4df6aa894cbf65d7fdfd0b1a35e89a264eb80ad..82fcd1f58845acc39f7aef012bad8a9ef05dd7ff 100644 (file)
@@ -69,6 +69,8 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testOperationsOnFields4 );
     CPPUNIT_TEST( testMergeNodesOnField );
     CPPUNIT_TEST( testCheckConsecutiveCellTypes );
+    CPPUNIT_TEST( testSplitByType );
+    CPPUNIT_TEST( testFuseUMeshesOnSameCoords );
     CPPUNIT_TEST( testBuildOrthogonalField );
     CPPUNIT_TEST( testGetCellsContainingPoint );
     CPPUNIT_TEST( testGetValueOn1 );
@@ -175,6 +177,8 @@ namespace ParaMEDMEM
     void testOperationsOnFields4();
     void testMergeNodesOnField();
     void testCheckConsecutiveCellTypes();
+    void testSplitByType();
+    void testFuseUMeshesOnSameCoords();
     void testBuildOrthogonalField();
     void testGetCellsContainingPoint();
     void testGetValueOn1();
index 45b7506c03c5ae8f2e5f1640a211c8a8eac6e5a5..18ce4fbdb9c9da362bd5d9da305e0a6bce27f400 100644 (file)
@@ -1761,6 +1761,81 @@ void MEDCouplingBasicsTest::testCheckConsecutiveCellTypes()
   sourceMesh->decrRef();
 }
 
+void MEDCouplingBasicsTest::testSplitByType()
+{
+  MEDCouplingUMesh *m1=build3DSurfTargetMesh_1();
+  std::vector<MEDCouplingUMesh *> v=m1->splitByType();
+  CPPUNIT_ASSERT_EQUAL(3,(int)v.size());
+  MEDCouplingUMesh *m2=MEDCouplingUMesh::mergeUMeshesOnSameCoords(v);
+  m2->setName(m1->getName());
+  CPPUNIT_ASSERT(m1->isEqual(m2,1.e-12));
+  for(std::vector<MEDCouplingUMesh *>::const_iterator iter=v.begin();iter!=v.end();iter++)
+    (*iter)->decrRef();
+  m2->decrRef();
+  m1->decrRef();
+}
+
+void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords()
+{
+  std::vector<MEDCouplingUMesh *> meshes;
+  MEDCouplingUMesh *m2=build2DTargetMesh_1();
+  int cells1[3]={2,3,4};
+  MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true);
+  MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1);
+  CPPUNIT_ASSERT(m3);
+  meshes.push_back(m3);
+  int cells2[3]={1,2,4};
+  MEDCouplingPointSet *m4_1=m2->buildPartOfMySelf(cells2,cells2+3,true);
+  MEDCouplingUMesh *m4=dynamic_cast<MEDCouplingUMesh *>(m4_1);
+  CPPUNIT_ASSERT(m4);
+  meshes.push_back(m4);
+  int cells3[2]={1,2};
+  MEDCouplingPointSet *m5_1=m2->buildPartOfMySelf(cells3,cells3+2,true);
+  MEDCouplingUMesh *m5=dynamic_cast<MEDCouplingUMesh *>(m5_1);
+  CPPUNIT_ASSERT(m5);
+  meshes.push_back(m5);
+  m2->decrRef();
+  //
+  std::vector<DataArrayInt *> corr;
+  MEDCouplingUMesh *m7=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr);
+  CPPUNIT_ASSERT_EQUAL(4,m7->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(3,(int)corr.size());
+  const int expectedVals1[3]={3,3,2};
+  const int expectedVals2[3][3]={{0,1,2},{3,0,2},{3,0,111111}};
+  for(int i=0;i<3;i++)
+    {
+      DataArrayInt *arr=corr[i];
+      CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents());
+      int nbOfVals=expectedVals1[i];
+      CPPUNIT_ASSERT_EQUAL(nbOfVals,arr->getNumberOfTuples());
+      const int *vals=arr->getConstPointer();
+      for(int j=0;j<nbOfVals;j++)
+        CPPUNIT_ASSERT_EQUAL(expectedVals2[i][j],vals[j]);
+    }
+  std::vector< std::vector<int> > fidsOfGroups;
+  DataArrayInt *arr2=DataArrayInt::makePartition(corr,m7->getNumberOfCells(),fidsOfGroups);
+  const int fidExp[4]={5,1,3,4};
+  const int fidsGrp[3][3]={{1,3,5},{3,4,5},{4,5,23344}};
+  CPPUNIT_ASSERT_EQUAL(3,(int)fidsOfGroups.size());
+  CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(fidExp,fidExp+4,arr2->getConstPointer()));
+  for(int i=0;i<3;i++)
+    {
+      int nbOfVals=expectedVals1[i];
+      CPPUNIT_ASSERT_EQUAL(nbOfVals,(int)fidsOfGroups[i].size());
+      CPPUNIT_ASSERT(std::equal(fidsOfGroups[i].begin(),fidsOfGroups[i].end(),fidsGrp[i]));
+    }
+  for(std::vector<DataArrayInt *>::iterator iter=corr.begin();iter!=corr.end();iter++)
+    (*iter)->decrRef();
+  arr2->decrRef();
+  m7->decrRef();
+  //
+  m3->decrRef();
+  m4->decrRef();
+  m5->decrRef();
+}
+
 void MEDCouplingBasicsTest::testBuildOrthogonalField()
 {
   MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1();