Nektar++
Classes | Public Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
Nektar::LibUtilities::Interpolator Class Reference

A class that contains algorithms for interpolation between pts fields, expansions and different meshes. More...

#include <Interpolator.h>

Inheritance diagram for Nektar::LibUtilities::Interpolator:
[legend]

Classes

class  PtsPoint
 

Public Member Functions

 Interpolator (InterpMethod method=eNoMethod, short int coordId=-1, NekDouble filtWidth=0.0, int maxPts=1000)
 Constructor of the Interpolator class. More...
 
void CalcWeights (const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField, bool reuseTree=false)
 Compute interpolation weights without doing any interpolation. More...
 
void Interpolate (const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
 Interpolate from a pts field to a pts field. More...
 
int GetDim () const
 returns the dimension of the Interpolator. Should be higher than the dimensions of the interpolated fields More...
 
NekDouble GetFiltWidth () const
 Returns the filter width. More...
 
int GetCoordId () const
 Returns the coordinate id along which the interpolation should be performed. More...
 
InterpMethod GetInterpMethod () const
 Returns the interpolation method used by this interpolator. More...
 
LibUtilities::PtsFieldSharedPtr GetInField () const
 Returns the input field. More...
 
LibUtilities::PtsFieldSharedPtr GetOutField () const
 Returns the output field. More...
 
void PrintStatistics ()
 Returns if the weights have already been computed. More...
 
template<typename FuncPointerT , typename ObjectPointerT >
void SetProgressCallback (FuncPointerT func, ObjectPointerT obj)
 sets a callback funtion which gets called every time the interpolation progresses More...
 

Protected Attributes

LibUtilities::PtsFieldSharedPtr m_ptsInField
 input field More...
 
LibUtilities::PtsFieldSharedPtr m_ptsOutField
 output field More...
 
std::function< void(const int position, const int goal)> m_progressCallback
 

Private Types

typedef boost::geometry::model::point< NekDouble, m_dim, boost::geometry::cs::cartesian > BPoint
 
typedef std::pair< BPoint, unsigned int > PtsPointPair
 
typedef boost::geometry::index::rtree< PtsPointPair, boost::geometry::index::rstar< 16 > > PtsRtree
 

Private Member Functions

void CalcW_Gauss (const PtsPoint &searchPt, const NekDouble sigma, const int maxPts=250)
 Computes interpolation weights using gaussian interpolation. More...
 
void CalcW_Linear (const PtsPoint &searchPt, int coordId)
 Computes interpolation weights using linear interpolation. More...
 
void CalcW_NNeighbour (const PtsPoint &searchPt)
 Computes interpolation weights using nearest neighbour interpolation. More...
 
void CalcW_Shepard (const PtsPoint &searchPt, int numPts)
 Computes interpolation weights using linear interpolation. More...
 
void CalcW_Quadratic (const PtsPoint &searchPt, int coordId)
 Computes interpolation weights using quadratic interpolation. More...
 
void SetupTree ()
 
void FindNeighbours (const PtsPoint &searchPt, std::vector< PtsPoint > &neighbourPts, const NekDouble dist, const unsigned int maxPts=1)
 Finds the neares neighbours of a point. More...
 
void FindNNeighbours (const PtsPoint &searchPt, std::vector< PtsPoint > &neighbourPts, const unsigned int numPts=1)
 Finds the neares neighbours of a point. More...
 

Private Attributes

InterpMethod m_method
 Interpolation Method. More...
 
std::shared_ptr< PtsRtreem_rtree
 A tree structure to speed up the neighbour search. Note that we fill it with an iterator, so instead of rstar, the packing algorithm is used. More...
 
Array< TwoD, NekDoublem_weights
 Interpolation weights for each neighbour. Structure: m_weights[physPtIdx][neighbourIdx]. More...
 
Array< TwoD, unsigned int > m_neighInds
 Indices of the relevant neighbours for each physical point. Structure: m_neighInds[ptIdx][neighbourIdx]. More...
 
NekDouble m_filtWidth
 Filter width used for some interpolation algorithms. More...
 
int m_maxPts
 Max number of interpolation points. More...
 
short int m_coordId
 coordinate id along which the interpolation should be performed More...
 

Static Private Attributes

static const int m_dim = 3
 dimension of this interpolator. Hardcoded to 3 More...
 

Detailed Description

A class that contains algorithms for interpolation between pts fields, expansions and different meshes.

Definition at line 70 of file LibUtilities/BasicUtils/Interpolator.h.

Member Typedef Documentation

◆ BPoint

typedef boost::geometry::model::point<NekDouble, m_dim, boost::geometry::cs::cartesian> Nektar::LibUtilities::Interpolator::BPoint
private

Definition at line 175 of file LibUtilities/BasicUtils/Interpolator.h.

◆ PtsPointPair

typedef std::pair<BPoint, unsigned int> Nektar::LibUtilities::Interpolator::PtsPointPair
private

Definition at line 176 of file LibUtilities/BasicUtils/Interpolator.h.

◆ PtsRtree

typedef boost::geometry::index::rtree<PtsPointPair, boost::geometry::index::rstar<16> > Nektar::LibUtilities::Interpolator::PtsRtree
private

Definition at line 177 of file LibUtilities/BasicUtils/Interpolator.h.

Constructor & Destructor Documentation

◆ Interpolator()

Nektar::LibUtilities::Interpolator::Interpolator ( InterpMethod  method = eNoMethod,
short int  coordId = -1,
NekDouble  filtWidth = 0.0,
int  maxPts = 1000 
)
inline

Constructor of the Interpolator class.

Parameters
methodinterpolation method, defaults to a sensible value if not set
coordIdcoordinate id along which the interpolation should be performed
filtWidthfilter width, required by some algorithms such as eGauss
maxPtslimit number of considered points

if method is not specified, the best algorithm is chosen autpomatically.

If coordId is not specified, a full 1D/2D/3D interpolation is performed without collapsing any coordinate.

filtWidth must be specified for the eGauss algorithm only.

Definition at line 91 of file LibUtilities/BasicUtils/Interpolator.h.

95  : m_method(method), m_filtWidth(filtWidth), m_maxPts(maxPts),
96  m_coordId(coordId)
97  {
98  }
int m_maxPts
Max number of interpolation points.
NekDouble m_filtWidth
Filter width used for some interpolation algorithms.
short int m_coordId
coordinate id along which the interpolation should be performed

Member Function Documentation

◆ CalcW_Gauss()

void Nektar::LibUtilities::Interpolator::CalcW_Gauss ( const PtsPoint searchPt,
const NekDouble  sigma,
const int  maxPts = 250 
)
private

Computes interpolation weights using gaussian interpolation.

Parameters
searchPtpoint for which the weights are computed
sigmastandard deviation of the gauss function

Performs an interpolation using gauss weighting. Ideal for filtering fields. The filter width should be half the FWHM (= 1.1774 sigma) and must be set in the constructor of the Interpolator class.

Definition at line 348 of file LibUtilities/BasicUtils/Interpolator.cpp.

351 {
352  // find nearest neighbours
353  vector<PtsPoint> neighbourPts;
354  FindNeighbours(searchPt, neighbourPts, 4 * sigma, maxPts);
355  size_t numPts = neighbourPts.size();
356 
357  // handle the cases that there was no or just one point within 4 * sigma
358  if (numPts == 0)
359  {
360  return;
361  }
362  if (numPts == 1)
363  {
364  m_neighInds[searchPt.idx][0] = neighbourPts.front().idx;
365  m_weights[searchPt.idx][0] = 1.0;
366 
367  return;
368  }
369 
370  NekDouble sigmaNew = 0.25 * neighbourPts.back().dist;
371 
372  for (size_t i = 0; i < numPts; i++)
373  {
374  m_neighInds[searchPt.idx][i] = neighbourPts.at(i).idx;
375  }
376 
377  NekDouble wSum = 0.0;
378  NekDouble ts2 = 2.0 * sigmaNew * sigmaNew;
379  for (size_t i = 0; i < numPts; ++i)
380  {
381  m_weights[searchPt.idx][i] =
382  exp(-1.0 * neighbourPts[i].dist * neighbourPts[i].dist / ts2);
383  wSum += m_weights[searchPt.idx][i];
384  }
385 
386  for (size_t i = 0; i < numPts; ++i)
387  {
388  m_weights[searchPt.idx][i] = m_weights[searchPt.idx][i] / wSum;
389  }
390 }
Array< TwoD, NekDouble > m_weights
Interpolation weights for each neighbour. Structure: m_weights[physPtIdx][neighbourIdx].
Array< TwoD, unsigned int > m_neighInds
Indices of the relevant neighbours for each physical point. Structure: m_neighInds[ptIdx][neighbourId...
void FindNeighbours(const PtsPoint &searchPt, std::vector< PtsPoint > &neighbourPts, const NekDouble dist, const unsigned int maxPts=1)
Finds the neares neighbours of a point.
double NekDouble

References Nektar::LibUtilities::Interpolator::PtsPoint::idx.

◆ CalcW_Linear()

void Nektar::LibUtilities::Interpolator::CalcW_Linear ( const PtsPoint searchPt,
int  m_coordId 
)
private

Computes interpolation weights using linear interpolation.

Parameters
searchPtpoint for which the weights are computed
m_coordIdcoordinate id along which the interpolation should be performed

Currently, only implemented for 1D

Definition at line 401 of file LibUtilities/BasicUtils/Interpolator.cpp.

402 {
403  int npts = m_ptsInField->GetNpoints();
404  int i;
405 
406  NekDouble coord = searchPt.coords[m_coordId];
407 
408  for (i = 0; i < npts - 1; ++i)
409  {
410  if ((m_ptsInField->GetPointVal(0, i) <=
411  (coord + NekConstants::kNekZeroTol)) &&
412  (coord <=
413  (m_ptsInField->GetPointVal(0, i + 1) + NekConstants::kNekZeroTol)))
414  {
415  NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
416  m_ptsInField->GetPointVal(0, i);
417 
418  m_neighInds[searchPt.idx][0] = i;
419  m_neighInds[searchPt.idx][1] = i + 1;
420 
421  m_weights[searchPt.idx][0] =
422  (m_ptsInField->GetPointVal(0, i + 1) - coord) / pdiff;
423  m_weights[searchPt.idx][1] =
424  (coord - m_ptsInField->GetPointVal(0, i)) / pdiff;
425 
426  break;
427  }
428  }
429  ASSERTL0(i != npts - 1, "Failed to find coordinate " +
430  boost::lexical_cast<string>(coord) +
431  " within provided input points");
432 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
LibUtilities::PtsFieldSharedPtr m_ptsInField
input field
static const NekDouble kNekZeroTol

References ASSERTL0, Nektar::LibUtilities::Interpolator::PtsPoint::coords, Nektar::LibUtilities::Interpolator::PtsPoint::idx, and Nektar::NekConstants::kNekZeroTol.

◆ CalcW_NNeighbour()

void Nektar::LibUtilities::Interpolator::CalcW_NNeighbour ( const PtsPoint searchPt)
private

Computes interpolation weights using nearest neighbour interpolation.

Parameters
searchPtpoint for which the weights are computed
m_coordIdcoordinate id along which the interpolation should be performed

Definition at line 442 of file LibUtilities/BasicUtils/Interpolator.cpp.

443 {
444  // find nearest neighbours
445  vector<PtsPoint> neighbourPts;
446  // TODO: we currently dont handle the case when there are more than one
447  // most distant points (of same distance)
448  FindNNeighbours(searchPt, neighbourPts, 1);
449 
450  m_neighInds[searchPt.idx][0] = neighbourPts[0].idx;
451  m_weights[searchPt.idx][0] = 1.0;
452 }
void FindNNeighbours(const PtsPoint &searchPt, std::vector< PtsPoint > &neighbourPts, const unsigned int numPts=1)
Finds the neares neighbours of a point.

References Nektar::LibUtilities::Interpolator::PtsPoint::idx.

◆ CalcW_Quadratic()

void Nektar::LibUtilities::Interpolator::CalcW_Quadratic ( const PtsPoint searchPt,
int  m_coordId 
)
private

Computes interpolation weights using quadratic interpolation.

Parameters
searchPtpoint for which the weights are computed
m_coordIdcoordinate id along which the interpolation should be performed

Currently, only implemented for 1D. Falls back to linear interpolation if only 2 values are available.

Definition at line 516 of file LibUtilities/BasicUtils/Interpolator.cpp.

517 {
518  int npts = m_ptsInField->GetNpoints();
519  int i;
520 
521  NekDouble coord = searchPt.coords[m_coordId];
522 
523  for (i = 0; i < npts - 1; ++i)
524  {
525  if ((m_ptsInField->GetPointVal(0, i) <=
526  (coord + NekConstants::kNekZeroTol)) &&
527  (coord <=
528  (m_ptsInField->GetPointVal(0, i + 1) + NekConstants::kNekZeroTol)))
529  {
530  NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
531  m_ptsInField->GetPointVal(0, i);
532  NekDouble h1, h2, h3;
533 
534  if (i < npts - 2)
535  {
536  // forwards stencil
537  NekDouble pdiff2 = m_ptsInField->GetPointVal(0, i + 2) -
538  m_ptsInField->GetPointVal(0, i + 1);
539 
540  h1 = (m_ptsInField->GetPointVal(0, i + 1) - coord) *
541  (m_ptsInField->GetPointVal(0, i + 2) - coord) /
542  (pdiff * (pdiff + pdiff2));
543  h2 = (coord - m_ptsInField->GetPointVal(0, i)) *
544  (m_ptsInField->GetPointVal(0, i + 2) - coord) /
545  (pdiff * pdiff2);
546  h3 = (coord - m_ptsInField->GetPointVal(0, i)) *
547  (coord - m_ptsInField->GetPointVal(0, i + 1)) /
548  ((pdiff + pdiff2) * pdiff2);
549 
550  m_neighInds[searchPt.idx][0] = i;
551  m_neighInds[searchPt.idx][1] = i + 1;
552  m_neighInds[searchPt.idx][2] = i + 2;
553  }
554  else
555  {
556  // backwards stencil
557  NekDouble pdiff2 = m_ptsInField->GetPointVal(0, i) -
558  m_ptsInField->GetPointVal(0, i - 1);
559 
560  h1 = (m_ptsInField->GetPointVal(0, i + 1) - coord) *
561  (coord - m_ptsInField->GetPointVal(0, i - 1)) /
562  (pdiff * pdiff2);
563  h2 = (coord - m_ptsInField->GetPointVal(0, i)) *
564  (coord - m_ptsInField->GetPointVal(0, i - 1)) /
565  (pdiff * (pdiff + pdiff2));
566  h3 = (m_ptsInField->GetPointVal(0, i) - coord) *
567  (m_ptsInField->GetPointVal(0, i + 1) - coord) /
568  ((pdiff + pdiff2) * pdiff);
569 
570  m_neighInds[searchPt.idx][0] = i;
571  m_neighInds[searchPt.idx][1] = i + 1;
572  m_neighInds[searchPt.idx][2] = i - 1;
573  }
574 
575  m_weights[searchPt.idx][0] = h1;
576  m_weights[searchPt.idx][1] = h2;
577  m_weights[searchPt.idx][2] = h3;
578 
579  break;
580  }
581  }
582  ASSERTL0(i != npts - 1, "Failed to find coordinate " +
583  boost::lexical_cast<string>(coord) +
584  " within provided input points");
585 }

References ASSERTL0, Nektar::LibUtilities::Interpolator::PtsPoint::coords, Nektar::LibUtilities::Interpolator::PtsPoint::idx, and Nektar::NekConstants::kNekZeroTol.

◆ CalcW_Shepard()

void Nektar::LibUtilities::Interpolator::CalcW_Shepard ( const PtsPoint searchPt,
int  numPts 
)
private

Computes interpolation weights using linear interpolation.

Parameters
searchPtpoint for which the weights are computed
m_coordIdcoordinate id along which the interpolation should be performed

The algorithm is based on Shepard, D. (1968). A two-dimensional interpolation function for irregularly-spaced data. Proceedings of the 1968 23rd ACM National Conference. pp. 517–524.

In order to save memory, for n dimesnions, only 2^n points are considered. Contrary to Shepard, we use a fixed number of points with fixed weighting factors 1/d^n.

Definition at line 469 of file LibUtilities/BasicUtils/Interpolator.cpp.

470 {
471  // find nearest neighbours
472  vector<PtsPoint> neighbourPts;
473  FindNNeighbours(searchPt, neighbourPts, numPts);
474 
475  for (int i = 0; i < neighbourPts.size(); i++)
476  {
477  m_neighInds[searchPt.idx][i] = neighbourPts[i].idx;
478  }
479 
480  // In case d < kVertexTheSameDouble ( d^2 < kNekSqrtTol), use the exact
481  // point and return
482  for (int i = 0; i < neighbourPts.size(); ++i)
483  {
484  if (neighbourPts[i].dist <= NekConstants::kNekZeroTol)
485  {
486  m_weights[searchPt.idx][i] = 1.0;
487  return;
488  }
489  }
490 
491  NekDouble wSum = 0.0;
492  for (int i = 0; i < neighbourPts.size(); ++i)
493  {
494  m_weights[searchPt.idx][i] = 1 / pow(double(neighbourPts[i].dist),
495  double(m_ptsInField->GetDim()));
496  wSum += m_weights[searchPt.idx][i];
497  }
498 
499  for (int i = 0; i < neighbourPts.size(); ++i)
500  {
501  m_weights[searchPt.idx][i] = m_weights[searchPt.idx][i] / wSum;
502  }
503 }

References Nektar::LibUtilities::Interpolator::PtsPoint::idx, and Nektar::NekConstants::kNekZeroTol.

◆ CalcWeights()

void Nektar::LibUtilities::Interpolator::CalcWeights ( const LibUtilities::PtsFieldSharedPtr  ptsInField,
LibUtilities::PtsFieldSharedPtr ptsOutField,
bool  reuseTree = false 
)

Compute interpolation weights without doing any interpolation.

Parameters
ptsInFieldinput field
ptsOutFieldoutput field
reuseTreeif an r-tree has been constructed already, reuse it (e.g. for repeated calls over the same input points).

In and output fields must have the same dimension. The most suitable algorithm is chosen automatically if it wasnt set explicitly.

Definition at line 60 of file LibUtilities/BasicUtils/Interpolator.cpp.

63 {
64  ASSERTL0(ptsInField->GetDim() <= m_dim, "too many dimesions in inField");
65  ASSERTL0(ptsOutField->GetDim() <= m_dim, "too many dimesions in outField");
66 
67  m_ptsInField = ptsInField;
68  m_ptsOutField = ptsOutField;
69 
70  size_t nOutPts = m_ptsOutField->GetNpoints();
71  int lastProg = 0;
72 
73  // set a default method
74  if (m_method == eNoMethod)
75  {
76  if (m_ptsInField->GetDim() == 1 || m_coordId >= 0)
77  {
79  }
80  else
81  {
83  }
84  }
85 
86  if ((!m_rtree || !reuseTree) && m_method != eQuadratic)
87  {
88  SetupTree();
89  }
90 
91  switch (m_method)
92  {
93  case eNearestNeighbour:
94  {
95  m_weights = Array<TwoD, NekDouble>(nOutPts, 1, 0.0);
96  m_neighInds = Array<TwoD, unsigned int>(nOutPts, 1, (unsigned int) 0);
97 
98  for (size_t i = 0; i < nOutPts; ++i)
99  {
100  Array<OneD, NekDouble> tmp(m_dim, 0.0);
101  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
102  {
103  tmp[j] = m_ptsOutField->GetPointVal(j, i);
104  }
105  PtsPoint searchPt(i, tmp, 1E30);
106 
107  CalcW_NNeighbour(searchPt);
108 
109  int progress = int(100 * i / nOutPts);
110  if (m_progressCallback && progress > lastProg)
111  {
112  m_progressCallback(i, nOutPts);
113  lastProg = progress;
114  }
115  }
116 
117  break;
118  }
119 
120  case eQuadratic:
121  {
122  ASSERTL0(m_ptsInField->GetDim() == 1 || m_coordId >= 0,
123  "not implemented");
124 
125  m_weights = Array<TwoD, NekDouble>(nOutPts, 3, 0.0);
126  m_neighInds = Array<TwoD, unsigned int>(nOutPts, 3, (unsigned int) 0);
127 
128  for (size_t i = 0; i < nOutPts; ++i)
129  {
130  Array<OneD, NekDouble> tmp(m_dim, 0.0);
131  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
132  {
133  tmp[j] = m_ptsOutField->GetPointVal(j, i);
134  }
135  PtsPoint searchPt(i, tmp, 1E30);
136 
137  if (m_ptsInField->GetNpoints() <= 2)
138  {
139  CalcW_Linear(searchPt, m_coordId);
140  }
141  else
142  {
143  CalcW_Quadratic(searchPt, m_coordId);
144  }
145 
146  int progress = int(100 * i / nOutPts);
147  if (m_progressCallback && progress > lastProg)
148  {
149  m_progressCallback(i, nOutPts);
150  lastProg = progress;
151  }
152  }
153 
154  break;
155  }
156 
157  case eShepard:
158  {
159  int numPts = m_ptsInField->GetDim();
160  numPts = 1 << numPts; // 2 ^ numPts
161  numPts = min(numPts, int(m_ptsInField->GetNpoints() / 2));
162 
163  m_weights = Array<TwoD, NekDouble>(nOutPts, numPts, 0.0);
164  m_neighInds = Array<TwoD, unsigned int>(nOutPts, numPts, (unsigned int) 0);
165 
166  for (size_t i = 0; i < nOutPts; ++i)
167  {
168  Array<OneD, NekDouble> tmp(m_dim, 0.0);
169  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
170  {
171  tmp[j] = m_ptsOutField->GetPointVal(j, i);
172  }
173  PtsPoint searchPt(i, tmp, 1E30);
174 
175  CalcW_Shepard(searchPt, numPts);
176 
177  int progress = int(100 * i / nOutPts);
178  if (m_progressCallback && progress > lastProg)
179  {
180  m_progressCallback(i, nOutPts);
181  lastProg = progress;
182  }
183  }
184 
185  break;
186  }
187 
188  case eGauss:
189  {
191  "No filter width set");
192  // use m_filtWidth as FWHM
193  NekDouble sigma = m_filtWidth * 0.4246609001;
194 
195  m_maxPts = min(m_maxPts, int(m_ptsInField->GetNpoints() / 2));
196 
197  m_weights = Array<TwoD, NekDouble>(nOutPts, m_maxPts, 0.0);
198  m_neighInds = Array<TwoD, unsigned int>(nOutPts, m_maxPts, (unsigned int) 0);
199 
200  for (size_t i = 0; i < nOutPts; ++i)
201  {
202  Array<OneD, NekDouble> tmp(m_dim, 0.0);
203  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
204  {
205  tmp[j] = m_ptsOutField->GetPointVal(j, i);
206  }
207  PtsPoint searchPt(i, tmp, 1E30);
208 
209  CalcW_Gauss(searchPt, sigma, m_maxPts);
210 
211  int progress = int(100 * i / nOutPts);
212  if (m_progressCallback && progress > lastProg)
213  {
214  m_progressCallback(i, nOutPts);
215  lastProg = progress;
216  }
217  }
218 
219  break;
220  }
221 
222  default:
223  NEKERROR(ErrorUtil::efatal, "Invalid interpolation m_method");
224  break;
225  }
226 }
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
static const int m_dim
dimension of this interpolator. Hardcoded to 3
std::shared_ptr< PtsRtree > m_rtree
A tree structure to speed up the neighbour search. Note that we fill it with an iterator,...
void CalcW_Linear(const PtsPoint &searchPt, int coordId)
Computes interpolation weights using linear interpolation.
void CalcW_NNeighbour(const PtsPoint &searchPt)
Computes interpolation weights using nearest neighbour interpolation.
void CalcW_Shepard(const PtsPoint &searchPt, int numPts)
Computes interpolation weights using linear interpolation.
void CalcW_Gauss(const PtsPoint &searchPt, const NekDouble sigma, const int maxPts=250)
Computes interpolation weights using gaussian interpolation.
std::function< void(const int position, const int goal)> m_progressCallback
void CalcW_Quadratic(const PtsPoint &searchPt, int coordId)
Computes interpolation weights using quadratic interpolation.
LibUtilities::PtsFieldSharedPtr m_ptsOutField
output field

References ASSERTL0, Nektar::LibUtilities::eGauss, Nektar::LibUtilities::eNearestNeighbour, Nektar::LibUtilities::eNoMethod, Nektar::LibUtilities::eQuadratic, Nektar::LibUtilities::eShepard, Nektar::NekConstants::kNekZeroTol, and NEKERROR.

Referenced by Nektar::SolverUtils::SessionFunction::EvaluatePts().

◆ FindNeighbours()

void Nektar::LibUtilities::Interpolator::FindNeighbours ( const PtsPoint searchPt,
std::vector< PtsPoint > &  neighbourPts,
const NekDouble  dist,
const unsigned int  maxPts = 1 
)
private

Finds the neares neighbours of a point.

Parameters
searchPtpoint for which the neighbours are searched
neighbourPtspossible neighbour points
distlimits the distance of the neighbours

Definition at line 672 of file LibUtilities/BasicUtils/Interpolator.cpp.

676 {
677  BPoint searchBPoint(searchPt.coords[0], searchPt.coords[1],
678  searchPt.coords[2]);
679  BPoint bbMin(searchPt.coords[0] - dist, searchPt.coords[1] - dist,
680  searchPt.coords[2] - dist);
681  BPoint bbMax(searchPt.coords[0] + dist, searchPt.coords[1] + dist,
682  searchPt.coords[2] + dist);
683  bg::model::box<BPoint> bbox(bbMin, bbMax);
684 
685  // find points within the distance box
686  std::vector<PtsPointPair> result;
687  if (maxPts >= 1)
688  {
689  m_rtree->query(bgi::within(bbox) && bgi::nearest(searchBPoint, maxPts),
690  std::back_inserter(result));
691  }
692  else
693  {
694  m_rtree->query(bgi::within(bbox), std::back_inserter(result));
695  }
696 
697  // massage into or own format
698  for (int i = 0; i < result.size(); ++i)
699  {
700  int idx = result[i].second;
701  Array<OneD, NekDouble> coords(m_dim, 0.0);
702  for (int j = 0; j < m_ptsInField->GetDim(); ++j)
703  {
704  coords[j] = m_ptsInField->GetPointVal(j, idx);
705  }
706  NekDouble d = bg::distance(searchBPoint, result[i].first);
707 
708  // discard points beyonf dist
709  if (d <= dist)
710  {
711  neighbourPts.push_back(PtsPoint(idx, coords, d));
712  }
713  }
714 
715  sort(neighbourPts.begin(), neighbourPts.end());
716 }
boost::geometry::model::point< NekDouble, m_dim, boost::geometry::cs::cartesian > BPoint

References Nektar::LibUtilities::Interpolator::PtsPoint::coords.

◆ FindNNeighbours()

void Nektar::LibUtilities::Interpolator::FindNNeighbours ( const PtsPoint searchPt,
std::vector< PtsPoint > &  neighbourPts,
const unsigned int  numPts = 1 
)
private

Finds the neares neighbours of a point.

Parameters
searchPtpoint for which the neighbours are searched
neighbourPtspossible neighbour points
numPtslimits the number of neighbours found to the numPts nearest ones

Definition at line 638 of file LibUtilities/BasicUtils/Interpolator.cpp.

641 {
642  std::vector<PtsPointPair> result;
643  BPoint searchBPoint(searchPt.coords[0], searchPt.coords[1],
644  searchPt.coords[2]);
645  m_rtree->query(bgi::nearest(searchBPoint, numPts),
646  std::back_inserter(result));
647 
648  // massage into or own format
649  for (int i = 0; i < result.size(); ++i)
650  {
651  int idx = result[i].second;
652  Array<OneD, NekDouble> coords(m_dim, 0.0);
653  for (int j = 0; j < m_ptsInField->GetDim(); ++j)
654  {
655  coords[j] = m_ptsInField->GetPointVal(j, idx);
656  }
657  NekDouble d = bg::distance(searchBPoint, result[i].first);
658  neighbourPts.push_back(PtsPoint(idx, coords, d));
659  }
660 
661  sort(neighbourPts.begin(), neighbourPts.end());
662 }

References Nektar::LibUtilities::Interpolator::PtsPoint::coords.

◆ GetCoordId()

int Nektar::LibUtilities::Interpolator::GetCoordId ( ) const

Returns the coordinate id along which the interpolation should be performed.

Definition at line 291 of file LibUtilities/BasicUtils/Interpolator.cpp.

292 {
293  return m_coordId;
294 }

◆ GetDim()

int Nektar::LibUtilities::Interpolator::GetDim ( ) const

returns the dimension of the Interpolator. Should be higher than the dimensions of the interpolated fields

Definition at line 286 of file LibUtilities/BasicUtils/Interpolator.cpp.

287 {
288  return m_dim;
289 }

◆ GetFiltWidth()

NekDouble Nektar::LibUtilities::Interpolator::GetFiltWidth ( ) const

Returns the filter width.

Definition at line 296 of file LibUtilities/BasicUtils/Interpolator.cpp.

297 {
298  return m_filtWidth;
299 }

◆ GetInField()

LibUtilities::PtsFieldSharedPtr Nektar::LibUtilities::Interpolator::GetInField ( ) const

Returns the input field.

Definition at line 306 of file LibUtilities/BasicUtils/Interpolator.cpp.

307 {
308  return m_ptsInField;
309 }

◆ GetInterpMethod()

InterpMethod Nektar::LibUtilities::Interpolator::GetInterpMethod ( ) const

Returns the interpolation method used by this interpolator.

Definition at line 301 of file LibUtilities/BasicUtils/Interpolator.cpp.

302 {
303  return m_method;
304 }

◆ GetOutField()

LibUtilities::PtsFieldSharedPtr Nektar::LibUtilities::Interpolator::GetOutField ( ) const

Returns the output field.

Definition at line 311 of file LibUtilities/BasicUtils/Interpolator.cpp.

312 {
313  return m_ptsOutField;
314 }

◆ Interpolate()

void Nektar::LibUtilities::Interpolator::Interpolate ( const LibUtilities::PtsFieldSharedPtr  ptsInField,
LibUtilities::PtsFieldSharedPtr ptsOutField 
)

Interpolate from a pts field to a pts field.

Parameters
ptsInFieldinput field
ptsOutFieldoutput field

In and output fields must have the same dimension and number of fields. The most suitable algorithm is chosen automatically if it wasnt set explicitly.

Definition at line 238 of file LibUtilities/BasicUtils/Interpolator.cpp.

240 {
241  ASSERTL0(ptsInField->GetNFields() == ptsOutField->GetNFields(),
242  "number of fields does not match");
243  ASSERTL0(ptsInField->GetDim() <= m_dim, "too many dimesions in inField");
244  ASSERTL0(ptsOutField->GetDim() <= m_dim, "too many dimesions in outField");
245 
246  m_ptsInField = ptsInField;
247  m_ptsOutField = ptsOutField;
248 
249  if (m_weights.GetRows() == 0)
250  {
252  }
253 
254  ASSERTL0(m_weights.GetRows() == m_ptsOutField->GetNpoints(),
255  "weights dimension mismatch");
256 
257  size_t nFields = m_ptsOutField->GetNFields();
258  size_t nOutPts = m_ptsOutField->GetNpoints();
259  size_t inDim = m_ptsInField->GetDim();
260 
261  // interpolate points and transform
262  for (size_t i = 0; i < nFields; ++i)
263  {
264  for (size_t j = 0; j < nOutPts; ++j)
265  {
266  size_t nPts = m_weights.GetColumns();
267 
268  // skip if there were no neighbours found for this point
269  if (nPts == 0)
270  {
271  continue;
272  }
273 
274  NekDouble val = 0.0;
275  for (size_t k = 0; k < nPts; ++k)
276  {
277  size_t nIdx = m_neighInds[j][k];
278  val += m_weights[j][k] *
279  m_ptsInField->GetPointVal(inDim + i, nIdx);
280  }
281  m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + i, j, val);
282  }
283  }
284 }
void CalcWeights(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField, bool reuseTree=false)
Compute interpolation weights without doing any interpolation.

References ASSERTL0.

◆ PrintStatistics()

void Nektar::LibUtilities::Interpolator::PrintStatistics ( )

Returns if the weights have already been computed.

Definition at line 316 of file LibUtilities/BasicUtils/Interpolator.cpp.

317 {
318  int meanN = 0;
319  for (int i = 0; i < m_neighInds.GetRows(); ++i)
320  {
321  for (int j = 0; j < m_neighInds.GetColumns(); ++j)
322  {
323  if (m_neighInds[i][j] > 0)
324  {
325  meanN +=1;
326  }
327  }
328  }
329 
330  cout << "Number of points: " << m_neighInds.GetRows() << endl;
331  if (m_neighInds.GetRows() > 0)
332  {
333  cout << "mean Number of Neighbours per point: "
334  << meanN / m_neighInds.GetRows() << endl;
335  }
336 }

Referenced by Nektar::SolverUtils::SessionFunction::EvaluatePts().

◆ SetProgressCallback()

template<typename FuncPointerT , typename ObjectPointerT >
void Nektar::LibUtilities::Interpolator::SetProgressCallback ( FuncPointerT  func,
ObjectPointerT  obj 
)
inline

sets a callback funtion which gets called every time the interpolation progresses

Definition at line 137 of file LibUtilities/BasicUtils/Interpolator.h.

138  {
139  m_progressCallback = std::bind(
140  func, obj, std::placeholders::_1, std::placeholders::_2);
141  }

References m_progressCallback.

Referenced by Nektar::SolverUtils::SessionFunction::EvaluatePts(), Nektar::FieldUtils::ProcessInterpPoints::InterpolateFieldToPts(), Nektar::FieldUtils::ProcessInterpPtsToPts::InterpolatePtsToPts(), Nektar::FieldUtils::ProcessInterpField::Process(), and Nektar::FieldUtils::ProcessInterpPointDataToFld::Process().

◆ SetupTree()

void Nektar::LibUtilities::Interpolator::SetupTree ( )
private

Definition at line 587 of file LibUtilities/BasicUtils/Interpolator.cpp.

588 {
589  std::vector<PtsPointPair> inPoints;
590  for (int i = 0; i < m_ptsInField->GetNpoints(); ++i)
591  {
592  Array<OneD, NekDouble> coords(3, 0.0);
593  for (int j = 0; j < m_ptsInField->GetDim(); ++j)
594  {
595  coords[j] = m_ptsInField->GetPointVal(j, i);
596  }
597  inPoints.push_back(
598  PtsPointPair(BPoint(coords[0], coords[1], coords[2]), i));
599  }
601  m_rtree->insert(inPoints.begin(), inPoints.end());
602 
603  // remove duplicates from tree
604  for (auto &it : inPoints)
605  {
606  std::vector<PtsPointPair> result;
607 
608  // find nearest 2 points (2 because one of these might be the one we
609  // are
610  // checking)
611  m_rtree->query(bgi::nearest(it.first, 2),
612  std::back_inserter(result));
613 
614  // in case any of these 2 points is too close, remove the current
615  // point
616  // from the tree
617  for (auto &it2 : result)
618  {
619  if (it.second != it2.second &&
620  bg::distance(it.first, it2.first) <= NekConstants::kNekZeroTol)
621  {
622  m_rtree->remove(it);
623  break;
624  }
625  }
626  }
627 }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.

References Nektar::NekConstants::kNekZeroTol.

Member Data Documentation

◆ m_coordId

short int Nektar::LibUtilities::Interpolator::m_coordId
private

coordinate id along which the interpolation should be performed

Definition at line 198 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_dim

const int Nektar::LibUtilities::Interpolator::m_dim = 3
staticprivate

dimension of this interpolator. Hardcoded to 3

Definition at line 174 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_filtWidth

NekDouble Nektar::LibUtilities::Interpolator::m_filtWidth
private

Filter width used for some interpolation algorithms.

Definition at line 194 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_maxPts

int Nektar::LibUtilities::Interpolator::m_maxPts
private

Max number of interpolation points.

Definition at line 196 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_method

InterpMethod Nektar::LibUtilities::Interpolator::m_method
private

Interpolation Method.

Definition at line 182 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_neighInds

Array<TwoD, unsigned int> Nektar::LibUtilities::Interpolator::m_neighInds
private

Indices of the relevant neighbours for each physical point. Structure: m_neighInds[ptIdx][neighbourIdx].

Definition at line 192 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_progressCallback

std::function<void(const int position, const int goal)> Nektar::LibUtilities::Interpolator::m_progressCallback
protected

Definition at line 151 of file LibUtilities/BasicUtils/Interpolator.h.

Referenced by SetProgressCallback().

◆ m_ptsInField

LibUtilities::PtsFieldSharedPtr Nektar::LibUtilities::Interpolator::m_ptsInField
protected

input field

Definition at line 146 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_ptsOutField

LibUtilities::PtsFieldSharedPtr Nektar::LibUtilities::Interpolator::m_ptsOutField
protected

output field

Definition at line 148 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_rtree

std::shared_ptr<PtsRtree> Nektar::LibUtilities::Interpolator::m_rtree
private

A tree structure to speed up the neighbour search. Note that we fill it with an iterator, so instead of rstar, the packing algorithm is used.

Definition at line 186 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_weights

Array<TwoD, NekDouble> Nektar::LibUtilities::Interpolator::m_weights
private

Interpolation weights for each neighbour. Structure: m_weights[physPtIdx][neighbourIdx].

Definition at line 189 of file LibUtilities/BasicUtils/Interpolator.h.