Salome HOME
[EDF26877] : management of computation of measure field on field on Gauss Point in...
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.txx
index 750620d9a065bc28ee63268b70ae52c3d484ddad..0a0128161c97e2d1b14e8a8a604250f58dd9fe5f 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2021  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2022  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
@@ -4920,6 +4920,56 @@ struct NotInRange
         nc[nbOfCompo*i+compoIds[j]]=*ac;
   }
 
+  /*!
+   * This method searches each value in \a valToSearchIntoTuples among values in \a this given the corresponding tuple to find into.
+   * If the value at the corresponding tuple is not found in the tuple an exception will be thrown.
+   * If the value is found the corresponding component id is returned.
+   * 
+   *  \param [in] valToSearchIntoTuples - a one component array containing the values to find in \a this
+   *  \param [in] tupleIdHint - a one component array having same size than \a valToSearchIntoTuples giving for each value the tuple to find into
+   *  \return DataArrayInt * - A newly allocated array having same size than \a valToSearchIntoTuples with one component
+   * 
+   *   \b Example: <br>
+   *          - \a this: [(0, 1, 2), (3, 4, 5), (6, 2, 3), (7, 8, 9), (9, 0, 10), (11, 12, 13), (14, 5, 11), (15, 16, 17)]
+   *          - \a valToSearchIntoTuples: [1, 4, 6, 8, 10, 12, 14, 16, 17]
+   *          - \a tupleIdHint: [0, 1, 2, 3, 4, 5, 6, 7, 7]
+   *          - result array: [1, 1, 0, 1, 2, 1, 0, 1, 2] == <br>
+   */
+  template <class T>
+  DataArrayIdType *DataArrayDiscrete<T>::locateComponentId(const DataArrayType *valToSearchIntoTuples, const DataArrayIdType *tupleIdHint) const
+  {
+    if(!valToSearchIntoTuples || !tupleIdHint)
+      THROW_IK_EXCEPTION("DataArrayInt::locateComponentId : valToSearchIntoTuples and tupleIdHint must be not nullptr !");
+    valToSearchIntoTuples->checkAllocated(); tupleIdHint->checkAllocated();
+    this->checkAllocated();
+    constexpr char MSG1[] = "DataArrayInt::locateComponentId : single component array expected";
+    valToSearchIntoTuples->checkNbOfComps(1,MSG1); tupleIdHint->checkNbOfComps(1,MSG1);
+    std::size_t nbOfCompo( this->getNumberOfComponents() );
+    mcIdType thisNbTuples( this->getNumberOfTuples() );
+    mcIdType nbOfTuples( valToSearchIntoTuples->getNumberOfTuples() );
+    tupleIdHint->checkNbOfTuples(nbOfTuples,"Number of tuples of input arrays must be the same.");
+    const T *cPtr(this->begin()),*valSearchPt(valToSearchIntoTuples->begin());
+    const mcIdType *tHintPtr(tupleIdHint->begin());
+    MCAuto<DataArrayIdType> ret = DataArrayIdType::New();
+    ret->alloc(nbOfTuples,1);
+    mcIdType *retPtr(ret->getPointer());
+    for(auto i = 0 ; i < nbOfTuples ; ++i)
+    {
+      if( tHintPtr[i] >=0 && tHintPtr[i] < thisNbTuples )
+      {
+        auto strtSearch(cPtr+nbOfCompo*tHintPtr[i]),endSearch(cPtr+nbOfCompo*(tHintPtr[i]+1));
+        auto pos = std::find(strtSearch,endSearch,valSearchPt[i]);
+        if(pos != endSearch)
+          *retPtr++ = ToIdType( std::distance(strtSearch,pos) );
+        else
+          THROW_IK_EXCEPTION("At pos " << i << " value " << valSearchPt[i] << " is not present at tuple " << tHintPtr[i]);
+      }
+      else
+        THROW_IK_EXCEPTION("At pos " << i << " hint tuple is " << tHintPtr[i] << " not in [0," << thisNbTuples << ")");
+    }
+    return ret.retn();
+  }
+
   /*!
    * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
    * equal to a given one.
@@ -5866,7 +5916,7 @@ struct NotInRange
       throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
     std::size_t nbOfElements=this->getNumberOfTuples();
     if(nbOfElements<2)
-      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
+      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 2 tuples at least must be present in 'this' !");
     const T *ptr=this->getConstPointer();
     DataArrayType *ret=DataArrayType::New();
     ret->alloc(nbOfElements-1,1);
@@ -6248,7 +6298,7 @@ struct NotInRange
    *
    * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
    *
-   * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
+   * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortToHaveConsecutivePairs(), DataArrayInt::fromLinkedListOfPairToList
    */
   template <class T>
   void DataArrayDiscrete<T>::sortEachPairToMakeALinkedList()
@@ -6269,6 +6319,11 @@ struct NotInRange
                 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
                 throw INTERP_KERNEL::Exception(oss.str().c_str());
               }
+            if(conn[2]!=conn[1] && conn[3]!=conn[1])
+              {
+                std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : There is no common noeud between the tuple #" << i << " and the tuple #" << i + 1 << ". Need call DataArrayInt::sortToHaveConsecutivePairs() ";
+                throw INTERP_KERNEL::Exception(oss.str().c_str());
+              }
             if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
               std::swap(conn[2],conn[3]);
             //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
@@ -6307,6 +6362,57 @@ struct NotInRange
       }
   }
 
+  /*!
+   * This method is the improvement from the method sortEachPairToMakeALinkedList().
+   *
+   * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortEachPairToMakeALinkedList(), DataArrayInt::fromLinkedListOfPairToList
+   */
+  template <class T>
+  void DataArrayDiscrete<T>::sortToHaveConsecutivePairs()
+  {
+    this->checkAllocated();
+    if(this->getNumberOfComponents()!=2)
+      throw INTERP_KERNEL::Exception("DataArrayInt::sortToHaveConsecutivePairs : Only works on DataArrayInt instance with nb of components equal to 2 !");
+    mcIdType nbOfTuples(this->getNumberOfTuples());
+    T *thisPtr(this->getPointer());
+    mcIdType idOfLastTuple = 0;
+    std::pair<T*,T*> tmp;
+    if(thisPtr[0]==thisPtr[1])
+      {
+        THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the first tuple presence of a pair filled with same ids !");
+      }
+    while(idOfLastTuple < nbOfTuples-1)
+    {
+      mcIdType i = idOfLastTuple+1;
+      tmp.first = &thisPtr[2*i];
+      tmp.second = &thisPtr[2*i+1];
+      if(std::get<0>(tmp)[0] == std::get<1>(tmp)[0])
+        {
+          THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the tuple #" << i << " presence of a pair filled with same ids !");
+        }
+      while((this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0] &&
+            this->getIJ(idOfLastTuple,1) != std::get<1>(tmp)[0]) &&
+            i < nbOfTuples-1)
+        {
+          std::swap(std::get<0>(tmp)[0],thisPtr[2*(i+1)]);
+          std::swap(std::get<1>(tmp)[0],thisPtr[2*(i+1)+1]);
+          i++;
+        }
+      if(i < nbOfTuples-1 ||
+         this->getIJ(idOfLastTuple,1) == std::get<0>(tmp)[0] ||
+         this->getIJ(idOfLastTuple,1) == std::get<1>(tmp)[0])
+      {
+        if(this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0])
+          std::swap(std::get<0>(tmp)[0],std::get<1>(tmp)[0]);
+        idOfLastTuple++;
+      }
+      else
+      {
+        THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : not found the tuple which have the common noeud = " << this->getIJ(idOfLastTuple,1));
+      }
+    }
+  }
+
   /*!
    * \a this is expected to be a correctly linked list of pairs.
    *