58 ASSERTL0(ptsInField->GetDim() <= m_dim,
"too many dimesions in inField");
59 ASSERTL0(ptsOutField->GetDim() <= m_dim,
"too many dimesions in outField");
61 m_ptsInField = ptsInField;
62 m_ptsOutField = ptsOutField;
64 int nOutPts = m_ptsOutField->GetNpoints();
73 if (m_ptsInField->GetDim() == 1 || m_coordId >= 0)
92 for (
int i = 0; i < nOutPts; ++i)
95 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
97 tmp[j] = m_ptsOutField->GetPointVal(j, i);
101 CalcW_NNeighbour(searchPt);
103 int progress = int(100 * i / nOutPts);
104 if (m_progressCallback && progress > lastProg)
106 m_progressCallback(i, nOutPts);
116 ASSERTL0(m_ptsInField->GetDim() == 1 || m_coordId >= 0,
119 if (m_ptsInField->GetDim() == 1)
124 for (
int i = 0; i < nOutPts; ++i)
127 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
129 tmp[j] = m_ptsOutField->GetPointVal(j, i);
133 if (m_ptsInField->GetNpoints() <= 2)
135 CalcW_Linear(searchPt, m_coordId);
139 CalcW_Quadratic(searchPt, m_coordId);
142 int progress = int(100 * i / nOutPts);
143 if (m_progressCallback && progress > lastProg)
145 m_progressCallback(i, nOutPts);
155 for (
int i = 0; i < nOutPts; ++i)
158 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
160 tmp[j] = m_ptsOutField->GetPointVal(j, i);
164 CalcW_Shepard(searchPt);
166 int progress = int(100 * i / nOutPts);
167 if (m_progressCallback && progress > lastProg)
169 m_progressCallback(i, nOutPts);
180 "No filter width set");
182 NekDouble sigma = m_filtWidth * 0.4246609001;
184 for (
int i = 0; i < nOutPts; ++i)
187 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
189 tmp[j] = m_ptsOutField->GetPointVal(j, i);
193 CalcW_Gauss(searchPt, sigma, m_maxPts);
195 int progress = int(100 * i / nOutPts);
196 if (m_progressCallback && progress > lastProg)
198 m_progressCallback(i, nOutPts);
207 ASSERTL0(
false,
"Invalid interpolation m_method");
225 ASSERTL0(ptsInField->GetNFields() == ptsOutField->GetNFields(),
226 "number of fields does not match");
227 ASSERTL0(ptsInField->GetDim() <= m_dim,
"too many dimesions in inField");
228 ASSERTL0(ptsOutField->GetDim() <= m_dim,
"too many dimesions in outField");
230 m_ptsInField = ptsInField;
231 m_ptsOutField = ptsOutField;
233 if (m_weights.num_elements() == 0)
235 CalcWeights(m_ptsInField, m_ptsOutField);
238 ASSERTL0(m_weights.num_elements() == m_ptsOutField->GetNpoints(),
239 "weights dimension mismatch");
241 int nFields = m_ptsOutField->GetNFields();
242 int nOutPts = m_ptsOutField->GetNpoints();
243 int inDim = m_ptsInField->GetDim();
246 for (
int i = 0; i < nFields; ++i)
248 for (
int j = 0; j < nOutPts; ++j)
250 int nPts = m_weights[j].num_elements();
259 for (
int k = 0; k < nPts; ++k)
261 unsigned int nIdx = m_neighInds[j][k];
262 val += m_weights[j][k] *
263 m_ptsInField->GetPointVal(inDim + i, nIdx);
265 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + i, j, val);
284 void Interpolator::Interpolate(
285 const vector<MultiRegions::ExpListSharedPtr> expInField,
286 vector<MultiRegions::ExpListSharedPtr> &expOutField,
289 ASSERTL0(expInField.size() == expOutField.size(),
290 "number of fields does not match");
291 ASSERTL0(expInField[0]->GetCoordim(0) <= m_dim,
292 "too many dimesions in inField");
293 ASSERTL0(expOutField[0]->GetCoordim(0) <= m_dim,
294 "too many dimesions in outField")
296 "only direct evaluation supported for this interpolation");
298 m_expInField = expInField;
299 m_expOutField = expOutField;
301 int nInDim = expInField[0]->GetCoordim(0);
302 int nOutPts = m_expOutField[0]->GetTotPoints();
303 int nOutDim = m_expOutField[0]->GetCoordim(0);
312 for (
int i = 0; i < nOutDim; ++i)
318 m_expOutField[0]->GetCoords(coords[0]);
320 else if (nOutDim == 2)
322 m_expOutField[0]->GetCoords(coords[0], coords[1]);
324 else if (nOutDim == 3)
326 m_expOutField[0]->GetCoords(coords[0], coords[1], coords[2]);
329 for (
int i = 0; i < nOutPts; ++i)
331 for (
int j = 0; j < nOutDim; ++j)
333 Scoords[j] = coords[j][i];
337 int elmtid = m_expInField[0]->GetExpIndex(Scoords, Lcoords,
342 int offset = m_expInField[0]->GetPhys_Offset(elmtid);
344 for (
int f = 0; f < m_expInField.size(); ++f)
347 m_expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
348 Lcoords, m_expInField[f]->GetPhys() + offset);
350 if ((boost::math::isnan)(value))
352 ASSERTL0(
false,
"new value is not a number");
356 m_expOutField[f]->UpdatePhys()[i] = value;
362 for (
int f = 0; f < m_expInField.size(); ++f)
364 m_expOutField[f]->UpdatePhys()[i] = def_value;
368 int progress = int(100 * i / nOutPts);
369 if (m_progressCallback && progress > lastProg)
371 m_progressCallback(i, nOutPts);
388 void Interpolator::Interpolate(
389 const vector<MultiRegions::ExpListSharedPtr> expInField,
393 ASSERTL0(expInField.size() == ptsOutField->GetNFields(),
394 "number of fields does not match");
395 ASSERTL0(expInField[0]->GetCoordim(0) <= m_dim,
396 "too many dimesions in inField");
397 ASSERTL0(ptsOutField->GetDim() <= m_dim,
"too many dimesions in outField");
399 "only direct evaluation supported for this interpolation");
401 m_expInField = expInField;
402 m_ptsOutField = ptsOutField;
404 int nInDim = expInField[0]->GetCoordim(0);
405 int nOutPts = m_ptsOutField->GetNpoints();
411 for (
int i = 0; i < nOutPts; ++i)
415 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
417 coords[j] = m_ptsOutField->GetPointVal(j, i);
421 int elmtid = m_expInField[0]->GetExpIndex(coords, Lcoords,
426 int offset = m_expInField[0]->GetPhys_Offset(elmtid);
428 for (
int f = 0; f < m_expInField.size(); ++f)
431 m_expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
432 Lcoords, m_expInField[f]->GetPhys() + offset);
434 if ((boost::math::isnan)(value))
436 ASSERTL0(
false,
"new value is not a number");
440 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
447 for (
int f = 0; f < m_expInField.size(); ++f)
449 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
454 int progress = int(100 * i / nOutPts);
455 if (m_progressCallback && progress > lastProg)
457 m_progressCallback(i, nOutPts);
471 void Interpolator::Interpolate(
473 vector<MultiRegions::ExpListSharedPtr> &expOutField)
475 ASSERTL0(expOutField.size() == ptsInField->GetNFields(),
476 "number of fields does not match");
477 ASSERTL0(ptsInField->GetDim() <= m_dim,
"too many dimesions in inField");
478 ASSERTL0(expOutField[0]->GetCoordim(0) <= m_dim,
479 "too many dimesions in outField");
481 m_ptsInField = ptsInField;
482 m_expOutField = expOutField;
484 int nFields = max((
int)ptsInField->GetNFields(), (int)m_expOutField.size());
485 int nOutPts = m_expOutField[0]->GetTotPoints();
486 int outDim = m_expOutField[0]->GetCoordim(0);
490 for (
int i = 0; i < outDim; ++i)
496 m_expOutField[0]->GetCoords(pts[0]);
498 else if (outDim == 2)
500 m_expOutField[0]->GetCoords(pts[0], pts[1]);
502 else if (outDim == 3)
504 m_expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
509 for (
int f = 0; f < expOutField.size(); ++f)
511 tmpPts->AddField(m_expOutField[f]->GetCoeffs(),
512 m_ptsInField->GetFieldName(f));
516 Interpolate(m_ptsInField, tmpPts);
519 for (
int i = 0; i < nFields; i++)
521 for (
int j = 0; j < nOutPts; ++j)
523 m_expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(i, j);
528 int Interpolator::GetDim()
const
533 int Interpolator::GetCoordId()
const
555 return m_ptsOutField;
558 void Interpolator::PrintStatistics()
561 for (
int i = 0; i < m_neighInds.num_elements(); ++i)
563 meanN += m_neighInds[i].num_elements();
566 cout <<
"Number of points: " << m_neighInds.num_elements() << endl;
567 cout <<
"mean Number of Neighbours per point: "
568 << meanN / m_neighInds.num_elements() << endl;
581 void Interpolator::CalcW_Gauss(
const PtsPoint &searchPt,
586 vector<PtsPoint> neighbourPts;
587 FindNeighbours(searchPt, neighbourPts, 4 * sigma, maxPts);
588 int numPts = neighbourPts.size();
600 m_neighInds[searchPt.
idx] =
607 NekDouble sigmaNew = 0.25 * neighbourPts.back().dist;
610 for (
int i = 0; i < numPts; i++)
612 m_neighInds[searchPt.
idx][i] = neighbourPts.at(i).idx;
619 for (
int i = 0; i < numPts; ++i)
621 m_weights[searchPt.
idx][i] =
622 exp(-1 * pow(neighbourPts[i].dist,
double(2.0)) / ts2);
623 wSum += m_weights[searchPt.
idx][i];
626 for (
int i = 0; i < numPts; ++i)
628 m_weights[searchPt.
idx][i] = m_weights[searchPt.
idx][i] / wSum;
632 "NaN found in weights");
644 void Interpolator::CalcW_Linear(
const PtsPoint &searchPt,
int m_coordId)
646 int npts = m_ptsInField->GetNpoints();
655 for (i = 0; i < npts - 1; ++i)
657 if ((m_ptsInField->GetPointVal(0, i) <=
662 NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
663 m_ptsInField->GetPointVal(0, i);
665 m_neighInds[searchPt.
idx][0] = i;
666 m_neighInds[searchPt.
idx][1] = i + 1;
668 m_weights[searchPt.
idx][0] =
669 (m_ptsInField->GetPointVal(0, i + 1) - coord) / pdiff;
670 m_weights[searchPt.
idx][1] =
671 (coord - m_ptsInField->GetPointVal(0, i)) / pdiff;
676 ASSERTL0(i != npts - 1,
"Failed to find coordinate " +
677 boost::lexical_cast<string>(coord) +
678 " within provided input points");
689 void Interpolator::CalcW_NNeighbour(
const PtsPoint &searchPt)
692 vector<PtsPoint> neighbourPts;
695 FindNNeighbours(searchPt, neighbourPts, 1);
697 m_neighInds[searchPt.
idx] =
717 void Interpolator::CalcW_Shepard(
const PtsPoint &searchPt)
720 vector<PtsPoint> neighbourPts;
721 int numPts = pow(
double(2), m_ptsInField->GetDim());
722 numPts = min(numPts,
int(m_ptsInField->GetNpoints() / 2));
723 FindNNeighbours(searchPt, neighbourPts, numPts);
726 for (
int i = 0; i < numPts; i++)
728 m_neighInds[searchPt.
idx][i] = neighbourPts.at(i).idx;
735 for (
int i = 0; i < numPts; ++i)
739 m_weights[searchPt.
idx][i] = 1.0;
745 for (
int i = 0; i < numPts; ++i)
747 m_weights[searchPt.
idx][i] = 1 / pow(
double(neighbourPts[i].dist),
748 double(m_ptsInField->GetDim()));
749 wSum += m_weights[searchPt.
idx][i];
752 for (
int i = 0; i < numPts; ++i)
754 m_weights[searchPt.
idx][i] = m_weights[searchPt.
idx][i] / wSum;
758 "NaN found in weights");
772 void Interpolator::CalcW_Quadratic(
const PtsPoint &searchPt,
int m_coordId)
774 int npts = m_ptsInField->GetNpoints();
783 for (i = 0; i < npts - 1; ++i)
785 if ((m_ptsInField->GetPointVal(0, i) <=
790 NekDouble pdiff = m_ptsInField->GetPointVal(0, i + 1) -
791 m_ptsInField->GetPointVal(0, i);
797 NekDouble pdiff2 = m_ptsInField->GetPointVal(0, i + 2) -
798 m_ptsInField->GetPointVal(0, i + 1);
800 h1 = (m_ptsInField->GetPointVal(0, i + 1) - coord) *
801 (m_ptsInField->GetPointVal(0, i + 2) - coord) /
802 (pdiff * (pdiff + pdiff2));
803 h2 = (coord - m_ptsInField->GetPointVal(0, i)) *
804 (m_ptsInField->GetPointVal(0, i + 2) - coord) /
806 h3 = (coord - m_ptsInField->GetPointVal(0, i)) *
807 (coord - m_ptsInField->GetPointVal(0, i + 1)) /
808 ((pdiff + pdiff2) * pdiff2);
810 m_neighInds[searchPt.
idx][0] = i;
811 m_neighInds[searchPt.
idx][1] = i + 1;
812 m_neighInds[searchPt.
idx][2] = i + 2;
817 NekDouble pdiff2 = m_ptsInField->GetPointVal(0, i) -
818 m_ptsInField->GetPointVal(0, i - 1);
820 h1 = (m_ptsInField->GetPointVal(0, i + 1) - coord) *
821 (coord - m_ptsInField->GetPointVal(0, i - 1)) /
823 h2 = (coord - m_ptsInField->GetPointVal(0, i)) *
824 (coord - m_ptsInField->GetPointVal(0, i - 1)) /
825 (pdiff * (pdiff + pdiff2));
826 h3 = (m_ptsInField->GetPointVal(0, i) - coord) *
827 (m_ptsInField->GetPointVal(0, i + 1) - coord) /
828 ((pdiff + pdiff2) * pdiff);
830 m_neighInds[searchPt.
idx][0] = i;
831 m_neighInds[searchPt.
idx][1] = i + 1;
832 m_neighInds[searchPt.
idx][2] = i - 1;
835 m_weights[searchPt.
idx][0] = h1;
836 m_weights[searchPt.
idx][1] = h2;
837 m_weights[searchPt.
idx][2] = h3;
842 ASSERTL0(i != npts - 1,
"Failed to find coordinate " +
843 boost::lexical_cast<string>(coord) +
844 " within provided input points");
847 void Interpolator::SetupTree()
849 std::vector<PtsPointPair> inPoints;
850 for (
int i = 0; i < m_ptsInField->GetNpoints(); ++i)
853 for (
int j = 0; j < m_ptsInField->GetDim(); ++j)
855 coords[j] = m_ptsInField->GetPointVal(j, i);
861 m_rtree->insert(inPoints.begin(), inPoints.end());
865 it != inPoints.end(); ++it)
867 std::vector<PtsPointPair> result;
872 m_rtree->query(bgi::nearest((*it).first, 2),
873 std::back_inserter(result));
879 it2 != result.end(); ++it2)
881 if ((*it).second != (*it2).second &&
882 bg::distance((*it).first, (*it2).first) <=
885 m_rtree->remove(*it);
901 void Interpolator::FindNNeighbours(
const PtsPoint &searchPt,
902 vector<PtsPoint> &neighbourPts,
903 const unsigned int numPts)
905 std::vector<PtsPointPair> result;
908 m_rtree->query(bgi::nearest(searchBPoint, numPts),
909 std::back_inserter(result));
912 for (
int i = 0; i < result.size(); ++i)
914 int idx = result[i].second;
916 for (
int j = 0; j < m_ptsInField->GetDim(); ++j)
918 coords[j] = m_ptsInField->GetPointVal(j, idx);
920 NekDouble d = bg::distance(searchBPoint, result[i].first);
921 neighbourPts.push_back(
PtsPoint(idx, coords, d));
924 sort(neighbourPts.begin(), neighbourPts.end());
935 void Interpolator::FindNeighbours(
const PtsPoint &searchPt,
936 vector<PtsPoint> &neighbourPts,
938 const unsigned int maxPts)
943 searchPt.
coords[2] - dist);
945 searchPt.
coords[2] + dist);
946 bg::model::box<BPoint> bbox(bbMin, bbMax);
949 std::vector<PtsPointPair> result;
952 m_rtree->query(bgi::within(bbox) && bgi::nearest(searchBPoint, maxPts),
953 std::back_inserter(result));
957 m_rtree->query(bgi::within(bbox), std::back_inserter(result));
961 for (
int i = 0; i < result.size(); ++i)
963 int idx = result[i].second;
965 for (
int j = 0; j < m_ptsInField->GetDim(); ++j)
967 coords[j] = m_ptsInField->GetPointVal(j, idx);
969 NekDouble d = bg::distance(searchBPoint, result[i].first);
974 neighbourPts.push_back(
PtsPoint(idx, coords, d));
978 sort(neighbourPts.begin(), neighbourPts.end());
std::pair< BPoint, unsigned int > PtsPointPair
#define ASSERTL0(condition, msg)
bg::model::point< NekDouble, m_dim, bg::cs::cartesian > BPoint
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
Array< OneD, NekDouble > coords
boost::shared_ptr< PtsField > PtsFieldSharedPtr
static const NekDouble kNekZeroTol
int Nnan(int n, const T *x, const int incx)
Return number of NaN elements of x.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator