OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
SplineTimeDependence.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018, Chris Rogers
3 * All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * 1. Redistributions of source code must retain the above copyright notice,
7 * this list of conditions and the following disclaimer.
8 * 2. Redistributions in binary form must reproduce the above copyright notice,
9 * this list of conditions and the following disclaimer in the documentation
10 * and/or other materials provided with the distribution.
11 * 3. Neither the name of STFC nor the names of its contributors may be used to
12 * endorse or promote products derived from this software without specific
13 * prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <gsl/gsl_spline.h>
31#include "Utility/Inform.h"
32
34 const std::vector<double>& times, const std::vector<double>& values){
35 setSpline(splineOrder, times, values);
36}
37
41
43 if (spline_m != nullptr) {
44 gsl_spline_free(spline_m);
45 }
46 if (acc_m != nullptr) {
47 gsl_interp_accel_free(acc_m);
48 }
49}
50
52 auto* timeDep = new SplineTimeDependence();
53 timeDep->setSpline(splineOrder_m, times_m, values_m);
54 return timeDep;
55}
56
58 if (spline_m == nullptr) {
59 os << "Uninitialised SplineTimeDependence" << endl;
60 } else {
61 os << "SplineTimeDependence of order " << splineOrder_m
62 << " with " << times_m.size() << " entries" << endl;
63 }
64 return os;
65}
66
67void SplineTimeDependence::setSpline(const size_t splineOrder, const std::vector<double>& times,
68 const std::vector<double>& values) {
69 if (times.size() != values.size()) {
71 "SplineTimeDependence::SplineTimeDependence",
72 "Times and values should be of equal length");
73 }
74 if (times.size() <= splineOrder) {
76 "SplineTimeDependence::SplineTimeDependence",
77 "Times and values should be of length > splineOrder");
78 }
79 if (splineOrder != 1 and splineOrder != 3) {
81 "SplineTimeDependence::SplineTimeDependence",
82 "Only linear or cubic interpolation is supported");
83 }
84 for (size_t i = 0; i < times.size() - 1; ++i) {
85 if (times[i] >= times[i + 1]) {
87 "SplineTimeDependence::SplineTimeDependence",
88 "Times should increase monotonically");
89 }
90 }
91 if (spline_m != nullptr) {
92 gsl_spline_free(spline_m);
93 spline_m = nullptr;
94 }
95 if (splineOrder == 1) {
96 spline_m = gsl_spline_alloc (gsl_interp_linear, times.size());
97 } else {
98 spline_m = gsl_spline_alloc (gsl_interp_cspline, times.size());
99 }
100 times_m = times;
101 values_m = values;
102 gsl_spline_init(spline_m, &times[0], &values[0], times.size());
103 if (acc_m == nullptr) {
104 acc_m = gsl_interp_accel_alloc();
105 } else {
106 gsl_interp_accel_reset(acc_m);
107 }
108}
109
110double SplineTimeDependence::getValue(const double time) {
111 if (time < times_m[0] or time > times_m.back()) {
112 std::stringstream ss;
113 ss << "time out of spline range: " << time;
114 throw GeneralClassicException("SplineTimeDependence::getValue",
115 ss.str());
116 }
117 return gsl_spline_eval (spline_m, time, acc_m);
118}
119
120double SplineTimeDependence::getIntegral(const double time) {
121 if (time < times_m[0] or time > times_m.back()) {
122 throw GeneralClassicException("SplineTimeDependence::getValue",
123 "time out of spline range");
124 }
125 return gsl_spline_eval_integ (spline_m, 0, time, acc_m);
126}
127
Inform & endl(Inform &inf)
Definition Inform.cpp:42
void setSpline(size_t splineOrder, const std::vector< double > &times, const std::vector< double > &values)
Inform & print(Inform &os) const
SplineTimeDependence * clone() override
std::vector< double > values_m
double getValue(double time) override
double getIntegral(double time) override
std::vector< double > times_m
SplineTimeDependence()=default