Skip to content

Commit e7e34f5

Browse files
committed
HINIT (initial step size guess) and CONTD8 (dense output) functions ported from FORTRAN
1 parent 44b83b5 commit e7e34f5

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

include/integrators/ode/dop853.hpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
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+
};
133
#pragma once
234
#include <core/adaptive_integrator.hpp>
335
#include <core/state_creator.hpp>
@@ -66,8 +98,11 @@ class DOP853Integrator : public AdaptiveIntegrator<S, T> {
6698
} else {
6799
h1 = std::max(1e-6, std::abs(h) * 1e-3);
68100
}
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);
71106
return h;
72107
}
73108

0 commit comments

Comments
 (0)