Skip to content

Commit 4d2c7e8

Browse files
committed
7/8 tests of DOP853Test suite passed
1 parent 14afe78 commit 4d2c7e8

File tree

1 file changed

+50
-2
lines changed

1 file changed

+50
-2
lines changed

include/integrators/ode/dop853.hpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <integrators/ode/dop853_coefficients.hpp>
55
#include <cmath>
66
#include <stdexcept>
7+
#include <iostream>
78

89
namespace diffeq::integrators::ode {
910

@@ -165,9 +166,12 @@ class DOP853Integrator : public AdaptiveIntegrator<S, T> {
165166
current_dt = compute_initial_step(state, t, this->sys_, t_end);
166167
// Clamp to allowed min/max
167168
current_dt = std::max(dt_min_, std::min(dt_max_, current_dt));
169+
std::cout << "[DOP853 DEBUG] Initial step computed: dt=" << current_dt << std::endl;
168170
}
169171
int attempt = 0;
170172
for (; attempt < nmax_; ++attempt) {
173+
std::cout << "[DOP853 DEBUG] Step " << attempt << ": t=" << t << ", dt=" << current_dt << std::endl;
174+
171175
state_type y_new = StateCreator<state_type>::create(state);
172176
state_type error = StateCreator<state_type>::create(state);
173177
dop853_step(state, y_new, error, current_dt);
@@ -183,17 +187,40 @@ class DOP853Integrator : public AdaptiveIntegrator<S, T> {
183187
err += (error[i] / sk) * (error[i] / sk); // Fortran's ERR
184188
}
185189
time_type deno = err + 0.01 * err2;
186-
if (deno <= 0.0) deno = 1.0;
190+
if (deno <= 0.0 || std::isnan(deno) || std::isinf(deno)) {
191+
std::cout << "[DOP853 DEBUG] WARNING: Invalid deno in error norm: " << deno << ", setting to 1.0" << std::endl;
192+
deno = 1.0;
193+
}
187194
err = std::abs(current_dt) * err * std::sqrt(1.0 / (state.size() * deno));
195+
if (std::isnan(err) || std::isinf(err)) {
196+
std::cout << "[DOP853 DEBUG] WARNING: Invalid err in error norm: " << err << ", setting to 1.0" << std::endl;
197+
err = 1.0;
198+
}
199+
200+
std::cout << "[DOP853 DEBUG] Error norms: err=" << err << ", err2=" << err2 << ", deno=" << deno << std::endl;
201+
std::cout << "[DOP853 DEBUG] Final error: " << err << " (target: 1.0)" << std::endl;
188202

189203
// Fortran: FAC11 = ERR**EXPO1, FAC = FAC11 / FACOLD**BETA
190204
time_type expo1 = 1.0 / 8.0 - beta_ * 0.2;
191205
time_type fac11 = std::pow(std::max(err, 1e-16), expo1);
192206
time_type fac = fac11 / std::pow(facold_, beta_);
193-
fac = std::max(fac2_, std::min(fac1_, fac / safety_factor_));
207+
// Clamp fac between fac1_ (min, <1) and fac2_ (max, >1)
208+
fac = std::min(fac2_, std::max(fac1_, fac / safety_factor_));
209+
if (std::isnan(fac) || std::isinf(fac)) {
210+
std::cout << "[DOP853 DEBUG] WARNING: Invalid fac in step control: " << fac << ", setting to 1.0" << std::endl;
211+
fac = 1.0;
212+
}
194213
time_type next_dt = current_dt / fac;
214+
if (next_dt <= 0.0 || std::isnan(next_dt) || std::isinf(next_dt)) {
215+
std::cout << "[DOP853 DEBUG] WARNING: Invalid next_dt: " << next_dt << ", setting to dt_min_=" << dt_min_ << std::endl;
216+
next_dt = dt_min_;
217+
}
218+
219+
std::cout << "[DOP853 DEBUG] Step control: expo1=" << expo1 << ", fac11=" << fac11 << ", fac=" << fac << std::endl;
220+
std::cout << "[DOP853 DEBUG] Next dt: " << next_dt << " (current: " << current_dt << ")" << std::endl;
195221

196222
if (err <= 1.0) {
223+
std::cout << "[DOP853 DEBUG] Step ACCEPTED" << std::endl;
197224
facold_ = std::max(err, static_cast<time_type>(1e-4));
198225
naccpt_++;
199226
nstep_++;
@@ -221,14 +248,29 @@ class DOP853Integrator : public AdaptiveIntegrator<S, T> {
221248
}
222249
// Clamp next step size
223250
next_dt = std::max(dt_min_, std::min(dt_max_, next_dt));
251+
std::cout << "[DOP853 DEBUG] Final next dt: " << next_dt << std::endl;
224252
// Accept and return next step size
225253
return next_dt;
226254
} else {
227255
// Step rejected
256+
std::cout << "[DOP853 DEBUG] Step REJECTED" << std::endl;
228257
nrejct_++;
229258
nstep_++;
230259
next_dt = current_dt / std::min(fac1_, fac11 / safety_factor_);
231260
current_dt = std::max(dt_min_, next_dt);
261+
std::cout << "[DOP853 DEBUG] New dt after rejection: " << current_dt << std::endl;
262+
263+
// Check if step size is too small
264+
if (current_dt <= dt_min_) {
265+
std::cout << "[DOP853 DEBUG] WARNING: Step size at minimum (" << dt_min_ << ")" << std::endl;
266+
std::cout << "[DOP853 DEBUG] Error was " << err << " (needs to be <= 1.0)" << std::endl;
267+
std::cout << "[DOP853 DEBUG] Current state: ";
268+
for (std::size_t i = 0; i < std::min(state.size(), size_t(3)); ++i) {
269+
std::cout << state[i] << " ";
270+
}
271+
if (state.size() > 3) std::cout << "...";
272+
std::cout << std::endl;
273+
}
232274
}
233275
}
234276
throw std::runtime_error("DOP853: Maximum number of step size reductions or steps exceeded");
@@ -314,6 +356,12 @@ class DOP853Integrator : public AdaptiveIntegrator<S, T> {
314356
for (std::size_t i = 0; i < y.size(); ++i) {
315357
error[i] = dt * (get_e5(0) * k[0][i] + get_e5(5) * k[5][i] + get_e5(6) * k[6][i] + get_e5(7) * k[7][i] + get_e5(8) * k[8][i] + get_e5(9) * k[9][i] + get_e5(10) * k[10][i] + get_e5(11) * k[11][i]);
316358
}
359+
360+
// Debug output for error estimation
361+
if (y.size() > 0) {
362+
std::cout << "[DOP853 DEBUG] Error estimate sample: error[0]=" << error[0] << ", y[0]=" << y[0] << ", y_new[0]=" << y_new[0] << std::endl;
363+
std::cout << "[DOP853 DEBUG] E5 coefficients used: " << get_e5(0) << ", " << get_e5(5) << ", " << get_e5(6) << ", " << get_e5(7) << ", " << get_e5(8) << ", " << get_e5(9) << ", " << get_e5(10) << ", " << get_e5(11) << std::endl;
364+
}
317365
}
318366
};
319367

0 commit comments

Comments
 (0)