16#ifndef __B2SPLINES_H__
17#define __B2SPLINES_H__
29 template <
typename T1,
typename T2>
31 T1 x_begin, T1 x_end, T2 y_begin, T2 y_end,
bool natural,
double yp1 = 0,
double ypn = 0)
32 : xa(x_begin, x_end), ya(y_begin, y_end) {
33 compute_y2a(natural, yp1, ypn);
36 template <
typename T1>
37 CubicSpline(T1 xy_begin, T1 xy_end,
bool natural,
double yp1 = 0,
double ypn = 0) {
38 size_t s = (xy_end - xy_begin) / 2;
41 while (xy_begin != xy_end) {
42 xa.push_back(*xy_begin);
44 ya.push_back(*xy_begin);
47 compute_y2a(natural, yp1, ypn);
50 template <
typename T1,
typename T2>
52 size_t s, std::pair<T1, T2> xy_begin, std::pair<T1, T2> xy_end,
bool natural,
53 double yp1 = 0,
double ypn = 0) {
56 while (xy_begin != xy_end) {
57 xa.push_back(xy_begin->first);
58 ya.push_back(xy_begin->second);
61 compute_y2a(natural, yp1, ypn);
64 void add_point(
double x,
double y) {
69 void finalise(
bool natural,
double yp1 = 0,
double ypn = 0) { compute_y2a(natural, yp1, ypn); }
71 double operator()(
double x)
const {
72 if (x < xa.front()) {
return ya.front(); }
73 if (x > xa.back()) {
return ya.back(); }
75 size_t khi = xa.size() - 1;
78 while (khi - klo > 1) {
87 const double h = xa[khi] - xa[klo];
88 if (h == 0) { Exception() <<
THROW; }
89 const double a = (xa[khi] - x) / h;
90 const double b = (x - xa[klo]) / h;
91 return a * ya[klo] + b * ya[khi]
92 + ((a * a * a - a) * y2a[klo] + (b * b * b - b) * y2a[khi]) * (h * h) / 6.0;
95 void get_value_and_derivative(
double x,
double& v,
double& dv)
const {
107 size_t khi = xa.size() - 1;
110 while (khi - klo > 1) {
119 const double h = xa[khi] - xa[klo];
120 if (h == 0) { Exception() <<
THROW; }
121 const double a = (xa[khi] - x) / h;
122 const double b = (x - xa[klo]) / h;
123 v = a * ya[klo] + b * ya[khi]
124 + ((a * a * a - a) * y2a[klo] + (b * b * b - b) * y2a[khi]) * (h * h) / 6.0;
125 dv = (-ya[klo] + ya[khi]) / h
126 + ((1 - 3 * a * a) * y2a[klo] + (3 * b * b - 1) * y2a[khi]) * h / 6.0;
130 void compute_y2a(
bool natural,
double yp1 = 0,
double ypn = 0) {
131 std::vector<double> u(xa.size() - 1);
132 y2a.resize(xa.size());
137 u[0] = (3.0 / (xa[1] - xa[0])) * ((ya[1] - ya[0]) / (xa[1] - xa[0]) - yp1);
139 const size_t i_max = xa.size() - 1;
140 for (
size_t i = 1; i != i_max; ++i) {
141 const double sig = (xa[i] - xa[i - 1]) / (xa[i + 1] - xa[i - 1]);
142 const double p = sig * y2a[i - 1] + 2.0;
143 y2a[i] = (sig - 1.0) / p;
144 u[i] = (ya[i + 1] - ya[i]) / (xa[i + 1] - xa[i])
145 - (ya[i] - ya[i - 1]) / (xa[i] - xa[i - 1]);
146 u[i] = (6.0 * u[i] / (xa[i + 1] - xa[i - 1]) - sig * u[i - 1]) / p;
150 size_t n = xa.size();
155 un = (3.0 / (xa[n - 1] - xa[n - 2]))
156 * (ypn - (ya[n - 1] - ya[n - 2]) / (xa[n - 1] - xa[n - 2]));
158 y2a[n - 1] = (un - qn * u[n - 2]) / (qn * y2a[n - 2] + 1.0);
160 for (
size_t i = xa.size() - 1; i > 0; --i) { y2a[i - 1] = y2a[i - 1] * y2a[i] + u[i - 1]; }
163 std::vector<double> xa;
164 std::vector<double> ya;
165 std::vector<double> y2a;
#define THROW
Definition b2exception.H:198
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32