]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Improvement of perf of zipConnectivityTraducer. PostV660_2
authorageay <ageay>
Tue, 18 Dec 2012 09:15:37 +0000 (09:15 +0000)
committerageay <ageay>
Tue, 18 Dec 2012 09:15:37 +0000 (09:15 +0000)
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i

index 588456b089614a7b84612bef32587e592d77c6f1..5a0c387e2b19c27a0af85a5b8e71998c8c875634 100644 (file)
@@ -1408,63 +1408,6 @@ bool MEDCouplingUMesh::areCellsEqualInPool(const std::vector<int>& candidates, i
   return ret;
 }
 
-/*!
- * 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 startCellId, int compType, std::vector<int>& res, std::vector<int>& resI) const
-{
-  res.clear(); resI.clear();
-  resI.push_back(0);
-  std::vector<double> bbox;
-  int nbOfCells=getNumberOfCells();
-  getBoundingBoxForBBTree(bbox);
-  double bb[2*SPACEDIM];
-  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();
-  std::vector<bool> isFetched(nbOfCells);
-  for(int k=startCellId;k<nbOfCells;k++)
-    {
-      if(!isFetched[k])
-        {
-          for(int j=0;j<SPACEDIM;j++)
-            { bb[2*j]=std::numeric_limits<double>::max(); bb[2*j+1]=-std::numeric_limits<double>::max(); }
-          for(const int *pt=conn+connI[k]+1;pt!=conn+connI[k+1];pt++)
-            if(*pt>-1)
-              {
-                for(int j=0;j<SPACEDIM;j++)
-                  {
-                    bb[2*j]=std::min(bb[2*j],coords[SPACEDIM*(*pt)+j]);
-                    bb[2*j+1]=std::max(bb[2*j+1],coords[SPACEDIM*(*pt)+j]);
-                  }
-              }
-          std::vector<int> candidates1;
-          myTree.getIntersectingElems(bb,candidates1);
-          std::vector<int> candidates;
-          for(std::vector<int>::const_iterator iter=candidates1.begin();iter!=candidates1.end();iter++)
-            if(!isFetched[*iter])
-              candidates.push_back(*iter);
-          if(areCellsEqualInPool(candidates,compType,res))
-            {
-              int pos=resI.back();
-              resI.push_back((int)res.size());
-              for(std::vector<int>::const_iterator it=res.begin()+pos;it!=res.end();it++)
-                isFetched[*it]=true;
-            }
-          isFetched[k]=true;
-        }
-    }
-}
-
 /*!
  * This method find cells that are cells equal (regarding \a compType) in \a this. The comparison is specified by \a compType.
  * This method keeps the coordiantes of \a this. This method is time consuming and is called 
@@ -1476,16 +1419,17 @@ void MEDCouplingUMesh::findCommonCellsBase(int startCellId, int compType, std::v
  *   - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy
  * can be used for users not sensitive to orientation of cell
  * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned.
- * \param [out] newNbOfCells
+ * \param [out] commonCells
+ * \param [out] commonCellsI
  * \return the correspondance array old to new in a newly allocated array.
  * 
  */
-DataArrayInt *MEDCouplingUMesh::findEqualCells(int compType, int startCellId, int& newNbOfCells) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, std::vector<int>& commonCells, std::vector<int>& commonCellsI) const throw(INTERP_KERNEL::Exception)
 {
   checkConnectivityFullyDefined();
   int nbOfCells=getNumberOfCells();
-  std::vector<int> commonCells;
-  std::vector<int> commonCellsI(1,0);
+  commonCells.clear();
+  commonCellsI.resize(1); commonCellsI[0]=0;
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New();
   getReverseNodalConnectivity(revNodal,revNodalI);
   const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer();
@@ -1559,10 +1503,6 @@ DataArrayInt *MEDCouplingUMesh::findEqualCells(int compType, int startCellId, in
             }
         }
     }
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfCells,&commonCells[0],&commonCellsI[0],
-                                                                                                          &commonCellsI[0]+commonCellsI.size(),newNbOfCells);
-  ret->incrRef();
-  return ret;
 }
 
 /*!
@@ -1583,8 +1523,11 @@ DataArrayInt *MEDCouplingUMesh::findEqualCells(int compType, int startCellId, in
  */
 DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId) throw(INTERP_KERNEL::Exception)
 {
+  std::vector<int> commonCells,commonCellsI;
+  findCommonCells(compType,startCellId,commonCells,commonCellsI);
   int newNbOfCells=-1;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=findEqualCells(compType,startCellId,newNbOfCells);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),&commonCells[0],&commonCellsI[0],
+                                                                                                          &commonCellsI[0]+commonCellsI.size(),newNbOfCells);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2O(newNbOfCells);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> self=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(ret2->begin(),ret2->end(),true));
   setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true);
@@ -1607,6 +1550,14 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com
 {
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
   int nbOfCells=getNumberOfCells();
+  static const int possibleCompType[]={0,1,2};
+  if(std::find(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),compType)==possibleCompType+sizeof(possibleCompType)/sizeof(int))
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::areCellsIncludedIn : only following policies are possible : ";
+      std::copy(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),std::ostream_iterator<int>(oss," "));
+      oss << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=mesh->zipConnectivityTraducer(compType,nbOfCells);
   arr=o2n->substr(nbOfCells);
   arr->setName(other->getName());
@@ -1628,30 +1579,9 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com
 bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception)
 {
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
-  int spaceDim=mesh->getSpaceDimension();
-  std::vector<int> commonCells;
-  std::vector<int> commonCellsI;
+  std::vector<int> commonCells,commonCellsI;
   int thisNbCells=getNumberOfCells();
-  switch(spaceDim)
-    {
-    case 3:
-      {
-        findCommonCellsBase<3>(thisNbCells,7,commonCells,commonCellsI);
-        break;
-      }
-    case 2:
-      {
-        findCommonCellsBase<2>(thisNbCells,7,commonCells,commonCellsI);
-        break;
-      }
-    case 1:
-      {
-        findCommonCellsBase<1>(thisNbCells,7,commonCells,commonCellsI);
-        break;
-      }
-    default:
-      throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3.");
-    }
+  mesh->findCommonCells(7,thisNbCells,commonCells,commonCellsI);
   int otherNbCells=other->getNumberOfCells();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=DataArrayInt::New();
   arr2->alloc(otherNbCells,1);
index 4811eb6661a8feca1effd3302b0ef7444eb1b63b..1366374c232371df7eb420908b81912cb6922490 100644 (file)
@@ -109,7 +109,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT DataArrayInt *findEqualCells(int compType, int startCellId, int& newNbOfCells) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, std::vector<int>& commonCells, std::vector<int>& commonCellsI) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception);
@@ -252,8 +252,6 @@ namespace ParaMEDMEM
     DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception);
-    template<int SPACEDIM>
-    void findCommonCellsBase(int startCellId, int compType, std::vector<int>& res, std::vector<int>& resI) const;
     bool areCellsEqualInPool(const std::vector<int>& candidates, int compType, std::vector<int>& result) const;
     MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const;
     MEDCouplingUMesh *buildPartOfMySelfKeepCoords2(int start, int end, int step) const;
index 614141b6c63f9152b25afdec34cedbac4d606ecb..0a16344f461805d5c42a0d5485f6c412d6ca2f65 100644 (file)
@@ -5508,6 +5508,10 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(pt[1],tmp.getIJ(0,1));
         ret,tmp=m2.areCellsIncludedIn(m,0)
         self.assertTrue(not ret);
+        m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m,m2)
+        c,cI=m3.findCommonCells(2,m.getNumberOfCells())
+        self.assertTrue(c.isEqual(DataArrayInt([1,5,3,6])))
+        self.assertTrue(cI.isEqual(DataArrayInt([0,2,4])))
         pass
 
     def testSwigErrorProtection1(self):
index fdfbffe9f3ec15c0e617ec9c7609ec16644b2282..28f4071437401f92ec7c3fd1cc906d964c6440ef 100644 (file)
@@ -1677,13 +1677,16 @@ namespace ParaMEDMEM
         return res;
       }
 
-      PyObject *findEqualCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception)
+      PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception)
       {
-        int newNbOfCells=-1;
-        DataArrayInt *ret0=self->findEqualCells(compType,startCellId,newNbOfCells);
+        std::vector<int> v0,v1;
+        self->findCommonCells(compType,startCellId,v0,v1);
+        DataArrayInt *v0a=DataArrayInt::New(),*v1a=DataArrayInt::New();
+        v0a->alloc((int)v0.size(),1); std::copy(v0.begin(),v0.end(),v0a->getPointer());
+        v1a->alloc((int)v1.size(),1); std::copy(v1.begin(),v1.end(),v1a->getPointer());
         PyObject *res = PyList_New(2);
-        PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
-        PyList_SetItem(res,1,SWIG_From_int(newNbOfCells));
+        PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0a),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1a),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
         return res;
       }