https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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.
 
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.
 
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)
 
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.
 
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.
 
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)
 

Public Attributes

std::vector< Real > _x1
 Independent values in the x1 direction.
 
std::vector< Real > _x2
 Independent values in the x2 direction.
 

Private Member Functions

template<typename T >
sampleInternal (const T &s1, const T &s2) const
 sampleInternal only used by BilinearInterpolation, hence made private
 
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}
This class interpolates tabulated data with a Bidimension function (either bicubic or bilinear).

◆ ~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.

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)

Referenced by sampleDerivativeInternal(), and sampleInternal().

◆ sample() [1/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() [2/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}

◆ sample() [3/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.

61{
62 return sampleInternal(s1, s2);
63}

Referenced by sampleValueAndDerivatives().

◆ 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:311

◆ sampleDerivative() [1/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() [2/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}

◆ sampleDerivative() [3/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.

126{
127 return sampleDerivativeInternal(s1, s2, deriv_var);
128}

Referenced by sampleValueAndDerivatives().

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

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}
std::vector< Real > _x1
Independent values in the x1 direction.
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
auto raw_value(const Eigen::Map< T > &in)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

Referenced by sampleDerivative(), sampleDerivative(), and sampleDerivative().

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

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}

Referenced by sample(), sample(), and sample().

◆ sampleValueAndDerivatives() [1/4]

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

Reimplemented from BidimensionalInterpolation.

Definition at line 90 of file BidimensionalInterpolation.h.

95 {
96 mooseError("sampleValueAndDerivatives for ADReal numbers is not implemented for this "
97 "interpolation class");
98 }

◆ sampleValueAndDerivatives() [2/4]

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

Reimplemented from BidimensionalInterpolation.

Definition at line 99 of file BidimensionalInterpolation.h.

104 {
105 mooseError("sampleValueAndDerivatives for ChainedReal numbers is not implemented for this "
106 "interpolation class");
107 }

◆ sampleValueAndDerivatives() [3/4]

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 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...
Real sampleDerivative(const Real s1, const Real s2, unsigned int deriv_var) const override
Samples first derivative at point (s1, s2)

◆ sampleValueAndDerivatives() [4/4]

virtual void BidimensionalInterpolation::sampleValueAndDerivatives ( Real  ,
Real  ,
Real &  ,
Real &  ,
Real &   
) const
inlinevirtual

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 84 of file BidimensionalInterpolation.h.

86 {
87 mooseError("sampleValueAndDerivatives for Real numbers is not implemented for this "
88 "interpolation class");
89 }

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: