DFT-EFE
 
Loading...
Searching...
No Matches
Spline.h
Go to the documentation of this file.
1/*
2 * spline.h
3 *
4 * simple cubic spline interpolation library without external
5 * dependencies
6 *
7 * ---------------------------------------------------------------------
8 * Copyright (C) 2011, 2014, 2016, 2021 Tino Kluge (ttk448 at gmail.com)
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * ---------------------------------------------------------------------
23 *
24 */
25
26
27#ifndef dftefeSpline_h
28#define dftefeSpline_h
29
30#include <cstdio>
31#include <cassert>
32#include <cmath>
33#include <vector>
34#include <algorithm>
35#include <sstream>
36#include <string>
37#include <utils/MemoryStorage.h>
38#include <memory>
41
42
43// header file and we don't want to export symbols to the obj files
44namespace dftefe
45{
46 namespace utils
47 {
48 // spline interpolation
49 class Spline
50 {
51 public:
52 template <dftefe::utils::MemorySpace memorySpace>
53 class Func
54 {
55 public:
57 : d_knotX(nullptr)
58 , d_knotY(nullptr)
59 , d_coefB(nullptr)
60 , d_coefC(nullptr)
61 , d_coefD(nullptr)
62 , d_nKnots(0)
63 , d_c0(0.0)
64 , d_isSubdivGrid(false)
65 , d_a(0.0)
66 , d_r(0.0)
67 , d_numSubDiv(0)
68 {}
69
70 Func(const double * knotX,
71 const double * knotY,
72 const double * coefB,
73 const double * coefC,
74 const double * coefD,
75 size_type nKnots,
76 double c0,
77 bool isSubdivGrid,
78 double a,
79 double r,
80 dftefe::size_type numSubDiv);
81
83 eval(double xi) const;
85 deriv(int order, double xi) const;
86
87 private:
88 const double * d_knotX;
89 const double * d_knotY;
90 const double * d_coefB;
91 const double * d_coefC;
92 const double * d_coefD;
94 double d_c0;
96 double d_a;
97 double d_r;
99 };
100
101 // spline types
103 {
104 linear = 10, // linear interpolation
105 cspline = 30, // cubic splines (classical C^2)
106 cspline_hermite = 31 // cubic hermite splines (local, only C^1)
107 };
108
109 // boundary condition type for the spline end-points
111 {
113 second_deriv = 2
114 };
115
116 private:
117 std::vector<double> d_x, d_y; // x,y coordinates of points
118 // interpolation parameters
119 // f(x) = a_i + b_i*(x-x_i) + c_i*(x-x_i)^2 + d_i*(x-x_i)^3
120 // where a_i = y_i, or else it won't go through grid points
121 std::vector<double> d_b, d_c, d_d; // spline coefficients
122 double d_c0; // for left extrapolation
128 double d_a, d_r;
130 void
131 set_coeffs_from_b(); // calculate c_i, d_i from b_i
132 size_t
133 find_closest(double x) const; // closest idx so that d_x[idx]<=x
134
135 // Compute spline coefficients from d_x_host/d_y_host, then syncToDevice.
136 void
138
139#ifdef DFTEFE_WITH_DEVICE
140 // Copy host vectors -> Device (lazy: called on first device access)
141 void
142 syncToDevice() const;
143
144 // ---- device-resident MemoryStorage ----
145 mutable std::unique_ptr<MemoryStorage<double, utils::MemorySpace::DEVICE>>
146 d_x_device;
147 mutable std::unique_ptr<MemoryStorage<double, utils::MemorySpace::DEVICE>>
148 d_y_device;
149 mutable std::unique_ptr<MemoryStorage<double, utils::MemorySpace::DEVICE>>
150 d_b_device;
151 mutable std::unique_ptr<MemoryStorage<double, utils::MemorySpace::DEVICE>>
152 d_c_device;
153 mutable std::unique_ptr<MemoryStorage<double, utils::MemorySpace::DEVICE>>
154 d_d_device;
155 mutable bool d_deviceSynced;
156#endif
157
158 public:
159 // default constructor: set boundary condition to be zero curvature
160 // at both ends, i.e. natural splines
161 Spline();
162
163 Spline(const std::vector<double> &X,
164 const std::vector<double> &Y,
165 const bool isSubdivPowerLawGrid = false,
166 spline_type type = cspline,
167 bool make_monotonic = false,
168 bd_type left = first_deriv,
169 double left_value = 0.0,
170 bd_type right = first_deriv,
171 double right_value = 0.0);
172
173 // modify boundary conditions: if called it must be before set_points()
174 void
176 double left_value,
177 bd_type right,
178 double right_value);
179
180 // set all data points (cubic_spline=false means linear interpolation)
181 void
182 set_points(const std::vector<double> &x,
183 const std::vector<double> &y,
184 spline_type type = cspline);
185
186 // adjust coefficients so that the spline becomes piecewise monotonic
187 // where possible
188 // this is done by adjusting slopes at grid points by a non-negative
189 // factor and this will break C^2
190 // this can also break boundary conditions if adjustments need to
191 // be made at the boundary points
192 // returns false if no adjustments have been made, true otherwise
193 bool
195
196 // evaluates the spline at point x
197 double
198 operator()(double x) const;
199 std::vector<double>
200 coefficients(double x) const;
201 double
202 deriv(int order, double x) const;
203
204 // returns the input data points
205 std::vector<double>
206 get_x() const
207 {
208 return d_x;
209 }
210 std::vector<double>
211 get_y() const
212 {
213 return d_y;
214 }
215 double
216 get_x_min() const
217 {
218 assert(!d_x.empty());
219 return d_x.front();
220 }
221 double
222 get_x_max() const
223 {
224 assert(!d_x.empty());
225 return d_x.back();
226 }
227
228 // spline info string, i.e. spline type, boundary conditions etc.
229 std::string
230 info() const;
231
232 template <dftefe::utils::MemorySpace memorySpace>
233 Func<memorySpace>
234 getFunc() const;
235
236 template <dftefe::utils::MemorySpace memorySpace>
237 void
239 const double * x,
240 double * y,
242
243 template <dftefe::utils::MemorySpace memorySpace>
244 void
246 int order,
247 const double * x,
248 double * y,
250 };
251
252 namespace splineInternal
253 {
254 // band matrix solver
256 {
257 private:
258 std::vector<std::vector<double>> d_upper; // upper band
259 std::vector<std::vector<double>> d_lower; // lower band
260 public:
261 band_matrix(){}; // constructor
262 band_matrix(int dim, int n_u, int n_l); // constructor
263 ~band_matrix(){}; // destructor
264 void
265 resize(int dim, int n_u, int n_l); // init with dim,n_u,n_l
266 int
267 dim() const; // matrix dimension
268 int
269 num_upper() const
270 {
271 return (int)d_upper.size() - 1;
272 }
273 int
274 num_lower() const
275 {
276 return (int)d_lower.size() - 1;
277 }
278 // access operator
279 double &
280 operator()(int i, int j); // write
281 double
282 operator()(int i, int j) const; // read
283 // we can store an additional diagonal (in d_lower)
284 double &
285 saved_diag(int i);
286 double
287 saved_diag(int i) const;
288 void
289 lu_decompose();
290 std::vector<double>
291 r_solve(const std::vector<double> &b) const;
292 std::vector<double>
293 l_solve(const std::vector<double> &b) const;
294 std::vector<double>
295 lu_solve(const std::vector<double> &b, bool is_lu_decomposed = false);
296 };
297 } // namespace splineInternal
298 } // namespace utils
299} // namespace dftefe
300
301#include <utils/SplineKernels.h>
302
303#endif // dftefeSpline_h
#define DFTEFE_HOST_DEVICE_FUNC
Definition: DeviceKernelLauncherHelpers.h:306
Definition: Spline.h:54
DFTEFE_HOST_DEVICE_FUNC double eval(double xi) const
Definition: SplineKernels.h:215
const double * d_coefD
Definition: Spline.h:92
bool d_isSubdivGrid
Definition: Spline.h:95
const double * d_knotX
Definition: Spline.h:88
double d_c0
Definition: Spline.h:94
Func()
Definition: Spline.h:56
const double * d_coefC
Definition: Spline.h:91
dftefe::size_type d_numSubDiv
Definition: Spline.h:98
const double * d_knotY
Definition: Spline.h:89
double d_a
Definition: Spline.h:96
size_type d_nKnots
Definition: Spline.h:93
double d_r
Definition: Spline.h:97
const double * d_coefB
Definition: Spline.h:90
DFTEFE_HOST_DEVICE_FUNC double deriv(int order, double xi) const
Definition: SplineKernels.h:233
Definition: Spline.h:50
double d_right_value
Definition: Spline.h:125
double d_left_value
Definition: Spline.h:125
void evalAll(size_type numPoints, const double *x, double *y, utils::deviceStream_t streamId=utils::defaultStream) const
double deriv(int order, double x) const
Definition: Spline.cpp:621
double get_x_max() const
Definition: Spline.h:222
spline_type d_type
Definition: Spline.h:123
void set_points(const std::vector< double > &x, const std::vector< double > &y, spline_type type=cspline)
Definition: Spline.cpp:418
double get_x_min() const
Definition: Spline.h:216
double d_r
Definition: Spline.h:128
double d_c0
Definition: Spline.h:122
void set_boundary(bd_type left, double left_value, bd_type right, double right_value)
Definition: Spline.cpp:158
std::vector< double > get_y() const
Definition: Spline.h:211
void derivAll(size_type numPoints, int order, const double *x, double *y, utils::deviceStream_t streamId=utils::defaultStream) const
bd_type
Definition: Spline.h:111
@ second_deriv
Definition: Spline.h:113
@ first_deriv
Definition: Spline.h:112
bd_type d_left
Definition: Spline.h:124
spline_type
Definition: Spline.h:103
@ cspline
Definition: Spline.h:105
@ cspline_hermite
Definition: Spline.h:106
@ linear
Definition: Spline.h:104
std::vector< double > d_b
Definition: Spline.h:121
std::vector< double > d_y
Definition: Spline.h:117
double operator()(double x) const
Definition: Spline.cpp:551
bd_type d_right
Definition: Spline.h:124
std::vector< double > coefficients(double x) const
Definition: Spline.cpp:582
std::vector< double > d_d
Definition: Spline.h:121
bool d_made_monotonic
Definition: Spline.h:126
std::string info() const
Definition: Spline.cpp:684
Func< memorySpace > getFunc() const
size_t find_closest(double x) const
Definition: Spline.cpp:495
Spline()
Definition: Spline.cpp:111
std::vector< double > get_x() const
Definition: Spline.h:206
bool make_monotonic()
Definition: Spline.cpp:431
void computeAndSync(spline_type type)
Definition: Spline.cpp:235
void set_coeffs_from_b()
Definition: Spline.cpp:172
std::vector< double > d_c
Definition: Spline.h:121
dftefe::size_type d_numSubDiv
Definition: Spline.h:129
std::vector< double > d_x
Definition: Spline.h:117
bool d_isSubdivPowerLawGrid
Definition: Spline.h:127
double d_a
Definition: Spline.h:128
std::vector< std::vector< double > > d_lower
Definition: Spline.h:259
int num_lower() const
Definition: Spline.h:274
band_matrix()
Definition: Spline.h:261
std::vector< std::vector< double > > d_upper
Definition: Spline.h:258
~band_matrix()
Definition: Spline.h:263
double & saved_diag(int i)
Definition: Spline.cpp:813
std::vector< double > r_solve(const std::vector< double > &b) const
Definition: Spline.cpp:882
int num_upper() const
Definition: Spline.h:269
std::vector< double > l_solve(const std::vector< double > &b) const
Definition: Spline.cpp:864
int dim() const
Definition: Spline.cpp:766
void resize(int dim, int n_u, int n_l)
Definition: Spline.cpp:749
double & operator()(int i, int j)
Definition: Spline.cpp:782
std::vector< double > lu_solve(const std::vector< double > &b, bool is_lu_decomposed=false)
Definition: Spline.cpp:900
void lu_decompose()
Definition: Spline.cpp:821
static cudaStream_t defaultStream
Definition: DeviceTypeConfig.cu.h:62
cudaStream_t deviceStream_t
Definition: DeviceTypeConfig.cu.h:27
dealii includes
Definition: AtomFieldDataSpherical.cpp:31
std::uint64_t size_type
Definition: TypeConfig.h:9