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 : #include "BicubicSplineFunction.h"
11 :
12 : registerMooseObject("MooseApp", BicubicSplineFunction);
13 :
14 : InputParameters
15 14340 : BicubicSplineFunction::validParams()
16 : {
17 14340 : InputParameters params = Function::validParams();
18 14340 : params.addClassDescription(
19 : "Define a bicubic spline function from interpolated data defined by input parameters.");
20 :
21 14340 : MooseEnum normal_component("x=0 y=1 z=2", "z");
22 14340 : params.addParam<MooseEnum>(
23 : "normal_component",
24 : normal_component,
25 : "The component of the geometry that is normal to the spline x1/x2 values");
26 14340 : params.addRequiredParam<std::vector<Real>>("x1", "The first independent coordinate.");
27 14340 : params.addRequiredParam<std::vector<Real>>("x2", "The second independent coordinate.");
28 14340 : params.addRequiredParam<std::vector<Real>>("y", "The dependent values");
29 14340 : params.addParam<std::vector<Real>>(
30 : "yx11", "The values of the derivative wrt x1 on the lower interpolation grid points.");
31 14340 : params.addParam<std::vector<Real>>(
32 : "yx1n", "The values of the derivative wrt x1 on the upper interpolation grid points.");
33 14340 : params.addParam<std::vector<Real>>(
34 : "yx21", "The values of the derivative wrt x2 on the lower interpolation grid points.");
35 14340 : params.addParam<std::vector<Real>>(
36 : "yx2n", "The values of the derivative wrt x2 on the upper interpolation grid points.");
37 14340 : params.addParam<FunctionName>(
38 : "yx1", "1e30", "The functional form of the derivative with respect to x1.");
39 14340 : params.addParam<FunctionName>(
40 : "yx2", "1e30", "The functional form of the derivative with respect to x2.");
41 :
42 28680 : return params;
43 14340 : }
44 :
45 39 : BicubicSplineFunction::BicubicSplineFunction(const InputParameters & parameters)
46 : : Function(parameters),
47 : FunctionInterface(this),
48 39 : _normal_component(getParam<MooseEnum>("normal_component")),
49 39 : _yx1(getFunction("yx1")),
50 117 : _yx2(getFunction("yx2"))
51 : {
52 39 : _x1 = getParam<std::vector<Real>>("x1");
53 39 : _x2 = getParam<std::vector<Real>>("x2");
54 39 : std::vector<Real> yvec = getParam<std::vector<Real>>("y");
55 39 : if (isParamValid("yx11"))
56 39 : _yx11 = getParam<std::vector<Real>>("yx11");
57 39 : if (isParamValid("yx1n"))
58 39 : _yx1n = getParam<std::vector<Real>>("yx1n");
59 39 : if (isParamValid("yx21"))
60 39 : _yx21 = getParam<std::vector<Real>>("yx21");
61 39 : if (isParamValid("yx2n"))
62 39 : _yx2n = getParam<std::vector<Real>>("yx2n");
63 :
64 39 : unsigned int m = _x1.size(), n = _x2.size(), mn = yvec.size();
65 39 : if (m * n != mn)
66 0 : mooseError("The length of the supplied y must be equal to the lengths of x1 and x2 multiplied "
67 : "together");
68 :
69 39 : std::vector<std::vector<Real>> y(m, std::vector<Real>(n));
70 39 : unsigned int k = 0;
71 156 : for (unsigned int i = 0; i < m; ++i)
72 585 : for (unsigned int j = 0; j < n; ++j)
73 468 : y[i][j] = yvec[k++];
74 :
75 39 : if (_yx11.empty())
76 0 : _yx11.resize(n, 1e30);
77 39 : else if (_yx11.size() != n)
78 0 : mooseError("The length of the vectors holding the first derivatives of y with respect to x1 "
79 : "must match the length of x2.");
80 :
81 39 : if (_yx1n.empty())
82 0 : _yx1n.resize(n, 1e30);
83 39 : else if (_yx1n.size() != n)
84 0 : mooseError("The length of the vectors holding the first derivatives of y with respect to x1 "
85 : "must match the length of x2.");
86 :
87 39 : if (_yx21.empty())
88 0 : _yx21.resize(m, 1e30);
89 39 : else if (_yx21.size() != m)
90 0 : mooseError("The length of the vectors holding the first derivatives of y with respect to x2 "
91 : "must match the length of x1.");
92 :
93 39 : if (_yx2n.empty())
94 0 : _yx2n.resize(m, 1e30);
95 39 : else if (_yx2n.size() != m)
96 0 : mooseError("The length of the vectors holding the first derivatives of y with respect to x2 "
97 : "must match the length of x1.");
98 :
99 39 : _ipol.setData(_x1, _x2, y, _yx11, _yx1n, _yx21, _yx2n);
100 :
101 39 : if (_normal_component == 0)
102 : {
103 : // YZ plane
104 13 : _x1_index = 1;
105 13 : _x2_index = 2;
106 : }
107 26 : else if (_normal_component == 1)
108 : {
109 : // ZX plane
110 13 : _x1_index = 2;
111 13 : _x2_index = 0;
112 : }
113 : else
114 : {
115 : // XY plane
116 13 : _x1_index = 0;
117 13 : _x2_index = 1;
118 : }
119 39 : }
120 :
121 : Real
122 6600 : BicubicSplineFunction::value(Real /*t*/, const Point & p) const
123 : {
124 : // Call yx11/yx1n with the correctly oriented points
125 6600 : Real x1_begin = _x1[0];
126 6600 : Real x1_end = p(_x2_index);
127 6600 : Real xn_begin = _x1.back();
128 6600 : Real xn_end = p(_x2_index);
129 :
130 6600 : Point x1(0, 0, 0);
131 6600 : Point xn(0, 0, 0);
132 :
133 6600 : x1(_x1_index) = x1_begin;
134 6600 : x1(_x2_index) = x1_end;
135 6600 : xn(_x1_index) = xn_begin;
136 6600 : xn(_x2_index) = xn_end;
137 :
138 6600 : Real yx11 = _yx1.value(0, x1);
139 6600 : Real yx1n = _yx1.value(0, xn);
140 :
141 13200 : return _ipol.sample(p(_x1_index), p(_x2_index), yx11, yx1n);
142 : }
143 :
144 : Real
145 16800 : BicubicSplineFunction::derivative(const Point & p, unsigned int deriv_var) const
146 : {
147 : Real yp1, ypn;
148 16800 : Point x1(0, 0, 0);
149 16800 : Point xn(0, 0, 0);
150 16800 : if (deriv_var == 1)
151 : {
152 : // Call yx11/yx1n with the correctly oriented points
153 8400 : Real x1_begin = _x1[0];
154 8400 : Real x1_end = p(_x2_index);
155 8400 : Real xn_begin = _x1.back();
156 8400 : Real xn_end = p(_x2_index);
157 :
158 8400 : x1(_x1_index) = x1_begin;
159 8400 : x1(_x2_index) = x1_end;
160 8400 : xn(_x1_index) = xn_begin;
161 8400 : xn(_x2_index) = xn_end;
162 :
163 8400 : yp1 = _yx1.value(0, x1);
164 8400 : ypn = _yx1.value(0, xn);
165 : }
166 8400 : else if (deriv_var == 2)
167 : {
168 : // Call yx11/yx1n with the correctly oriented points
169 8400 : Real x1_begin = p(_x1_index);
170 8400 : Real x1_end = _x2[0];
171 8400 : Real xn_begin = p(_x1_index);
172 8400 : Real xn_end = _x2.back();
173 :
174 8400 : x1(_x1_index) = x1_begin;
175 8400 : x1(_x2_index) = x1_end;
176 8400 : xn(_x1_index) = xn_begin;
177 8400 : xn(_x2_index) = xn_end;
178 :
179 8400 : yp1 = _yx2.value(0, x1);
180 8400 : ypn = _yx2.value(0, xn);
181 : }
182 : else
183 0 : mooseError("deriv_var must equal 1 or 2");
184 :
185 33600 : return _ipol.sampleDerivative(p(_x1_index), p(_x2_index), deriv_var, yp1, ypn);
186 : }
187 :
188 : RealGradient
189 8400 : BicubicSplineFunction::gradient(Real /*t*/, const Point & p) const
190 : {
191 8400 : RealGradient grad = RealGradient(0, 0, 0);
192 :
193 8400 : Real dF_dx1 = derivative(p, 1);
194 8400 : Real dF_dx2 = derivative(p, 2);
195 :
196 8400 : grad(_x1_index) = dF_dx1;
197 8400 : grad(_x2_index) = dF_dx2;
198 :
199 8400 : return grad;
200 : }
201 :
202 : Real
203 0 : BicubicSplineFunction::secondDerivative(const Point & p, unsigned int deriv_var) const
204 : {
205 : Real yp1, ypn;
206 0 : Point x1(0, 0, 0);
207 0 : Point xn(0, 0, 0);
208 0 : if (deriv_var == 1)
209 : {
210 : // Call yx11/yx1n with the correctly oriented points
211 0 : Real x1_begin = _x1[0];
212 0 : Real x1_end = p(_x2_index);
213 0 : Real xn_begin = _x1.back();
214 0 : Real xn_end = p(_x2_index);
215 :
216 0 : x1(_x1_index) = x1_begin;
217 0 : x1(_x2_index) = x1_end;
218 0 : xn(_x1_index) = xn_begin;
219 0 : xn(_x2_index) = xn_end;
220 :
221 0 : yp1 = _yx1.value(0, x1);
222 0 : ypn = _yx1.value(0, xn);
223 : }
224 0 : else if (deriv_var == 2)
225 : {
226 : // Call yx11/yx1n with the correctly oriented points
227 0 : Real x1_begin = p(_x1_index);
228 0 : Real x1_end = _x2[0];
229 0 : Real xn_begin = p(_x1_index);
230 0 : Real xn_end = _x2.back();
231 :
232 0 : x1(_x1_index) = x1_begin;
233 0 : x1(_x2_index) = x1_end;
234 0 : xn(_x1_index) = xn_begin;
235 0 : xn(_x2_index) = xn_end;
236 :
237 0 : yp1 = _yx2.value(0, x1);
238 0 : ypn = _yx2.value(0, xn);
239 : }
240 : else
241 0 : mooseError("deriv_var must equal 1 or 2");
242 :
243 0 : return _ipol.sample2ndDerivative(p(_x1_index), p(_x2_index), deriv_var, yp1, ypn);
244 : }
|