Commit 88ef1ad
committed
Compose step-size knobs into CommonControllerOptions; replace DummyController for BDF/JVODE
In v7, `qmin` (alongside `qmax`, `gamma`, `beta1/beta2`, `qsteady_*`,
`qoldinit`) moved off `DEOptions` and onto the controller object. The
out-of-domain rejection path in `handle_step_rejection!` was still
reaching for the old `integrator.opts.qmin`, which throws on the v7
`DEOptions` struct — only the legacy DelayDiffEq constructor still
mentions it. The same was true of `integrator.opts.failfactor` in
`post_newton_controller!`.
Reported in
NumericalMathematics/PositiveIntegrators.jl#194 (comment)
Rather than papering over with a one-off `hasfield` walk, this lifts
the standard step-size knobs into a composable building block and
retires the `DummyController` workaround that BDF / Nordsieck were
using to keep the knobs on their algorithm structs.
A new `CommonControllerOptions{T}` struct holds `qmin`, `qmax`,
`qmax_first_step`, `gamma`, `qsteady_min`, `qsteady_max`, `failfactor`
— the seven scalars the integrator-level paths actually read. A single
type parameter `T` keeps the type signatures simple even if more knobs
are added later. All fields default to `nothing`; algorithm-specific
defaults are filled in by `resolve_basic` at `setup_controller_cache`
time. Concrete controllers (`IController`, `PIController`,
`PIDController`, `PredictiveController`, `ExtrapolationController`,
`KantorovichTypeController`, plus the new `BDFController` and
`JVODEController`) all embed a `CommonControllerOptions` as
`controller.basic`.
Seven generic accessors — `get_qmin`, `get_qmax`, `get_qmax_first_step`,
`get_gamma`, `get_qsteady_min`, `get_qsteady_max`, `get_failfactor` —
dispatch on `cache::AbstractControllerCache` and read through
`cache.controller.basic`. `CompositeControllerCache` overrides each one
to delegate to the active sub-cache. `DummyControllerCache` keeps an
alg-field fallback for any SDE algorithm still using it.
`integrator.opts.qmin` → `get_qmin(integrator)`,
`integrator.opts.failfactor` → `get_failfactor(integrator)`. Same in
the BDF post-Newton paths.
QNDF/FBDF/DFBDF used to keep `qmax`, `qsteady_min`, `qsteady_max` as
fields on the algorithm struct itself, with a `DummyController`
hard-wired into `default_controller`. The stepsize logic read
`alg.qmax` / `alg.qsteady_min` / `alg.qsteady_max` directly, plus a
hard-coded `zₛ = 1.2` magic-number gamma, so the controller surface was
unsettable.
`BDFController` embeds `CommonControllerOptions` and has a cache that
delegates back to alg-level dispatch (the existing BDF order-selection
logic is left intact). The hard-coded `zₛ = 1.2` is now
`get_gamma(integrator)`. `default_controller(QT, alg::Union{QNDF, FBDF, DFBDF})`
threads `alg.qmax` / `alg.qsteady_min` / `alg.qsteady_max` through to
the controller, so existing usage like `QNDF(qmax = 20)` keeps working.
Users can now also pass `controller = BDFController(qmin = …, gamma = …)`
to set knobs that previously had no surface (incl. `qmin` and `gamma`).
BDF-tuned per-algorithm defaults (`qmax = 5//1`, `qsteady_min = 9//10`,
`qsteady_max = 12//10`, `gamma = 12//10`) are encoded as
`qmax_default(::QNDF)` / `gamma_default(::QNDF)` etc.
Same pattern. `setη!` / `chooseη!` / `step_accept_controller!(::JVODE)`
now read `get_qmin(integrator)` / `get_qmax(integrator)` /
`get_qsteady_*(integrator)` instead of `alg.qmin` etc.
- `IController` / `PIController` / `PredictiveController` /
`PIDController` shed their flat `qmin/qmax/...` fields and embed
`CommonControllerOptions` instead. PI-specific knobs (`beta1`,
`beta2`, `qoldinit`) and PID-specific knobs (`beta`, `accept_safety`,
`limiter`) stay on the controller alongside `basic`.
- `ExtrapolationController` and `KantorovichTypeController` likewise
embed `CommonControllerOptions`. Their stepsize logic reads
`get_qmax(integrator)` / `get_qmin(integrator)` rather than direct
field access.
`test/runtests.jl` walks transitive `[sources]` dependencies and
`Pkg.develop`s them. Pre-seed the `developed` set with the active
project so a `[sources]` entry that points back to it (e.g. via the
umbrella `OrdinaryDiffEq`'s transitive sources) is skipped — `Pkg.develop`
cannot develop the active project itself, and that error was the
"package X has the same name or UUID as the active project" failure
across the sublibrary CI matrix.
Reproducer (`isoutofdomain` predicate that fires once on the first
proposed step) plus a smoke test of every controller path (default
`solve`, user-supplied `BDFController`, `CommonControllerOptions`
construction, controller-composition invariants) — 21/21 pass on Julia
1.12.
- On master (without this fix): all algorithms error out — accessing
`integrator.opts.qmin` throws because the v7 `DEOptions` struct
doesn't have the field.
- With this fix: `Tsit5` / `Vern7` / `Rosenbrock23` / `FBDF` / `QNDF`
all complete the isout-rejection problem successfully, and
`BDFController(qmax = 3)` is honored end-to-end.
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>1 parent 9b8e7e1 commit 88ef1ad
14 files changed
Lines changed: 573 additions & 254 deletions
File tree
- lib
- ImplicitDiscreteSolve/src
- OrdinaryDiffEqBDF/src
- OrdinaryDiffEqCore/src
- integrators
- OrdinaryDiffEqExtrapolation/src
- OrdinaryDiffEqFIRK/src
- OrdinaryDiffEqNordsieck/src
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
| 29 | + | |
29 | 30 | | |
30 | 31 | | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
37 | 48 | | |
38 | 49 | | |
39 | 50 | | |
40 | | - | |
| 51 | + | |
41 | 52 | | |
42 | 53 | | |
43 | 54 | | |
44 | 55 | | |
45 | 56 | | |
46 | 57 | | |
47 | | - | |
| 58 | + | |
48 | 59 | | |
49 | 60 | | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
54 | 67 | | |
| 68 | + | |
| 69 | + | |
55 | 70 | | |
56 | 71 | | |
57 | 72 | | |
| |||
62 | 77 | | |
63 | 78 | | |
64 | 79 | | |
65 | | - | |
| 80 | + | |
| 81 | + | |
66 | 82 | | |
67 | 83 | | |
68 | 84 | | |
| |||
84 | 100 | | |
85 | 101 | | |
86 | 102 | | |
87 | | - | |
| 103 | + | |
| 104 | + | |
88 | 105 | | |
89 | 106 | | |
90 | 107 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
22 | 27 | | |
23 | 28 | | |
24 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
1 | 61 | | |
2 | | - | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
3 | 70 | | |
4 | 71 | | |
5 | 72 | | |
| |||
18 | 85 | | |
19 | 86 | | |
20 | 87 | | |
21 | | - | |
| 88 | + | |
22 | 89 | | |
23 | 90 | | |
24 | 91 | | |
25 | 92 | | |
26 | 93 | | |
27 | 94 | | |
28 | 95 | | |
29 | | - | |
| 96 | + | |
30 | 97 | | |
31 | 98 | | |
32 | 99 | | |
| |||
86 | 153 | | |
87 | 154 | | |
88 | 155 | | |
89 | | - | |
| 156 | + | |
90 | 157 | | |
91 | 158 | | |
92 | 159 | | |
| |||
100 | 167 | | |
101 | 168 | | |
102 | 169 | | |
103 | | - | |
| 170 | + | |
104 | 171 | | |
105 | 172 | | |
106 | 173 | | |
| |||
154 | 221 | | |
155 | 222 | | |
156 | 223 | | |
157 | | - | |
| 224 | + | |
158 | 225 | | |
159 | 226 | | |
160 | 227 | | |
| |||
299 | 366 | | |
300 | 367 | | |
301 | 368 | | |
302 | | - | |
| 369 | + | |
303 | 370 | | |
304 | 371 | | |
305 | 372 | | |
| |||
320 | 387 | | |
321 | 388 | | |
322 | 389 | | |
323 | | - | |
| 390 | + | |
324 | 391 | | |
325 | 392 | | |
326 | 393 | | |
| |||
348 | 415 | | |
349 | 416 | | |
350 | 417 | | |
351 | | - | |
| 418 | + | |
352 | 419 | | |
353 | 420 | | |
354 | 421 | | |
| |||
465 | 532 | | |
466 | 533 | | |
467 | 534 | | |
468 | | - | |
| 535 | + | |
469 | 536 | | |
470 | 537 | | |
471 | 538 | | |
| |||
483 | 550 | | |
484 | 551 | | |
485 | 552 | | |
486 | | - | |
| 553 | + | |
487 | 554 | | |
488 | 555 | | |
489 | 556 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
468 | 468 | | |
469 | 469 | | |
470 | 470 | | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
471 | 481 | | |
472 | 482 | | |
473 | 483 | | |
| |||
0 commit comments