]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Remapper takes advantage of implementation of MEDCouplingFieldDiscretizationOnNodesFE...
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 23 Aug 2022 15:05:35 +0000 (17:05 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 23 Aug 2022 15:05:35 +0000 (17:05 +0200)
src/MEDCoupling/MEDCouplingFieldDiscretizationOnNodesFE.cxx
src/MEDCoupling/MEDCouplingFieldDiscretizationOnNodesFE.hxx
src/MEDCoupling/MEDCouplingRemapper.cxx
src/MEDCoupling/MEDCouplingRemapper.hxx

index f769818e9841a33e42a2f95b44d97212b650178f..4e013891171af2edf1772f629e897f94ed9190dd 100755 (executable)
@@ -146,16 +146,46 @@ bool IsInside3D(const MEDCouplingGaussLocalization& gl, const std::vector<double
   return false;
 }
 
-void MEDCouplingFieldDiscretizationOnNodesFE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const
+void MEDCouplingFieldDiscretizationOnNodesFE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *ptsCoo, double *res) const
 {
-  MCAuto<DataArrayDouble> res2( this->getValueOnMulti(arr,mesh,loc,1) );
+  MCAuto<DataArrayDouble> res2( this->getValueOnMulti(arr,mesh,ptsCoo,1) );
   std::copy(res2->begin(),res2->end(),res);
 }
 
-/*void GetValueOnMulti()
+void MEDCouplingFieldDiscretizationOnNodesFE::GetRefCoordOfListOf3DPtsIn3D(const MEDCouplingUMesh *umesh, const double *ptsCoo, mcIdType nbOfPts,
+  std::function<void(const MEDCouplingGaussLocalization&, const std::vector<mcIdType>&)> customFunc)
 {
-
-}*/
+  const double *coordsOfMesh( umesh->getCoords()->begin() );
+  MEDCouplingNormalizedUnstructuredMesh<3,3> mesh_wrapper(umesh);
+  BBTreeStandAlone<3,mcIdType> tree( INTERP_KERNEL::BuildBBTree( mesh_wrapper ) );
+  for(mcIdType iPt = 0 ; iPt < nbOfPts ; ++iPt)
+  {
+    std::vector<mcIdType> elems;
+    tree.getElementsAroundPoint(ptsCoo+3*iPt,elems);
+    bool found(false);
+    for(auto cellId = elems.cbegin() ; cellId != elems.cend() && !found ; ++cellId)
+    {
+      INTERP_KERNEL::NormalizedCellType gt( umesh->getTypeOfCell(*cellId) );
+      std::vector<mcIdType> conn;
+      umesh->getNodeIdsOfCell(*cellId,conn);
+      MCAuto<DataArrayDouble> refCoo( MEDCouplingGaussLocalization::GetDefaultReferenceCoordinatesOf(gt) );
+      std::vector<double> refCooCpp(refCoo->begin(),refCoo->end());
+      std::vector<double> gsCoo(ptsCoo + iPt*3,ptsCoo + (iPt+1)*3); 
+      MEDCouplingGaussLocalization gl(gt,refCooCpp,{0,0,0},{1.});
+      std::vector<double> ptsInCell; ptsInCell.reserve(conn.size()*gl.getDimension());
+      std::for_each( conn.cbegin(), conn.cend(), [coordsOfMesh,&ptsInCell](mcIdType c) { ptsInCell.insert(ptsInCell.end(),coordsOfMesh+c*3,coordsOfMesh+(c+1)*3); } );
+      std::vector<double> locInRef(3);
+      if( IsInside3D(gl,ptsInCell,gsCoo.data(),locInRef.data()) )
+      {
+        gl.setGaussCoords(locInRef);
+        customFunc(gl,conn);
+        found = true;
+      }
+    }
+    if(!found)
+      THROW_IK_EXCEPTION("getValueOnMulti on MEDCouplingFieldDiscretizationOnNodesFE : fail to locate point #" << iPt << " X=" << ptsCoo[0] << " Y=" << ptsCoo[1] << " Z=" << ptsCoo[2] << " !");
+  }
+}
 
 DataArrayDouble *MEDCouplingFieldDiscretizationOnNodesFE::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, mcIdType nbOfTargetPoints) const
 {
@@ -176,46 +206,24 @@ DataArrayDouble *MEDCouplingFieldDiscretizationOnNodesFE::getValueOnMulti(const
   std::size_t nbCompo( arr->getNumberOfComponents() );
   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
   ret->alloc(nbOfTargetPoints,nbCompo);
-  const double *coordsOfMesh( umesh->getCoords()->begin() );
-  MEDCouplingNormalizedUnstructuredMesh<3,3> mesh_wrapper(umesh);
-  BBTreeStandAlone<3,mcIdType> tree( INTERP_KERNEL::BuildBBTree( mesh_wrapper ) );
   double *res( ret->getPointer() );
-  for(mcIdType iPt = 0 ; iPt < nbOfTargetPoints ; ++iPt, res+=nbCompo )
+
+  auto arrayFeeder = [arr,&res,nbCompo](const MEDCouplingGaussLocalization& gl, const std::vector<mcIdType>& conn)
   {
-    std::vector<mcIdType> elems;
-    tree.getElementsAroundPoint(loc+3*iPt,elems);
-    bool found(false);
-    for(auto cellId = elems.cbegin() ; cellId != elems.cend() && !found ; ++cellId)
+    MCAuto<DataArrayDouble> resVector( gl.getShapeFunctionValues() );
     {
-      INTERP_KERNEL::NormalizedCellType gt( umesh->getTypeOfCell(*cellId) );
-      std::vector<mcIdType> conn;
-      umesh->getNodeIdsOfCell(*cellId,conn);
-      MCAuto<DataArrayDouble> refCoo( MEDCouplingGaussLocalization::GetDefaultReferenceCoordinatesOf(gt) );
-      std::vector<double> refCooCpp(refCoo->begin(),refCoo->end());
-      std::vector<double> gsCoo(loc + iPt*3,loc + (iPt+1)*3); 
-      MEDCouplingGaussLocalization gl(gt,refCooCpp,{0,0,0},{1.});
-      std::vector<double> ptsInCell; ptsInCell.reserve(conn.size()*gl.getDimension());
-      std::for_each( conn.cbegin(), conn.cend(), [coordsOfMesh,&ptsInCell](mcIdType c) { ptsInCell.insert(ptsInCell.end(),coordsOfMesh+c*3,coordsOfMesh+(c+1)*3); } );
-      std::vector<double> locInRef(3);
-      if( IsInside3D(gl,ptsInCell,gsCoo.data(),locInRef.data()) )
-      {
-        gl.setGaussCoords(locInRef);
-        MCAuto<DataArrayDouble> resVector( gl.getShapeFunctionValues() );
+      std::for_each(res,res+nbCompo,[](double& v) { v = 0.0; });
+      for(std::size_t iComp = 0 ; iComp < nbCompo ; ++iComp)
+        for(int iPt = 0 ; iPt < gl.getNumberOfPtsInRefCell(); ++iPt)
         {
-          std::for_each(res,res+nbCompo,[](double& v) { v = 0.0; });
-          for(std::size_t iComp = 0 ; iComp < nbCompo ; ++iComp)
-            for(int iPt = 0 ; iPt < gl.getNumberOfPtsInRefCell(); ++iPt)
-            {
-              {
-                res[iComp] += resVector->getIJ(0,iPt) * arr->getIJ(conn[iPt],iComp);
-              }
-            }
+          {
+            res[iComp] += resVector->getIJ(0,iPt) * arr->getIJ(conn[iPt],iComp);
+          }
         }
-        found = true;
-      }
+      res += nbCompo;
     }
-    if(!found)
-      THROW_IK_EXCEPTION("getValueOnMulti on MEDCouplingFieldDiscretizationOnNodesFE : fail to locate point #" << iPt << " X=" << loc[0] << " Y=" << loc[1] << " Z=" << loc[2] << " !");
-  }
+  };
+
+  GetRefCoordOfListOf3DPtsIn3D(umesh,loc,nbOfTargetPoints,arrayFeeder);
   return ret.retn();
 }
index 04559381b65a917fd9bc548fdaa79756adc594e3..3aa28072b5fb6ca099c0110a0f9943cd5d9a212e 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "MEDCouplingFieldDiscretization.hxx"
 
+#include <functional>
+
 namespace MEDCoupling
 {
   /*!
@@ -42,6 +44,9 @@ namespace MEDCoupling
       MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const override;
       MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const override;
       MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, mcIdType nbOfPoints) const override;
+    public:
+      MEDCOUPLING_EXPORT static void GetRefCoordOfListOf3DPtsIn3D(const MEDCouplingUMesh *umesh, const double *ptsCoo, mcIdType nbOfPts,
+  std::function<void(const MEDCouplingGaussLocalization&, const std::vector<mcIdType>&)> customFunc);
     public:
       static const char REPR[];
       static constexpr TypeOfField TYPE = ON_NODES_FE;
index c85f44ccceaea60876eb798983a895d85abf40c8..231f29bba6d4906dd59c30e3a39c842bf4e1c5f8 100755 (executable)
@@ -27,6 +27,7 @@
 #include "MEDCouplingCMesh.hxx"
 #include "MEDCouplingNormalizedUnstructuredMesh.txx"
 #include "MEDCouplingNormalizedCartesianMesh.txx"
+#include "MEDCouplingFieldDiscretizationOnNodesFE.hxx"
 
 #include "Interpolation1D.txx"
 #include "Interpolation2DCurve.hxx"
@@ -123,10 +124,7 @@ void MEDCouplingRemapper::setCrudeMatrixEx(const MEDCouplingFieldTemplate *src,
         }
     }
   _matrix=m;
-  _deno_multiply.clear();
-  _deno_multiply.resize(_matrix.size());
-  _deno_reverse_multiply.clear();
-  _deno_reverse_multiply.resize(srcNbElem);
+  synchronizeSizeOfSideMatricesAfterMatrixComputation(srcNbElem);
 }
 
 int MEDCouplingRemapper::prepareInterpKernelOnly()
@@ -691,11 +689,7 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUU()
     }
   else
     throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension");
-  _deno_multiply.clear();
-  _deno_multiply.resize(_matrix.size());
-  _deno_reverse_multiply.clear();
-  _deno_reverse_multiply.resize(nbCols);
-  declareAsNew();
+  synchronizeSizeOfSideMatricesAfterMatrixComputation(nbCols);
   return 1;
 }
 
@@ -729,11 +723,7 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyEE()
   buildFinalInterpolationMatrixByConvolution(matrix1D,matrix2D,src_mesh->getMesh3DIds()->getConstPointer(),nbCols2D,nbCols1D,
                                              target_mesh->getMesh3DIds()->getConstPointer());
   //
-  _deno_multiply.clear();
-  _deno_multiply.resize(_matrix.size());
-  _deno_reverse_multiply.clear();
-  _deno_reverse_multiply.resize(nbCols2D*nbCols1D);
-  declareAsNew();
+  synchronizeSizeOfSideMatricesAfterMatrixComputation(nbCols2D*nbCols1D);
   return 1;
 }
 
@@ -785,11 +775,7 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUC()
   ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix);
   nullifiedTinyCoeffInCrudeMatrixAbs(0.);
   //
-  _deno_multiply.clear();
-  _deno_multiply.resize(_matrix.size());
-  _deno_reverse_multiply.clear();
-  _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
-  declareAsNew();
+  synchronizeSizeOfSideMatricesAfterMatrixComputation(src_mesh->getNumberOfCells());
   return 1;
 }
 
@@ -839,11 +825,7 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyCU()
   }
   nullifiedTinyCoeffInCrudeMatrixAbs(0.);
   //
-  _deno_multiply.clear();
-  _deno_multiply.resize(_matrix.size());
-  _deno_reverse_multiply.clear();
-  _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
-  declareAsNew();
+  synchronizeSizeOfSideMatricesAfterMatrixComputation(src_mesh->getNumberOfCells());
   return 1;
 }
 
@@ -892,11 +874,7 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyCC()
   }
   nullifiedTinyCoeffInCrudeMatrixAbs(0.);
   //
-  _deno_multiply.clear();
-  _deno_multiply.resize(_matrix.size());
-  _deno_reverse_multiply.clear();
-  _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
-  declareAsNew();
+  synchronizeSizeOfSideMatricesAfterMatrixComputation(src_mesh->getNumberOfCells());
   return 1;
 }
 
@@ -951,11 +929,7 @@ int MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss()
       for(const mcIdType *orphanTrgId=orphanTrgIds->begin();orphanTrgId!=orphanTrgIds->end();orphanTrgId++,srcIdPerTrgPtr++)
         _matrix[*orphanTrgId][*srcIdPerTrgPtr]=2.;
     }
-  _deno_multiply.clear();
-  _deno_multiply.resize(_matrix.size());
-  _deno_reverse_multiply.clear();
-  _deno_reverse_multiply.resize(srcLoc->getNumberOfTuples());
-  declareAsNew();
+  synchronizeSizeOfSideMatricesAfterMatrixComputation( srcLoc->getNumberOfTuples() );
   return 1;
 }
 
@@ -969,8 +943,29 @@ int MEDCouplingRemapper::prepareNotInterpKernelOnlyFEFE()
     THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only spacedim 3 supported for target !")
   if(_src_ft->getMesh()->getSpaceDimension() != 3)
     THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only spacedim 3 supported for source !")
-  
-  declareAsNew();
+  const MEDCouplingUMesh *srcUMesh( dynamic_cast<const MEDCouplingUMesh *>(_src_ft->getMesh()) );
+  const MEDCouplingPointSet *trgMesh( dynamic_cast<const MEDCouplingPointSet *>(_target_ft->getMesh()) );
+  if( !srcUMesh )
+    THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only 3D UMesh supported as source !");
+  if( !trgMesh )
+    THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only 3D PointSet mesh supported as target !");
+
+  _matrix.clear();
+  _matrix.resize(trgMesh->getNumberOfNodes());
+  mcIdType rowId(0);
+
+  auto matrixFeeder = [this,&rowId](const MEDCouplingGaussLocalization& gl, const std::vector<mcIdType>& conn)
+  {
+    auto& row = this->_matrix[rowId++];
+    MCAuto<DataArrayDouble> resVector( gl.getShapeFunctionValues() );
+    for(int iPt = 0 ; iPt < gl.getNumberOfPtsInRefCell(); ++iPt)
+    {
+      row[ conn[iPt] ] = resVector->getIJ(0,iPt);
+    }
+  };
+
+  MEDCouplingFieldDiscretizationOnNodesFE::GetRefCoordOfListOf3DPtsIn3D(srcUMesh,trgMesh->getCoords()->begin(),trgMesh->getNumberOfNodes(),matrixFeeder);
+  synchronizeSizeOfSideMatricesAfterMatrixComputation( srcUMesh->getNumberOfNodes() );
   return 1;
 }
 
@@ -1048,6 +1043,15 @@ void MEDCouplingRemapper::checkPrepare() const
     throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that no all field templates have their mesh set !");
 }
 
+void MEDCouplingRemapper::synchronizeSizeOfSideMatricesAfterMatrixComputation(mcIdType nbOfColsInMatrix)
+{
+  _deno_multiply.clear();
+  _deno_multiply.resize(_matrix.size());
+  _deno_reverse_multiply.clear();
+  _deno_reverse_multiply.resize(nbOfColsInMatrix);
+  declareAsNew();
+}
+
 /*!
  * This method builds a code considering already set field discretization int \a this : \a _src_ft and \a _target_ft.
  * This method returns 3 information (2 in output parameters and 1 in return).
index 2acdafea1b183c0d7cb47c5917013543da6fa26e..23bf893b3e1ad500313e362f2939a5d03a85bafd 100644 (file)
@@ -96,6 +96,7 @@ namespace MEDCoupling
     bool isInterpKernelOnlyOrNotOnly() const;
     void updateTime() const;
     void checkPrepare() const;
+    void synchronizeSizeOfSideMatricesAfterMatrixComputation(mcIdType nbOfColsInMatrix);
     std::string checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const;
     void releaseData(bool matrixSuppression);
     void restartUsing(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target);