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...
 
template<typename T >
integratePartial (const T &x1, const T &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 271 of file LinearInterpolation.C.

272 {
273  return _x[i];
274 }
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 283 of file LinearInterpolation.C.

284 {
285  return _x.size();
286 }
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()

template<typename T >
template ADReal LinearInterpolation::integratePartial ( const T &  x1,
const T &  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 134 of file LinearInterpolation.C.

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

278 {
279  return _y[i];
280 }
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:311
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 89 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: