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 73 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 174 of file LibUtilities/BasicUtils/Interpolator.h.

◆ PtsPointPair

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

Definition at line 175 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 178 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 automatically.

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 94 of file LibUtilities/BasicUtils/Interpolator.h.

96  : m_method(method), m_filtWidth(filtWidth), m_maxPts(maxPts),
97  m_coordId(coordId)
98  {
99  }
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 356 of file LibUtilities/BasicUtils/Interpolator.cpp.

358 {
359  // find nearest neighbours
360  vector<PtsPoint> neighbourPts;
361  FindNeighbours(searchPt, neighbourPts, 4 * sigma, maxPts);
362  size_t numPts = neighbourPts.size();
363 
364  // handle the cases that there was no or just one point within 4 * sigma
365  if (numPts == 0)
366  {
367  return;
368  }
369  if (numPts == 1)
370  {
371  m_neighInds[searchPt.idx][0] = neighbourPts.front().idx;
372  m_weights[searchPt.idx][0] = 1.0;
373 
374  return;
375  }
376 
377  NekDouble sigmaNew = 0.25 * neighbourPts.back().dist;
378 
379  for (size_t i = 0; i < numPts; i++)
380  {
381  m_neighInds[searchPt.idx][i] = neighbourPts.at(i).idx;
382  }
383 
384  NekDouble wSum = 0.0;
385  NekDouble ts2 = 2.0 * sigmaNew * sigmaNew;
386  for (size_t i = 0; i < numPts; ++i)
387  {
388  m_weights[searchPt.idx][i] =
389  exp(-1.0 * neighbourPts[i].dist * neighbourPts[i].dist / ts2);
390  wSum += m_weights[searchPt.idx][i];
391  }
392 
393  for (size_t i = 0; i < numPts; ++i)
394  {
395  m_weights[searchPt.idx][i] = m_weights[searchPt.idx][i] / wSum;
396  }
397 }
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 408 of file LibUtilities/BasicUtils/Interpolator.cpp.

409 {
410  int npts = m_ptsInField->GetNpoints();
411  int i;
412 
413  NekDouble coord = searchPt.coords[m_coordId];
414 
415  for (i = 0; i < npts - 1; ++i)
416  {
417  if ((m_ptsInField->GetPointVal(0, i) <=
418  (coord + NekConstants::kNekZeroTol)) &&
419  (coord <=
420  (m_ptsInField->GetPointVal(0, i + 1) + NekConstants::kNekZeroTol)))
421  {
422  NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
423  m_ptsInField->GetPointVal(0, i);
424 
425  m_neighInds[searchPt.idx][0] = i;
426  m_neighInds[searchPt.idx][1] = i + 1;
427 
428  m_weights[searchPt.idx][0] =
429  (m_ptsInField->GetPointVal(0, i + 1) - coord) / pdiff;
430  m_weights[searchPt.idx][1] =
431  (coord - m_ptsInField->GetPointVal(0, i)) / pdiff;
432 
433  break;
434  }
435  }
436  ASSERTL0(i != npts - 1, "Failed to find coordinate " +
437  boost::lexical_cast<string>(coord) +
438  " within provided input points");
439 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
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 449 of file LibUtilities/BasicUtils/Interpolator.cpp.

450 {
451  // find nearest neighbours
452  vector<PtsPoint> neighbourPts;
453  // TODO: we currently dont handle the case when there are more than one
454  // most distant points (of same distance)
455  FindNNeighbours(searchPt, neighbourPts, 1);
456 
457  m_neighInds[searchPt.idx][0] = neighbourPts[0].idx;
458  m_weights[searchPt.idx][0] = 1.0;
459 }
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 523 of file LibUtilities/BasicUtils/Interpolator.cpp.

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

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 476 of file LibUtilities/BasicUtils/Interpolator.cpp.

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

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() == 3)
77  {
79  }
80  else if (m_ptsInField->GetDim() == 1 || m_coordId >= 0)
81  {
83  }
84  else
85  {
87  }
88  }
89 
90  if ((!m_rtree || !reuseTree) && m_method != eQuadratic)
91  {
92  SetupTree();
93  }
94 
95  switch (m_method)
96  {
97  case eNearestNeighbour:
98  {
99  m_weights = Array<TwoD, NekDouble>(nOutPts, 1, 0.0);
100  m_neighInds =
101  Array<TwoD, unsigned int>(nOutPts, 1, (unsigned int)0);
102 
103  for (size_t i = 0; i < nOutPts; ++i)
104  {
105  Array<OneD, NekDouble> tmp(m_dim, 0.0);
106  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
107  {
108  tmp[j] = m_ptsOutField->GetPointVal(j, i);
109  }
110  PtsPoint searchPt(i, tmp, 1E30);
111 
112  CalcW_NNeighbour(searchPt);
113 
114  int progress = int(100 * i / nOutPts);
115  if (m_progressCallback && progress > lastProg)
116  {
117  m_progressCallback(i, nOutPts);
118  lastProg = progress;
119  }
120  }
121 
122  break;
123  }
124 
125  case eQuadratic:
126  {
127  ASSERTL0(m_ptsInField->GetDim() == 1 || m_coordId >= 0,
128  "not implemented");
129 
130  m_weights = Array<TwoD, NekDouble>(nOutPts, 3, 0.0);
131  m_neighInds =
132  Array<TwoD, unsigned int>(nOutPts, 3, (unsigned int)0);
133 
134  for (size_t i = 0; i < nOutPts; ++i)
135  {
136  Array<OneD, NekDouble> tmp(m_dim, 0.0);
137  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
138  {
139  tmp[j] = m_ptsOutField->GetPointVal(j, i);
140  }
141  PtsPoint searchPt(i, tmp, 1E30);
142 
143  if (m_ptsInField->GetNpoints() <= 2)
144  {
145  CalcW_Linear(searchPt, m_coordId);
146  }
147  else
148  {
149  CalcW_Quadratic(searchPt, m_coordId);
150  }
151 
152  int progress = int(100 * i / nOutPts);
153  if (m_progressCallback && progress > lastProg)
154  {
155  m_progressCallback(i, nOutPts);
156  lastProg = progress;
157  }
158  }
159 
160  break;
161  }
162 
163  case eShepard:
164  {
165  int numPts = m_ptsInField->GetDim();
166  numPts = 1 << numPts; // 2 ^ numPts
167  numPts = min(numPts, int(m_ptsInField->GetNpoints() / 2));
168 
169  m_weights = Array<TwoD, NekDouble>(nOutPts, numPts, 0.0);
170  m_neighInds =
171  Array<TwoD, unsigned int>(nOutPts, numPts, (unsigned int)0);
172 
173  for (size_t i = 0; i < nOutPts; ++i)
174  {
175  Array<OneD, NekDouble> tmp(m_dim, 0.0);
176  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
177  {
178  tmp[j] = m_ptsOutField->GetPointVal(j, i);
179  }
180  PtsPoint searchPt(i, tmp, 1E30);
181 
182  CalcW_Shepard(searchPt, numPts);
183 
184  int progress = int(100 * i / nOutPts);
185  if (m_progressCallback && progress > lastProg)
186  {
187  m_progressCallback(i, nOutPts);
188  lastProg = progress;
189  }
190  }
191 
192  break;
193  }
194 
195  case eGauss:
196  {
198  "No filter width set");
199  // use m_filtWidth as FWHM
200  NekDouble sigma = m_filtWidth * 0.4246609001;
201 
202  m_maxPts = min(m_maxPts, int(m_ptsInField->GetNpoints() / 2));
203 
204  m_weights = Array<TwoD, NekDouble>(nOutPts, m_maxPts, 0.0);
205  m_neighInds =
206  Array<TwoD, unsigned int>(nOutPts, m_maxPts, (unsigned int)0);
207 
208  for (size_t i = 0; i < nOutPts; ++i)
209  {
210  Array<OneD, NekDouble> tmp(m_dim, 0.0);
211  for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
212  {
213  tmp[j] = m_ptsOutField->GetPointVal(j, i);
214  }
215  PtsPoint searchPt(i, tmp, 1E30);
216 
217  CalcW_Gauss(searchPt, sigma, m_maxPts);
218 
219  int progress = int(100 * i / nOutPts);
220  if (m_progressCallback && progress > lastProg)
221  {
222  m_progressCallback(i, nOutPts);
223  lastProg = progress;
224  }
225  }
226 
227  break;
228  }
229 
230  default:
231  NEKERROR(ErrorUtil::efatal, "Invalid interpolation m_method");
232  break;
233  }
234 }
#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 678 of file LibUtilities/BasicUtils/Interpolator.cpp.

682 {
683  BPoint searchBPoint(searchPt.coords[0], searchPt.coords[1],
684  searchPt.coords[2]);
685  BPoint bbMin(searchPt.coords[0] - dist, searchPt.coords[1] - dist,
686  searchPt.coords[2] - dist);
687  BPoint bbMax(searchPt.coords[0] + dist, searchPt.coords[1] + dist,
688  searchPt.coords[2] + dist);
689  bg::model::box<BPoint> bbox(bbMin, bbMax);
690 
691  // find points within the distance box
692  std::vector<PtsPointPair> result;
693  if (maxPts >= 1)
694  {
695  m_rtree->query(bgi::within(bbox) && bgi::nearest(searchBPoint, maxPts),
696  std::back_inserter(result));
697  }
698  else
699  {
700  m_rtree->query(bgi::within(bbox), std::back_inserter(result));
701  }
702 
703  // massage into or own format
704  for (int i = 0; i < result.size(); ++i)
705  {
706  int idx = result[i].second;
707  Array<OneD, NekDouble> coords(m_dim, 0.0);
708  for (int j = 0; j < m_ptsInField->GetDim(); ++j)
709  {
710  coords[j] = m_ptsInField->GetPointVal(j, idx);
711  }
712  NekDouble d = bg::distance(searchBPoint, result[i].first);
713 
714  // discard points beyonf dist
715  if (d <= dist)
716  {
717  neighbourPts.push_back(PtsPoint(idx, coords, d));
718  }
719  }
720 
721  sort(neighbourPts.begin(), neighbourPts.end());
722 }
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 644 of file LibUtilities/BasicUtils/Interpolator.cpp.

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

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 299 of file LibUtilities/BasicUtils/Interpolator.cpp.

300 {
301  return m_coordId;
302 }

◆ 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 294 of file LibUtilities/BasicUtils/Interpolator.cpp.

295 {
296  return m_dim;
297 }

◆ GetFiltWidth()

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

Returns the filter width.

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

305 {
306  return m_filtWidth;
307 }

◆ GetInField()

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

Returns the input field.

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

315 {
316  return m_ptsInField;
317 }

◆ GetInterpMethod()

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

Returns the interpolation method used by this interpolator.

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

310 {
311  return m_method;
312 }

◆ GetOutField()

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

Returns the output field.

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

320 {
321  return m_ptsOutField;
322 }

◆ 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 246 of file LibUtilities/BasicUtils/Interpolator.cpp.

248 {
249  ASSERTL0(ptsInField->GetNFields() == ptsOutField->GetNFields(),
250  "number of fields does not match");
251  ASSERTL0(ptsInField->GetDim() <= m_dim, "too many dimesions in inField");
252  ASSERTL0(ptsOutField->GetDim() <= m_dim, "too many dimesions in outField");
253 
254  m_ptsInField = ptsInField;
255  m_ptsOutField = ptsOutField;
256 
257  if (m_weights.GetRows() == 0)
258  {
260  }
261 
262  ASSERTL0(m_weights.GetRows() == m_ptsOutField->GetNpoints(),
263  "weights dimension mismatch");
264 
265  size_t nFields = m_ptsOutField->GetNFields();
266  size_t nOutPts = m_ptsOutField->GetNpoints();
267  size_t inDim = m_ptsInField->GetDim();
268 
269  // interpolate points and transform
270  for (size_t i = 0; i < nFields; ++i)
271  {
272  for (size_t j = 0; j < nOutPts; ++j)
273  {
274  size_t nPts = m_weights.GetColumns();
275 
276  // skip if there were no neighbours found for this point
277  if (nPts == 0)
278  {
279  continue;
280  }
281 
282  NekDouble val = 0.0;
283  for (size_t k = 0; k < nPts; ++k)
284  {
285  size_t nIdx = m_neighInds[j][k];
286  val += m_weights[j][k] *
287  m_ptsInField->GetPointVal(inDim + i, nIdx);
288  }
289  m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + i, j, val);
290  }
291  }
292 }
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 324 of file LibUtilities/BasicUtils/Interpolator.cpp.

325 {
326  int meanN = 0;
327  for (int i = 0; i < m_neighInds.GetRows(); ++i)
328  {
329  for (int j = 0; j < m_neighInds.GetColumns(); ++j)
330  {
331  if (m_neighInds[i][j] > 0)
332  {
333  meanN += 1;
334  }
335  }
336  }
337 
338  cout << "Number of points: " << m_neighInds.GetRows() << endl;
339  if (m_neighInds.GetRows() > 0)
340  {
341  cout << "mean Number of Neighbours per point: "
342  << meanN / m_neighInds.GetRows() << endl;
343  }
344 }

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  {
140  std::bind(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::v_Process(), and Nektar::FieldUtils::ProcessInterpPointDataToFld::v_Process().

◆ SetupTree()

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

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

595 {
596  std::vector<PtsPointPair> inPoints;
597  for (int i = 0; i < m_ptsInField->GetNpoints(); ++i)
598  {
599  Array<OneD, NekDouble> coords(3, 0.0);
600  for (int j = 0; j < m_ptsInField->GetDim(); ++j)
601  {
602  coords[j] = m_ptsInField->GetPointVal(j, i);
603  }
604  inPoints.push_back(
605  PtsPointPair(BPoint(coords[0], coords[1], coords[2]), i));
606  }
608  m_rtree->insert(inPoints.begin(), inPoints.end());
609 
610  // remove duplicates from tree
611  for (auto &it : inPoints)
612  {
613  std::vector<PtsPointPair> result;
614 
615  // find nearest 2 points (2 because one of these might be the one we
616  // are
617  // checking)
618  m_rtree->query(bgi::nearest(it.first, 2), std::back_inserter(result));
619 
620  // in case any of these 2 points is too close, remove the current
621  // point
622  // from the tree
623  for (auto &it2 : result)
624  {
625  if (it.second != it2.second &&
626  bg::distance(it.first, it2.first) <= NekConstants::kNekZeroTol)
627  {
628  m_rtree->remove(it);
629  break;
630  }
631  }
632  }
633 }
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 197 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 171 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 193 of file LibUtilities/BasicUtils/Interpolator.h.

◆ m_maxPts

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

Max number of interpolation points.

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

◆ m_method

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

Interpolation Method.

Definition at line 181 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 191 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 149 of file LibUtilities/BasicUtils/Interpolator.h.

Referenced by SetProgressCallback().

◆ m_ptsInField

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

input field

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

◆ m_ptsOutField

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

output field

Definition at line 147 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 185 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 188 of file LibUtilities/BasicUtils/Interpolator.h.