From ce5b3e8b8aba8039c2a69bb2f4a90e46d624647e Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 29 Jul 2026 17:30:22 -0400 Subject: [PATCH] Restore DelayDiffEq extension hooks as public API Co-Authored-By: Chris Rackauckas --- docs/src/devtools/internals/public_api.md | 18 +++++++++++++++--- .../src/OrdinaryDiffEqCore.jl | 10 +++++----- lib/OrdinaryDiffEqCore/src/algorithms.jl | 5 +++++ lib/OrdinaryDiffEqCore/test/qa/qa.jl | 8 +++++++- lib/OrdinaryDiffEqDefault/test/qa/qa.jl | 4 ---- .../src/OrdinaryDiffEqNonlinearSolve.jl | 7 ++++--- lib/OrdinaryDiffEqNonlinearSolve/test/qa/qa.jl | 9 ++++++--- 7 files changed, 42 insertions(+), 19 deletions(-) diff --git a/docs/src/devtools/internals/public_api.md b/docs/src/devtools/internals/public_api.md index ccbd713987..9b1172d3e5 100644 --- a/docs/src/devtools/internals/public_api.md +++ b/docs/src/devtools/internals/public_api.md @@ -10,9 +10,9 @@ documented under the API section. Do not build application code against these hooks. They exist so solver packages can extend common traits, controllers, interpolation hooks, and initialization protocols without depending on undocumented implementation - details. Concrete per-algorithm cache types and low-level nonlinear solve - helper functions are not public API; only the abstract cache supertypes a - solver package subtypes are. + details. Concrete per-algorithm caches and low-level nonlinear-solve helpers + remain internal unless listed below; the listed automatic-switch caches and + nonlinear-solver hooks are shared with sibling integrator packages. ## DiffEqBase solver hooks @@ -99,6 +99,7 @@ OrdinaryDiffEqCore.StochasticDiffEqJumpNewtonDiffusionAdaptiveAlgorithm ```@docs OrdinaryDiffEqCore.CompositeAlgorithm +OrdinaryDiffEqCore.AutoSwitchCache OrdinaryDiffEqCore.isautoswitch OrdinaryDiffEqCore.default_autoswitch OrdinaryDiffEqCore.unwrap_alg @@ -193,6 +194,7 @@ extension points. ```@docs OrdinaryDiffEqCore.AbstractNLSolver OrdinaryDiffEqCore.AbstractNLSolverAlgorithm +OrdinaryDiffEqCore.AbstractNLSolverCache OrdinaryDiffEqCore.nlsolve_f OrdinaryDiffEqCore.get_W OrdinaryDiffEqCore.set_new_W! @@ -204,6 +206,12 @@ OrdinaryDiffEqCore.isJcurrent OrdinaryDiffEqCore.resize_J_W! OrdinaryDiffEqCore.resize_nlsolver! OrdinaryDiffEqCore.default_nlsolve +OrdinaryDiffEqNonlinearSolve.nlsolve! +OrdinaryDiffEqNonlinearSolve.nlsolvefail +OrdinaryDiffEqNonlinearSolve.compute_step! +OrdinaryDiffEqNonlinearSolve.initial_η +OrdinaryDiffEqNonlinearSolve.anderson +OrdinaryDiffEqNonlinearSolve.anderson! ``` ## Jacobian / W-matrix / differentiation configuration @@ -249,6 +257,7 @@ OrdinaryDiffEqCore.OrdinaryDiffEqMutableCache OrdinaryDiffEqCore.StochasticDiffEqCache OrdinaryDiffEqCore.StochasticDiffEqConstantCache OrdinaryDiffEqCore.StochasticDiffEqMutableCache +OrdinaryDiffEqCore.DefaultCache OrdinaryDiffEqCore.@cache OrdinaryDiffEqCore.alg_cache OrdinaryDiffEqCore.get_fsalfirstlast @@ -266,6 +275,9 @@ OrdinaryDiffEqCore._ode_init OrdinaryDiffEqCore._initialize_dae! OrdinaryDiffEqCore.find_algebraic_vars_eqs OrdinaryDiffEqCore.get_differential_vars +OrdinaryDiffEqCore.handle_callback_modifiers! +OrdinaryDiffEqCore.resolve_stage_step_limiters +OrdinaryDiffEqCore.trivial_limiter! ``` ## Dense output / interpolation diff --git a/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl b/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl index 2d1d032042..ba474114b4 100644 --- a/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl +++ b/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl @@ -429,12 +429,12 @@ include("precompilation_setup.jl") eval( Expr( :public, - :AbstractController, :AbstractControllerCache, :AbstractNLSolver, :AbstractNLSolverAlgorithm, :AbstractThreadingOption, + :AbstractController, :AbstractControllerCache, :AbstractNLSolver, :AbstractNLSolverAlgorithm, :AbstractNLSolverCache, :AbstractThreadingOption, :accept_step_controller, :alg_adaptive_order, :alg_autodiff, :alg_cache, :alg_difftype, :alg_extrapolates, - :alg_maximum_order, :alg_stability_size, :AutoAlgSwitch, :AutoSwitch, :BaseThreads, + :alg_maximum_order, :alg_stability_size, :AutoAlgSwitch, :AutoSwitch, :AutoSwitchCache, :BaseThreads, :beta1_default, :beta2_default, Symbol("@cache"), :COEFFICIENT_MULTISTEP, :CommonControllerOptions, :CompositeAlgorithm, :CompositeController, :constvalue, :Convergence, :current_extrapolant, - :current_interpolant, :DAEAlgorithm, :default_autoswitch, :default_controller, :default_linear_interpolation, + :current_interpolant, :DAEAlgorithm, :default_autoswitch, :DefaultCache, :default_controller, :default_linear_interpolation, :default_nlsolve, :DEOptions, :DIRK, :Divergence, :dt_required, :DummyController, :explicit_rk_docstring, :ExponentialAlgorithm, :FastConvergence, :gamma_default, :generic_solver_docstring, :get_current_adaptive_order, :get_current_alg_autodiff, :get_differential_vars, :get_EEst, :get_failfactor, :get_fsalfirstlast, @@ -477,7 +477,7 @@ include("precompilation_setup.jl") # Integrator step / cache / initialization hooks. :_ode_init, :_determine_initdt, :ode_determine_initdt, :_initialize_dae!, :find_algebraic_vars_eqs, :postamble!, :apply_step!, :last_step_failed, :reset_alg_dependent_opts!, - :resolve_basic, + :handle_callback_modifiers!, :resolve_basic, :resolve_stage_step_limiters, # Noise hooks used by the SDE/RODE solver sublibs. :accept_noise!, :reinit_noise!, :reject_noise!, :save_noise!, :noise_curt, :is_noise_saveable, @@ -487,7 +487,7 @@ include("precompilation_setup.jl") # OrdinaryDiffEqCache trio: every StochasticDiffEq solver cache subtypes one # of these, so they are a required solver-author extension point. :StochasticDiffEqCache, :StochasticDiffEqConstantCache, - :StochasticDiffEqMutableCache, + :StochasticDiffEqMutableCache, :trivial_limiter!, ) ) end diff --git a/lib/OrdinaryDiffEqCore/src/algorithms.jl b/lib/OrdinaryDiffEqCore/src/algorithms.jl index 585e3253e3..b8e2f77be0 100644 --- a/lib/OrdinaryDiffEqCore/src/algorithms.jl +++ b/lib/OrdinaryDiffEqCore/src/algorithms.jl @@ -334,6 +334,11 @@ end ################################################################################ +""" + trivial_limiter!(u, integrator, p, t) + +No-op stage/step limiter used when no solve-level limiter is supplied. +""" @inline trivial_limiter!(u, integrator, p, t) = nothing ################################################################################ diff --git a/lib/OrdinaryDiffEqCore/test/qa/qa.jl b/lib/OrdinaryDiffEqCore/test/qa/qa.jl index 3fe66ed4bc..6b954ddd8a 100644 --- a/lib/OrdinaryDiffEqCore/test/qa/qa.jl +++ b/lib/OrdinaryDiffEqCore/test/qa/qa.jl @@ -5,7 +5,13 @@ using SciMLTesting, OrdinaryDiffEqCore, Test const UNANALYZABLE = (OrdinaryDiffEqCore.Predictor,) @static if VERSION >= v"1.11.0-DEV.469" - @test Base.ispublic(OrdinaryDiffEqCore, :isdiscretecache) + for name in ( + :AbstractNLSolverCache, :AutoSwitchCache, :DefaultCache, + :handle_callback_modifiers!, :isdiscretecache, + :resolve_stage_step_limiters, :trivial_limiter!, + ) + @test Base.ispublic(OrdinaryDiffEqCore, name) + end end run_qa( diff --git a/lib/OrdinaryDiffEqDefault/test/qa/qa.jl b/lib/OrdinaryDiffEqDefault/test/qa/qa.jl index 6ac323055a..36b7f71ee1 100644 --- a/lib/OrdinaryDiffEqDefault/test/qa/qa.jl +++ b/lib/OrdinaryDiffEqDefault/test/qa/qa.jl @@ -50,10 +50,6 @@ without_local_project_sources(OrdinaryDiffEqDefault) do # stale because of the unanalyzable enum submodule above. ignore = (:Tsit5, :Vern7, :Rosenbrock23, :Rodas5P, :FBDF), ), - all_explicit_imports_are_public = (; - # Internal monorepo extension point; `AutoSwitchCache` is not user API. - ignore = (:AutoSwitchCache,), - ), all_qualified_accesses_are_public = (; # `lorenz`/`lorenz_oop` are OrdinaryDiffEqCore precompile-workload # test problems (defined in `precompilation_setup.jl`), deliberately diff --git a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl index fac420fd53..b089b4df3c 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl @@ -73,15 +73,16 @@ include("initialize_dae.jl") export BrownFullBasicInit, ShampineCollocationInit -# Nonlinear-solver algorithms accepted by OrdinaryDiffEq implicit methods. The -# lower-level build/step/Anderson helpers are implementation details, not public API. +# Nonlinear-solver algorithms accepted by OrdinaryDiffEq implicit methods and the +# solver-author hooks extended by sibling integrator packages. # The `public` keyword is only parseable on Julia >= 1.11.0-DEV.469, so it is # gated to keep the 1.10 floor parsing. @static if VERSION >= v"1.11.0-DEV.469" eval( Expr( :public, - :NLNewton, :NLFunctional, :NLAnderson, :HomotopyNonlinearSolveAlg + :NLNewton, :NLFunctional, :NLAnderson, :HomotopyNonlinearSolveAlg, + :nlsolve!, :nlsolvefail, :compute_step!, :initial_η, :anderson, :anderson! ) ) end diff --git a/lib/OrdinaryDiffEqNonlinearSolve/test/qa/qa.jl b/lib/OrdinaryDiffEqNonlinearSolve/test/qa/qa.jl index a2bc7abbe2..1e4d38c921 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/test/qa/qa.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/test/qa/qa.jl @@ -1,6 +1,12 @@ using SciMLTesting, OrdinaryDiffEqNonlinearSolve, Test using Aqua +@static if VERSION >= v"1.11.0-DEV.469" + for name in (:anderson, :anderson!, :compute_step!, :initial_η, :nlsolve!, :nlsolvefail) + @test Base.ispublic(OrdinaryDiffEqNonlinearSolve, name) + end +end + # Ambiguities are checked below over this package's own methods instead of Aqua's default # `[pkg, Base, Core]` module set; see the `Aqua.test_ambiguities` call. run_qa( @@ -45,9 +51,6 @@ run_qa( :AbstractSciMLOperator, # OrdinaryDiffEqDifferentiation W-operator types (attributed to SciMLOperators). :WOperator, :StaticWOperator, - # Owner-internal cross-sublibrary hooks with no public wrapper. - # OrdinaryDiffEqCore: - :AbstractNLSolverCache, # OrdinaryDiffEqDifferentiation: :build_J_W, :build_jac_config, :build_uf, :dolinsolve, :is_always_new, :jacobian!, :jacobian2W!, :resize_jac_config!,