OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
SplineTimeDependence.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2026, Paul Scherrer Institute, Villigen PSI, Switzerland
3// All rights reserved
4//
5// This file is part of OPAL.
6//
7// OPAL is free software: you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// You should have received a copy of the GNU General License
13// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
14//
15
17#include <stdexcept>
18#include "Utility/Inform.h"
19
21 const size_t splineOrder, const std::vector<double>& times,
22 const std::vector<double>& values) {
23 setSpline(splineOrder, times, values);
24}
25
27 auto* timeDep = new SplineTimeDependence();
28 timeDep->setSpline(splineOrder_m, times_m, values_m);
29 return timeDep;
30}
31
32Inform& SplineTimeDependence::print(Inform& os) const {
33 if (!spline_m) {
34 os << "Uninitialised SplineTimeDependence" << endl;
35 } else {
36 os << "SplineTimeDependence of order " << splineOrder_m << " with " << times_m.size()
37 << " entries" << endl;
38 }
39 return os;
40}
41
43 const size_t splineOrder, const std::vector<double>& times,
44 const std::vector<double>& values) {
45 if (times.size() != values.size()) {
46 throw std::invalid_argument(
47 "SplineTimeDependence::SplineTimeDependence: "
48 "Times and values should be of equal length");
49 }
50 if (times.size() <= splineOrder) {
51 throw std::invalid_argument(
52 "SplineTimeDependence::SplineTimeDependence: "
53 "Times and values should be of length > splineOrder");
54 }
55 if (splineOrder != LinearInterpolation and splineOrder != CubicInterpolation) {
56 throw std::invalid_argument(
57 "SplineTimeDependence::SplineTimeDependence: "
58 "Only linear or cubic interpolation is supported");
59 }
60 for (size_t i = 0; i < times.size() - 1; ++i) {
61 if (times[i] >= times[i + 1]) {
62 throw std::invalid_argument(
63 "SplineTimeDependence::SplineTimeDependence: "
64 "Times should increase monotonically");
65 }
66 }
67 splineOrder_m = splineOrder;
68 times_m = times;
69 values_m = values;
70 splineAcc_m = std::make_unique<AbstractSpline::Accelerator>();
72 spline_m = std::make_unique<LinearSpline>(times_m, values_m);
73 } else {
74 spline_m = std::make_unique<CubicSpline>(times_m, values_m);
75 }
76}
77
78double SplineTimeDependence::getValue(const double time) {
79 double result{};
80 if (time < times_m[0] or time > times_m.back()) {
81 std::stringstream ss;
82 ss << "SplineTimeDependence::getValue: time out of spline range: " << time;
83 throw std::invalid_argument(ss.str());
84 }
85 result = spline_m->eval(time, *splineAcc_m);
86 return result;
87}
88
89double SplineTimeDependence::getIntegral(const double time) {
90 double result{};
91 if (time < times_m[0] or time > times_m.back()) {
92 std::stringstream ss;
93 ss << "SplineTimeDependence::getValue: time out of spline range: " << time;
94 throw std::invalid_argument(ss.str());
95 }
96 result = spline_m->evalIntegral(0, time, *splineAcc_m);
97 return result;
98}
void setSpline(size_t splineOrder, const std::vector< double > &times, const std::vector< double > &values)
Inform & print(Inform &os) const
static constexpr size_t CubicInterpolation
SplineTimeDependence * clone() override
std::vector< double > values_m
std::unique_ptr< AbstractSpline > spline_m
double getValue(double time) override
std::unique_ptr< AbstractSpline::Accelerator > splineAcc_m
double getIntegral(double time) override
std::vector< double > times_m
SplineTimeDependence()=default
static constexpr size_t LinearInterpolation