Salome HOME
Make it compile with intel compiler into int64 mode
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMesh.cxx
index b764904fee4c0823f8c1fea2ba7542b27b4b679c..c22552bae39dff82cae00b8db7b5903495102537 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2020  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -1695,9 +1695,11 @@ int MEDCouplingUMesh::AreCellsEqualPolicy7(const mcIdType *conn, const mcIdType
 
 
 /*!
- * This method find cells that are 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.
+ * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified by \a compType (see zipConnectivityTraducer).
+ * This method keeps the coordinates of \a this. The comparison starts at rank \a startCellId cell id (included).
+ * If \a startCellId is equal to 0 algorithm starts at cell #0 and for each cell candidates being searched have cell id higher than current cellId.
+ * If \a startCellId is greater than 0 algorithm starts at cell #startCellId but for each cell all candidates are considered.
+ * This method is time consuming.
  *
  * \param [in] compType input specifying the technique used to compare cells each other.
  *   - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy.
@@ -1729,7 +1731,7 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, mcIdType startCellId, co
   std::vector<bool> isFetched(nbOfCells,false);
   if(startCellId==0)
     {
-      for(mcIdType i=0;i<nbOfCells;i++)
+      for(mcIdType i=startCellId;i<nbOfCells;i++)
         {
           if(!isFetched[i])
             {
@@ -1769,6 +1771,7 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, mcIdType startCellId, co
           if(!isFetched[i])
             {
               const mcIdType *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<mcIdType>(),-1));
+              // v2 contains the result of successive intersections using rev nodal on on each node of cell #i
               std::vector<mcIdType> v,v2;
               if(connOfNode!=connPtr+connIPtr[i+1])
                 {
@@ -1782,12 +1785,20 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, mcIdType startCellId, co
                     std::vector<mcIdType>::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin());
                     v2.resize(std::distance(v2.begin(),it));
                   }
+              // v2 contains now candidates. Problem candidates are sorted using id rank.
               if(v2.size()>1)
                 {
+                  if(v2[0]!=i)
+                  {
+                    auto it(std::find(v2.begin(),v2.end(),i));
+                    std::swap(*v2.begin(),*it);
+                  }
                   if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells))
                     {
-                      mcIdType pos=commonCellsI->back();
-                      commonCellsI->pushBackSilent(commonCells->getNumberOfTuples());
+                      mcIdType newPos(commonCells->getNumberOfTuples());
+                      mcIdType pos(commonCellsI->back());
+                      std::sort(commonCells->getPointerSilent()+pos,commonCells->getPointerSilent()+newPos);
+                      commonCellsI->pushBackSilent(newPos);
                       for(const mcIdType *it=commonCells->begin()+pos;it!=commonCells->end();it++)
                         isFetched[*it]=true;
                     }
@@ -1835,13 +1846,30 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com
       oss << " !";
       throw INTERP_KERNEL::Exception(oss.str());
     }
-  MCAuto<DataArrayIdType> o2n=mesh->zipConnectivityTraducer(compType,nbOfCells);
-  arr=o2n->subArray(nbOfCells);
-  arr->setName(other->getName());
-  mcIdType tmp;
+  //
   if(other->getNumberOfCells()==0)
+  {
+    MCAuto<DataArrayIdType> dftRet(DataArrayIdType::New()); dftRet->alloc(0,1); arr=dftRet.retn(); arr->setName(other->getName());
     return true;
-  return arr->getMaxValue(tmp)<nbOfCells;
+  }
+  DataArrayIdType *commonCells(nullptr),*commonCellsI(nullptr);
+  mesh->findCommonCells(compType,nbOfCells,commonCells,commonCellsI);
+  MCAuto<DataArrayIdType> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
+  mcIdType newNbOfCells=-1;
+  MCAuto<DataArrayIdType> o2n = DataArrayIdType::ConvertIndexArrayToO2N(ToIdType(mesh->getNumberOfCells()),commonCells->begin(),commonCellsI->begin(),commonCellsI->end(),newNbOfCells);
+  MCAuto<DataArrayIdType> p0(o2n->selectByTupleIdSafeSlice(0,nbOfCells,1));
+  mcIdType maxPart(p0->getMaxValueInArray());
+  bool ret(maxPart==newNbOfCells-1);
+  MCAuto<DataArrayIdType> p1(p0->invertArrayO2N2N2O(newNbOfCells));
+  // fill p1 array in case of presence of cells in other not in this
+  mcIdType *pt(p1->getPointer());
+  for(mcIdType i = maxPart ; i < newNbOfCells-1 ; ++i )
+    pt[i+1] = i+1;
+  //
+  MCAuto<DataArrayIdType> p2(o2n->subArray(nbOfCells));
+  p2->transformWithIndArr(p1->begin(),p1->end()); p2->setName(other->getName());
+  arr = p2.retn();
+  return ret;
 }
 
 /*!