Nektar++
Public Member Functions | Protected Attributes | List of all members
Nektar::FieldUtils::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::FieldUtils::Interpolator:
[legend]

Public Member Functions

 Interpolator (LibUtilities::InterpMethod method=LibUtilities::eNoMethod, short int coordId=-1, NekDouble filtWidth=0.0, int maxPts=1000)
 Constructor of the Interpolator class. More...
 
FIELD_UTILS_EXPORT void Interpolate (const std::vector< MultiRegions::ExpListSharedPtr > expInField, std::vector< MultiRegions::ExpListSharedPtr > &expOutField, NekDouble def_value=0.0)
 Interpolate from an expansion to an expansion. More...
 
FIELD_UTILS_EXPORT void Interpolate (const std::vector< MultiRegions::ExpListSharedPtr > expInField, LibUtilities::PtsFieldSharedPtr &ptsOutField, NekDouble def_value=0.0)
 Interpolate from an expansion to a pts field. More...
 
FIELD_UTILS_EXPORT void Interpolate (const LibUtilities::PtsFieldSharedPtr ptsInField, std::vector< MultiRegions::ExpListSharedPtr > &expOutField)
 Interpolate from a pts field to an expansion. More...
 
FIELD_UTILS_EXPORT void Interpolate (const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
 Interpolate from a pts field to a pts field. More...
 
- Public Member Functions inherited from Nektar::LibUtilities::Interpolator
 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

std::vector< MultiRegions::ExpListSharedPtrm_expInField
 input field More...
 
std::vector< MultiRegions::ExpListSharedPtrm_expOutField
 output field More...
 
- Protected Attributes inherited from Nektar::LibUtilities::Interpolator
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
 

Detailed Description

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

Definition at line 50 of file FieldUtils/Interpolator.h.

Constructor & Destructor Documentation

◆ Interpolator()

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

Constructor of the Interpolator class.

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

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

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

filtWidth must be specified for the eGauss algorithm only.

Definition at line 71 of file FieldUtils/Interpolator.h.

74  : LibUtilities::Interpolator(method, coordId, filtWidth, maxPts)
75  {
76  }

Member Function Documentation

◆ Interpolate() [1/4]

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

Interpolate from a pts field to a pts field.

Definition at line 350 of file FieldUtils/Interpolator.cpp.

352 {
353  LibUtilities::Interpolator::Interpolate(ptsInField, ptsOutField);
354 }
void Interpolate(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
Interpolate from a pts field to a pts field.

◆ Interpolate() [2/4]

void Nektar::FieldUtils::Interpolator::Interpolate ( const LibUtilities::PtsFieldSharedPtr  ptsInField,
std::vector< MultiRegions::ExpListSharedPtr > &  expOutField 
)

Interpolate from a pts field to an expansion.

Parameters
ptsInFieldinput field
expOutFieldoutput field

In and output fields must have the same dimension and number of fields.

Definition at line 282 of file FieldUtils/Interpolator.cpp.

285 {
286  ASSERTL0(expOutField.size() == ptsInField->GetNFields(),
287  "number of fields does not match");
288  ASSERTL0(ptsInField->GetDim() <= GetDim(), "too many dimesions in inField");
289  ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
290  "too many dimesions in outField");
291 
292  m_ptsInField = ptsInField;
293  m_expOutField = expOutField;
294 
295  int nFields = max((int)ptsInField->GetNFields(), (int)m_expOutField.size());
296  int nOutPts = m_expOutField[0]->GetTotPoints();
297  int outNumHomDir = 0;
298  if (m_expOutField[0]->GetExpType() == MultiRegions::e3DH1D ||
299  m_expOutField[0]->GetExpType() == MultiRegions::e2DH1D)
300  {
301  outNumHomDir = 1;
302  }
303  else if (m_expOutField[0]->GetExpType() == MultiRegions::e3DH2D)
304  {
305  outNumHomDir = 2;
306  }
307  int outDim = m_expOutField[0]->GetCoordim(0) + outNumHomDir;
308 
309  // create intermediate Ptsfield that wraps the expOutField
310  Array<OneD, Array<OneD, NekDouble>> pts(outDim);
311  for (int i = 0; i < outDim; ++i)
312  {
313  pts[i] = Array<OneD, NekDouble>(nOutPts);
314  }
315  if (outDim == 1)
316  {
317  m_expOutField[0]->GetCoords(pts[0]);
318  }
319  else if (outDim == 2)
320  {
321  m_expOutField[0]->GetCoords(pts[0], pts[1]);
322  }
323  else if (outDim == 3)
324  {
325  m_expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
326  }
327 
330  for (int f = 0; f < expOutField.size(); ++f)
331  {
332  tmpPts->AddField(m_expOutField[f]->GetPhys(),
333  m_ptsInField->GetFieldName(f));
334  }
335 
336  // interpolate m_ptsInField to this intermediate field
338 
339  // write the intermediate fields data into our expOutField
340  for (int i = 0; i < nFields; i++)
341  {
342  int ptsi = outDim + i;
343  for (int j = 0; j < nOutPts; ++j)
344  {
345  m_expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
346  }
347  }
348 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
std::vector< MultiRegions::ExpListSharedPtr > m_expOutField
output field
int GetDim() const
returns the dimension of the Interpolator. Should be higher than the dimensions of the interpolated f...
LibUtilities::PtsFieldSharedPtr m_ptsInField
input 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

References ASSERTL0, Nektar::MultiRegions::e2DH1D, Nektar::MultiRegions::e3DH1D, and Nektar::MultiRegions::e3DH2D.

◆ Interpolate() [3/4]

void Nektar::FieldUtils::Interpolator::Interpolate ( const std::vector< MultiRegions::ExpListSharedPtr expInField,
LibUtilities::PtsFieldSharedPtr ptsOutField,
NekDouble  def_value = 0.0 
)

Interpolate from an expansion to a pts field.

Parameters
expInFieldinput field
ptsOutFieldoutput field

In and output fields must have the same dimension and number of fields. Weights are currently not stored for later use. The interpolation is performed by evaluating the expInField at the points of ptsOutField, so only eNoMethod is supported.

Definition at line 144 of file FieldUtils/Interpolator.cpp.

147 {
148  ASSERTL0(expInField.size() == ptsOutField->GetNFields(),
149  "number of fields does not match");
150  ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
151  "too many dimesions in inField");
152  ASSERTL0(ptsOutField->GetDim() <= GetDim(),
153  "too many dimesions in outField");
154  ASSERTL0(ptsOutField->GetDim() >= expInField[0]->GetCoordim(0),
155  "too few dimesions in outField");
157  "only direct evaluation supported for this interpolation");
158  ASSERTL0(expInField[0]->GetExpType() != MultiRegions::e3DH2D,
159  "interpolation from 3DH2D expansion unsupported");
160 
161  m_expInField = expInField;
162  m_ptsOutField = ptsOutField;
163 
164  int nInDim = expInField[0]->GetCoordim(0);
165  int nOutPts = m_ptsOutField->GetNpoints();
166  int lastProg = 0;
167 
168  int elmtid = -1;
169  for (int i = 0; i < nOutPts; ++i)
170  {
171  Array<OneD, NekDouble> Lcoords(nInDim, 0.0);
172  Array<OneD, NekDouble> coords(3, 0.0);
173  for (int j = 0; j < m_ptsOutField->GetDim(); ++j)
174  {
175  coords[j] = m_ptsOutField->GetPointVal(j, i);
176  }
177 
178  // Obtain Element and LocalCoordinate to interpolate.
179  elmtid = m_expInField[0]->GetExpIndex(
180  coords, Lcoords, NekConstants::kGeomFactorsTol, true, elmtid,
182 
183  // we use kGeomFactorsTol as tolerance, while StdPhysEvaluate has
184  // kNekZeroTol hardcoded, so we need to limit Lcoords to not produce
185  // a ton of warnings
186  for (int j = 0; j < nInDim; ++j)
187  {
188  Lcoords[j] = std::max(Lcoords[j], -1.0);
189  Lcoords[j] = std::min(Lcoords[j], 1.0);
190  }
191 
192  if (elmtid >= 0)
193  {
194  int offset = m_expInField[0]->GetPhys_Offset(elmtid);
195 
196  for (int f = 0; f < m_expInField.size(); ++f)
197  {
198  NekDouble value;
199  if (m_expInField[f]->GetExpType() == MultiRegions::e3DH1D ||
200  m_expInField[f]->GetExpType() == MultiRegions::e2DH1D)
201  {
202  ASSERTL0(m_expInField[f]->GetWaveSpace(),
203  "interpolation from 3DH1D/2DH1D requires field in "
204  "wavespace");
205  NekDouble lHom = m_expInField[f]->GetHomoLen();
206  NekDouble BetaT =
207  2. * M_PI * fmod(coords[nInDim], lHom) / lHom;
208  int nPlanes =
209  m_expInField[f]->GetHomogeneousBasis()->GetZ().size();
210  NekDouble coeff = 0.;
211  Array<OneD, const unsigned int> planes =
212  m_expInField[f]->GetZIDs();
213  value = 0.;
214  for (size_t n = 0; n < planes.size(); ++n)
215  {
216  auto planeExp = m_expInField[f]->GetPlane(planes[n]);
217  coeff = planeExp->GetExp(elmtid)->StdPhysEvaluate(
218  Lcoords, planeExp->GetPhys() + offset);
219  if (planes[n] == 0)
220  {
221  value += coeff;
222  }
223  else if (planes[n] == 1)
224  {
225  value += cos(0.5 * nPlanes * BetaT) * coeff;
226  }
227  else if (planes[n] % 2 == 0)
228  {
229  NekDouble phase = (planes[n] >> 1) * BetaT;
230  value += cos(phase) * coeff;
231  }
232  else
233  {
234  NekDouble phase = (planes[n] >> 1) * BetaT;
235  value += -sin(phase) * coeff;
236  }
237  }
238  }
239  else
240  {
241  value = m_expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
242  Lcoords, m_expInField[f]->GetPhys() + offset);
243  }
244 
245  if ((boost::math::isnan)(value))
246  {
247  ASSERTL0(false, "new value is not a number");
248  }
249  else
250  {
251  m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
252  value);
253  }
254  }
255  }
256  else
257  {
258  for (int f = 0; f < m_expInField.size(); ++f)
259  {
260  m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
261  def_value);
262  }
263  }
264 
265  int progress = int(100 * i / nOutPts);
266  if (m_progressCallback && progress > lastProg)
267  {
268  m_progressCallback(i, nOutPts);
269  lastProg = progress;
270  }
271  }
272 }
std::vector< MultiRegions::ExpListSharedPtr > m_expInField
input field
InterpMethod GetInterpMethod() const
Returns the interpolation method used by this interpolator.
std::function< void(const int position, const int goal)> m_progressCallback
LibUtilities::PtsFieldSharedPtr m_ptsOutField
output field
static const NekDouble kGeomFactorsTol
double NekDouble

References ASSERTL0, Nektar::MultiRegions::e2DH1D, Nektar::MultiRegions::e3DH1D, Nektar::MultiRegions::e3DH2D, Nektar::LibUtilities::eNoMethod, and Nektar::NekConstants::kGeomFactorsTol.

◆ Interpolate() [4/4]

void Nektar::FieldUtils::Interpolator::Interpolate ( const std::vector< MultiRegions::ExpListSharedPtr expInField,
std::vector< MultiRegions::ExpListSharedPtr > &  expOutField,
NekDouble  def_value = 0.0 
)

Interpolate from an expansion to an expansion.

Interpolate from one expansion to an other.

Parameters
expInFieldinput field
expOutFieldoutput field

In and output fields must have the same dimension and number of fields. Weights are currently not stored for later use. The interpolation is performed by evaluating the expInField at the quadrature points of expOutField, so only eNoMethod is supported. If both expansions use the same mesh, use LibUtilities/Foundations/Interp.h instead.

Definition at line 63 of file FieldUtils/Interpolator.cpp.

66 {
67  ASSERTL0(expInField.size() == expOutField.size(),
68  "number of fields does not match");
69  ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
70  "too many dimesions in inField");
71  ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
72  "too many dimesions in outField");
74  "only direct evaluation supported for this interpolation");
75 
76  m_expInField = expInField;
77  m_expOutField = expOutField;
78 
79  int nFields = max((int)expInField.size(), (int)m_expOutField.size());
80  int nOutPts = m_expOutField[0]->GetTotPoints();
81  int outNumHomDir = 0;
82  if (m_expOutField[0]->GetExpType() == MultiRegions::e3DH1D ||
83  m_expOutField[0]->GetExpType() == MultiRegions::e2DH1D)
84  {
85  outNumHomDir = 1;
86  }
87  else if (m_expOutField[0]->GetExpType() == MultiRegions::e3DH2D)
88  {
89  outNumHomDir = 2;
90  }
91  int outDim = m_expOutField[0]->GetCoordim(0) + outNumHomDir;
92 
93  // create intermediate Ptsfield that wraps the expOutField
94  Array<OneD, Array<OneD, NekDouble>> pts(outDim);
95  for (int i = 0; i < outDim; ++i)
96  {
97  pts[i] = Array<OneD, NekDouble>(nOutPts);
98  }
99  if (outDim == 1)
100  {
101  m_expOutField[0]->GetCoords(pts[0]);
102  }
103  else if (outDim == 2)
104  {
105  m_expOutField[0]->GetCoords(pts[0], pts[1]);
106  }
107  else if (outDim == 3)
108  {
109  m_expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
110  }
111 
114  for (int f = 0; f < expOutField.size(); ++f)
115  {
116  tmpPts->AddField(m_expOutField[f]->GetPhys(), "DefaultVar");
117  }
118 
119  // interpolate m_ptsInField to this intermediate field
120  Interpolate(m_expInField, tmpPts, def_value);
121 
122  // write the intermediate fields data into our expOutField
123  for (int i = 0; i < nFields; i++)
124  {
125  int ptsi = outDim + i;
126  for (int j = 0; j < nOutPts; ++j)
127  {
128  m_expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
129  }
130  }
131 }
FIELD_UTILS_EXPORT void Interpolate(const std::vector< MultiRegions::ExpListSharedPtr > expInField, std::vector< MultiRegions::ExpListSharedPtr > &expOutField, NekDouble def_value=0.0)
Interpolate from an expansion to an expansion.

References ASSERTL0, Nektar::MultiRegions::e2DH1D, Nektar::MultiRegions::e3DH1D, Nektar::MultiRegions::e3DH2D, and Nektar::LibUtilities::eNoMethod.

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

Member Data Documentation

◆ m_expInField

std::vector<MultiRegions::ExpListSharedPtr> Nektar::FieldUtils::Interpolator::m_expInField
protected

input field

Definition at line 102 of file FieldUtils/Interpolator.h.

◆ m_expOutField

std::vector<MultiRegions::ExpListSharedPtr> Nektar::FieldUtils::Interpolator::m_expOutField
protected

output field

Definition at line 104 of file FieldUtils/Interpolator.h.