15 #include "libmesh/int_range.h" 18 const std::vector<Real> & x2,
19 const std::vector<std::vector<Real>> & y)
65 unsigned int x1l, x1u, x2l, x2u;
81 unsigned int x1l, x1u, x2l, x2u;
90 Real sample_deriv = 0.0;
106 else if (deriv_var == 2)
108 Real sample_deriv = 0.0;
124 mooseError(
"deriv_var must be either 1 or 2 in BicubicInterpolation");
130 unsigned int x1l, x1u, x2l, x2u;
139 Real sample_deriv = 0.0;
148 sample_deriv /= (d * d);
155 else if (deriv_var == 2)
157 Real sample_deriv = 0.0;
166 sample_deriv /= (d * d);
173 else if (deriv_var == 3)
175 Real sample_deriv = 0.0;
186 sample_deriv /= (d1 * d2);
192 mooseError(
"deriv_var must be either 1, 2 or 3 in BicubicInterpolation");
197 Real x1, Real x2, Real & y, Real & dy1, Real & dy2)
const 218 template <
typename T>
222 unsigned int x1l, x1u, x2l, x2u;
244 T d1 =
_x1[x1u] -
_x1[x1l];
249 T d2 =
_x2[x2u] -
_x2[x2l];
260 std::vector<std::vector<Real>> dy_dx1, dy_dx2, d2y_dx1x2;
272 std::vector<Real> y = {
_y[i][j],
_y[i + 1][j],
_y[i + 1][j + 1],
_y[i][j + 1]};
273 std::vector<Real> y1 = {
274 dy_dx1[i][j], dy_dx1[i + 1][j], dy_dx1[i + 1][j + 1], dy_dx1[i][j + 1]};
275 std::vector<Real> y2 = {
276 dy_dx2[i][j], dy_dx2[i + 1][j], dy_dx2[i + 1][j + 1], dy_dx2[i][j + 1]};
277 std::vector<Real> y12 = {
278 d2y_dx1x2[i][j], d2y_dx1x2[i + 1][j], d2y_dx1x2[i + 1][j + 1], d2y_dx1x2[i][j + 1]};
280 std::vector<Real> cl(16), x(16);
282 unsigned int count = 0;
288 x[k + 4] = y1[k] * d1;
289 x[k + 8] = y2[k] * d2;
290 x[k + 12] = y12[k] * d1 * d2;
298 xx +=
_wt[k][q] * x[q];
315 std::vector<std::vector<Real>> & dy_dx2,
316 std::vector<std::vector<Real>> & d2y_dx1x2)
318 const auto m =
_x1.size();
319 const auto n =
_x2.size();
328 d2y_dx1x2[i].resize(n);
338 dy_dx1[i][j] = (
_y[i + 1][j] -
_y[i][j]) / (
_x1[i + 1] -
_x1[i]);
341 dy_dx1[i][j] = (
_y[i][j] -
_y[i - 1][j]) / (
_x1[i] -
_x1[i - 1]);
343 dy_dx1[i][j] = (
_y[i + 1][j] -
_y[i - 1][j]) / (
_x1[i + 1] -
_x1[i - 1]);
347 dy_dx2[i][j] = (
_y[i][j + 1] -
_y[i][j]) / (
_x2[j + 1] -
_x2[j]);
349 dy_dx2[i][j] = (
_y[i][j] -
_y[i][j - 1]) / (
_x2[j] -
_x2[j - 1]);
351 dy_dx2[i][j] = (
_y[i][j + 1] -
_y[i][j - 1]) / (
_x2[j + 1] -
_x2[j - 1]);
354 if (i == 0 && j == 0)
355 d2y_dx1x2[i][j] = (
_y[i + 1][j + 1] -
_y[i + 1][j] -
_y[i][j + 1] +
_y[i][j]) /
357 else if (i == 0 && j == n - 1)
358 d2y_dx1x2[i][j] = (
_y[i + 1][j] -
_y[i + 1][j - 1] -
_y[i][j] +
_y[i][j - 1]) /
360 else if (i == m - 1 && j == 0)
361 d2y_dx1x2[i][j] = (
_y[i][j + 1] -
_y[i][j] -
_y[i - 1][j + 1] +
_y[i - 1][j]) /
363 else if (i == m - 1 && j == n - 1)
364 d2y_dx1x2[i][j] = (
_y[i][j] -
_y[i][j - 1] -
_y[i - 1][j] +
_y[i - 1][j - 1]) /
367 d2y_dx1x2[i][j] = (
_y[i + 1][j + 1] -
_y[i + 1][j - 1] -
_y[i][j + 1] +
_y[i][j - 1]) /
370 d2y_dx1x2[i][j] = (
_y[i][j + 1] -
_y[i][j - 1] -
_y[i - 1][j + 1] +
_y[i - 1][j - 1]) /
373 d2y_dx1x2[i][j] = (
_y[i + 1][j + 1] -
_y[i + 1][j] -
_y[i - 1][j + 1] +
_y[i - 1][j]) /
376 d2y_dx1x2[i][j] = (
_y[i + 1][j] -
_y[i + 1][j - 1] -
_y[i - 1][j] +
_y[i - 1][j - 1]) /
380 (
_y[i + 1][j + 1] -
_y[i + 1][j - 1] -
_y[i - 1][j + 1] +
_y[i - 1][j - 1]) /
385 template <
typename T>
388 const std::vector<Real> & x,
const T & xi,
unsigned int & klo,
unsigned int & khi, T & xs)
const 392 mooseAssert(x.size() >= 2,
393 "There must be at least two points in the table in BicubicInterpolation");
396 while (khi - klo > 1)
398 unsigned int kmid = (khi + klo) / 2;
406 Real d = x[khi] - x[klo];
427 auto m =
_x1.size(), n =
_x2.size();
430 mooseError(
"y row dimension does not match the size of x1 in BicubicInterpolation");
433 if (
_y[i].size() != n)
434 mooseError(
"y column dimension does not match the size of x2 in BicubicInterpolation");
void precomputeCoefficients()
Precompute all of the coefficients for the bicubic interpolation to avoid calculating them repeatedly...
const std::vector< std::vector< int > > _wt
Matrix used to calculate bicubic interpolation coefficients (from Numerical Recipes) ...
Real sampleDerivative(Real x1, Real x2, unsigned int deriv_var) const override
Samples first derivative at point (x1, x2)
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
virtual void sampleValueAndDerivatives(Real x1, Real x2, Real &y, Real &dy1, Real &dy2) const override
Samples value and first derivatives at point (x1, x2) Use this function for speed when computing both...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
DualNumber< Real, Real > ChainedReal
std::vector< std::vector< Real > > _y
The dependent values at (x1, x2) points.
BicubicInterpolation(const std::vector< Real > &x1, const std::vector< Real > &x2, const std::vector< std::vector< Real >> &y)
DualNumber< Real, DNDerivativeType, true > ADReal
std::vector< Real > _x1
Independent values in the x1 direction.
void findInterval(const std::vector< Real > &x, const T &xi, unsigned int &klo, unsigned int &khi, T &xs) const
Find the indices of the dependent values axis which bracket the point xi.
Real sample2ndDerivative(Real x1, Real x2, unsigned int deriv_var) const override
Samples second derivative at point (x1, x2)
std::vector< std::vector< std::vector< std::vector< Real > > > > _bicubic_coeffs
Matrix of precomputed coefficients There are four coefficients in each direction at each dependent va...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > _x2
Independent values in the x2 direction.
T sampleInternal(const T &x1, const T &x2) const
IntRange< T > make_range(T beg, T end)
Real sample(const Real x1, const Real x2) const override
Samples value at point (x1, x2)
void sampleValueAndDerivativesInternal(T x1, T x2, T &y, T &dy1, T &dy2) const
void errorCheck()
Sanity checks on input data.
This class interpolates tabulated data with a Bidimension function (either bicubic or bilinear)...
auto index_range(const T &sizable)
void tableDerivatives(std::vector< std::vector< Real >> &dy_dx1, std::vector< std::vector< Real >> &dy_dx2, std::vector< std::vector< Real >> &d2y_dx1x2)
Provides the values of the first derivatives in each direction at all points in the table of data...