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
44namespace Nektar
45{
46namespace LibUtilities
47{
48
49/**
50 * @brief Compute interpolation weights without doing any interpolation
51 *
52 * @param ptsInField input field
53 * @param ptsOutField output field
54 * @param reuseTree if an r-tree has been constructed already, reuse it
55 * (e.g. for repeated calls over the same input points).
56 *
57 * In and output fields must have the same dimension. The most suitable
58 * algorithm is chosen automatically if it wasnt set explicitly.
59 */
62 bool reuseTree)
63{
64 ASSERTL0(ptsInField->GetDim() <= m_dim, "too many dimensions in inField");
65 ASSERTL0(ptsOutField->GetDim() <= m_dim, "too many dimensions 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 {
98 {
99 m_weights = Array<TwoD, NekDouble>(nOutPts, 1, 0.0);
100 m_neighInds = Array<TwoD, unsigned int>(nOutPts, 1, 0u);
101
102 for (size_t i = 0; i < nOutPts; ++i)
103 {
105 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
106 {
107 tmp[j] = m_ptsOutField->GetPointVal(j, i);
108 }
109 PtsPoint searchPt(i, tmp, 1E30);
110
111 CalcW_NNeighbour(searchPt);
112
113 int progress = int(100 * i / nOutPts);
114 if (m_progressCallback && progress > lastProg)
115 {
116 m_progressCallback(i, nOutPts);
117 lastProg = progress;
118 }
119 }
120
121 break;
122 }
123
124 case eQuadratic:
125 {
126 ASSERTL0(m_ptsInField->GetDim() == 1 || m_coordId >= 0,
127 "not implemented");
128
129 m_weights = Array<TwoD, NekDouble>(nOutPts, 3, 0.0);
130 m_neighInds = Array<TwoD, unsigned int>(nOutPts, 3, 0u);
131
132 for (size_t i = 0; i < nOutPts; ++i)
133 {
135 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
136 {
137 tmp[j] = m_ptsOutField->GetPointVal(j, i);
138 }
139 PtsPoint searchPt(i, tmp, 1E30);
140
141 if (m_ptsInField->GetNpoints() <= 2)
142 {
143 CalcW_Linear(searchPt, m_coordId);
144 }
145 else
146 {
147 CalcW_Quadratic(searchPt, m_coordId);
148 }
149
150 int progress = int(100 * i / nOutPts);
151 if (m_progressCallback && progress > lastProg)
152 {
153 m_progressCallback(i, nOutPts);
154 lastProg = progress;
155 }
156 }
157
158 break;
159 }
160
161 case eShepard:
162 {
163 int numPts = m_ptsInField->GetDim();
164 numPts = 1 << numPts; // 2 ^ numPts
165 numPts = min(numPts, int(m_ptsInField->GetNpoints() / 2));
166
167 m_weights = Array<TwoD, NekDouble>(nOutPts, numPts, 0.0);
168 m_neighInds = Array<TwoD, unsigned int>(nOutPts, numPts, 0u);
169
170 for (size_t i = 0; i < nOutPts; ++i)
171 {
173 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
174 {
175 tmp[j] = m_ptsOutField->GetPointVal(j, i);
176 }
177 PtsPoint searchPt(i, tmp, 1E30);
178
179 CalcW_Shepard(searchPt, numPts);
180
181 int progress = int(100 * i / nOutPts);
182 if (m_progressCallback && progress > lastProg)
183 {
184 m_progressCallback(i, nOutPts);
185 lastProg = progress;
186 }
187 }
188
189 break;
190 }
191
192 case eGauss:
193 {
195 "No filter width set");
196 // use m_filtWidth as FWHM
197 NekDouble sigma = m_filtWidth * 0.4246609001;
198
199 m_maxPts = min(m_maxPts, int(m_ptsInField->GetNpoints() / 2));
200
203
204 for (size_t i = 0; i < nOutPts; ++i)
205 {
207 for (size_t j = 0; j < m_ptsOutField->GetDim(); ++j)
208 {
209 tmp[j] = m_ptsOutField->GetPointVal(j, i);
210 }
211 PtsPoint searchPt(i, tmp, 1E30);
212
213 CalcW_Gauss(searchPt, sigma, m_maxPts);
214
215 int progress = int(100 * i / nOutPts);
216 if (m_progressCallback && progress > lastProg)
217 {
218 m_progressCallback(i, nOutPts);
219 lastProg = progress;
220 }
221 }
222
223 break;
224 }
225
226 default:
227 NEKERROR(ErrorUtil::efatal, "Invalid interpolation m_method");
228 break;
229 }
230}
231
232/**
233 * @brief Interpolate from a pts field to a pts field
234 *
235 * @param ptsInField input field
236 * @param ptsOutField output field
237 *
238 * In and output fields must have the same dimension and number of fields.
239 * The most suitable algorithm is chosen automatically if it wasnt set
240 * explicitly.
241 */
244{
245 ASSERTL0(ptsInField->GetNFields() == ptsOutField->GetNFields(),
246 "number of fields does not match");
247 ASSERTL0(ptsInField->GetDim() <= m_dim, "too many dimesions in inField");
248 ASSERTL0(ptsOutField->GetDim() <= m_dim, "too many dimesions in outField");
249
250 m_ptsInField = ptsInField;
251 m_ptsOutField = ptsOutField;
252
253 if (m_weights.GetRows() == 0)
254 {
256 }
257
258 ASSERTL0(m_weights.GetRows() == m_ptsOutField->GetNpoints(),
259 "weights dimension mismatch");
260
261 size_t nFields = m_ptsOutField->GetNFields();
262 size_t nOutPts = m_ptsOutField->GetNpoints();
263 size_t inDim = m_ptsInField->GetDim();
264
265 // interpolate points and transform
266 for (size_t i = 0; i < nFields; ++i)
267 {
268 for (size_t j = 0; j < nOutPts; ++j)
269 {
270 size_t nPts = m_weights.GetColumns();
271
272 // skip if there were no neighbours found for this point
273 if (nPts == 0)
274 {
275 continue;
276 }
277
278 NekDouble val = 0.0;
279 for (size_t k = 0; k < nPts; ++k)
280 {
281 size_t nIdx = m_neighInds[j][k];
282 val += m_weights[j][k] *
283 m_ptsInField->GetPointVal(inDim + i, nIdx);
284 }
285 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + i, j, val);
286 }
287 }
288}
289
291{
292 return m_dim;
293}
294
296{
297 return m_coordId;
298}
299
301{
302 return m_filtWidth;
303}
304
306{
307 return m_method;
308}
309
311{
312 return m_ptsInField;
313}
314
316{
317 return m_ptsOutField;
318}
319
321{
322 int meanN = 0;
323 for (int i = 0; i < m_neighInds.GetRows(); ++i)
324 {
325 for (int j = 0; j < m_neighInds.GetColumns(); ++j)
326 {
327 if (m_neighInds[i][j] > 0)
328 {
329 meanN += 1;
330 }
331 }
332 }
333
334 cout << "Number of points: " << m_neighInds.GetRows() << endl;
335 if (m_neighInds.GetRows() > 0)
336 {
337 cout << "mean Number of Neighbours per point: "
338 << meanN / m_neighInds.GetRows() << endl;
339 }
340}
341
342/**
343 * @brief Computes interpolation weights using gaussian interpolation
344 *
345 * @param searchPt point for which the weights are computed
346 * @param sigma standard deviation of the gauss function
347 *
348 * Performs an interpolation using gauss weighting. Ideal for filtering fields.
349 * The filter width should be half the FWHM (= 1.1774 sigma) and must be set in
350 * the constructor of the Interpolator class.
351 */
352void Interpolator::CalcW_Gauss(const PtsPoint &searchPt, const NekDouble sigma,
353 const int maxPts)
354{
355 // find nearest neighbours
356 vector<PtsPoint> neighbourPts;
357 FindNeighbours(searchPt, neighbourPts, 4 * sigma, maxPts);
358 size_t numPts = neighbourPts.size();
359
360 // handle the cases that there was no or just one point within 4 * sigma
361 if (numPts == 0)
362 {
363 return;
364 }
365 if (numPts == 1)
366 {
367 m_neighInds[searchPt.idx][0] = neighbourPts.front().idx;
368 m_weights[searchPt.idx][0] = 1.0;
369
370 return;
371 }
372
373 NekDouble sigmaNew = 0.25 * neighbourPts.back().dist;
374
375 for (size_t i = 0; i < numPts; i++)
376 {
377 m_neighInds[searchPt.idx][i] = neighbourPts.at(i).idx;
378 }
379
380 NekDouble wSum = 0.0;
381 NekDouble ts2 = 2.0 * sigmaNew * sigmaNew;
382 for (size_t i = 0; i < numPts; ++i)
383 {
384 m_weights[searchPt.idx][i] =
385 exp(-1.0 * neighbourPts[i].dist * neighbourPts[i].dist / ts2);
386 wSum += m_weights[searchPt.idx][i];
387 }
388
389 for (size_t i = 0; i < numPts; ++i)
390 {
391 m_weights[searchPt.idx][i] = m_weights[searchPt.idx][i] / wSum;
392 }
393}
394
395/**
396 * @brief Computes interpolation weights using linear interpolation
397 *
398 * @param searchPt point for which the weights are computed
399 * @param m_coordId coordinate id along which the interpolation should be
400 * performed
401 *
402 * Currently, only implemented for 1D
403 */
404void Interpolator::CalcW_Linear(const PtsPoint &searchPt, int m_coordId)
405{
406 int npts = m_ptsInField->GetNpoints();
407 int i;
408
409 NekDouble coord = searchPt.coords[m_coordId];
410
411 for (i = 0; i < npts - 1; ++i)
412 {
413 if ((m_ptsInField->GetPointVal(0, i) <=
414 (coord + NekConstants::kNekZeroTol)) &&
415 (coord <=
416 (m_ptsInField->GetPointVal(0, i + 1) + NekConstants::kNekZeroTol)))
417 {
418 NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
419 m_ptsInField->GetPointVal(0, i);
420
421 m_neighInds[searchPt.idx][0] = i;
422 m_neighInds[searchPt.idx][1] = i + 1;
423
424 m_weights[searchPt.idx][0] =
425 (m_ptsInField->GetPointVal(0, i + 1) - coord) / pdiff;
426 m_weights[searchPt.idx][1] =
427 (coord - m_ptsInField->GetPointVal(0, i)) / pdiff;
428
429 break;
430 }
431 }
432 ASSERTL0(i != npts - 1, "Failed to find coordinate " +
433 boost::lexical_cast<string>(coord) +
434 " within provided input points");
435}
436
437/**
438 * @brief Computes interpolation weights using nearest neighbour interpolation
439 *
440 * @param searchPt point for which the weights are computed
441 * @param m_coordId coordinate id along which the interpolation should be
442 * performed
443 *
444 */
446{
447 // find nearest neighbours
448 vector<PtsPoint> neighbourPts;
449 // TODO: we currently dont handle the case when there are more than one
450 // most distant points (of same distance)
451 FindNNeighbours(searchPt, neighbourPts, 1);
452
453 m_neighInds[searchPt.idx][0] = neighbourPts[0].idx;
454 m_weights[searchPt.idx][0] = 1.0;
455}
456
457/**
458 * @brief Computes interpolation weights using linear interpolation
459 *
460 * @param searchPt point for which the weights are computed
461 * @param m_coordId coordinate id along which the interpolation should be
462 * performed
463 *
464 * The algorithm is based on Shepard, D. (1968). A two-dimensional interpolation
465 * function for irregularly-spaced data. Proceedings of the 1968 23rd ACM
466 * National Conference. pp. 517–524.
467 *
468 * In order to save memory, for n dimesnions, only 2^n points are considered.
469 * Contrary to Shepard, we use a fixed number of points with fixed weighting
470 * factors 1/d^n.
471 */
472void Interpolator::CalcW_Shepard(const PtsPoint &searchPt, int numPts)
473{
474 // find nearest neighbours
475 vector<PtsPoint> neighbourPts;
476 FindNNeighbours(searchPt, neighbourPts, numPts);
477
478 for (int i = 0; i < neighbourPts.size(); i++)
479 {
480 m_neighInds[searchPt.idx][i] = neighbourPts[i].idx;
481 }
482
483 // In case d < kNekZeroTol, use the exact point and return
484 for (int i = 0; i < neighbourPts.size(); ++i)
485 {
486 if (neighbourPts[i].dist <= NekConstants::kNekZeroTol)
487 {
488 m_weights[searchPt.idx][i] = 1.0;
489 return;
490 }
491 }
492
493 NekDouble wSum = 0.0;
494 for (int i = 0; i < neighbourPts.size(); ++i)
495 {
496 m_weights[searchPt.idx][i] = 1 / pow(double(neighbourPts[i].dist),
497 double(m_ptsInField->GetDim()));
498 wSum += m_weights[searchPt.idx][i];
499 }
500
501 for (int i = 0; i < neighbourPts.size(); ++i)
502 {
503 m_weights[searchPt.idx][i] = m_weights[searchPt.idx][i] / wSum;
504 }
505}
506
507/**
508 * @brief Computes interpolation weights using quadratic interpolation
509 *
510 * @param searchPt point for which the weights are computed
511 * @param m_coordId coordinate id along which the interpolation should be
512 * performed
513 *
514 * Currently, only implemented for 1D. Falls back to linear interpolation if
515 * only 2
516 * values are available.
517 */
518void Interpolator::CalcW_Quadratic(const PtsPoint &searchPt, int m_coordId)
519{
520 int npts = m_ptsInField->GetNpoints();
521 int i;
522
523 NekDouble coord = searchPt.coords[m_coordId];
524
525 for (i = 0; i < npts - 1; ++i)
526 {
527 if ((m_ptsInField->GetPointVal(0, i) <=
528 (coord + NekConstants::kNekZeroTol)) &&
529 (coord <=
530 (m_ptsInField->GetPointVal(0, i + 1) + NekConstants::kNekZeroTol)))
531 {
532 NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
533 m_ptsInField->GetPointVal(0, i);
534 NekDouble h1, h2, h3;
535
536 if (i < npts - 2)
537 {
538 // forwards stencil
539 NekDouble pdiff2 = m_ptsInField->GetPointVal(0, i + 2) -
540 m_ptsInField->GetPointVal(0, i + 1);
541
542 h1 = (m_ptsInField->GetPointVal(0, i + 1) - coord) *
543 (m_ptsInField->GetPointVal(0, i + 2) - coord) /
544 (pdiff * (pdiff + pdiff2));
545 h2 = (coord - m_ptsInField->GetPointVal(0, i)) *
546 (m_ptsInField->GetPointVal(0, i + 2) - coord) /
547 (pdiff * pdiff2);
548 h3 = (coord - m_ptsInField->GetPointVal(0, i)) *
549 (coord - m_ptsInField->GetPointVal(0, i + 1)) /
550 ((pdiff + pdiff2) * pdiff2);
551
552 m_neighInds[searchPt.idx][0] = i;
553 m_neighInds[searchPt.idx][1] = i + 1;
554 m_neighInds[searchPt.idx][2] = i + 2;
555 }
556 else
557 {
558 // backwards stencil
559 NekDouble pdiff2 = m_ptsInField->GetPointVal(0, i) -
560 m_ptsInField->GetPointVal(0, i - 1);
561
562 h1 = (m_ptsInField->GetPointVal(0, i + 1) - coord) *
563 (coord - m_ptsInField->GetPointVal(0, i - 1)) /
564 (pdiff * pdiff2);
565 h2 = (coord - m_ptsInField->GetPointVal(0, i)) *
566 (coord - m_ptsInField->GetPointVal(0, i - 1)) /
567 (pdiff * (pdiff + pdiff2));
568 h3 = (m_ptsInField->GetPointVal(0, i) - coord) *
569 (m_ptsInField->GetPointVal(0, i + 1) - coord) /
570 ((pdiff + pdiff2) * pdiff);
571
572 m_neighInds[searchPt.idx][0] = i;
573 m_neighInds[searchPt.idx][1] = i + 1;
574 m_neighInds[searchPt.idx][2] = i - 1;
575 }
576
577 m_weights[searchPt.idx][0] = h1;
578 m_weights[searchPt.idx][1] = h2;
579 m_weights[searchPt.idx][2] = h3;
580
581 break;
582 }
583 }
584 ASSERTL0(i != npts - 1, "Failed to find coordinate " +
585 boost::lexical_cast<string>(coord) +
586 " within provided input points");
587}
588
590{
591 std::vector<PtsPointPair> inPoints;
592 for (int i = 0; i < m_ptsInField->GetNpoints(); ++i)
593 {
594 Array<OneD, NekDouble> coords(3, 0.0);
595 for (int j = 0; j < m_ptsInField->GetDim(); ++j)
596 {
597 coords[j] = m_ptsInField->GetPointVal(j, i);
598 }
599 inPoints.push_back(
600 PtsPointPair(BPoint(coords[0], coords[1], coords[2]), i));
601 }
603 m_rtree->insert(inPoints.begin(), inPoints.end());
604
605 // remove duplicates from tree
606 for (auto &it : inPoints)
607 {
608 std::vector<PtsPointPair> result;
609
610 // find nearest 2 points (2 because one of these might be the one we
611 // are
612 // checking)
613 m_rtree->query(bgi::nearest(it.first, 2), std::back_inserter(result));
614
615 // in case any of these 2 points is too close, remove the current
616 // point
617 // from the tree
618 for (auto &it2 : result)
619 {
620 if (it.second != it2.second &&
621 bg::distance(it.first, it2.first) <= NekConstants::kNekZeroTol)
622 {
623 m_rtree->remove(it);
624 break;
625 }
626 }
627 }
628}
629
630/**
631 * @brief Finds the nearest neighbours of a point
632 *
633 * @param searchPt point for which the neighbours are searched
634 * @param neighbourPts possible neighbour points
635 * @param numPts limits the number of neighbours found to the numPts
636 * nearest ones
637 *
638 */
640 vector<PtsPoint> &neighbourPts,
641 const unsigned int numPts)
642{
643 std::vector<PtsPointPair> result;
644 BPoint searchBPoint(searchPt.coords[0], searchPt.coords[1],
645 searchPt.coords[2]);
646 m_rtree->query(bgi::nearest(searchBPoint, numPts),
647 std::back_inserter(result));
648
649 // massage into or own format
650 for (int i = 0; i < result.size(); ++i)
651 {
652 int idx = result[i].second;
653 Array<OneD, NekDouble> coords(m_dim, 0.0);
654 for (int j = 0; j < m_ptsInField->GetDim(); ++j)
655 {
656 coords[j] = m_ptsInField->GetPointVal(j, idx);
657 }
658 NekDouble d = bg::distance(searchBPoint, result[i].first);
659 neighbourPts.push_back(PtsPoint(idx, coords, d));
660 }
661
662 sort(neighbourPts.begin(), neighbourPts.end());
663}
664
665/**
666 * @brief Finds the nearest neighbours of a point
667 *
668 * @param searchPt point for which the neighbours are searched
669 * @param neighbourPts possible neighbour points
670 * @param dist limits the distance of the neighbours
671 *
672 */
674 vector<PtsPoint> &neighbourPts,
675 const NekDouble dist,
676 const unsigned int maxPts)
677{
678 BPoint searchBPoint(searchPt.coords[0], searchPt.coords[1],
679 searchPt.coords[2]);
680 BPoint bbMin(searchPt.coords[0] - dist, searchPt.coords[1] - dist,
681 searchPt.coords[2] - dist);
682 BPoint bbMax(searchPt.coords[0] + dist, searchPt.coords[1] + dist,
683 searchPt.coords[2] + dist);
684 bg::model::box<BPoint> bbox(bbMin, bbMax);
685
686 // find points within the distance box
687 std::vector<PtsPointPair> result;
688 if (maxPts >= 1)
689 {
690 m_rtree->query(bgi::within(bbox) && bgi::nearest(searchBPoint, maxPts),
691 std::back_inserter(result));
692 }
693 else
694 {
695 m_rtree->query(bgi::within(bbox), std::back_inserter(result));
696 }
697
698 // massage into or own format
699 for (int i = 0; i < result.size(); ++i)
700 {
701 int idx = result[i].second;
702 Array<OneD, NekDouble> coords(m_dim, 0.0);
703 for (int j = 0; j < m_ptsInField->GetDim(); ++j)
704 {
705 coords[j] = m_ptsInField->GetPointVal(j, idx);
706 }
707 NekDouble d = bg::distance(searchBPoint, result[i].first);
708
709 // discard points beyonf dist
710 if (d <= dist)
711 {
712 neighbourPts.push_back(PtsPoint(idx, coords, d));
713 }
714 }
715
716 sort(neighbourPts.begin(), neighbourPts.end());
717}
718} // namespace LibUtilities
719} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
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:190
static const NekDouble kNekZeroTol
std::vector< double > d(NPUPPER *NPUPPER)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble