|
| 1 | + |
| 2 | +template<system_state S, can_be_time T> |
| 3 | +class DOP853Integrator; |
| 4 | + |
| 5 | +template<system_state S, can_be_time T> |
| 6 | +class DOP853DenseOutputHelper { |
| 7 | +public: |
| 8 | + using value_type = typename DOP853Integrator<S, T>::value_type; |
| 9 | + // Dense output for DOP853: ported from Fortran CONTD8 |
| 10 | + // CON: continuous output coefficients, size 8*nd |
| 11 | + // ICOMP: index mapping, size nd |
| 12 | + // nd: number of dense output components |
| 13 | + // xold: left endpoint of interval, h: step size |
| 14 | + // x: interpolation point (xold <= x <= xold+h) |
| 15 | + // Returns: interpolated value for component ii at x |
| 16 | + static value_type contd8( |
| 17 | + int ii, value_type x, const value_type* con, const int* icomp, int nd, |
| 18 | + value_type xold, value_type h) { |
| 19 | + int i = -1; |
| 20 | + for (int j = 0; j < nd; ++j) { |
| 21 | + if (icomp[j] == ii) { i = j; break; } |
| 22 | + } |
| 23 | + if (i == -1) { |
| 24 | + throw std::runtime_error("No dense output available for component " + std::to_string(ii)); |
| 25 | + } |
| 26 | + value_type s = (x - xold) / h; |
| 27 | + value_type s1 = 1.0 - s; |
| 28 | + value_type conpar = con[i + nd*4] + s * (con[i + nd*5] + s1 * (con[i + nd*6] + s * con[i + nd*7])); |
| 29 | + value_type result = con[i] + s * (con[i + nd] + s1 * (con[i + nd*2] + s * (con[i + nd*3] + s1 * conpar))); |
| 30 | + return result; |
| 31 | + } |
| 32 | +}; |
1 | 33 | #pragma once |
2 | 34 | #include <core/adaptive_integrator.hpp> |
3 | 35 | #include <core/state_creator.hpp> |
@@ -66,8 +98,11 @@ class DOP853Integrator : public AdaptiveIntegrator<S, T> { |
66 | 98 | } else { |
67 | 99 | h1 = std::max(1e-6, std::abs(h) * 1e-3); |
68 | 100 | } |
69 | | - h = std::min(100 * std::abs(h), h1, std::abs(t_end - t)); |
70 | | - h = std::copysign(h, t_end - t); |
| 101 | + // Avoid std::min(a, b, c) which is not standard C++ |
| 102 | + time_type hmax = 100 * std::abs(h); |
| 103 | + time_type htmp = (h1 < hmax) ? h1 : hmax; |
| 104 | + htmp = (htmp < std::abs(t_end - t)) ? htmp : std::abs(t_end - t); |
| 105 | + h = std::copysign(htmp, t_end - t); |
71 | 106 | return h; |
72 | 107 | } |
73 | 108 |
|
|
0 commit comments