Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
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 : #pragma once
11 :
12 : #include "SplineInterpolationBase.h"
13 :
14 : /**
15 : * This class interpolates tabulated functions with a bi-cubic spline
16 : *
17 : * Adopted from Numerical Recipes in C (section 3.6).
18 : * Consistent with the terminology in Numerical Recipes, moving over a column spline means moving
19 : * over the x1 coord
20 : * Likewise, moving over a row spline means moving over the x2 coord
21 : */
22 : class BicubicSplineInterpolation : public SplineInterpolationBase
23 : {
24 : public:
25 : BicubicSplineInterpolation();
26 : /**
27 : * In the future, may add interface that allows necessary vector of boundary conditions to be
28 : * supplied for each edge of grid;
29 : * however, for now we just use natural splines at the grid boundaries
30 : */
31 : BicubicSplineInterpolation(const std::vector<Real> & x1,
32 : const std::vector<Real> & x2,
33 : const std::vector<std::vector<Real>> & y,
34 : const std::vector<Real> & yx11 = std::vector<Real>(),
35 : const std::vector<Real> & yx1n = std::vector<Real>(),
36 : const std::vector<Real> & yx21 = std::vector<Real>(),
37 : const std::vector<Real> & yx2n = std::vector<Real>());
38 :
39 40 : virtual ~BicubicSplineInterpolation() = default;
40 :
41 : /**
42 : * Set the x1, x2 and y values, and first derivatives at the edges
43 : */
44 : void setData(const std::vector<Real> & x1,
45 : const std::vector<Real> & x2,
46 : const std::vector<std::vector<Real>> & y,
47 : const std::vector<Real> & yx11 = std::vector<Real>(),
48 : const std::vector<Real> & yx1n = std::vector<Real>(),
49 : const std::vector<Real> & yx21 = std::vector<Real>(),
50 : const std::vector<Real> & yx2n = std::vector<Real>());
51 :
52 : /**
53 : * Sanity checks on input data
54 : */
55 : void errorCheck();
56 :
57 : /**
58 : * Samples value at point (x1, x2)
59 : */
60 : Real sample(Real x1, Real x2, Real yx11 = _deriv_bound, Real yx1n = _deriv_bound);
61 :
62 : /**
63 : * Samples value and first derivatives at point (x1, x2)
64 : * Use this function for speed when computing both value and derivatives,
65 : * as it minimizes the amount of spline evaluation
66 : */
67 : void sampleValueAndDerivatives(Real x1,
68 : Real x2,
69 : Real & y,
70 : Real & dy1,
71 : Real & dy2,
72 : Real yx11 = _deriv_bound,
73 : Real yx1n = _deriv_bound,
74 : Real yx21 = _deriv_bound,
75 : Real yx2n = _deriv_bound);
76 :
77 : /**
78 : * Samples first derivative at point (x1, x2)
79 : */
80 : Real sampleDerivative(
81 : Real x1, Real x2, unsigned int deriv_var, Real yp1 = _deriv_bound, Real ypn = _deriv_bound);
82 :
83 : /**
84 : * Samples second derivative at point (x1, x2)
85 : */
86 : Real sample2ndDerivative(
87 : Real x1, Real x2, unsigned int deriv_var, Real yp1 = _deriv_bound, Real ypn = _deriv_bound);
88 :
89 : protected:
90 : /// Independent values in the x1 direction
91 : std::vector<Real> _x1;
92 : /// Independent values in the x2 direction
93 : std::vector<Real> _x2;
94 : /// The dependent values at (x1, x2) points
95 : std::vector<std::vector<Real>> _y;
96 : /// Transpose of _y
97 : std::vector<std::vector<Real>> _y_trans;
98 :
99 : /**
100 : * Boundary conditions. The first index indicates the coordinate
101 : * the derivative is with respect to. The second index indicates
102 : * the grid index, e.g. 1 is the lower bound, and n is the upper
103 : * bound
104 : */
105 : std::vector<Real> _yx11;
106 : std::vector<Real> _yx1n;
107 : std::vector<Real> _yx21;
108 : std::vector<Real> _yx2n;
109 :
110 : /// Second derivatives
111 : std::vector<std::vector<Real>> _y2_rows;
112 : std::vector<std::vector<Real>> _y2_columns;
113 :
114 : /// Vectors used during sampling
115 : std::vector<Real> _row_spline_second_derivs;
116 : std::vector<Real> _row_spline_eval;
117 : std::vector<Real> _column_spline_second_derivs;
118 : std::vector<Real> _column_spline_eval;
119 :
120 : /**
121 : * Precompute tables of row (column) spline second derivatives
122 : * and store them to reduce computational demands
123 : */
124 : void constructRowSplineSecondDerivativeTable();
125 : void constructColumnSplineSecondDerivativeTable();
126 :
127 : /**
128 : * Calculates the tables of second derivatives
129 : */
130 : void solve();
131 :
132 : /**
133 : * Helper functions to evaluate column splines and construct row spline
134 : * for the given point
135 : */
136 : void constructRowSpline(Real x1,
137 : std::vector<Real> & spline_eval,
138 : std::vector<Real> & spline_second_derivs,
139 : Real yx11 = _deriv_bound,
140 : Real yx1n = _deriv_bound);
141 :
142 : /**
143 : * Helper functions to evaluate row splines and construct column spline
144 : * for the given point
145 : */
146 : void constructColumnSpline(Real x2,
147 : std::vector<Real> & spline_eval,
148 : std::vector<Real> & spline_second_derivs,
149 : Real yx21 = _deriv_bound,
150 : Real yx2n = _deriv_bound);
151 :
152 : /// File number for data dump
153 : static int _file_number;
154 : };
|