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., NekDouble tolerance=NekConstants::kFindDistanceMin)
 Interpolate from an expansion to an expansion. More...
 
FIELD_UTILS_EXPORT void Interpolate (const T expInField, LibUtilities::PtsFieldSharedPtr &ptsOutField, NekDouble def_value=0., NekDouble tolerance=1.E-5)
 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 48 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 69 of file FieldUtils/Interpolator.h.

72 : LibUtilities::Interpolator(method, coordId, filtWidth, maxPts)
73 {
74 }

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

348{
349 LibUtilities::Interpolator::Interpolate(ptsInField, ptsOutField);
350}
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 279 of file FieldUtils/Interpolator.cpp.

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

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.,
NekDouble  tolerance = 1.E-5 
)

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

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

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

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

◆ m_expOutField

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

output field

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