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