44#include < integrators/ode/dop853_coefficients.hpp>
55#include < cmath>
66#include < stdexcept>
7+ #include < iostream>
78
89namespace 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