Nektar++
LibUtilities/BasicUtils/Interpolator.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: Interpolator.cpp
4//
5// For more information, please see: http://www.nektar.info/
6//
7// The MIT License
8//
9// Copyright (c) 2016 Kilian Lackhove
10// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
11// Department of Aeronautics, Imperial College London (UK), and Scientific
12// Computing and Imaging Institute, University of Utah (USA).
13//
14// Permission is hereby granted, free of charge, to any person obtaining a
15// copy of this software and associated documentation files (the "Software"),
16// to deal in the Software without restriction, including without limitation
17// the rights to use, copy, modify, merge, publish, distribute, sublicense,
18// and/or sell copies of the Software, and to permit persons to whom the
19// Software is furnished to do so, subject to the following conditions:
20//
21// The above copyright notice and this permission notice shall be included
22// in all copies or substantial portions of the Software.
23//
24// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30// DEALINGS IN THE SOFTWARE.
31//
32// Description: Interpolator
33//
34////////////////////////////////////////////////////////////////////////////////
35
37#include <boost/geometry.hpp>
38
39using namespace std;
40
41namespace bg = boost::geometry;
42namespace bgi = boost::geometry::index;
43
45{
46
47/**
48 * @brief Compute interpolation weights without doing any interpolation
49 *
50 * @param ptsInField input field
51 * @param ptsOutField output field
52 * @param reuseTree if an r-tree has been constructed already, reuse it
53 * (e.g. for repeated calls over the same input points).
54 *
55 * In and output fields must have the same dimension. The most suitable
56 * algorithm is chosen automatically if it wasnt set explicitly.
57 */
60 bool reuseTree)
61{
62 ASSERTL0(ptsInField->GetDim() <= m_dim, "too many dimensions in inField");
63 ASSERTL0(ptsOutField->GetDim() <= m_dim, "too many dimensions in outField");
64
65 m_ptsInField = ptsInField;
66 m_ptsOutField = ptsOutField;
67
68 size_t nOutPts = m_ptsOutField->GetNpoints();
69 int lastProg = 0;
70
71 // set a default method
72 if (m_method == eNoMethod)
73 {
74 if (m_ptsInField->GetDim() == 3)
75 {
77 }
78 else if (m_ptsInField->GetDim() == 1 || m_coordId >= 0)
79 {
81 }
82 else
83 {
85 }
86 }
87
88 if ((!m_rtree || !reuseTree) && m_method != eQuadratic)
89 {
90 SetupTree();
91 }
92
93 switch (m_method)
94 {
96 {
97 m_weights = Array<TwoD, NekDouble>(nOutPts, 1, 0.0);
98 m_neighInds = Array<TwoD, unsigned int>(nOutPts, 1, 0u);
99
100 for (size_t i = 0; i < nOutPts; ++i)
101 {
103 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
104 {
105 tmp[j] = m_ptsOutField->GetPointVal(j, i);
106 }
107 PtsPoint searchPt(i, tmp, 1E30);
108
109 CalcW_NNeighbour(searchPt);
110
111 int progress = int(100 * i / nOutPts);
112 if (m_progressCallback && progress > lastProg)
113 {
114 m_progressCallback(i, nOutPts);
115 lastProg = progress;
116 }
117 }
118
119 break;
120 }
121
122 case eQuadratic:
123 {
124 ASSERTL0(m_ptsInField->GetDim() == 1 || m_coordId >= 0,
125 "not implemented");
126
127 m_weights = Array<TwoD, NekDouble>(nOutPts, 3, 0.0);
128 m_neighInds = Array<TwoD, unsigned int>(nOutPts, 3, 0u);
129
130 for (size_t i = 0; i < nOutPts; ++i)
131 {
133 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
134 {
135 tmp[j] = m_ptsOutField->GetPointVal(j, i);
136 }
137 PtsPoint searchPt(i, tmp, 1E30);
138
139 if (m_ptsInField->GetNpoints() <= 2)
140 {
141 CalcW_Linear(searchPt, m_coordId);
142 }
143 else
144 {
145 CalcW_Quadratic(searchPt, m_coordId);
146 }
147
148 int progress = int(100 * i / nOutPts);
149 if (m_progressCallback && progress > lastProg)
150 {
151 m_progressCallback(i, nOutPts);
152 lastProg = progress;
153 }
154 }
155
156 break;
157 }
158
159 case eShepard:
160 {
161 int numPts = m_ptsInField->GetDim();
162 numPts = 1 << numPts; // 2 ^ numPts
163 numPts = min(numPts, int(m_ptsInField->GetNpoints() / 2));
164
165 m_weights = Array<TwoD, NekDouble>(nOutPts, numPts, 0.0);
166 m_neighInds = Array<TwoD, unsigned int>(nOutPts, numPts, 0u);
167
168 for (size_t i = 0; i < nOutPts; ++i)
169 {
171 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
172 {
173 tmp[j] = m_ptsOutField->GetPointVal(j, i);
174 }
175 PtsPoint searchPt(i, tmp, 1E30);
176
177 CalcW_Shepard(searchPt, numPts);
178
179 int progress = int(100 * i / nOutPts);
180 if (m_progressCallback && progress > lastProg)
181 {
182 m_progressCallback(i, nOutPts);
183 lastProg = progress;
184 }
185 }
186
187 break;
188 }
189
190 case eGauss:
191 {
193 "No filter width set");
194 // use m_filtWidth as FWHM
195 NekDouble sigma = m_filtWidth * 0.4246609001;
196
197 m_maxPts = min(m_maxPts, int(m_ptsInField->GetNpoints() / 2));
198
201
202 for (size_t i = 0; i < nOutPts; ++i)
203 {
205 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
206 {
207 tmp[j] = m_ptsOutField->GetPointVal(j, i);
208 }
209 PtsPoint searchPt(i, tmp, 1E30);
210
211 CalcW_Gauss(searchPt, sigma, m_maxPts);
212
213 int progress = int(100 * i / nOutPts);
214 if (m_progressCallback && progress > lastProg)
215 {
216 m_progressCallback(i, nOutPts);
217 lastProg = progress;
218 }
219 }
220
221 break;
222 }
223
224 default:
225 NEKERROR(ErrorUtil::efatal, "Invalid interpolation m_method");
226 break;
227 }
228}
229
230/**
231 * @brief Interpolate from a pts field to a pts field
232 *
233 * @param ptsInField input field
234 * @param ptsOutField output field
235 *
236 * In and output fields must have the same dimension and number of fields.
237 * The most suitable algorithm is chosen automatically if it wasnt set
238 * explicitly.
239 */
242{
243 ASSERTL0(ptsInField->GetNFields() == ptsOutField->GetNFields(),
244 "number of fields does not match");
245 ASSERTL0(ptsInField->GetDim() <= m_dim, "too many dimesions in inField");
246 ASSERTL0(ptsOutField->GetDim() <= m_dim, "too many dimesions in outField");
247
248 m_ptsInField = ptsInField;
249 m_ptsOutField = ptsOutField;
250
251 if (m_weights.GetRows() == 0)
252 {
254 }
255
256 ASSERTL0(m_weights.GetRows() == m_ptsOutField->GetNpoints(),
257 "weights dimension mismatch");
258
259 size_t nFields = m_ptsOutField->GetNFields();
260 size_t nOutPts = m_ptsOutField->GetNpoints();
261 size_t inDim = m_ptsInField->GetDim();
262
263 // interpolate points and transform
264 for (size_t i = 0; i < nFields; ++i)
265 {
266 for (size_t j = 0; j < nOutPts; ++j)
267 {
268 size_t nPts = m_weights.GetColumns();
269
270 // skip if there were no neighbours found for this point
271 if (nPts == 0)
272 {
273 continue;
274 }
275
276 NekDouble val = 0.0;
277 for (size_t k = 0; k < nPts; ++k)
278 {
279 size_t nIdx = m_neighInds[j][k];
280 val += m_weights[j][k] *
281 m_ptsInField->GetPointVal(inDim + i, nIdx);
282 }
283 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + i, j, val);
284 }
285 }
286}
287
289{
290 return m_dim;
291}
292
294{
295 return m_coordId;
296}
297
299{
300 return m_filtWidth;
301}
302
304{
305 return m_method;
306}
307
309{
310 return m_ptsInField;
311}
312
314{
315 return m_ptsOutField;
316}
317
319{
320 int meanN = 0;
321 for (int i = 0; i < m_neighInds.GetRows(); ++i)
322 {
323 for (int j = 0; j < m_neighInds.GetColumns(); ++j)
324 {
325 if (m_neighInds[i][j] > 0)
326 {
327 meanN += 1;
328 }
329 }
330 }
331
332 cout << "Number of points: " << m_neighInds.GetRows() << endl;
333 if (m_neighInds.GetRows() > 0)
334 {
335 cout << "mean Number of Neighbours per point: "
336 << meanN / m_neighInds.GetRows() << endl;
337 }
338}
339
340/**
341 * @brief Computes interpolation weights using gaussian interpolation
342 *
343 * @param searchPt point for which the weights are computed
344 * @param sigma standard deviation of the gauss function
345 *
346 * Performs an interpolation using gauss weighting. Ideal for filtering fields.
347 * The filter width should be half the FWHM (= 1.1774 sigma) and must be set in
348 * the constructor of the Interpolator class.
349 */
350void Interpolator::CalcW_Gauss(const PtsPoint &searchPt, const NekDouble sigma,
351 const int maxPts)
352{
353 // find nearest neighbours
354 vector<PtsPoint> neighbourPts;
355 FindNeighbours(searchPt, neighbourPts, 4 * sigma, maxPts);
356 size_t numPts = neighbourPts.size();
357
358 // handle the cases that there was no or just one point within 4 * sigma
359 if (numPts == 0)
360 {
361 return;
362 }
363 if (numPts == 1)
364 {
365 m_neighInds[searchPt.idx][0] = neighbourPts.front().idx;
366 m_weights[searchPt.idx][0] = 1.0;
367
368 return;
369 }
370
371 NekDouble sigmaNew = 0.25 * neighbourPts.back().dist;
372
373 for (size_t i = 0; i < numPts; i++)
374 {
375 m_neighInds[searchPt.idx][i] = neighbourPts.at(i).idx;
376 }
377
378 NekDouble wSum = 0.0;
379 NekDouble ts2 = 2.0 * sigmaNew * sigmaNew;
380 for (size_t i = 0; i < numPts; ++i)
381 {
382 m_weights[searchPt.idx][i] =
383 exp(-1.0 * neighbourPts[i].dist * neighbourPts[i].dist / ts2);
384 wSum += m_weights[searchPt.idx][i];
385 }
386
387 for (size_t i = 0; i < numPts; ++i)
388 {
389 m_weights[searchPt.idx][i] = m_weights[searchPt.idx][i] / wSum;
390 }
391}
392
393/**
394 * @brief Computes interpolation weights using linear interpolation
395 *
396 * @param searchPt point for which the weights are computed
397 * @param m_coordId coordinate id along which the interpolation should be
398 * performed
399 *
400 * Currently, only implemented for 1D
401 */
402void Interpolator::CalcW_Linear(const PtsPoint &searchPt, int m_coordId)
403{
404 int npts = m_ptsInField->GetNpoints();
405 int i;
406
407 NekDouble coord = searchPt.coords[m_coordId];
408
409 for (i = 0; i < npts - 1; ++i)
410 {
411 if ((m_ptsInField->GetPointVal(0, i) <=
412 (coord + NekConstants::kNekZeroTol)) &&
413 (coord <=
414 (m_ptsInField->GetPointVal(0, i + 1) + NekConstants::kNekZeroTol)))
415 {
416 NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
417 m_ptsInField->GetPointVal(0, i);
418
419 m_neighInds[searchPt.idx][0] = i;
420 m_neighInds[searchPt.idx][1] = i + 1;
421
422 m_weights[searchPt.idx][0] =
423 (m_ptsInField->GetPointVal(0, i + 1) - coord) / pdiff;
424 m_weights[searchPt.idx][1] =
425 (coord - m_ptsInField->GetPointVal(0, i)) / pdiff;
426
427 break;
428 }
429 }
430 ASSERTL0(i != npts - 1, "Failed to find coordinate " +
431 boost::lexical_cast<string>(coord) +
432 " within provided input points");
433}
434
435/**
436 * @brief Computes interpolation weights using nearest neighbour interpolation
437 *
438 * @param searchPt point for which the weights are computed
439 * @param m_coordId coordinate id along which the interpolation should be
440 * performed
441 *
442 */
444{
445 // find nearest neighbours
446 vector<PtsPoint> neighbourPts;
447 // TODO: we currently dont handle the case when there are more than one
448 // most distant points (of same distance)
449 FindNNeighbours(searchPt, neighbourPts, 1);
450
451 m_neighInds[searchPt.idx][0] = neighbourPts[0].idx;
452 m_weights[searchPt.idx][0] = 1.0;
453}
454
455/**
456 * @brief Computes interpolation weights using linear interpolation
457 *
458 * @param searchPt point for which the weights are computed
459 * @param m_coordId coordinate id along which the interpolation should be
460 * performed
461 *
462 * The algorithm is based on Shepard, D. (1968). A two-dimensional interpolation
463 * function for irregularly-spaced data. Proceedings of the 1968 23rd ACM
464 * National Conference. pp. 517–524.
465 *
466 * In order to save memory, for n dimesnions, only 2^n points are considered.
467 * Contrary to Shepard, we use a fixed number of points with fixed weighting
468 * factors 1/d^n.
469 */
470void Interpolator::CalcW_Shepard(const PtsPoint &searchPt, int numPts)
471{
472 // find nearest neighbours
473 vector<PtsPoint> neighbourPts;
474 FindNNeighbours(searchPt, neighbourPts, numPts);
475
476 for (int i = 0; i < neighbourPts.size(); i++)
477 {
478 m_neighInds[searchPt.idx][i] = neighbourPts[i].idx;
479 }
480
481 // In case d < kNekZeroTol, use the exact 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}
504
505/**
506 * @brief Computes interpolation weights using quadratic interpolation
507 *
508 * @param searchPt point for which the weights are computed
509 * @param m_coordId coordinate id along which the interpolation should be
510 * performed
511 *
512 * Currently, only implemented for 1D. Falls back to linear interpolation if
513 * only 2
514 * values are available.
515 */
516void Interpolator::CalcW_Quadratic(const PtsPoint &searchPt, int m_coordId)
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}
586
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), std::back_inserter(result));
612
613 // in case any of these 2 points is too close, remove the current
614 // point
615 // from the tree
616 for (auto &it2 : result)
617 {
618 if (it.second != it2.second &&
619 bg::distance(it.first, it2.first) <= NekConstants::kNekZeroTol)
620 {
621 m_rtree->remove(it);
622 break;
623 }
624 }
625 }
626}
627
628/**
629 * @brief Finds the nearest neighbours of a point
630 *
631 * @param searchPt point for which the neighbours are searched
632 * @param neighbourPts possible neighbour points
633 * @param numPts limits the number of neighbours found to the numPts
634 * nearest ones
635 *
636 */
638 vector<PtsPoint> &neighbourPts,
639 const unsigned int numPts)
640{
641 std::vector<PtsPointPair> result;
642 BPoint searchBPoint(searchPt.coords[0], searchPt.coords[1],
643 searchPt.coords[2]);
644 m_rtree->query(bgi::nearest(searchBPoint, numPts),
645 std::back_inserter(result));
646
647 // massage into or own format
648 for (int i = 0; i < result.size(); ++i)
649 {
650 int idx = result[i].second;
651 Array<OneD, NekDouble> coords(m_dim, 0.0);
652 for (int j = 0; j < m_ptsInField->GetDim(); ++j)
653 {
654 coords[j] = m_ptsInField->GetPointVal(j, idx);
655 }
656 NekDouble d = bg::distance(searchBPoint, result[i].first);
657 neighbourPts.push_back(PtsPoint(idx, coords, d));
658 }
659
660 sort(neighbourPts.begin(), neighbourPts.end());
661}
662
663/**
664 * @brief Finds the nearest neighbours of a point
665 *
666 * @param searchPt point for which the neighbours are searched
667 * @param neighbourPts possible neighbour points
668 * @param dist limits the distance of the neighbours
669 *
670 */
672 vector<PtsPoint> &neighbourPts,
673 const NekDouble dist,
674 const unsigned int maxPts)
675{
676 BPoint searchBPoint(searchPt.coords[0], searchPt.coords[1],
677 searchPt.coords[2]);
678 BPoint bbMin(searchPt.coords[0] - dist, searchPt.coords[1] - dist,
679 searchPt.coords[2] - dist);
680 BPoint bbMax(searchPt.coords[0] + dist, searchPt.coords[1] + dist,
681 searchPt.coords[2] + dist);
682 bg::model::box<BPoint> bbox(bbMin, bbMax);
683
684 // find points within the distance box
685 std::vector<PtsPointPair> result;
686 if (maxPts >= 1)
687 {
688 m_rtree->query(bgi::within(bbox) && bgi::nearest(searchBPoint, maxPts),
689 std::back_inserter(result));
690 }
691 else
692 {
693 m_rtree->query(bgi::within(bbox), std::back_inserter(result));
694 }
695
696 // massage into or own format
697 for (int i = 0; i < result.size(); ++i)
698 {
699 int idx = result[i].second;
700 Array<OneD, NekDouble> coords(m_dim, 0.0);
701 for (int j = 0; j < m_ptsInField->GetDim(); ++j)
702 {
703 coords[j] = m_ptsInField->GetPointVal(j, idx);
704 }
705 NekDouble d = bg::distance(searchBPoint, result[i].first);
706
707 // discard points beyonf dist
708 if (d <= dist)
709 {
710 neighbourPts.push_back(PtsPoint(idx, coords, d));
711 }
712 }
713
714 sort(neighbourPts.begin(), neighbourPts.end());
715}
716} // namespace Nektar::LibUtilities
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202
void Interpolate(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
Interpolate from a pts field to a pts field.
Array< TwoD, NekDouble > m_weights
Interpolation weights for each neighbour. Structure: m_weights[physPtIdx][neighbourIdx].
int GetCoordId() const
Returns the coordinate id along which the interpolation should be performed.
void PrintStatistics()
Returns if the weights have already been computed.
LibUtilities::PtsFieldSharedPtr GetInField() const
Returns the input field.
int m_maxPts
Max number of interpolation points.
Array< TwoD, unsigned int > m_neighInds
Indices of the relevant neighbours for each physical point. Structure: m_neighInds[ptIdx][neighbourId...
LibUtilities::PtsFieldSharedPtr GetOutField() const
Returns the output field.
static const int m_dim
dimension of this interpolator. Hardcoded to 3
int GetDim() const
returns the dimension of the Interpolator. Should be higher than the dimensions of the interpolated f...
std::shared_ptr< PtsRtree > m_rtree
A tree structure to speed up the neighbour search. Note that we fill it with an iterator,...
NekDouble m_filtWidth
Filter width used for some interpolation algorithms.
void CalcW_Linear(const PtsPoint &searchPt, int coordId)
Computes interpolation weights using linear interpolation.
boost::geometry::model::point< NekDouble, m_dim, boost::geometry::cs::cartesian > BPoint
void CalcW_NNeighbour(const PtsPoint &searchPt)
Computes interpolation weights using nearest neighbour interpolation.
LibUtilities::PtsFieldSharedPtr m_ptsInField
input field
void CalcW_Shepard(const PtsPoint &searchPt, int numPts)
Computes interpolation weights using linear interpolation.
NekDouble GetFiltWidth() const
Returns the filter width.
InterpMethod GetInterpMethod() const
Returns the interpolation method used by this interpolator.
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 FindNNeighbours(const PtsPoint &searchPt, std::vector< PtsPoint > &neighbourPts, const unsigned int numPts=1)
Finds the nearest neighbours of a point.
void CalcW_Quadratic(const PtsPoint &searchPt, int coordId)
Computes interpolation weights using quadratic interpolation.
void CalcWeights(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField, bool reuseTree=false)
Compute interpolation weights without doing any interpolation.
void FindNeighbours(const PtsPoint &searchPt, std::vector< PtsPoint > &neighbourPts, const NekDouble dist, const unsigned int maxPts=1)
Finds the nearest neighbours of a point.
short int m_coordId
coordinate id along which the interpolation should be performed
LibUtilities::PtsFieldSharedPtr m_ptsOutField
output field
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:184
static const NekDouble kNekZeroTol
std::vector< double > d(NPUPPER *NPUPPER)
double NekDouble