Skip to content

Declare fix_dt_at_bounds!, handle_tstop!, initialize_tstops, initialize_saveat, initialize_d_discontinuities public - #4081

Merged
ChrisRackauckas merged 2 commits into
masterfrom
public-api-declarations
Aug 2, 2026
Merged

Declare fix_dt_at_bounds!, handle_tstop!, initialize_tstops, initialize_saveat, initialize_d_discontinuities public#4081
ChrisRackauckas merged 2 commits into
masterfrom
public-api-declarations

Conversation

@ChrisRackauckas

Copy link
Copy Markdown
Member

Declares five OrdinaryDiffEqCore bindings public (not exported) so that packages
building a custom integrator on top of the OrdinaryDiffEqCore machinery can call and
extend them without tripping strict ExplicitImports/SciMLTesting non-public checks.

Unblocks SciML/OrdinaryDiffEqOperatorSplitting.jl#102, which migrates that package to
SciMLTesting 2.4 strict QA. The alternative — rewriting the caller to dodge these
bindings — is not available here: OperatorSplitting adds methods to two of them for
its own integrator type, which is only possible by naming the generic function.

Bindings

Binding What it is Downstream use
fix_dt_at_bounds! Clamps integrator.dt into [dtmin, dtmax] respecting tdir (src/integrators/integrator_utils.jl:894) OperatorSplitting defines a method (src/utils.jl:164) and calls it (src/integrator.jl:536)
handle_tstop! Pops/consumes the reached tstop, sets just_hit_tstop, interpolates back for non-dtchangeable algorithms (src/integrators/integrator_utils.jl:909) OperatorSplitting defines a method (src/integrator.jl:419) and calls it in 3 places; DelayDiffEq calls it in src/solve.jl:584 and src/integrators/interface.jl:695
initialize_tstops Builds the internal BinaryHeap of tdir-signed tstops from user tstops/d_discontinuities/tspan (src/solve.jl:978) Called by OperatorSplitting (src/integrator.jl:233, :1020) and DelayDiffEq (src/solve.jl:277, src/integrators/interface.jl:436)
initialize_saveat Builds the internal saveat heap from the user saveat keyword (src/solve.jl:1030) Called by OperatorSplitting (src/integrator.jl:236) and DelayDiffEq (src/solve.jl:281, src/integrators/interface.jl:440)
initialize_d_discontinuities Builds the internal d_discontinuities heap (src/solve.jl:1075) Called by OperatorSplitting (src/integrator.jl:237) and DelayDiffEq (src/solve.jl:282, src/integrators/interface.jl:441)

Why interface, not implementation detail

  • fix_dt_at_bounds! and handle_tstop! are generic functions that downstream integrator
    packages are expected to extend — a generic function with downstream methods is an
    extension point by definition, and both existing custom-integrator consumers in the
    ecosystem (DelayDiffEq in this repo, OperatorSplitting out of tree) do exactly that.
  • handle_tstop! is already documented as part of the main solver loop in
    docs/src/devtools/contributing/diffeq_internals.md.
  • The three initialize_* functions are the only supported way to construct the internal
    heap representations that DEOptions requires. DEOptions is already public; a public
    struct whose fields cannot be constructed with public API is not usable.
  • lib/DelayDiffEq/test/qa/qa_tests.jl already carries all five (well, four of them, plus a
    larger set) on its non-public ignore list with the comment "make-public candidates" — this
    PR resolves that subset in the owning package rather than in each caller.

Already public — deliberately not touched

stepsize_controller!, step_accept_controller! and step_reject_controller! were also
flagged upstream, but they are already declared public in
lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl (the controller-author block at the top,
and again in the solver-author block). No change needed; declaring them again would be noise.

Style

Matches the file's existing @static if VERSION >= v"1.11.0-DEV.469" /
eval(Expr(:public, ...)) pattern, which keeps the Julia 1.10 floor parsing. This repo does
not use SciMLPublic, so no new dependency was added.

Verification

julia --project=lib/OrdinaryDiffEqCore -e 'using OrdinaryDiffEqCore'   # succeeds
length(names(OrdinaryDiffEqCore))  # 369 before -> 374 after (+5, no losses)

All five confirmed non-public before the edit and public after. Runic clean. Minor version
bump 4.12.0 -> 4.13.0 so downstream can set a compat bound that guarantees the declarations.

🤖 Generated with Claude Code

ChrisRackauckas and others added 2 commits July 30, 2026 13:44
Declares fix_dt_at_bounds!, handle_tstop!, initialize_tstops,
initialize_saveat and initialize_d_discontinuities public in
OrdinaryDiffEqCore. These are the hooks packages use to build their own
integrator on top of the OrdinaryDiffEqCore machinery; DelayDiffEq and
OrdinaryDiffEqOperatorSplitting both call them and add methods to them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ChrisRackauckas
ChrisRackauckas merged commit a7080c6 into master Aug 2, 2026
17 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant