Commit c1879d3
committed
Fix spurious tiny final step for fixed-dt methods
When solving with a fixed-dt method (e.g. `solve(prob, Euler(); dt = 0.1)`),
the accumulated `t + dt + dt + ...` drifts and used to produce a spurious
trailing step at `1 - eps` followed by `1.0`. PR #2869 removed the
`100eps(tstop)` snap hack that previously masked this in
`fixed_t_for_floatingpoint_error!`.
Two coordinated changes restore the expected 11-step result without
reintroducing the old hack:
1. `_ode_init` expands `tstops` to `tspan[1]:dt:tspan[end]` when the user
specifies `dt` for a fixed-time method and did not supply their own
`tstops`/`d_discontinuities`. Julia's range semantics use TwicePrecision
internally, so each range element is the exact floating-point
representative of `k*dt` and lands on `tspan[end]` cleanly. The
expansion is skipped whenever the user supplied any tstops, which
preserves the existing "continue at dtcache between user tstops"
behavior that tests like `sol.t == [0, 1/3, 1/2, 5/6, 1]` depend on.
2. `modify_dt_for_tstops!` compares `dt` against `distance_to_tstop` with
a small floating-point tolerance (`100 * eps(max(t, tstop))`). Without
this tolerance, `dtcache = 0.1` reads as strictly less than a
`distance_to_tstop` of `0.10000000000000009` and the integrator takes
a full step that overshoots the tstop by one ulp, then takes a
matching tiny corrective step. The tolerance guard is gated on
`isfinite(tdir_tstop) && isfinite(integrator.t)` so that semi-infinite
`tspan = (0.0, Inf)` integrations still work.
Adds a regression test covering forward, reverse, and non-evenly-dividing
`dt` on `tspan = (0.0, 1.0)`.
Fixes the PositiveIntegrators.jl CI failure noted in
NumericalMathematics/PositiveIntegrators.jl#192 where
`solve(prob, Euler(); dt = 0.1)` began returning 12 steps instead of 11.
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>1 parent ba0dfa2 commit c1879d3
3 files changed
Lines changed: 52 additions & 2 deletions
File tree
- lib/OrdinaryDiffEqCore/src
- integrators
- test/interface
Lines changed: 13 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
178 | 178 | | |
179 | 179 | | |
180 | 180 | | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
181 | 192 | | |
182 | 193 | | |
183 | 194 | | |
184 | 195 | | |
185 | | - | |
| 196 | + | |
186 | 197 | | |
187 | 198 | | |
188 | 199 | | |
| |||
198 | 209 | | |
199 | 210 | | |
200 | 211 | | |
201 | | - | |
| 212 | + | |
202 | 213 | | |
203 | 214 | | |
204 | 215 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
401 | 401 | | |
402 | 402 | | |
403 | 403 | | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
404 | 417 | | |
405 | 418 | | |
406 | 419 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
272 | 272 | | |
273 | 273 | | |
274 | 274 | | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
275 | 301 | | |
276 | 302 | | |
277 | 303 | | |
| |||
0 commit comments