www.mooseframework.org
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
BilinearInterpolation Class Reference

This class applies the Least Squares algorithm to a set of points to provide a smooth curve for sampling values. More...

#include <BilinearInterpolation.h>

Inheritance diagram for BilinearInterpolation:
[legend]

Public Member Functions

 BilinearInterpolation (const std::vector< Real > &xaxis, const std::vector< Real > &yaxis, const ColumnMajorMatrix &zsurface)
 Constructor, Takes two vectors of points for which to apply the fit. More...
 
virtual ~BilinearInterpolation ()=default
 
Real sample (const Real s1, const Real s2) const override
 This function will take an independent variable input and will return the dependent variable based on the generated fit. More...
 
ADReal sample (const ADReal &s1, const ADReal &s2) const override
 
ChainedReal sample (const ChainedReal &s1, const ChainedReal &s2) const override
 
Real sampleDerivative (const Real s1, const Real s2, unsigned int deriv_var) const override
 Samples first derivative at point (s1, s2) More...
 
ADReal sampleDerivative (const ADReal &s1, const ADReal &s2, unsigned int deriv_var) const override
 
ChainedReal sampleDerivative (const ChainedReal &s1, const ChainedReal &s2, unsigned int deriv_var) const override
 
void sampleValueAndDerivatives (Real s1, Real s2, Real &y, Real &dy_ds1, Real &dy_ds2) const override
 Samples value and first derivatives at point (x1, x2) Use this function for speed when computing both value and derivatives, as it minimizes the amount of time spent locating the point in the tabulated data. More...
 
void getNeighborIndices (const std::vector< Real > &inArr, Real x, unsigned int &lowerX, unsigned int &upperX) const
 
virtual void sampleValueAndDerivatives (Real, Real, Real &, Real &, Real &) const
 Samples value and first derivatives at point (x1, x2) Use this function for speed when computing both value and derivatives, as it minimizes the amount of time spent locating the point in the tabulated data. More...
 
virtual void sampleValueAndDerivatives (const ADReal &, const ADReal &, ADReal &, ADReal &, ADReal &) const
 
virtual void sampleValueAndDerivatives (const ChainedReal &, const ChainedReal &, ChainedReal &, ChainedReal &, ChainedReal &) const
 
virtual Real sample2ndDerivative (Real, Real, unsigned int) const
 Samples second derivative at point (x1, x2) More...
 
virtual void sampleValueAndDerivatives (const ADReal &, const ADReal &, ADReal &, ADReal &, ADReal &) const
 
virtual void sampleValueAndDerivatives (const ChainedReal &, const ChainedReal &, ChainedReal &, ChainedReal &, ChainedReal &) const
 

Public Attributes

std::vector< Real_x1
 Independent values in the x1 direction. More...
 
std::vector< Real_x2
 Independent values in the x2 direction. More...
 

Private Member Functions

template<typename T >
sampleInternal (const T &s1, const T &s2) const
 sampleInternal only used by BilinearInterpolation, hence made private More...
 
template<typename T >
sampleDerivativeInternal (const T s1, const T s2, const unsigned int deriv_var) const
 

Private Attributes

ColumnMajorMatrix _z_surface
 

Static Private Attributes

static int _file_number = 0
 

Detailed Description

This class applies the Least Squares algorithm to a set of points to provide a smooth curve for sampling values.

BilinearInterpolation is designed to linearly interpolate a function of two values e.g. z(x,y). Supply Bilinearlinear with a vector of x and a vector of y and a ColumnMajorMatrix of function values, z, that correspond to the values in the vectors x and y...and also a sample point (s1 and s2), and BilinearInterpolation will return the value of the function at the sample point. A simple example:

x = [1 2], y = [1 2],

z = [1 2] [3 4]

with s1 = 1.5 and s2 = 1.5 returns a value of 2.5.

Definition at line 37 of file BilinearInterpolation.h.

Constructor & Destructor Documentation

◆ BilinearInterpolation()

BilinearInterpolation::BilinearInterpolation ( const std::vector< Real > &  xaxis,
const std::vector< Real > &  yaxis,
const ColumnMajorMatrix zsurface 
)

Constructor, Takes two vectors of points for which to apply the fit.

One should be of the independent variable while the other should be of the dependent variable. These values should correspond to one and other in the same position.

Definition at line 15 of file BilinearInterpolation.C.

18  : BidimensionalInterpolation(xaxis, yaxis), _z_surface(zsurface)
19 {
20 }
BidimensionalInterpolation(const std::vector< Real > &x1, const std::vector< Real > &x2)
ColumnMajorMatrix _z_surface

◆ ~BilinearInterpolation()

virtual BilinearInterpolation::~BilinearInterpolation ( )
virtualdefault

Member Function Documentation

◆ getNeighborIndices()

void BilinearInterpolation::getNeighborIndices ( const std::vector< Real > &  inArr,
Real  x,
unsigned int lowerX,
unsigned int upperX 
) const

Definition at line 23 of file BilinearInterpolation.C.

Referenced by sampleDerivativeInternal(), and sampleInternal().

27 {
28  int N = inArr.size();
29  if (x <= inArr[0])
30  {
31  lowerX = 0;
32  upperX = 0;
33  }
34  else if (x >= inArr[N - 1])
35  {
36  lowerX = N - 1;
37  upperX = N - 1;
38  }
39  else
40  {
41  for (const auto i : make_range(1, N))
42  {
43  if (x < inArr[i])
44  {
45  lowerX = i - 1;
46  upperX = i;
47  break;
48  }
49  else if (x == inArr[i])
50  {
51  lowerX = i;
52  upperX = i;
53  break;
54  }
55  }
56  }
57 }
IntRange< T > make_range(T beg, T end)

◆ sample() [1/3]

Real BilinearInterpolation::sample ( const Real  s1,
const Real  s2 
) const
overridevirtual

This function will take an independent variable input and will return the dependent variable based on the generated fit.

Implements BidimensionalInterpolation.

Definition at line 60 of file BilinearInterpolation.C.

Referenced by sampleValueAndDerivatives().

61 {
62  return sampleInternal(s1, s2);
63 }
T sampleInternal(const T &s1, const T &s2) const
sampleInternal only used by BilinearInterpolation, hence made private

◆ sample() [2/3]

ADReal BilinearInterpolation::sample ( const ADReal s1,
const ADReal s2 
) const
overridevirtual

Implements BidimensionalInterpolation.

Definition at line 66 of file BilinearInterpolation.C.

67 {
68  return sampleInternal(s1, s2);
69 }
T sampleInternal(const T &s1, const T &s2) const
sampleInternal only used by BilinearInterpolation, hence made private

◆ sample() [3/3]

ChainedReal BilinearInterpolation::sample ( const ChainedReal s1,
const ChainedReal s2 
) const
overridevirtual

Implements BidimensionalInterpolation.

Definition at line 72 of file BilinearInterpolation.C.

73 {
74  return sampleInternal(s1, s2);
75 }
T sampleInternal(const T &s1, const T &s2) const
sampleInternal only used by BilinearInterpolation, hence made private

◆ sample2ndDerivative()

virtual Real BidimensionalInterpolation::sample2ndDerivative ( Real  ,
Real  ,
unsigned int   
) const
inlinevirtualinherited

Samples second derivative at point (x1, x2)

Reimplemented in BicubicInterpolation.

Definition at line 73 of file BidimensionalInterpolation.h.

74  {
75  mooseError("sample2ndDerivative is not implemented for this interpolation class");
76  }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284

◆ sampleDerivative() [1/3]

Real BilinearInterpolation::sampleDerivative ( const Real  s1,
const Real  s2,
unsigned int  deriv_var 
) const
overridevirtual

Samples first derivative at point (s1, s2)

Reimplemented from BidimensionalInterpolation.

Definition at line 125 of file BilinearInterpolation.C.

Referenced by sampleValueAndDerivatives().

126 {
127  return sampleDerivativeInternal(s1, s2, deriv_var);
128 }
T sampleDerivativeInternal(const T s1, const T s2, const unsigned int deriv_var) const

◆ sampleDerivative() [2/3]

ADReal BilinearInterpolation::sampleDerivative ( const ADReal s1,
const ADReal s2,
unsigned int  deriv_var 
) const
overridevirtual

Reimplemented from BidimensionalInterpolation.

Definition at line 131 of file BilinearInterpolation.C.

134 {
135  return sampleDerivativeInternal(s1, s2, deriv_var);
136 }
T sampleDerivativeInternal(const T s1, const T s2, const unsigned int deriv_var) const

◆ sampleDerivative() [3/3]

ChainedReal BilinearInterpolation::sampleDerivative ( const ChainedReal s1,
const ChainedReal s2,
unsigned int  deriv_var 
) const
overridevirtual

Reimplemented from BidimensionalInterpolation.

Definition at line 139 of file BilinearInterpolation.C.

142 {
143  return sampleDerivativeInternal(s1, s2, deriv_var);
144 }
T sampleDerivativeInternal(const T s1, const T s2, const unsigned int deriv_var) const

◆ sampleDerivativeInternal()

template<typename T >
T BilinearInterpolation::sampleDerivativeInternal ( const T  s1,
const T  s2,
const unsigned int  deriv_var 
) const
private

Definition at line 148 of file BilinearInterpolation.C.

Referenced by sampleDerivative().

151 {
152  // check input
153  if (deriv_var != 1 && deriv_var != 2)
154  mooseError("deriv_var must equal 1 or 2");
155 
156  // first find 4 neighboring points
157  unsigned int lx = 0; // index of x coordinate of adjacent grid point to left of P
158  unsigned int ux = 0; // index of x coordinate of adjacent grid point to right of P
160 
161  unsigned int ly = 0; // index of y coordinate of adjacent grid point below P
162  unsigned int uy = 0; // index of y coordinate of adjacent grid point above P
164 
165  // xy indexing
166  // 11 is point on lower-left (x low, y low), 22 on upper-right (x high, y high)
167  const Real & fQ11 = _z_surface(ly, lx);
168  const Real & fQ21 = _z_surface(ly, ux);
169  const Real & fQ12 = _z_surface(uy, lx);
170  const Real & fQ22 = _z_surface(uy, ux);
171  // when on a grid bound or node, lx can be equal to ux or ly be equal to uy
172  // this would lead to a 0 slope, which isn't desirable
173  // we then refer to 0 as the coordinate before, so 00 is lx-1, ly-1
174  // and 3 as the coordinate after, so 33 is ux+1, uy+1
175 
176  const auto & x = s1;
177  const auto & y = s2;
178  const Real & x1 = _x1[lx];
179  const Real & x2 = _x1[ux];
180  const Real & y1 = _x2[ly];
181  const Real & y2 = _x2[uy];
182 
183  // Grid sizes
184  const auto nx1 = _x1.size();
185  const auto nx2 = _x2.size();
186 
187  // On interior grid lines, the equal weighting of both sides of both neighbor
188  // cells slopes is an implementation choice
189  // Alternatively on interior grid nodes, we instead use the super cell around the grid node
190  // instead of a weighting of the four neighbor cells
191 
192  // Check all four grid corners, use a quarter of the slope in the cell next to the corner
193  if (ux == 0 && uy == 0) // bottom left node
194  {
195  const auto & fQ13 = _z_surface(ly + 1, lx); // fQ at (x1,y3)
196  const auto & fQ31 = _z_surface(ly, lx + 1); // fQ at (x3,y1)
197  const auto & fQ33 = _z_surface(ly + 1, lx + 1); // fQ at (x3,y3)
198  const Real & x3 = _x1[lx + 1]; // ux value
199  const Real & y3 = _x2[ly + 1]; // uy value
200 
201  if (deriv_var == 1)
202  {
203  auto dfdx = fQ11 * (y - y3);
204  dfdx += fQ31 * (y3 - y);
205  dfdx += fQ13 * (y1 - y);
206  dfdx += fQ33 * (y - y1);
207  dfdx /= ((x3 - x1) * (y3 - y1));
208  return dfdx;
209  }
210  else if (deriv_var == 2)
211  {
212  auto dfdy = fQ11 * (x - x3);
213  dfdy += fQ31 * (x1 - x);
214  dfdy += fQ13 * (x3 - x);
215  dfdy += fQ33 * (x - x1);
216  dfdy /= ((x3 - x1) * (y3 - y1));
217  return dfdy;
218  }
219  }
220  else if (uy == 0 && lx == nx1 - 1) // bottom right node
221  {
222  const auto & fQ01 = _z_surface(ly, lx - 1); // fQ at (x0,y1)
223  const auto & fQ03 = _z_surface(ly + 1, lx - 1); // fQ at (x0,y3)
224  const auto & fQ23 = _z_surface(ly + 1, lx); // fQ at (x2,y3)
225  const Real & x0 = _x1[lx - 1]; // lx value
226  const Real & y3 = _x2[ly + 1]; // uy value
227 
228  if (deriv_var == 1)
229  {
230  auto dfdx = fQ01 * (y - y3);
231  dfdx += fQ21 * (y3 - y);
232  dfdx += fQ03 * (y1 - y);
233  dfdx += fQ23 * (y - y1);
234  dfdx /= ((x2 - x0) * (y3 - y1));
235  return dfdx;
236  }
237  else if (deriv_var == 2)
238  {
239  auto dfdy = fQ01 * (x - x2);
240  dfdy += fQ21 * (x0 - x);
241  dfdy += fQ03 * (x2 - x);
242  dfdy += fQ23 * (x - x0);
243  dfdy /= ((x2 - x0) * (y3 - y1));
244  return dfdy;
245  }
246  }
247  else if (ly == nx2 - 1 && ux == 0) // top left node
248  {
249  const auto & fQ10 = _z_surface(ly - 1, lx); // fQ at (x1,y0)
250  const auto & fQ30 = _z_surface(ly - 1, lx + 1); // fQ at (x3,y0)
251  const auto & fQ32 = _z_surface(ly, lx + 1); // fQ at (x3,y2)
252  const Real & x3 = _x1[lx + 1]; // ux value
253  const Real & y0 = _x2[ly - 1]; // ly value
254 
255  if (deriv_var == 1)
256  {
257  auto dfdx = fQ10 * (y - y2);
258  dfdx += fQ30 * (y2 - y);
259  dfdx += fQ12 * (y0 - y);
260  dfdx += fQ32 * (y - y0);
261  dfdx /= ((x3 - x1) * (y2 - y0));
262  return dfdx;
263  }
264  else if (deriv_var == 2)
265  {
266  auto dfdy = fQ10 * (x - x3);
267  dfdy += fQ30 * (x1 - x);
268  dfdy += fQ12 * (x3 - x);
269  dfdy += fQ32 * (x - x1);
270  dfdy /= ((x3 - x1) * (y2 - y0));
271  return dfdy;
272  }
273  }
274  else if (ly == nx2 - 1 && lx == nx1 - 1) // top right node
275  {
276  const auto & fQ00 = _z_surface(ly - 1, lx - 1); // fQ at (x0,y0)
277  const auto & fQ20 = _z_surface(ly - 1, lx); // fQ at (x2,y0)
278  const auto & fQ02 = _z_surface(ly, lx - 1); // fQ at (x0,y2)
279  const Real & x0 = _x1[lx - 1]; // lx value
280  const Real & y0 = _x2[ly - 1]; // ly value
281 
282  if (deriv_var == 1)
283  {
284  auto dfdx = fQ00 * (y - y2);
285  dfdx += fQ20 * (y2 - y);
286  dfdx += fQ02 * (y0 - y);
287  dfdx += fQ22 * (y - y0);
288  dfdx /= ((x2 - x0) * (y2 - y0));
289  return dfdx;
290  }
291  else if (deriv_var == 2)
292  {
293  auto dfdy = fQ00 * (x - x2);
294  dfdy += fQ20 * (x0 - x);
295  dfdy += fQ02 * (x2 - x);
296  dfdy += fQ22 * (x - x0);
297  dfdy /= ((x2 - x0) * (y2 - y0));
298  return dfdy;
299  }
300  }
301 
302  // Nodes along the four grid bounds, use the two grid cells adjacent to the node
303  else if (ux == 0 && ly == uy && ux == lx) // when along left boundary, at a grid node
304  {
305  const auto & fQ10 = _z_surface(uy - 1, lx); // fQ at (x1,y0)
306  const auto & fQ30 = _z_surface(uy, ux + 1); // fQ at (x3,y0)
307  const auto & fQ13 = _z_surface(uy + 1, lx); // fQ at (x1,y3)
308  const auto & fQ33 = _z_surface(uy + 1, ux + 1); // fQ at (x3,y3)
309 
310  const Real & x3 = _x1[lx + 1]; // ux value
311  const Real & y0 = _x2[ly - 1]; // ly value
312  const Real & y3 = _x2[ly + 1]; // uy value
313 
314  if (deriv_var == 1)
315  {
316  auto dfdx = fQ10 * (y - y3);
317  dfdx += fQ30 * (y3 - y);
318  dfdx += fQ13 * (y0 - y);
319  dfdx += fQ33 * (y - y0);
320  dfdx /= ((x3 - x1) * (y3 - y0));
321  return dfdx;
322  }
323  else if (deriv_var == 2)
324  {
325  auto dfdy = fQ10 * (x - x3);
326  dfdy += fQ30 * (x1 - x);
327  dfdy += fQ13 * (x3 - x);
328  dfdy += fQ33 * (x - x1);
329  dfdy /= ((x3 - x1) * (y3 - y0));
330  return dfdy;
331  }
332  }
333  else if (lx == nx1 - 1 && ly == uy && ux == lx) // when along right boundary, at a grid node
334  {
335  const auto & fQ00 = _z_surface(uy - 1, lx - 1); // fQ at (x0,y0)
336  const auto & fQ10 = _z_surface(uy - 1, lx); // fQ at (x1,y0)
337  const auto & fQ03 = _z_surface(uy + 1, lx - 1); // fQ at (x0,y3)
338  const auto & fQ13 = _z_surface(uy + 1, lx); // fQ at (x1,y3)
339 
340  const Real & x0 = _x1[lx - 1]; // lx value
341  const Real & y0 = _x2[ly - 1]; // ly value
342  const Real & y3 = _x2[ly + 1]; // uy value
343 
344  if (deriv_var == 1)
345  {
346  auto dfdx = fQ00 * (y - y3);
347  dfdx += fQ10 * (y3 - y);
348  dfdx += fQ03 * (y0 - y);
349  dfdx += fQ13 * (y - y0);
350  dfdx /= ((x1 - x0) * (y3 - y0));
351  return dfdx;
352  }
353  else if (deriv_var == 2)
354  {
355  auto dfdy = fQ00 * (x - x1);
356  dfdy += fQ10 * (x0 - x);
357  dfdy += fQ03 * (x1 - x);
358  dfdy += fQ13 * (x - x0);
359  dfdy /= ((x1 - x0) * (y3 - y0));
360  return dfdy;
361  }
362  }
363  else if (uy == nx2 - 1 && ly == uy && ux == lx) // when along top boundary, at a grid node
364  {
365  const auto & fQ00 = _z_surface(uy - 1, lx - 1); // fQ at (x0,y0)
366  const auto & fQ01 = _z_surface(uy, lx - 1); // fQ at (x0,y1)
367  const auto & fQ30 = _z_surface(uy - 1, lx + 1); // fQ at (x3,y0)
368  const auto & fQ31 = _z_surface(uy, lx + 1); // fQ at (x3,y1)
369 
370  const Real & x0 = _x1[lx - 1]; // lx value
371  const Real & x3 = _x1[lx + 1]; // ux value
372  const Real & y0 = _x2[ly - 1]; // ly value
373 
374  if (deriv_var == 1)
375  {
376  auto dfdx = fQ00 * (y - y1);
377  dfdx += fQ30 * (y1 - y);
378  dfdx += fQ01 * (y0 - y);
379  dfdx += fQ31 * (y - y0);
380  dfdx /= ((x3 - x0) * (y1 - y0));
381  return dfdx;
382  }
383  else if (deriv_var == 2)
384  {
385  auto dfdy = fQ00 * (x - x3);
386  dfdy += fQ30 * (x0 - x);
387  dfdy += fQ01 * (x3 - x);
388  dfdy += fQ31 * (x - x0);
389  dfdy /= ((x3 - x0) * (y1 - y0));
390  return dfdy;
391  }
392  }
393  else if (uy == 0 && ly == uy && ux == lx) // when along bottom boundary, at a grid node
394  {
395  const auto & fQ01 = _z_surface(ly, lx - 1); // fQ at (x0,y1)
396  const auto & fQ03 = _z_surface(ly + 1, lx - 1); // fQ at (x0,y3)
397  const auto & fQ31 = _z_surface(ly, lx + 1); // fQ at (x3,y1)
398  const auto & fQ33 = _z_surface(ly + 1, lx + 1); // fQ at (x3,y3)
399 
400  const Real & x0 = _x1[lx - 1]; // lx value
401  const Real & x3 = _x1[lx + 1]; // ux value
402  const Real & y3 = _x2[ly + 1]; // uy value
403 
404  if (deriv_var == 1)
405  {
406  auto dfdx = fQ01 * (y - y3);
407  dfdx += fQ31 * (y3 - y);
408  dfdx += fQ03 * (y1 - y);
409  dfdx += fQ33 * (y - y1);
410  dfdx /= ((x3 - x0) * (y3 - y1));
411  return dfdx;
412  }
413  else if (deriv_var == 2)
414  {
415  auto dfdy = fQ01 * (x - x3);
416  dfdy += fQ31 * (x0 - x);
417  dfdy += fQ03 * (x3 - x);
418  dfdy += fQ33 * (x - x0);
419  dfdy /= ((x3 - x0) * (y3 - y1));
420  return dfdy;
421  }
422  }
423 
424  // at a grid node inside the domain, use the super box around
425  else if (ux == lx && uy == ly)
426  {
427  const auto & fQ00 = _z_surface(ly - 1, lx - 1); // fQ at (x0,y0)
428  const auto & fQ03 = _z_surface(ly + 1, lx - 1); // fQ at (x0,y3)
429  const auto & fQ30 = _z_surface(ly - 1, lx + 1); // fQ at (x3,y0)
430  const auto & fQ33 = _z_surface(ly + 1, lx + 1); // fQ at (x3,y3)
431 
432  const Real & x0 = _x1[lx - 1]; // lx value
433  const Real & x3 = _x1[lx + 1]; // ux value
434  const Real & y0 = _x2[ly - 1]; // ly value
435  const Real & y3 = _x2[ly + 1]; // uy value
436 
437  if (deriv_var == 1)
438  {
439  auto dfdx = fQ00 * (y - y3);
440  dfdx += fQ30 * (y3 - y);
441  dfdx += fQ03 * (y0 - y);
442  dfdx += fQ33 * (y - y0);
443  dfdx /= ((x3 - x0) * (y3 - y0));
444  return dfdx;
445  }
446  else if (deriv_var == 2)
447  {
448  auto dfdy = fQ00 * (x - x3);
449  dfdy += fQ30 * (x0 - x);
450  dfdy += fQ03 * (x3 - x);
451  dfdy += fQ33 * (x - x0);
452  dfdy /= ((x3 - x0) * (y3 - y0));
453  return dfdy;
454  }
455  }
456 
457  // Inside the domain, not at a grid node
458  // calculate derivative wrt to x
459  if (deriv_var == 1)
460  {
461  // Find derivative when on interval between two nodes
462  if (y == y1)
463  return (fQ21 - fQ11) / (x2 - x1);
464  // interior grid line
465  else if (lx == ux && lx > 0 && ux < nx1 - 1)
466  {
467  // expand grid size so x1 does not equal x2
468  const auto & fQ01 = _z_surface(ly, lx - 1); // new lx at ly
469  const auto & fQ31 = _z_surface(ly, lx + 1); // new ux at ly
470  const auto & fQ02 = _z_surface(uy, lx - 1); // new lx at uy
471  const auto & fQ32 = _z_surface(uy, lx + 1); // new ux at uy
472 
473  const Real & x0 = _x1[lx - 1]; // lx value
474  const Real & x3 = _x1[lx + 1]; // ux value
475 
476  auto dfdx_a = fQ01 * (y - y2);
477  dfdx_a += fQ11 * (y2 - y);
478  dfdx_a += fQ02 * (y1 - y);
479  dfdx_a += fQ12 * (y - y1);
480  dfdx_a /= ((x1 - x0) * (y2 - y1));
481 
482  auto dfdx_b = fQ11 * (y - y2);
483  dfdx_b += fQ31 * (y2 - y);
484  dfdx_b += fQ12 * (y1 - y);
485  dfdx_b += fQ32 * (y - y1);
486  dfdx_b /= ((x3 - x1) * (y2 - y1));
487  return 0.5 * (dfdx_a + dfdx_b);
488  }
489  // left boundary
490  else if (lx == ux && lx == 0)
491  {
492  const auto & fQ31 = _z_surface(ly, lx + 1); // new ux at ly
493  const auto & fQ32 = _z_surface(uy, lx + 1); // new ux at uy
494 
495  const Real & x3 = _x1[lx + 1]; // ux value
496 
497  auto dfdx = fQ11 * (y - y2);
498  dfdx += fQ31 * (y2 - y);
499  dfdx += fQ12 * (y1 - y);
500  dfdx += fQ32 * (y - y1);
501  dfdx /= ((x3 - x1) * (y2 - y1));
502  return dfdx;
503  }
504  // right boundary
505  else if (lx == ux && ux == nx1 - 1)
506  {
507  const auto & fQ01 = _z_surface(ly, ux - 1); // new lx at ly
508  const auto & fQ02 = _z_surface(uy, ux - 1); // new lx at uy
509  const Real & x0 = _x1[ux - 1]; // lx value
510 
511  auto dfdx = fQ01 * (y - y2);
512  dfdx += fQ11 * (y2 - y);
513  dfdx += fQ02 * (y1 - y);
514  dfdx += fQ12 * (y - y1);
515  dfdx /= ((x1 - x0) * (y2 - y1));
516  return dfdx;
517  }
518  // Derivative (w/ respect to x) for some point inside box
519  else
520  {
521  auto dfdx_xy = fQ11 * (y - y2);
522  dfdx_xy += fQ21 * (y2 - y);
523  dfdx_xy += fQ12 * (y1 - y);
524  dfdx_xy += fQ22 * (y - y1);
525  dfdx_xy /= ((x2 - x1) * (y2 - y1));
526  return dfdx_xy;
527  }
528  }
529 
530  else if (deriv_var == 2)
531  {
532  if (x == x1) // if x equal to x1 node
533  return (fQ12 - fQ11) / (y2 - y1);
534  // interior grid line
535  else if (ly == uy && ly > 0 && uy < nx2 - 1)
536  {
537  // expand grid size so x1 does not equal x2
538  const auto & fQ10 = _z_surface(ly - 1, lx); // new ly at lx
539  const auto & fQ20 = _z_surface(ly - 1, ux); // new uy at lx
540  const auto & fQ13 = _z_surface(ly + 1, lx); // new ly at ux
541  const auto & fQ23 = _z_surface(ly + 1, ux); // new uy at ux
542  const Real & y0 = _x2[ly - 1];
543  const Real & y3 = _x2[ly + 1];
544 
545  auto dfdy_a = fQ10 * (x - x2);
546  dfdy_a += fQ20 * (x1 - x);
547  dfdy_a += fQ11 * (x2 - x);
548  dfdy_a += fQ21 * (x - x1);
549  dfdy_a /= ((x2 - x1) * (y1 - y0));
550 
551  auto dfdy_b = fQ11 * (x - x2);
552  dfdy_b += fQ21 * (x1 - x);
553  dfdy_b += fQ13 * (x2 - x);
554  dfdy_b += fQ23 * (x - x1);
555  dfdy_b /= ((x2 - x1) * (y3 - y1));
556  return 0.5 * (dfdy_a + dfdy_b);
557  }
558  // bottom boundary
559  else if (ly == uy && ly == 0)
560  {
561  const auto & fQ13 = _z_surface(ly + 1, lx); // new uy at lx
562  const auto & fQ23 = _z_surface(ly + 1, ux); // new uy at ux
563 
564  const Real & y3 = _x2[ly + 1]; // lx value
565 
566  auto dfdy = fQ11 * (x - x2);
567  dfdy += fQ21 * (x1 - x);
568  dfdy += fQ13 * (x2 - x);
569  dfdy += fQ23 * (x - x1);
570  dfdy /= ((x2 - x1) * (y3 - y1));
571  return dfdy;
572  }
573  // top boundary
574  else if (ly == uy && uy == nx2 - 1)
575  {
576  const auto & fQ10 = _z_surface(ly - 1, lx); // new ly at lx
577  const auto & fQ20 = _z_surface(ly - 1, ux); // new ly at ux
578  const Real & y0 = _x2[ly - 1]; // lx value
579 
580  auto dfdy = fQ10 * (x - x2);
581  dfdy += fQ20 * (x1 - x);
582  dfdy += fQ11 * (x2 - x);
583  dfdy += fQ21 * (x - x1);
584  dfdy /= ((x2 - x1) * (y1 - y0));
585  return dfdy;
586  }
587  else
588  {
589  // Derivative (w/ respect to y) for any point inside box
590  auto dfdy_xy = fQ11 * (x - x2);
591  dfdy_xy += fQ21 * (x1 - x);
592  dfdy_xy += fQ12 * (x2 - x);
593  dfdy_xy += fQ22 * (x - x1);
594  dfdy_xy /= ((x2 - x1) * (y2 - y1));
595  return dfdy_xy;
596  }
597  }
598  mooseError("Bilinear interpolation failed to select a case for x1= ", s1, " x2= ", s2);
599 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
auto raw_value(const Eigen::Map< T > &in)
Definition: ADReal.h:73
std::vector< Real > _x1
Independent values in the x1 direction.
ColumnMajorMatrix _z_surface
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > _x2
Independent values in the x2 direction.
void getNeighborIndices(const std::vector< Real > &inArr, Real x, unsigned int &lowerX, unsigned int &upperX) const

◆ sampleInternal()

template<typename T >
T BilinearInterpolation::sampleInternal ( const T &  s1,
const T &  s2 
) const
private

sampleInternal only used by BilinearInterpolation, hence made private

Definition at line 79 of file BilinearInterpolation.C.

Referenced by sample().

80 {
81  // first find 4 neighboring points
82  unsigned int lx = 0; // index of x coordinate of adjacent grid point to left of P
83  unsigned int ux = 0; // index of x coordinate of adjacent grid point to right of P
85 
86  unsigned int ly = 0; // index of y coordinate of adjacent grid point below P
87  unsigned int uy = 0; // index of y coordinate of adjacent grid point above P
89 
90  const Real & fQ11 = _z_surface(ly, lx);
91  const Real & fQ21 = _z_surface(ly, ux);
92  const Real & fQ12 = _z_surface(uy, lx);
93  const Real & fQ22 = _z_surface(uy, ux);
94 
95  // if point exactly found on a node do not interpolate
96  if ((lx == ux) && (ly == uy))
97  {
98  return fQ11;
99  }
100 
101  const auto & x = s1;
102  const auto & y = s2;
103  const Real & x1 = _x1[lx];
104  const Real & x2 = _x1[ux];
105  const Real & y1 = _x2[ly];
106  const Real & y2 = _x2[uy];
107 
108  // if x1 lies exactly on an xAxis node do linear interpolation
109  if (lx == ux)
110  return fQ11 + (fQ12 - fQ11) * (y - y1) / (y2 - y1);
111 
112  // if x2 lies exactly on an yAxis node do linear interpolation
113  if (ly == uy)
114  return fQ11 + (fQ21 - fQ11) * (x - x1) / (x2 - x1);
115 
116  auto fxy = fQ11 * (x2 - x) * (y2 - y);
117  fxy += fQ21 * (x - x1) * (y2 - y);
118  fxy += fQ12 * (x2 - x) * (y - y1);
119  fxy += fQ22 * (x - x1) * (y - y1);
120  fxy /= ((x2 - x1) * (y2 - y1));
121  return fxy;
122 }
auto raw_value(const Eigen::Map< T > &in)
Definition: ADReal.h:73
std::vector< Real > _x1
Independent values in the x1 direction.
ColumnMajorMatrix _z_surface
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > _x2
Independent values in the x2 direction.
void getNeighborIndices(const std::vector< Real > &inArr, Real x, unsigned int &lowerX, unsigned int &upperX) const

◆ sampleValueAndDerivatives() [1/6]

virtual void BidimensionalInterpolation::sampleValueAndDerivatives
inline

Samples value and first derivatives at point (x1, x2) Use this function for speed when computing both value and derivatives, as it minimizes the amount of time spent locating the point in the tabulated data.

Definition at line 84 of file BidimensionalInterpolation.h.

86  {
87  mooseError("sampleValueAndDerivatives for Real numbers is not implemented for this "
88  "interpolation class");
89  }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284

◆ sampleValueAndDerivatives() [2/6]

virtual void BidimensionalInterpolation::sampleValueAndDerivatives
inline

Definition at line 99 of file BidimensionalInterpolation.h.

104  {
105  mooseError("sampleValueAndDerivatives for ChainedReal numbers is not implemented for this "
106  "interpolation class");
107  }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284

◆ sampleValueAndDerivatives() [3/6]

virtual void BidimensionalInterpolation::sampleValueAndDerivatives
inline

Definition at line 90 of file BidimensionalInterpolation.h.

95  {
96  mooseError("sampleValueAndDerivatives for ADReal numbers is not implemented for this "
97  "interpolation class");
98  }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284

◆ sampleValueAndDerivatives() [4/6]

void BilinearInterpolation::sampleValueAndDerivatives ( Real  ,
Real  ,
Real ,
Real ,
Real  
) const
overridevirtual

Samples value and first derivatives at point (x1, x2) Use this function for speed when computing both value and derivatives, as it minimizes the amount of time spent locating the point in the tabulated data.

Reimplemented from BidimensionalInterpolation.

Definition at line 602 of file BilinearInterpolation.C.

604 {
605  y = sample(s1, s2);
606  dy_ds1 = sampleDerivative(s1, s2, 1);
607  dy_ds2 = sampleDerivative(s1, s2, 2);
608 }
Real sampleDerivative(const Real s1, const Real s2, unsigned int deriv_var) const override
Samples first derivative at point (s1, s2)
Real sample(const Real s1, const Real s2) const override
This function will take an independent variable input and will return the dependent variable based on...

◆ sampleValueAndDerivatives() [5/6]

virtual void BidimensionalInterpolation::sampleValueAndDerivatives ( const ADReal ,
const ADReal ,
ADReal ,
ADReal ,
ADReal  
) const
inlinevirtualinherited

Reimplemented in BicubicInterpolation.

Definition at line 90 of file BidimensionalInterpolation.h.

95  {
96  mooseError("sampleValueAndDerivatives for ADReal numbers is not implemented for this "
97  "interpolation class");
98  }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284

◆ sampleValueAndDerivatives() [6/6]

virtual void BidimensionalInterpolation::sampleValueAndDerivatives ( const ChainedReal ,
const ChainedReal ,
ChainedReal ,
ChainedReal ,
ChainedReal  
) const
inlinevirtualinherited

Reimplemented in BicubicInterpolation.

Definition at line 99 of file BidimensionalInterpolation.h.

104  {
105  mooseError("sampleValueAndDerivatives for ChainedReal numbers is not implemented for this "
106  "interpolation class");
107  }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284

Member Data Documentation

◆ _file_number

int BilinearInterpolation::_file_number = 0
staticprivate

Definition at line 88 of file BilinearInterpolation.h.

◆ _x1

std::vector<Real> BidimensionalInterpolation::_x1
inherited

◆ _x2

std::vector<Real> BidimensionalInterpolation::_x2
inherited

◆ _z_surface

ColumnMajorMatrix BilinearInterpolation::_z_surface
private

Definition at line 87 of file BilinearInterpolation.h.

Referenced by sampleDerivativeInternal(), and sampleInternal().


The documentation for this class was generated from the following files: