diff --git a/Project.toml b/Project.toml index 70a4ca03..c3fde825 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "JumpProcesses" uuid = "ccbc3e58-028d-4f4c-8cd5-9ae44345cda5" authors = ["Chris Rackauckas "] -version = "9.26.0" +version = "9.27.0" [deps] ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" @@ -45,8 +45,9 @@ Graphs = "1.11" KernelAbstractions = "0.9" LinearAlgebra = "1" LinearSolve = "3" -OrdinaryDiffEq = "6" -OrdinaryDiffEqCore = "3, 4" +OrdinaryDiffEq = "6, 7" +OrdinaryDiffEqCore = "3.17, 4" +OrdinaryDiffEqFunctionMap = "1, 2" Pkg = "1" PoissonRandom = "0.4" Random = "1" @@ -57,7 +58,7 @@ SciMLBase = "2.115, 3.1" StableRNGs = "1" StaticArrays = "1.9.8" Statistics = "1" -StochasticDiffEq = "6.82" +StochasticDiffEq = "6.82, 7" SymbolicIndexingInterface = "0.3.36" Test = "1" julia = "1.10" @@ -70,6 +71,7 @@ FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +OrdinaryDiffEqFunctionMap = "d3585ca7-f5d3-4ba6-8057-292ed1abd90f" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" @@ -78,4 +80,4 @@ StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["ADTypes", "Aqua", "ExplicitImports", "FastBroadcast", "LinearAlgebra", "LinearSolve", "OrdinaryDiffEq", "Pkg", "SafeTestsets", "StableRNGs", "Statistics", "StochasticDiffEq", "Test"] +test = ["ADTypes", "Aqua", "ExplicitImports", "FastBroadcast", "LinearAlgebra", "LinearSolve", "OrdinaryDiffEq", "OrdinaryDiffEqFunctionMap", "Pkg", "SafeTestsets", "StableRNGs", "Statistics", "StochasticDiffEq", "Test"] diff --git a/docs/Project.toml b/docs/Project.toml index c69a2805..027165fb 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -20,8 +20,8 @@ Distributions = "0.25" Documenter = "1.1" Graphs = "1.9" JumpProcesses = "9.13.2" -OrdinaryDiffEq = "6.59" +OrdinaryDiffEq = "6.59, 7" Plots = "1.39" PointProcesses = "0.5" StableRNGs = "1.0" -StochasticDiffEq = "6.63" +StochasticDiffEq = "6.63, 7" diff --git a/docs/src/assets/Project.toml b/docs/src/assets/Project.toml index c69a2805..027165fb 100644 --- a/docs/src/assets/Project.toml +++ b/docs/src/assets/Project.toml @@ -20,8 +20,8 @@ Distributions = "0.25" Documenter = "1.1" Graphs = "1.9" JumpProcesses = "9.13.2" -OrdinaryDiffEq = "6.59" +OrdinaryDiffEq = "6.59, 7" Plots = "1.39" PointProcesses = "0.5" StableRNGs = "1.0" -StochasticDiffEq = "6.63" +StochasticDiffEq = "6.63, 7" diff --git a/src/SSA_stepper.jl b/src/SSA_stepper.jl index b3e69b97..bcc38694 100644 --- a/src/SSA_stepper.jl +++ b/src/SSA_stepper.jl @@ -113,6 +113,28 @@ end (integrator::SSAIntegrator)(t) = copy(integrator.u) (integrator::SSAIntegrator)(out, t) = (out .= integrator.u) +# SciMLBase v3 / DiffEqBase v7 renamed the integrator's `u_modified` field to +# `derivative_discontinuity` and internal callback code now reads/writes the +# field directly (e.g. `integrator.derivative_discontinuity`, not via a +# method). Aliasing here so both names access the same underlying storage — +# v6-era callbacks that look for `:u_modified` and v7-era callbacks that look +# for `:derivative_discontinuity` both keep working without renaming the +# struct field (which would be a breaking ABI change). +@inline function Base.getproperty(integrator::SSAIntegrator, sym::Symbol) + sym === :derivative_discontinuity && return getfield(integrator, :u_modified) + return getfield(integrator, sym) +end + +@inline function Base.setproperty!(integrator::SSAIntegrator, sym::Symbol, val) + sym === :derivative_discontinuity && + return setfield!(integrator, :u_modified, convert(Bool, val)) + return setfield!(integrator, sym, convert(fieldtype(typeof(integrator), sym), val)) +end + +function Base.propertynames(integrator::SSAIntegrator, private::Bool = false) + return (fieldnames(SSAIntegrator)..., :derivative_discontinuity) +end + function DiffEqBase.u_modified!(integrator::SSAIntegrator, bool::Bool) integrator.u_modified = bool end diff --git a/test/constant_rate.jl b/test/constant_rate.jl index 86c237c0..f404d8cf 100644 --- a/test/constant_rate.jl +++ b/test/constant_rate.jl @@ -1,4 +1,4 @@ -using JumpProcesses, DiffEqBase, OrdinaryDiffEq, Statistics +using JumpProcesses, DiffEqBase, OrdinaryDiffEq, OrdinaryDiffEqFunctionMap, Statistics using Test using StableRNGs rng = StableRNG(12345) diff --git a/test/ensemble_problems.jl b/test/ensemble_problems.jl index 75f82618..b8725d1c 100644 --- a/test/ensemble_problems.jl +++ b/test/ensemble_problems.jl @@ -108,7 +108,7 @@ end jprob = make_ssa_jump_prob() sol = solve(EnsembleProblem(jprob), SSAStepper(), EnsembleThreads(); trajectories = 4) - @test length(sol) == 4 + @test length(sol.u) == 4 end @testset "ODE + VR ($agg)" for agg in (VR_FRM(), VR_Direct(), VR_DirectFW()) @@ -117,7 +117,7 @@ end # randexp!(_jump_prob.rng, ...) on the shared original problem. sol = solve(EnsembleProblem(jprob), Tsit5(), EnsembleThreads(); trajectories = 4, save_everystep = false) - @test length(sol) == 4 + @test length(sol.u) == 4 end @testset "SDE + VR (VR_FRM): unique trajectories" begin @@ -126,7 +126,7 @@ end # resetted_jump_problem, so trajectories should be distinct. sol = solve(EnsembleProblem(jprob), EM(), EnsembleThreads(); trajectories = 4, dt = 0.01, save_everystep = false) - @test length(sol) == 4 + @test length(sol.u) == 4 finals = [sol.u[i].u[end][1] for i in 1:4] @test length(unique(finals)) > 1 end diff --git a/test/ensemble_uniqueness.jl b/test/ensemble_uniqueness.jl index adb97df3..2db8543f 100644 --- a/test/ensemble_uniqueness.jl +++ b/test/ensemble_uniqueness.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, JumpProcesses, Test +using OrdinaryDiffEq, OrdinaryDiffEqFunctionMap, JumpProcesses, Test using StableRNGs, Random j1 = ConstantRateJump((u, p, t) -> 10, (integrator) -> integrator.u[1] += 1) @@ -11,7 +11,7 @@ dprob = DiscreteProblem(u0, (0.0, 100.0)) # This ensures different trajectories while maintaining reproducibility. # Generate seeds from a seeded RNG for reproducibility of ensemble results. function make_seeded_prob_func(dprob, aggregator, jumps, base_rng) - return function prob_func(prob, i, repeat) + return function prob_func(prob, ctx) seed = rand(base_rng, UInt64) JumpProblem(dprob, aggregator, jumps...; rng = StableRNG(seed)) end diff --git a/test/saveat_regression.jl b/test/saveat_regression.jl index 03665d76..7b314051 100644 --- a/test/saveat_regression.jl +++ b/test/saveat_regression.jl @@ -17,7 +17,7 @@ Nsims = 10_000 sol = JumpProcesses.solve(EnsembleProblem(jprob), SSAStepper(), saveat = ts, trajectories = Nsims) -for i in 1:length(sol) +for i in 1:length(sol.u) NA .+= sol.u[i][1, :] end diff --git a/test/sir_model.jl b/test/sir_model.jl index e8cea455..86f20621 100644 --- a/test/sir_model.jl +++ b/test/sir_model.jl @@ -1,4 +1,4 @@ -using JumpProcesses, DiffEqBase, OrdinaryDiffEq +using JumpProcesses, DiffEqBase, OrdinaryDiffEq, OrdinaryDiffEqFunctionMap using Test using StableRNGs rng = StableRNG(12345) diff --git a/test/splitcoupled.jl b/test/splitcoupled.jl index e871e2c0..0bd5ba62 100644 --- a/test/splitcoupled.jl +++ b/test/splitcoupled.jl @@ -1,4 +1,4 @@ -using JumpProcesses, DiffEqBase, OrdinaryDiffEq, StochasticDiffEq, Statistics +using JumpProcesses, DiffEqBase, OrdinaryDiffEq, OrdinaryDiffEqFunctionMap, StochasticDiffEq, Statistics using Test using StableRNGs rng = StableRNG(12345) diff --git a/test/thread_safety.jl b/test/thread_safety.jl index 7356ce2f..7659670c 100644 --- a/test/thread_safety.jl +++ b/test/thread_safety.jl @@ -26,11 +26,11 @@ let for agg in (VR_FRM(), VR_Direct(), VR_DirectFW()) jump_prob = JumpProblem(ode_prob, Direct(), vrj; vr_aggregator = agg) - prob_func(prob, i, repeat) = deepcopy(prob) + prob_func(prob, ctx) = deepcopy(prob) prob = EnsembleProblem(jump_prob, prob_func = prob_func) sol = solve(prob, Tsit5(), EnsembleThreads(), trajectories = 400, save_everystep = false) - firstrx_time = [sol.u[i].t[findfirst(>(sol.u[i].t[1]), sol.u[i].t)] for i in 1:length(sol)] + firstrx_time = [sol.u[i].t[findfirst(>(sol.u[i].t[1]), sol.u[i].t)] for i in 1:length(sol.u)] @test allunique(firstrx_time) end end diff --git a/test/variable_rate.jl b/test/variable_rate.jl index ce08781d..0b81a14b 100644 --- a/test/variable_rate.jl +++ b/test/variable_rate.jl @@ -41,8 +41,8 @@ integrator = init(jump_prob_gill, Tsit5()) sol_gill = solve(jump_prob_gill, Tsit5()) sol_gill = solve(jump_prob, Rosenbrock23(autodiff = AutoFiniteDiff())) sol_gill = solve(jump_prob, Rosenbrock23()) -@test maximum([sol.u[i][2] for i in 1:length(sol)]) <= 1e-12 -@test maximum([sol.u[i][3] for i in 1:length(sol)]) <= 1e-12 +@test maximum([sol.u[i][2] for i in 1:length(sol.u)]) <= 1e-12 +@test maximum([sol.u[i][3] for i in 1:length(sol.u)]) <= 1e-12 g = function (du, u, p, t) du[1] = u[1] @@ -52,8 +52,8 @@ jump_prob = JumpProblem(prob, jump, jump2; vr_aggregator = VR_FRM(), rng = rng) sol = solve(jump_prob, SRIW1()) jump_prob_gill = JumpProblem(prob, jump, jump2; vr_aggregator = VR_Direct(), rng = rng) sol_gill = solve(jump_prob_gill, SRIW1()) -@test maximum([sol.u[i][2] for i in 1:length(sol)]) <= 1e-12 -@test maximum([sol.u[i][3] for i in 1:length(sol)]) <= 1e-12 +@test maximum([sol.u[i][2] for i in 1:length(sol.u)]) <= 1e-12 +@test maximum([sol.u[i][3] for i in 1:length(sol.u)]) <= 1e-12 function ff(du, u, p, t) if p == 0