www.mooseframework.org
BicubicSplineFunction.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 "BicubicSplineFunction.h"
11 
13 
16 {
18  params.addClassDescription(
19  "Define a bicubic spline function from interpolated data defined by input parameters.");
20 
21  MooseEnum normal_component("x=0 y=1 z=2", "z");
22  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  params.addRequiredParam<std::vector<Real>>("x1", "The first independent coordinate.");
27  params.addRequiredParam<std::vector<Real>>("x2", "The second independent coordinate.");
28  params.addRequiredParam<std::vector<Real>>("y", "The dependent values");
29  params.addParam<std::vector<Real>>(
30  "yx11", "The values of the derivative wrt x1 on the lower interpolation grid points.");
31  params.addParam<std::vector<Real>>(
32  "yx1n", "The values of the derivative wrt x1 on the upper interpolation grid points.");
33  params.addParam<std::vector<Real>>(
34  "yx21", "The values of the derivative wrt x2 on the lower interpolation grid points.");
35  params.addParam<std::vector<Real>>(
36  "yx2n", "The values of the derivative wrt x2 on the upper interpolation grid points.");
37  params.addParam<FunctionName>(
38  "yx1", "1e30", "The functional form of the derivative with respect to x1.");
39  params.addParam<FunctionName>(
40  "yx2", "1e30", "The functional form of the derivative with respect to x2.");
41 
42  return params;
43 }
44 
46  : Function(parameters),
47  FunctionInterface(this),
48  _normal_component(getParam<MooseEnum>("normal_component")),
49  _yx1(getFunction("yx1")),
50  _yx2(getFunction("yx2"))
51 {
52  _x1 = getParam<std::vector<Real>>("x1");
53  _x2 = getParam<std::vector<Real>>("x2");
54  std::vector<Real> yvec = getParam<std::vector<Real>>("y");
55  if (isParamValid("yx11"))
56  _yx11 = getParam<std::vector<Real>>("yx11");
57  if (isParamValid("yx1n"))
58  _yx1n = getParam<std::vector<Real>>("yx1n");
59  if (isParamValid("yx21"))
60  _yx21 = getParam<std::vector<Real>>("yx21");
61  if (isParamValid("yx2n"))
62  _yx2n = getParam<std::vector<Real>>("yx2n");
63 
64  unsigned int m = _x1.size(), n = _x2.size(), mn = yvec.size();
65  if (m * n != mn)
66  mooseError("The length of the supplied y must be equal to the lengths of x1 and x2 multiplied "
67  "together");
68 
69  std::vector<std::vector<Real>> y(m, std::vector<Real>(n));
70  unsigned int k = 0;
71  for (unsigned int i = 0; i < m; ++i)
72  for (unsigned int j = 0; j < n; ++j)
73  y[i][j] = yvec[k++];
74 
75  if (_yx11.empty())
76  _yx11.resize(n, 1e30);
77  else if (_yx11.size() != n)
78  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  if (_yx1n.empty())
82  _yx1n.resize(n, 1e30);
83  else if (_yx1n.size() != n)
84  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  if (_yx21.empty())
88  _yx21.resize(m, 1e30);
89  else if (_yx21.size() != m)
90  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  if (_yx2n.empty())
94  _yx2n.resize(m, 1e30);
95  else if (_yx2n.size() != m)
96  mooseError("The length of the vectors holding the first derivatives of y with respect to x2 "
97  "must match the length of x1.");
98 
100 
101  if (_normal_component == 0)
102  {
103  // YZ plane
104  _x1_index = 1;
105  _x2_index = 2;
106  }
107  else if (_normal_component == 1)
108  {
109  // ZX plane
110  _x1_index = 2;
111  _x2_index = 0;
112  }
113  else
114  {
115  // XY plane
116  _x1_index = 0;
117  _x2_index = 1;
118  }
119 }
120 
121 Real
122 BicubicSplineFunction::value(Real /*t*/, const Point & p) const
123 {
124  // Call yx11/yx1n with the correctly oriented points
125  Real x1_begin = _x1[0];
126  Real x1_end = p(_x2_index);
127  Real xn_begin = _x1.back();
128  Real xn_end = p(_x2_index);
129 
130  Point x1(0, 0, 0);
131  Point xn(0, 0, 0);
132 
133  x1(_x1_index) = x1_begin;
134  x1(_x2_index) = x1_end;
135  xn(_x1_index) = xn_begin;
136  xn(_x2_index) = xn_end;
137 
138  Real yx11 = _yx1.value(0, x1);
139  Real yx1n = _yx1.value(0, xn);
140 
141  return _ipol.sample(p(_x1_index), p(_x2_index), yx11, yx1n);
142 }
143 
144 Real
145 BicubicSplineFunction::derivative(const Point & p, unsigned int deriv_var) const
146 {
147  Real yp1, ypn;
148  Point x1(0, 0, 0);
149  Point xn(0, 0, 0);
150  if (deriv_var == 1)
151  {
152  // Call yx11/yx1n with the correctly oriented points
153  Real x1_begin = _x1[0];
154  Real x1_end = p(_x2_index);
155  Real xn_begin = _x1.back();
156  Real xn_end = p(_x2_index);
157 
158  x1(_x1_index) = x1_begin;
159  x1(_x2_index) = x1_end;
160  xn(_x1_index) = xn_begin;
161  xn(_x2_index) = xn_end;
162 
163  yp1 = _yx1.value(0, x1);
164  ypn = _yx1.value(0, xn);
165  }
166  else if (deriv_var == 2)
167  {
168  // Call yx11/yx1n with the correctly oriented points
169  Real x1_begin = p(_x1_index);
170  Real x1_end = _x2[0];
171  Real xn_begin = p(_x1_index);
172  Real xn_end = _x2.back();
173 
174  x1(_x1_index) = x1_begin;
175  x1(_x2_index) = x1_end;
176  xn(_x1_index) = xn_begin;
177  xn(_x2_index) = xn_end;
178 
179  yp1 = _yx2.value(0, x1);
180  ypn = _yx2.value(0, xn);
181  }
182  else
183  mooseError("deriv_var must equal 1 or 2");
184 
185  return _ipol.sampleDerivative(p(_x1_index), p(_x2_index), deriv_var, yp1, ypn);
186 }
187 
189 BicubicSplineFunction::gradient(Real /*t*/, const Point & p) const
190 {
191  RealGradient grad = RealGradient(0, 0, 0);
192 
193  Real dF_dx1 = derivative(p, 1);
194  Real dF_dx2 = derivative(p, 2);
195 
196  grad(_x1_index) = dF_dx1;
197  grad(_x2_index) = dF_dx2;
198 
199  return grad;
200 }
201 
202 Real
203 BicubicSplineFunction::secondDerivative(const Point & p, unsigned int deriv_var) const
204 {
205  Real yp1, ypn;
206  Point x1(0, 0, 0);
207  Point xn(0, 0, 0);
208  if (deriv_var == 1)
209  {
210  // Call yx11/yx1n with the correctly oriented points
211  Real x1_begin = _x1[0];
212  Real x1_end = p(_x2_index);
213  Real xn_begin = _x1.back();
214  Real xn_end = p(_x2_index);
215 
216  x1(_x1_index) = x1_begin;
217  x1(_x2_index) = x1_end;
218  xn(_x1_index) = xn_begin;
219  xn(_x2_index) = xn_end;
220 
221  yp1 = _yx1.value(0, x1);
222  ypn = _yx1.value(0, xn);
223  }
224  else if (deriv_var == 2)
225  {
226  // Call yx11/yx1n with the correctly oriented points
227  Real x1_begin = p(_x1_index);
228  Real x1_end = _x2[0];
229  Real xn_begin = p(_x1_index);
230  Real xn_end = _x2.back();
231 
232  x1(_x1_index) = x1_begin;
233  x1(_x2_index) = x1_end;
234  xn(_x1_index) = xn_begin;
235  xn(_x2_index) = xn_end;
236 
237  yp1 = _yx2.value(0, x1);
238  ypn = _yx2.value(0, xn);
239  }
240  else
241  mooseError("deriv_var must equal 1 or 2");
242 
243  return _ipol.sample2ndDerivative(p(_x1_index), p(_x2_index), deriv_var, yp1, ypn);
244 }
Real sample(Real x1, Real x2, Real yx11=_deriv_bound, Real yx1n=_deriv_bound)
Samples value at point (x1, x2)
Base class for function objects.
Definition: Function.h:37
virtual RealGradient gradient(Real t, const Point &p) const override
Function objects can optionally provide a gradient at a point.
BicubicSplineInterpolation _ipol
BicubicSplineFunction(const InputParameters &parameters)
virtual Real secondDerivative(const Point &p, unsigned int deriv_var) const
std::vector< Real > _x1
registerMooseObject("MooseApp", BicubicSplineFunction)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Real sampleDerivative(Real x1, Real x2, unsigned int deriv_var, Real yp1=_deriv_bound, Real ypn=_deriv_bound)
Samples first derivative at point (x1, x2)
std::vector< Real > _yx2n
std::vector< Real > _yx1n
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
static InputParameters validParams()
virtual Real derivative(const Point &p, unsigned int deriv_var) const
std::vector< Real > _x2
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
Function that uses spline interpolation.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > _yx21
std::vector< Real > _yx11
Real sample2ndDerivative(Real x1, Real x2, unsigned int deriv_var, Real yp1=_deriv_bound, Real ypn=_deriv_bound)
Samples second derivative at point (x1, x2)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
virtual Real value(Real t, const Point &p) const
Override this to evaluate the scalar function at point (t,x,y,z), by default this returns zero...
Definition: Function.C:41
static InputParameters validParams()
Class constructor.
Definition: Function.C:15
Interface for objects that need to use functions.
virtual Real value(Real t, const Point &p) const override
Override this to evaluate the scalar function at point (t,x,y,z), by default this returns zero...
void setData(const std::vector< Real > &x1, const std::vector< Real > &x2, const std::vector< std::vector< Real >> &y, const std::vector< Real > &yx11=std::vector< Real >(), const std::vector< Real > &yx1n=std::vector< Real >(), const std::vector< Real > &yx21=std::vector< Real >(), const std::vector< Real > &yx2n=std::vector< Real >())
Set the x1, x2 and y values, and first derivatives at the edges.