https://mooseframework.inl.gov
Public Member Functions | Private Attributes | List of all members
LinearInterpolation Class Reference

This class interpolates values given a set of data pairs and an abscissa. More...

#include <LinearInterpolation.h>

Inheritance diagram for LinearInterpolation:
[legend]

Public Member Functions

 LinearInterpolation (const std::vector< Real > &X, const std::vector< Real > &Y, const bool extrap=false)
 
 LinearInterpolation ()
 
virtual ~LinearInterpolation ()=default
 
void setData (const std::vector< Real > &X, const std::vector< Real > &Y)
 Set the x and y values. More...
 
void errorCheck ()
 
template<typename T >
sample (const T &x) const
 This function will take an independent variable input and will return the dependent variable based on the generated fit. More...
 
template<typename T >
sampleDerivative (const T &x) const
 This function will take an independent variable input and will return the derivative of the dependent variable with respect to the independent variable based on the generated fit. More...
 
unsigned int getSampleSize () const
 This function returns the size of the array holding the points, i.e. More...
 
Real integrate ()
 This function returns the integral of the function over the whole domain. More...
 
Real integratePartial (Real x1, Real x2) const
 Returns the integral of the function over a specified domain. More...
 
Real domain (int i) const
 
Real range (int i) const
 

Private Attributes

std::vector< Real_x
 
std::vector< Real_y
 
bool _extrap
 

Detailed Description

This class interpolates values given a set of data pairs and an abscissa.

Definition at line 21 of file LinearInterpolation.h.

Constructor & Destructor Documentation

◆ LinearInterpolation() [1/2]

LinearInterpolation::LinearInterpolation ( const std::vector< Real > &  X,
const std::vector< Real > &  Y,
const bool  extrap = false 
)

Definition at line 19 of file LinearInterpolation.C.

22  : _x(x), _y(y), _extrap(extrap)
23 {
24  errorCheck();
25 }
std::vector< Real > _x
std::vector< Real > _y

◆ LinearInterpolation() [2/2]

LinearInterpolation::LinearInterpolation ( )
inline

Definition at line 31 of file LinearInterpolation.h.

31 : _x(std::vector<Real>()), _y(std::vector<Real>()), _extrap(false) {}
std::vector< Real > _x
std::vector< Real > _y

◆ ~LinearInterpolation()

virtual LinearInterpolation::~LinearInterpolation ( )
virtualdefault

Member Function Documentation

◆ domain()

Real LinearInterpolation::domain ( int  i) const

Definition at line 257 of file LinearInterpolation.C.

258 {
259  return _x[i];
260 }
std::vector< Real > _x

◆ errorCheck()

void LinearInterpolation::errorCheck ( )

Definition at line 28 of file LinearInterpolation.C.

Referenced by LinearInterpolation(), and setData().

29 {
30  if (_x.size() != _y.size())
31  throw std::domain_error("Vectors are not the same length");
32 
33  for (unsigned int i = 0; i + 1 < _x.size(); ++i)
34  if (_x[i] >= _x[i + 1])
35  {
36  std::ostringstream oss;
37  oss << "x-values are not strictly increasing: x[" << i << "]: " << _x[i] << " x[" << i + 1
38  << "]: " << _x[i + 1];
39  throw std::domain_error(oss.str());
40  }
41 }
std::vector< Real > _x
std::vector< Real > _y

◆ getSampleSize()

unsigned int LinearInterpolation::getSampleSize ( ) const

This function returns the size of the array holding the points, i.e.

the number of sample points

Definition at line 269 of file LinearInterpolation.C.

270 {
271  return _x.size();
272 }
std::vector< Real > _x

◆ integrate()

Real LinearInterpolation::integrate ( )

This function returns the integral of the function over the whole domain.

Definition at line 123 of file LinearInterpolation.C.

124 {
125  Real answer = 0;
126  for (unsigned int i = 1; i < _x.size(); ++i)
127  answer += 0.5 * (_y[i] + _y[i - 1]) * (_x[i] - _x[i - 1]);
128 
129  return answer;
130 }
std::vector< Real > _x
std::vector< Real > _y
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ integratePartial()

Real LinearInterpolation::integratePartial ( Real  x1,
Real  x2 
) const

Returns the integral of the function over a specified domain.

Parameters
[in]x1First point in integral domain
[in]x2Second point in integral domain

Definition at line 133 of file LinearInterpolation.C.

134 {
135  // integral computation below will assume that x2 > x1; if this is not the
136  // case, compute as if it is and then use identity to convert
137  Real x1, x2;
138  bool switch_bounds;
139  if (MooseUtils::absoluteFuzzyEqual(xA, xB))
140  return 0.0;
141  else if (xB > xA)
142  {
143  x1 = xA;
144  x2 = xB;
145  switch_bounds = false;
146  }
147  else
148  {
149  x1 = xB;
150  x2 = xA;
151  switch_bounds = true;
152  }
153 
154  // compute integral with knowledge that x2 > x1
155  Real integral = 0.0;
156  // find minimum i : x[i] > x; if x > x[n-1], i = n
157  auto n = _x.size();
158  const unsigned int i1 =
159  x1 <= _x[n - 1] ? std::distance(_x.begin(), std::upper_bound(_x.begin(), _x.end(), x1)) : n;
160  const unsigned int i2 =
161  x2 <= _x[n - 1] ? std::distance(_x.begin(), std::upper_bound(_x.begin(), _x.end(), x2)) : n;
162  unsigned int i = i1;
163  while (i <= i2)
164  {
165  if (i == 0)
166  {
167  // note i1 = i
168  Real integral1, integral2;
169  if (_extrap)
170  {
171  const Real dydx = (_y[1] - _y[0]) / (_x[1] - _x[0]);
172  const Real y1 = _y[0] + dydx * (x1 - _x[0]);
173  integral1 = 0.5 * (y1 + _y[0]) * (_x[0] - x1);
174  if (i2 == i)
175  {
176  const Real y2 = _y[0] + dydx * (x2 - _x[0]);
177  integral2 = 0.5 * (y2 + _y[0]) * (_x[0] - x2);
178  }
179  else
180  integral2 = 0.0;
181  }
182  else
183  {
184  integral1 = _y[0] * (_x[0] - x1);
185  if (i2 == i)
186  integral2 = _y[0] * (_x[0] - x2);
187  else
188  integral2 = 0.0;
189  }
190 
191  integral += integral1 - integral2;
192  }
193  else if (i == n)
194  {
195  // note i2 = i
196  Real integral1, integral2;
197  if (_extrap)
198  {
199  const Real dydx = (_y[n - 1] - _y[n - 2]) / (_x[n - 1] - _x[n - 2]);
200  const Real y2 = _y[n - 1] + dydx * (x2 - _x[n - 1]);
201  integral2 = 0.5 * (y2 + _y[n - 1]) * (x2 - _x[n - 1]);
202  if (i1 == n)
203  {
204  const Real y1 = _y[n - 1] + dydx * (x1 - _x[n - 1]);
205  integral1 = 0.5 * (y1 + _y[n - 1]) * (x1 - _x[n - 1]);
206  }
207  else
208  integral1 = 0.0;
209  }
210  else
211  {
212  integral2 = _y[n - 1] * (x2 - _x[n - 1]);
213  if (i1 == n)
214  integral1 = _y[n - 1] * (x1 - _x[n - 1]);
215  else
216  integral1 = 0.0;
217  }
218 
219  integral += integral2 - integral1;
220  }
221  else
222  {
223  Real integral1;
224  if (i == i1)
225  {
226  const Real dydx = (_y[i] - _y[i - 1]) / (_x[i] - _x[i - 1]);
227  const Real y1 = _y[i - 1] + dydx * (x1 - _x[i - 1]);
228  integral1 = 0.5 * (y1 + _y[i - 1]) * (x1 - _x[i - 1]);
229  }
230  else
231  integral1 = 0.0;
232 
233  Real integral2;
234  if (i == i2)
235  {
236  const Real dydx = (_y[i] - _y[i - 1]) / (_x[i] - _x[i - 1]);
237  const Real y2 = _y[i - 1] + dydx * (x2 - _x[i - 1]);
238  integral2 = 0.5 * (y2 + _y[i - 1]) * (x2 - _x[i - 1]);
239  }
240  else
241  integral2 = 0.5 * (_y[i] + _y[i - 1]) * (_x[i] - _x[i - 1]);
242 
243  integral += integral2 - integral1;
244  }
245 
246  i++;
247  }
248 
249  // apply identity if bounds were switched
250  if (switch_bounds)
251  return -1.0 * integral;
252  else
253  return integral;
254 }
std::vector< Real > _x
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.
Definition: MooseUtils.h:371
std::vector< Real > _y
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ range()

Real LinearInterpolation::range ( int  i) const

Definition at line 263 of file LinearInterpolation.C.

264 {
265  return _y[i];
266 }
std::vector< Real > _y

◆ sample()

template<typename T >
template ChainedReal LinearInterpolation::sample< ChainedReal > ( const T &  x) const

This function will take an independent variable input and will return the dependent variable based on the generated fit.

Definition at line 45 of file LinearInterpolation.C.

Referenced by IterationAdaptiveDT::computeDT(), IterationAdaptiveDT::computeInitialDT(), and IterationAdaptiveDT::computeInterpolationDT().

46 {
47  // this is a hard error
48  if (_x.empty())
49  mooseError("Trying to evaluate an empty LinearInterpolation");
50 
51  // special case for single function nodes
52  if (_x.size() == 1)
53  return _y[0];
54 
55  // endpoint cases
56  if (_extrap)
57  {
58  if (x < _x[0])
59  return _y[0] + (x - _x[0]) / (_x[1] - _x[0]) * (_y[1] - _y[0]);
60  if (x >= _x.back())
61  return _y.back() +
62  (x - _x.back()) / (_x[_x.size() - 2] - _x.back()) * (_y[_y.size() - 2] - _y.back());
63  }
64  else
65  {
66  if (x < _x[0])
67  return _y[0];
68  if (x >= _x.back())
69  return _y.back();
70  }
71 
72  auto upper = std::upper_bound(_x.begin(), _x.end(), x);
73  const auto i = cast_int<std::size_t>(std::distance(_x.begin(), upper) - 1);
74  if (i == cast_int<std::size_t>(_x.size() - 1))
75  // std::upper_bound returns the end() iterator if there are no elements that are
76  // an upper bound to the value. Since x >= _x.back() has already returned above,
77  // this means x is a NaN, so we return a NaN here.
78  return std::nan("");
79  else
80  return _y[i] + (_y[i + 1] - _y[i]) * (x - _x[i]) / (_x[i + 1] - _x[i]);
81 }
std::vector< Real > _x
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
std::vector< Real > _y

◆ sampleDerivative()

template<typename T >
template ChainedReal LinearInterpolation::sampleDerivative< ChainedReal > ( const T &  x) const

This function will take an independent variable input and will return the derivative of the dependent variable with respect to the independent variable based on the generated fit.

Definition at line 89 of file LinearInterpolation.C.

90 {
91  // endpoint cases
92  if (_extrap)
93  {
94  if (x <= _x[0])
95  return (_y[1] - _y[0]) / (_x[1] - _x[0]);
96  if (x >= _x.back())
97  return (_y[_y.size() - 2] - _y.back()) / (_x[_x.size() - 2] - _x.back());
98  }
99  else
100  {
101  if (x < _x[0])
102  return 0.0;
103  if (x >= _x.back())
104  return 0.0;
105  }
106 
107  auto upper = std::upper_bound(_x.begin(), _x.end(), x);
108  const auto i = cast_int<std::size_t>(std::distance(_x.begin(), upper) - 1);
109  if (i == cast_int<std::size_t>(_x.size() - 1))
110  // std::upper_bound returns the end() iterator if there are no elements that are
111  // an upper bound to the value. Since x >= _x.back() has already returned above,
112  // this means x is a NaN, so we return a NaN here.
113  return std::nan("");
114  else
115  return (_y[i + 1] - _y[i]) / (_x[i + 1] - _x[i]);
116 }
std::vector< Real > _x
std::vector< Real > _y

◆ setData()

void LinearInterpolation::setData ( const std::vector< Real > &  X,
const std::vector< Real > &  Y 
)
inline

Set the x and y values.

Definition at line 38 of file LinearInterpolation.h.

39  {
40  _x = X;
41  _y = Y;
42  errorCheck();
43  }
std::vector< Real > _x
std::vector< Real > _y

Member Data Documentation

◆ _extrap

bool LinearInterpolation::_extrap
private

Definition at line 88 of file LinearInterpolation.h.

Referenced by integratePartial(), sample(), and sampleDerivative().

◆ _x

std::vector<Real> LinearInterpolation::_x
private

◆ _y

std::vector<Real> LinearInterpolation::_y
private

The documentation for this class was generated from the following files: