1 #ifndef VTESTBED_CORE_RKF45_HH 2 #define VTESTBED_CORE_RKF45_HH 7 #include <vtestbed/base/blitz.hh> 8 #include <vtestbed/core/math.hh> 35 T _tolerance = T(1e-6);
37 bool _verbose =
false;
65 template <
class Function,
int N>
66 inline blitz::TinyVector<T,N>
67 solve(Function f, T t0, T t1,
const blitz::TinyVector<T,N>& x0) {
68 typedef blitz::TinyVector<T,N> vec;
74 state st = state::normal_iteration;
75 const T tol = this->_tolerance;
76 const T h_min = this->_minstep;
77 const T h_max = this->_maxstep;
83 << std::setw(8) <<
"rkf45" 84 << std::setw(10) << t0
86 << std::setw(10) << x0
89 while (st != state::end) {
130 const vec k_1 = h*f(t, x_i);
145 + (T(1932)/T(2197))*k_1
146 - (T(7200)/T(2197))*k_2
147 + (T(7296)/T(2197))*k_3
152 + (T(439)/T(216))*k_1
154 + (T(3680)/T(513))*k_3
155 - (T(845)/T(4104))*k_4
162 - (T(3544)/T(2565))*k_3
163 + (T(1859)/T(4104))*k_4
178 + (T(1408)/T(2565))*k_3
179 + (T(2197)/T(4101))*k_4
195 + (T(6656)/T(12825))*k_3
196 + (T(28561)/T(56430))*k_4
199 if (this->_verbose) {
201 << std::setw(8) <<
"rkf45" 202 << std::setw(10) << t
203 << std::setw(10) << h
204 << std::setw(10) << x_ip1
207 if (st == state::last_iteration) {
220 const T diff = max(abs(x_ip1 - z_ip1));
221 const T s = std::pow((tol*h) / (T(2)*diff), T(1)/T(4));
227 h = blitz::clamp(s*h, h_min, h_max);
228 if (t + h + h_min > t1) {
231 st = state::last_iteration;
242 template <
class Function,
int N>
243 inline blitz::TinyVector<T,N>
244 operator()(Function f, T t0, T t1,
const blitz::TinyVector<T,N>& x0) {
245 return this->solve<Function,N>(f, t0, t1, x0);
249 min_step() const noexcept {
250 return this->_minstep;
258 this->_minstep = rhs;
262 max_step() const noexcept {
263 return this->_maxstep;
271 this->_maxstep = rhs;
275 tolerance() const noexcept {
276 return this->_tolerance;
284 this->_tolerance = rhs;
288 verbose(
bool rhs) noexcept {
289 this->_verbose = rhs;
293 verbose() const noexcept {
294 return this->_verbose;
303 #endif // vim:filetype=cpp blitz::TinyVector< T, N > solve(Function f, T t0, T t1, const blitz::TinyVector< T, N > &x0)
Solve system of ordinary differential equations with right hand sides f.
blitz::TinyVector< T, N > operator()(Function f, T t0, T t1, const blitz::TinyVector< T, N > &x0)
Solve system of ordinary differential equations with right hand sides f.
Runge—Khutta—Fehlberg initial value problem solver.