]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
DataArrayDouble::findClosestTupleId (for Gauss<->Gauss interpolation)
authorageay <ageay>
Mon, 11 Mar 2013 16:23:32 +0000 (16:23 +0000)
committerageay <ageay>
Mon, 11 Mar 2013 16:23:32 +0000 (16:23 +0000)
src/INTERP_KERNEL/Interpolation.hxx
src/INTERP_KERNEL/Interpolation.txx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingRemapper.i

index 3c5eab1316e210bd112256f59b61b3e7aeec435f..92c38349d410debf0fbef124b4507b2fd151b4cc 100644 (file)
@@ -43,7 +43,7 @@ namespace INTERP_KERNEL
     int fromIntegralUniform(const MyMeshType& meshT, MatrixType& result, const char *method) { return fromToIntegralUniform(false,meshT,result,method); }
     template<class MyMeshType, class MatrixType>
     int toIntegralUniform(const MyMeshType& meshS, MatrixType& result, const char *method) { return fromToIntegralUniform(true,meshS,result,method); }
-    static void checkAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception);
+    static void CheckAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception);
     template<class MyMeshType>
     static double CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel);
   protected:
index 201b4467151a798485760407c4cb8cd89592386d..befbd4714995521bfd5d04bfbe95934c26ab96e0 100644 (file)
@@ -56,7 +56,7 @@ namespace INTERP_KERNEL
   }
 
   template<class TrueMainInterpolator>
-  void Interpolation<TrueMainInterpolator>::checkAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception)
+  void Interpolation<TrueMainInterpolator>::CheckAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception)
   {
     const int NB_OF_METH_MANAGED=4;
     const char *METH_MANAGED[NB_OF_METH_MANAGED]={"P0P0","P0P1","P1P0","P1P1"};
@@ -66,7 +66,7 @@ namespace INTERP_KERNEL
       found=(methodC==METH_MANAGED[i]);
     if(!found)
       {
-        std::string msg("The interpolation method : \'"); msg+=method; msg+="\' not managed !";
+        std::string msg("The interpolation method : \'"); msg+=method; msg+="\' not managed by INTERP_KERNEL interpolators ! Supported are \"P0P0\", \"P0P1\", \"P1P0\" and \"P1P1\".";
         throw INTERP_KERNEL::Exception(msg.c_str());
       }
     srcMeth=methodC.substr(0,2);
index 0bb80568bfb9d5f1647d4ef832604456fe63c3d0..04e3cff2a93c163815ce6e406a3dd63282951490 100644 (file)
@@ -84,6 +84,47 @@ void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTr
     }
 }
 
+template<int SPACEDIM>
+int DataArrayDouble::ComputeBasicClosestTupleIdAlg(const std::vector<int>& elems, const double *thisPt, const double *zePt)
+{
+  double val=std::numeric_limits<double>::max();
+  int ret=-1;
+  for(std::vector<int>::const_iterator it=elems.begin();it!=elems.end();it++)
+    {
+      double tmp=0.;
+      for(int j=0;j<SPACEDIM;j++) tmp+=thisPt[SPACEDIM*(*it)+j]-zePt[j];
+      if(tmp<val)
+        { val=tmp; ret=*it; }
+    }
+  return ret;
+}
+
+template<int SPACEDIM>
+void DataArrayDouble::FindClosestTupleIdAlg(const BBTree<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
+{
+  double distOpt(dist);
+  const double *p(pos);
+  int *r(res);
+  double bbox[2*SPACEDIM];
+  for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
+    {
+      double failVal(distOpt),okVal(std::numeric_limits<double>::max());
+      int nbOfTurn=15;
+      while(nbOfTurn>0)
+        {
+          for(int j=0;j<SPACEDIM;j++) { bbox[2*j]=p[j]-distOpt; bbox[2*j]=p[j]+distOpt; }
+          std::vector<int> elems;
+          myTree.getIntersectingElems(bbox,elems); nbOfTurn--;
+          if(elems.empty())
+            { failVal=distOpt; distOpt=okVal==std::numeric_limits<double>::max()?2*distOpt:(okVal+failVal)/2.; continue; }
+          if( elems.size()<=15 || nbOfTurn>0)
+            { *r=ComputeBasicClosestTupleIdAlg<SPACEDIM>(elems,thisPt,p); break; }
+          else
+            { okVal=distOpt; distOpt=(distOpt+failVal)/2.; continue; }
+        }
+    }
+}
+
 std::size_t DataArray::getHeapMemorySize() const
 {
   std::size_t sz1=_name.capacity();
@@ -1311,6 +1352,65 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const th
   return ret.retn();
 }
 
+/*!
+ * This methods returns for each tuple in \a other which tuple in \a this is the closest.
+ * So \a this and \a other have to have the same number of components.
+ *
+ * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
+ */
+DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
+{
+  if(!other)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
+  checkAllocated(); other->checkAllocated();
+  int nbOfCompo=getNumberOfComponents();
+  if(nbOfCompo!=other->getNumberOfComponents())
+    {
+      std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
+      oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbOfTuples=other->getNumberOfTuples();
+  int thisNbOfTuples=getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
+  double bounds[6];
+  getMinMaxPerComponent(bounds);
+  switch(nbOfCompo)
+    {
+    case 3:
+      {
+        double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
+        double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
+        double characSize=pow((delta*delta*delta)/thisNbOfTuples,1./3.);
+        MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(characSize*1e-12);
+        BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),characSize*1e-12);
+        FindClosestTupleIdAlg<3>(myTree,2.*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
+        break;
+      }
+    case 2:
+      {
+        double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
+        double delta=std::max(xDelta,yDelta);
+        double characSize=sqrt((delta*delta)/thisNbOfTuples);
+        MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(characSize*1e-12);
+        BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),characSize*1e-12);
+        FindClosestTupleIdAlg<2>(myTree,2.*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
+        break;
+      }
+    case 1:
+      {
+        double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
+        MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(characSize*1e-12);
+        BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),characSize*1e-12);
+        FindClosestTupleIdAlg<1>(myTree,2.*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
+    }
+  return ret.retn();
+}
+
 /*!
  * This method returns a newly allocated object the user should deal with.
  * This method works for arrays which have number of components into [1,2,3]. If not an exception will be thrown.
@@ -5345,13 +5445,11 @@ DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEn
   const int *cptr=getConstPointer();
   std::vector<int> res;
   int nbOfTuples=getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   for(int i=0;i<nbOfTuples;i++,cptr++)
     if(vals2.find(*cptr)!=vals2.end())
-      res.push_back(i);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)res.size(),1);
-  std::copy(res.begin(),res.end(),ret->getPointer());
-  return ret;
+      ret->pushBackSilent(i);
+  return ret.retn();
 }
 
 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
@@ -5362,13 +5460,11 @@ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *val
   const int *cptr=getConstPointer();
   std::vector<int> res;
   int nbOfTuples=getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   for(int i=0;i<nbOfTuples;i++,cptr++)
     if(vals2.find(*cptr)==vals2.end())
-      res.push_back(i);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)res.size(),1);
-  std::copy(res.begin(),res.end(),ret->getPointer());
-  return ret;
+      ret->pushBackSilent(i);
+  return ret.retn();
 }
 
 /*!
index e09e9e8c666c3fe47a033b96848980860acf339b..b7205f15f8821141103114a855f7ec6f2df5a003 100644 (file)
@@ -215,6 +215,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception);
     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 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);
@@ -316,6 +317,10 @@ namespace ParaMEDMEM
     template<int SPACEDIM>
     void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const;
     template<int SPACEDIM>
+    static void FindClosestTupleIdAlg(const BBTree<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res);
+    template<int SPACEDIM>
+    static int ComputeBasicClosestTupleIdAlg(const std::vector<int>& elems, const double *thisPt, const double *zePt);
+    template<int SPACEDIM>
     static void FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
                                           DataArrayInt *c, DataArrayInt *cI);
   private:
index 804e96ab04d7f9593bd12961014cd41be061a6a3..72ddf3688a6e5d0f449d84df73dd4e2bc4f6bb3c 100644 (file)
@@ -245,6 +245,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::DataArrayDouble::fromCylToCart;
 %newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart;
 %newobject ParaMEDMEM::DataArrayDouble::getDifferentValues;
+%newobject ParaMEDMEM::DataArrayDouble::findClosestTupleId;
 %newobject ParaMEDMEM::DataArrayDouble::duplicateEachTupleNTimes;
 %newobject ParaMEDMEM::DataArrayDouble::__neg__;
 %newobject ParaMEDMEM::DataArrayDouble::__add__;
index 3b2359a61f6b28cc6ccb3b5800093b5c7b9988bb..489c9e56515e00516eaefc189a6ddbcc34a0dff9 100644 (file)
@@ -42,6 +42,14 @@ using namespace INTERP_KERNEL;
 
 namespace ParaMEDMEM
 {
+  typedef enum
+    {
+      IK_ONLY_PREFERED = 0,
+      NOT_IK_ONLY_PREFERED = 1,
+      IK_ONLY_FORCED = 2,
+      NOT_IK_ONLY_FORCED =3
+    } InterpolationMatrixPolicy;
+
   class MEDCouplingRemapper : public TimeLabel, public INTERP_KERNEL::InterpolationOptions
     {
     private:
@@ -56,16 +64,18 @@ namespace ParaMEDMEM
       void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception);
       MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception);
       MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception);
-      bool setOptionInt(const std::string& key, int value);
-      bool setOptionDouble(const std::string& key, double value);
-      bool setOptionString(const std::string& key, const std::string& value);
+      bool setOptionInt(const std::string& key, int value) throw(INTERP_KERNEL::Exception);
+      bool setOptionDouble(const std::string& key, double value) throw(INTERP_KERNEL::Exception);
+      bool setOptionString(const std::string& key, const std::string& value) throw(INTERP_KERNEL::Exception);
+      int getInterpolationMatrixPolicy() const throw(INTERP_KERNEL::Exception);
+      void setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception);
       //
       int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) throw(INTERP_KERNEL::Exception);
       int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception);
       double getMaxValueInCrudeMatrix() const throw(INTERP_KERNEL::Exception);
       %extend
          {
-           PyObject *getCrudeMatrix() const
+           PyObject *getCrudeMatrix() const throw(INTERP_KERNEL::Exception)
            {
              const std::vector<std::map<int,double> >& m=self->getCrudeMatrix();
              std::size_t sz=m.size();