Nektar++
Public Member Functions | Protected Attributes | List of all members
Nektar::FieldUtils::Interpolator< T > Class Template 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< T >:
[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 T expInField, T &expOutField, NekDouble def_value=0.0)
 Interpolate from an expansion to an expansion. More...
 
FIELD_UTILS_EXPORT void Interpolate (const T 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, T &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

m_expInField
 input field More...
 
m_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

template<typename T>
class Nektar::FieldUtils::Interpolator< T >

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()

template<typename T >
Nektar::FieldUtils::Interpolator< T >::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]

template<typename T >
void Nektar::FieldUtils::Interpolator< T >::Interpolate ( const LibUtilities::PtsFieldSharedPtr  ptsInField,
LibUtilities::PtsFieldSharedPtr ptsOutField 
)

Interpolate from a pts field to a pts field.

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

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

References Nektar::LibUtilities::Interpolator::Interpolate().

◆ Interpolate() [2/4]

template<typename T >
void Nektar::FieldUtils::Interpolator< T >::Interpolate ( const LibUtilities::PtsFieldSharedPtr  ptsInField,
T &  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.

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

◆ Interpolate() [3/4]

template<typename T >
void Nektar::FieldUtils::Interpolator< T >::Interpolate ( const T  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 140 of file FieldUtils/Interpolator.cpp.

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

template<typename T >
void Nektar::FieldUtils::Interpolator< T >::Interpolate ( const T  expInField,
T &  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 64 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 dimensions in inField");
71 ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
72 "too many dimensions in outField");
74 "only direct evaluation supported for this interpolation");
75
76 int nFields = max((int)expInField.size(), (int)expOutField.size());
77 int nOutPts = expOutField[0]->GetTotPoints();
78 int outNumHomDir = 0;
79 if (expOutField[0]->GetExpType() == MultiRegions::e3DH1D ||
80 expOutField[0]->GetExpType() == MultiRegions::e2DH1D)
81 {
82 outNumHomDir = 1;
83 }
84 else if (expOutField[0]->GetExpType() == MultiRegions::e3DH2D)
85 {
86 outNumHomDir = 2;
87 }
88 int outDim = expOutField[0]->GetCoordim(0) + outNumHomDir;
89
90 // create intermediate Ptsfield that wraps the expOutField
91 Array<OneD, Array<OneD, NekDouble>> pts(outDim);
92 for (int i = 0; i < outDim; ++i)
93 {
94 pts[i] = Array<OneD, NekDouble>(nOutPts);
95 }
96 if (outDim == 1)
97 {
98 expOutField[0]->GetCoords(pts[0]);
99 }
100 else if (outDim == 2)
101 {
102 expOutField[0]->GetCoords(pts[0], pts[1]);
103 }
104 else if (outDim == 3)
105 {
106 expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
107 }
108
111 for (int f = 0; f < expOutField.size(); ++f)
112 {
113 tmpPts->AddField(expOutField[f]->GetPhys(), "DefaultVar");
114 }
115 // interpolate m_ptsInField to this intermediate field
116 Interpolate(expInField, tmpPts, def_value);
117 // write the intermediate fields data into our expOutField
118 for (int i = 0; i < nFields; i++)
119 {
120 int ptsi = outDim + i;
121 for (int j = 0; j < nOutPts; ++j)
122 {
123 expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
124 }
125 }
126}
FIELD_UTILS_EXPORT void Interpolate(const T expInField, T &expOutField, NekDouble def_value=0.0)
Interpolate from an expansion to an expansion.

References ASSERTL0, and Nektar::LibUtilities::eNoMethod.

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

Member Data Documentation

◆ m_expInField

template<typename T >
T Nektar::FieldUtils::Interpolator< T >::m_expInField
protected

input field

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

◆ m_expOutField

template<typename T >
T Nektar::FieldUtils::Interpolator< T >::m_expOutField
protected

output field

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