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.

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

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 349 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 281 of file FieldUtils/Interpolator.cpp.

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

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 145 of file FieldUtils/Interpolator.cpp.

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

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

◆ m_expOutField

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

output field

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