www.mooseframework.org
BilinearInterpolation.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "BilinearInterpolation.h"
11 #include "libmesh/int_range.h"
12 
14 
15 BilinearInterpolation::BilinearInterpolation(const std::vector<Real> & xaxis,
16  const std::vector<Real> & yaxis,
17  const ColumnMajorMatrix & zsurface)
18  : BidimensionalInterpolation(xaxis, yaxis), _z_surface(zsurface)
19 {
20 }
21 
22 void
23 BilinearInterpolation::getNeighborIndices(const std::vector<Real> & inArr,
24  Real x,
25  unsigned int & lowerX,
26  unsigned int & upperX) const
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 }
58 
59 Real
60 BilinearInterpolation::sample(Real s1, Real s2) const
61 {
62  return sampleInternal(s1, s2);
63 }
64 
65 ADReal
66 BilinearInterpolation::sample(const ADReal & s1, const ADReal & s2) const
67 {
68  return sampleInternal(s1, s2);
69 }
70 
73 {
74  return sampleInternal(s1, s2);
75 }
76 
77 template <typename T>
78 T
79 BilinearInterpolation::sampleInternal(const T & s1, const T & s2) const
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 }
123 
124 Real
125 BilinearInterpolation::sampleDerivative(Real s1, Real s2, const unsigned int deriv_var) const
126 {
127  return sampleDerivativeInternal(s1, s2, deriv_var);
128 }
129 
130 ADReal
132  const ADReal & s2,
133  const unsigned int deriv_var) const
134 {
135  return sampleDerivativeInternal(s1, s2, deriv_var);
136 }
137 
140  const ChainedReal & s2,
141  const unsigned int deriv_var) const
142 {
143  return sampleDerivativeInternal(s1, s2, deriv_var);
144 }
145 
146 template <typename T>
147 T
149  const T s2,
150  const unsigned int deriv_var) const
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 }
600 
601 void
603  Real s1, Real s2, Real & y, Real & dy_ds1, Real & dy_ds2) const
604 {
605  y = sample(s1, s2);
606  dy_ds1 = sampleDerivative(s1, s2, 1);
607  dy_ds2 = sampleDerivative(s1, s2, 2);
608 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
DualNumber< Real, Real > ChainedReal
Definition: ChainedReal.h:30
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.
auto raw_value(const Eigen::Map< T > &in)
Definition: ADReal.h:73
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...
std::vector< Real > _x1
Independent values in the x1 direction.
ColumnMajorMatrix _z_surface
Real sampleDerivative(const Real s1, const Real s2, unsigned int deriv_var) const override
Samples first derivative at point (s1, s2)
DualReal ADReal
Definition: ADRealForward.h:14
T sampleDerivativeInternal(const T s1, const T s2, const unsigned int deriv_var) const
T sampleInternal(const T &s1, const T &s2) const
sampleInternal only used by BilinearInterpolation, hence made private
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > _x2
Independent values in the x2 direction.
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...
IntRange< T > make_range(T beg, T end)
void getNeighborIndices(const std::vector< Real > &inArr, Real x, unsigned int &lowerX, unsigned int &upperX) const
This class interpolates tabulated data with a Bidimension function (either bicubic or bilinear)...