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

References FIELD_UTILS_EXPORT, and Interpolate().

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

Member Function Documentation

◆ Interpolate() [1/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.

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

Referenced by Nektar::FieldUtils::ProcessInterpPoints::InterpolateFieldToPts(), Nektar::FieldUtils::ProcessInterpPtsToPts::InterpolatePtsToPts(), Interpolator(), Nektar::FieldUtils::ProcessInterpField::Process(), and Nektar::FieldUtils::ProcessInterpPointDataToFld::Process().

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 nInDim = expInField[0]->GetCoordim(0);
81  int nOutPts = m_expOutField[0]->GetTotPoints();
82  int nOutDim = m_expOutField[0]->GetCoordim(0);
83  int lastProg = 0;
84 
85  Array<OneD, NekDouble> Lcoords(nInDim, 0.0);
86  Array<OneD, NekDouble> Scoords(nOutDim, 0.0);
87  Array<OneD, Array<OneD, NekDouble> > coords(nOutDim);
88  for (int i = 0; i < nOutDim; ++i)
89  {
90  coords[i] = Array<OneD, NekDouble>(nOutPts);
91  }
92  if (nOutDim == 1)
93  {
94  m_expOutField[0]->GetCoords(coords[0]);
95  }
96  else if (nOutDim == 2)
97  {
98  m_expOutField[0]->GetCoords(coords[0], coords[1]);
99  }
100  else if (nOutDim == 3)
101  {
102  m_expOutField[0]->GetCoords(coords[0], coords[1], coords[2]);
103  }
104 
105  for (int i = 0; i < nOutPts; ++i)
106  {
107  for (int j = 0; j < nOutDim; ++j)
108  {
109  Scoords[j] = coords[j][i];
110  }
111 
112  // Obtain Element and LocalCoordinate to interpolate
113  int elmtid = m_expInField[0]->GetExpIndex(Scoords, Lcoords,
115  true);
116 
117  // we use kGeomFactorsTol as tolerance, while StdPhysEvaluate has
118  // kNekZeroTol hardcoded, so we need to limit Lcoords to not produce
119  // a ton of warnings
120  for(int j = 0; j < nInDim; ++j)
121  {
122  Lcoords[j] = std::max(Lcoords[j], -1.0);
123  Lcoords[j] = std::min(Lcoords[j], 1.0);
124  }
125 
126  if (elmtid >= 0)
127  {
128  int offset = m_expInField[0]->GetPhys_Offset(elmtid);
129 
130  for (int f = 0; f < m_expInField.size(); ++f)
131  {
132  NekDouble value =
133  m_expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
134  Lcoords, m_expInField[f]->GetPhys() + offset);
135 
136  if ((boost::math::isnan)(value))
137  {
138  ASSERTL0(false, "new value is not a number");
139  }
140  else
141  {
142  m_expOutField[f]->UpdatePhys()[i] = value;
143  }
144  }
145  }
146  else
147  {
148  for (int f = 0; f < m_expInField.size(); ++f)
149  {
150  m_expOutField[f]->UpdatePhys()[i] = def_value;
151  }
152  }
153 
154  int progress = int(100 * i / nOutPts);
155  if (m_progressCallback && progress > lastProg)
156  {
157  m_progressCallback(i, nOutPts);
158  lastProg = progress;
159  }
160  }
161 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
double NekDouble
std::function< void(const int position, const int goal)> m_progressCallback
std::vector< MultiRegions::ExpListSharedPtr > m_expOutField
output field
InterpMethod GetInterpMethod() const
Returns the interpolation method used by this interpolator.
static const NekDouble kGeomFactorsTol
int GetDim() const
returns the dimension of the Interpolator. Should be higher than the dimensions of the interpolated f...
std::vector< MultiRegions::ExpListSharedPtr > m_expInField
input field

◆ Interpolate() [2/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 174 of file FieldUtils/Interpolator.cpp.

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

178 {
179  ASSERTL0(expInField.size() == ptsOutField->GetNFields(),
180  "number of fields does not match");
181  ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
182  "too many dimesions in inField");
183  ASSERTL0(ptsOutField->GetDim() <= GetDim(),
184  "too many dimesions in outField");
185  ASSERTL0(ptsOutField->GetDim() >= expInField[0]->GetCoordim(0),
186  "too few dimesions in outField");
188  "only direct evaluation supported for this interpolation");
189 
190  m_expInField = expInField;
191  m_ptsOutField = ptsOutField;
192 
193  int nInDim = expInField[0]->GetCoordim(0);
194  int nOutPts = m_ptsOutField->GetNpoints();
195  int lastProg = 0;
196 
197  for (int i = 0; i < nOutPts; ++i)
198  {
199  Array<OneD, NekDouble> Lcoords(nInDim, 0.0);
200  Array<OneD, NekDouble> coords(m_ptsOutField->GetDim(), 0.0);
201  for (int j = 0; j < m_ptsOutField->GetDim(); ++j)
202  {
203  coords[j] = m_ptsOutField->GetPointVal(j, i);
204  }
205 
206  // Obtain Element and LocalCoordinate to interpolate
207  int elmtid = m_expInField[0]->GetExpIndex(coords, Lcoords,
209 
210  // we use kGeomFactorsTol as tolerance, while StdPhysEvaluate has
211  // kNekZeroTol hardcoded, so we need to limit Lcoords to not produce
212  // a ton of warnings
213  for(int j = 0; j < nInDim; ++j)
214  {
215  Lcoords[j] = std::max(Lcoords[j], -1.0);
216  Lcoords[j] = std::min(Lcoords[j], 1.0);
217  }
218 
219  if (elmtid >= 0)
220  {
221  int offset = m_expInField[0]->GetPhys_Offset(elmtid);
222 
223  for (int f = 0; f < m_expInField.size(); ++f)
224  {
225  NekDouble value =
226  m_expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
227  Lcoords, m_expInField[f]->GetPhys() + offset);
228 
229  if ((boost::math::isnan)(value))
230  {
231  ASSERTL0(false, "new value is not a number");
232  }
233  else
234  {
235  m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
236  value);
237  }
238  }
239  }
240  else
241  {
242  for (int f = 0; f < m_expInField.size(); ++f)
243  {
244  m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
245  def_value);
246  }
247  }
248 
249  int progress = int(100 * i / nOutPts);
250  if (m_progressCallback && progress > lastProg)
251  {
252  m_progressCallback(i, nOutPts);
253  lastProg = progress;
254  }
255  }
256 }
LibUtilities::PtsFieldSharedPtr m_ptsOutField
output field
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
double NekDouble
std::function< void(const int position, const int goal)> m_progressCallback
InterpMethod GetInterpMethod() const
Returns the interpolation method used by this interpolator.
static const NekDouble kGeomFactorsTol
int GetDim() const
returns the dimension of the Interpolator. Should be higher than the dimensions of the interpolated f...
std::vector< MultiRegions::ExpListSharedPtr > m_expInField
input field

◆ Interpolate() [3/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 266 of file FieldUtils/Interpolator.cpp.

References ASSERTL0.

269 {
270  ASSERTL0(expOutField.size() == ptsInField->GetNFields(),
271  "number of fields does not match");
272  ASSERTL0(ptsInField->GetDim() <= GetDim(), "too many dimesions in inField");
273  ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
274  "too many dimesions in outField");
275 
276  m_ptsInField = ptsInField;
277  m_expOutField = expOutField;
278 
279  int nFields = max((int)ptsInField->GetNFields(), (int)m_expOutField.size());
280  int nOutPts = m_expOutField[0]->GetTotPoints();
281  int outDim = m_expOutField[0]->GetCoordim(0);
282 
283  // create intermediate Ptsfield that wraps the expOutField
284  Array<OneD, Array<OneD, NekDouble> > pts(outDim);
285  for (int i = 0; i < outDim; ++i)
286  {
287  pts[i] = Array<OneD, NekDouble>(nOutPts);
288  }
289  if (outDim == 1)
290  {
291  m_expOutField[0]->GetCoords(pts[0]);
292  }
293  else if (outDim == 2)
294  {
295  m_expOutField[0]->GetCoords(pts[0], pts[1]);
296  }
297  else if (outDim == 3)
298  {
299  m_expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
300  }
301 
304  for (int f = 0; f < expOutField.size(); ++f)
305  {
306  tmpPts->AddField(m_expOutField[f]->GetCoeffs(),
307  m_ptsInField->GetFieldName(f));
308  }
309 
310  // interpolate m_ptsInField to this intermediate field
312 
313  // write the intermediate fields data into our expOutField
314  for (int i = 0; i < nFields; i++)
315  {
316  for (int j = 0; j < nOutPts; ++j)
317  {
318  m_expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(i, j);
319  }
320  }
321 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
LibUtilities::PtsFieldSharedPtr m_ptsInField
input field
void Interpolate(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
Interpolate from a pts field to a pts field.
std::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:179
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
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...

◆ Interpolate() [4/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 323 of file FieldUtils/Interpolator.cpp.

326 {
327  LibUtilities::Interpolator::Interpolate(ptsInField, ptsOutField);
328 }
void Interpolate(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
Interpolate from a pts field to a pts field.

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.