Salome HOME
For load balancing on // interpolation
authorageay <ageay>
Thu, 8 Aug 2013 10:08:34 +0000 (10:08 +0000)
committerageay <ageay>
Thu, 8 Aug 2013 10:08:34 +0000 (10:08 +0000)
- MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells
- DataArrayDouble::computeNbOfInteractionsWith
- DataArrayInt::splitInBalancedSlices

doc/doxygen/Doxyfile_med_user.in
src/INTERP_KERNEL/BBTree.txx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index 92b73ff7b6a58f27cd1727ce5daaa8bf54c18a5e..ca7b61bbdf8dfc85bbd1a6b82f87a0115c2bb2d8 100644 (file)
@@ -108,7 +108,7 @@ FILE_PATTERNS          = InterpKernelDEC.* \
                          ParaFIELD.* \
                          MEDCouplingMesh.* \
                          MEDCouplingUMesh.* \
-                         MEDCouplingUMeshDesc.* \
+                        MEDCoupling1GTUMesh.* \
                          MEDCouplingPointSet.* \
                          MEDCouplingCMesh.* \
                         MEDCouplingStructuredMesh.* \
index f977e24e3cb33a27e6c32be3c7c75308e0b67df7..212e43d78d51165fda293e52d58249d6a82098be 100644 (file)
@@ -194,6 +194,39 @@ public:
     _right->getIntersectingElems(bb,elems);
   }
 
+  /*!
+   * This method is very close to getIntersectingElems except that it returns number of elems instead of elems themselves.
+   */
+  int getNbOfIntersectingElems(const double* bb)
+  {
+    //  terminal node : return list of elements intersecting bb
+    int ret(0);
+    if (_terminal)
+      {
+        for (int i=0; i<_nbelems; i++)
+          {
+            const double* const  bb_ptr=_bb+_elems[i]*2*dim;
+            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)
+                  intersects=false;
+              }
+            if (intersects)
+              ret++;
+          }
+        return ret;
+      }
+    //non terminal node 
+    double min = bb[(_level%dim)*2];
+    double max = bb[(_level%dim)*2+1];
+    if (max < _min_right)
+      return _left->getNbOfIntersectingElems(bb);
+    if (min> _max_left)
+      return _right->getNbOfIntersectingElems(bb);
+    return _left->getNbOfIntersectingElems(bb)+_right->getNbOfIntersectingElems(bb);
+  }
+
  
   /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx
     \param xx pointer to query point coords
index 43c1d4866ac0838415acfe4d8b657b9f41ef6488..e96490c05902ab81504f25be836541ae9e1ba18b 100644 (file)
@@ -21,6 +21,7 @@
 #include "MEDCouplingMemArray.txx"
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
+#include "BBTree.txx"
 #include "GenMathFormulae.hxx"
 #include "InterpKernelExprParser.hxx"
 
@@ -2084,6 +2085,68 @@ DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other)
   return ret.retn();
 }
 
+/*!
+ * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
+ * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this
+ * how many bounding boxes in \a otherBBoxFrmt.
+ * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
+ *
+ * \param [in] otherBBoxFrmt - It is an array .
+ * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched.
+ * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
+ * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
+ * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
+ */
+DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception)
+{
+  if(!otherBBoxFrmt)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
+  if(!isAllocated() || !otherBBoxFrmt->isAllocated())
+    throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
+  int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
+  if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
+    {
+      std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(nbOfComp%2!=0)
+    {
+      std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
+  const double *thisBBPtr(begin());
+  int *retPtr(ret->getPointer());
+  switch(nbOfComp/2)
+    {
+    case 3:
+      {
+        BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
+        for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
+          *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
+        break;
+      }
+    case 2:
+      {
+        BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
+        for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
+          *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
+        break;
+      }
+    case 1:
+      {
+        BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
+        for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
+          *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
+        break;
+      }
+    defaut:
+      throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
+    }
+  
+  return ret.retn();
+}
+
 /*!
  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
  * considered as coordinates of a point in getNumberOfComponents()-dimensional
@@ -9843,6 +9906,38 @@ std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector
   return ret;
 }
 
+/*!
+ * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
+ * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
+ *
+ * \param [in] nbOfSlices - number of slices expected.
+ * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
+ * 
+ * \sa DataArray::GetSlice
+ * \throw If \a this is not allocated or not with exactly one component.
+ * \throw If an element in \a this if < 0.
+ */
+std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception)
+{
+  if(!isAllocated() || getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
+  if(nbOfSlices<=0)
+    throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
+  int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
+  int sumPerSlc(sum/nbOfSlices),pos(0);
+  const int *w(begin());
+  std::vector< std::pair<int,int> > ret(nbOfSlices);
+  for(int i=0;i<nbOfSlices;i++)
+    {
+      std::pair<int,int> p(pos,-1);
+      int locSum(0);
+      while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
+      p.second=pos;
+      ret[i]=p;
+    }
+  return ret;
+}
+
 /*!
  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
  * valid cases.
index 835fa35783f251d547cc320777e4a33c6e29cd6c..fa254c59c42ad54a8ad50c97f93ea08ba16324fb 100644 (file)
@@ -261,6 +261,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception);
@@ -579,6 +580,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *getDifferentValues() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT std::vector< std::pair<int,int> > splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception);
     template<class InputIterator>
index 961fb248ae519aea59adff548a442cc6d5e52aba..f216276c6c66bf1a23f73bccf30944f76fc775de 100644 (file)
@@ -1039,6 +1039,25 @@ void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect,
     }
 }
 
+/*!
+ * This method allows to give for each cell in \a trgMesh, how much it interacts with cells of \a srcMesh.
+ * The returned array can be seen as a weighted array on the target cells of \a trgMesh input parameter.
+ *
+ * \param [in] srcMesh - source mesh
+ * \param [in] trgMesh - target mesh
+ * \param [in] eps - precision of the detection
+ * \return DataArrayInt * - An array that gives for each cell of \a trgMesh, how many cells in \a srcMesh (regarding the precision of detection \a eps) can interacts.
+ * 
+ * \throw If \a srcMesh and \a trgMesh have not the same space dimension.
+ */
+DataArrayInt *MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) throw(INTERP_KERNEL::Exception)
+{
+  if(!srcMesh || !trgMesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells : the input meshes must be not NULL !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> sbbox(srcMesh->getBoundingBoxForBBTree()),tbbox(trgMesh->getBoundingBoxForBBTree());
+  return tbbox->computeNbOfInteractionsWith(sbbox,eps);
+}
+
 /*!
  * Creates a new MEDCouplingMesh containing a part of cells of \a this mesh. The new
  * mesh shares a coordinates array with \a this one. The cells to include to the
index 3faefb9b06e2d1b06576be3a97774540dc0fe33a..00d9a33b50d54fc769082bdbb09f521502cccf5a 100644 (file)
@@ -102,6 +102,7 @@ namespace ParaMEDMEM
     static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type);
     static void Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords);
     static void Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords);
+    static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) throw(INTERP_KERNEL::Exception);
     MEDCouplingMesh *buildPart(const int *start, const int *end) const;
     MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
     MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception);
index 49b1903c4e8d39c302baa1c2274aeb96180c3577..92bdc3a2a3a74cb96273a669a313d00bd62849d6 100644 (file)
@@ -352,6 +352,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart;
 %newobject ParaMEDMEM::DataArrayDouble::getDifferentValues;
 %newobject ParaMEDMEM::DataArrayDouble::findClosestTupleId;
+%newobject ParaMEDMEM::DataArrayDouble::computeNbOfInteractionsWith;
 %newobject ParaMEDMEM::DataArrayDouble::duplicateEachTupleNTimes;
 %newobject ParaMEDMEM::DataArrayDouble::__neg__;
 %newobject ParaMEDMEM::DataArrayDouble::__radd__;
@@ -395,6 +396,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingPointSet::getCellIdsLyingOnNodes;
 %newobject ParaMEDMEM::MEDCouplingPointSet::deepCpyConnectivityOnly;
 %newobject ParaMEDMEM::MEDCouplingPointSet::getBoundingBoxForBBTree;
+%newobject ParaMEDMEM::MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells;
 %newobject ParaMEDMEM::MEDCouplingPointSet::__getitem__;
 %newobject ParaMEDMEM::MEDCouplingUMesh::New;
 %newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivity;
@@ -1151,6 +1153,7 @@ namespace ParaMEDMEM
       virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
       static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception);
       static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception);
+      static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) throw(INTERP_KERNEL::Exception);
       virtual int getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception);
       virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const throw(INTERP_KERNEL::Exception);
       virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception);
index b86a95d2febd6b0c0478670389c104ff004cf748..65e159cbbb2b4760020082c0bd2e26b8a6c46a0f 100644 (file)
@@ -346,6 +346,7 @@ namespace ParaMEDMEM
     DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception);
+    DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception);
     void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception);
     void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception);
     void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception);
@@ -2559,6 +2560,15 @@ namespace ParaMEDMEM
         return self->accumulatePerChunck(bg,bg+sz);
       }
 
+      PyObject *splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::pair<int,int> > slcs(self->splitInBalancedSlices(nbOfSlices));
+        PyObject *ret=PyList_New(slcs.size());
+        for(std::size_t i=0;i<slcs.size();i++)
+          PyList_SetItem(ret,i,PySlice_New(PyInt_FromLong(slcs[i].first),PyInt_FromLong(slcs[i].second),PyInt_FromLong(1)));
+        return ret;
+      }
+
       DataArrayInt *buildExplicitArrOfSliceOnScaledArr(PyObject *slic) const throw(INTERP_KERNEL::Exception)
       {
         if(!PySlice_Check(slic))