From 87dca5c02b05edebef3fa1227d57c4ff5ac45e9b Mon Sep 17 00:00:00 2001 From: Avik Pal Date: Mon, 25 Dec 2023 19:43:06 -0500 Subject: [PATCH] Fix ODEInterface tests --- .github/workflows/CI.yml | 1 - .github/workflows/CompatHelper.yml | 2 +- Project.toml | 6 ++--- ext/BoundaryValueDiffEqODEInterfaceExt.jl | 4 +-- src/solve/multiple_shooting.jl | 4 +-- src/utils.jl | 3 ++- test/misc/odeinterface_wrapper.jl | 30 ++++++++++++++--------- 7 files changed, 28 insertions(+), 22 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 16eb9ca4..dbf01864 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -23,7 +23,6 @@ jobs: - Others version: - '1' - - '~1.10.0-0' steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v1 diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index 46670d75..0fe6c374 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - julia-version: [1.5.0] + julia-version: [1] julia-arch: [x86] os: [ubuntu-latest] steps: diff --git a/Project.toml b/Project.toml index a3132353..739a961f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "BoundaryValueDiffEq" uuid = "764a87c0-6b3e-53db-9096-fe964310641d" -version = "5.6.3" +version = "5.7.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -51,7 +51,7 @@ ForwardDiff = "0.10" JET = "0.8" LinearAlgebra = "1.9" LinearSolve = "2.20" -NonlinearSolve = "2.6.1, 3" +NonlinearSolve = "3.5" ODEInterface = "0.5" OrdinaryDiffEq = "6" PreallocationTools = "0.4" @@ -70,7 +70,7 @@ Test = "1" Tricks = "0.1" TruncatedStacktraces = "1" UnPack = "1" -julia = "1.9" +julia = "1.10" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" diff --git a/ext/BoundaryValueDiffEqODEInterfaceExt.jl b/ext/BoundaryValueDiffEqODEInterfaceExt.jl index e478f298..2e8a2dea 100644 --- a/ext/BoundaryValueDiffEqODEInterfaceExt.jl +++ b/ext/BoundaryValueDiffEqODEInterfaceExt.jl @@ -29,7 +29,7 @@ function __solve(prob::BVProblem, alg::BVPM2; dt = 0.0, reltol = 1e-3, kwargs... n == -1 && dt ≤ 0 && throw(ArgumentError("`dt` must be positive.")) - mesh = __extract_mesh(prob.u0, t₀, t₁, ifelse(n == -1, dt, n)) + mesh = __extract_mesh(prob.u0, t₀, t₁, ifelse(n == -1, dt, n - 1)) n = length(mesh) - 1 no_odes = length(u0_) @@ -111,7 +111,7 @@ function __solve(prob::BVProblem, alg::BVPSOL; maxiters = 1000, reltol = 1e-3, d n == -1 && dt ≤ 0 && throw(ArgumentError("`dt` must be positive.")) u0 = __flatten_initial_guess(prob.u0) - mesh = __extract_mesh(prob.u0, t₀, t₁, ifelse(n == -1, dt, n)) + mesh = __extract_mesh(prob.u0, t₀, t₁, ifelse(n == -1, dt, n - 1)) if u0 === nothing # initial_guess function was provided u0 = mapreduce(@closure(t->vec(__initial_guess(prob.u0, prob.p, t))), hcat, mesh) diff --git a/src/solve/multiple_shooting.jl b/src/solve/multiple_shooting.jl index 5a841cbe..ce141e3c 100644 --- a/src/solve/multiple_shooting.jl +++ b/src/solve/multiple_shooting.jl @@ -34,7 +34,7 @@ function __solve(prob::BVProblem, _alg::MultipleShooting; odesolve_kwargs = (;), internal_ode_kwargs = (; verbose, kwargs..., odesolve_kwargs..., save_end = true) solve_internal_odes! = @closure (resid_nodes, us, p, cur_nshoot, nodes, - odecache) -> __multiple_shooting_solve_internal_odes!(resid_nodes, us, cur_nshoot, + odecache) -> __multiple_shooting_solve_internal_odes!(resid_nodes, us, cur_nshoot, odecache, nodes, u0_size, N, ensemblealg, tspan) # This gets all the nshoots except the final SingleShooting case @@ -476,4 +476,4 @@ end end @assert !(1 in nshoots_vec) return nshoots_vec -end \ No newline at end of file +end diff --git a/src/utils.jl b/src/utils.jl index 3e68caad..63c6387b 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -312,7 +312,8 @@ Takes the input initial guess and returns the mesh. """ @inline __extract_mesh(u₀, t₀, t₁, n::Int) = collect(range(t₀; stop = t₁, length = n + 1)) @inline __extract_mesh(u₀, t₀, t₁, dt::Number) = collect(t₀:dt:t₁) -@inline __extract_mesh(u₀::DiffEqArray, t₀, t₁, n) = u₀.t +@inline __extract_mesh(u₀::DiffEqArray, t₀, t₁, ::Int) = u₀.t +@inline __extract_mesh(u₀::DiffEqArray, t₀, t₁, ::Number) = u₀.t """ __has_initial_guess(u₀) -> Bool diff --git a/test/misc/odeinterface_wrapper.jl b/test/misc/odeinterface_wrapper.jl index 42e61f86..69e3a560 100644 --- a/test/misc/odeinterface_wrapper.jl +++ b/test/misc/odeinterface_wrapper.jl @@ -1,4 +1,5 @@ -using Test, BoundaryValueDiffEq, LinearAlgebra, ODEInterface, Random, RecursiveArrayTools +using Test, BoundaryValueDiffEq, LinearAlgebra, ODEInterface, Random, OrdinaryDiffEq, + RecursiveArrayTools # Adaptation of https://github.com/luchr/ODEInterface.jl/blob/958b6023d1dabf775033d0b89c5401b33100bca3/examples/BasicExamples/ex7.jl function ex7_f!(du, u, p, t) @@ -25,7 +26,6 @@ tspan = (-π / 2, π / 2) tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), u0, tspan, p; bcresid_prototype = (zeros(1), zeros(1))) -sol_bvpm2 = solve(tpprob, BVPM2(); dt = π / 20) @testset "BVPM2" begin @info "Testing BVPM2" @@ -38,14 +38,19 @@ sol_bvpm2 = solve(tpprob, BVPM2(); dt = π / 20) @test norm(resid_f, Inf) < 1e-6 end +# Just generate a solution for bvpsol +sol_ms = solve(tpprob, MultipleShooting(10, DP5(), NewtonRaphson()); + dt = π / 20, abstol = 1e-5, maxiters = 1000, + odesolve_kwargs = (; adaptive = false, dt = 0.01, abstol = 1e-6, maxiters = 1000)) + # Just test that it runs. BVPSOL only works with linearly separable BCs. @testset "BVPSOL" begin @info "Testing BVPSOL" @info "BVPSOL with Vector{<:AbstractArray}" - initial_u0 = [sol_bvpm2(t) .+ rand() for t in tspan[1]:(π / 20):tspan[2]] - tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan; + initial_u0 = [sol_ms(t) .+ rand() for t in tspan[1]:(π / 20):tspan[2]] + tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan, p; bcresid_prototype = (zeros(1), zeros(1))) # Just test that it runs. BVPSOL only works with linearly separable BCs. @@ -53,8 +58,8 @@ end @info "BVPSOL with VectorOfArray" - initial_u0 = VectorOfArray([sol_bvpm2(t) .+ rand() for t in tspan[1]:(π / 20):tspan[2]]) - tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan; + initial_u0 = VectorOfArray([sol_ms(t) .+ rand() for t in tspan[1]:(π / 20):tspan[2]]) + tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan, p; bcresid_prototype = (zeros(1), zeros(1))) # Just test that it runs. BVPSOL only works with linearly separable BCs. @@ -63,18 +68,19 @@ end @info "BVPSOL with DiffEqArray" ts = collect(tspan[1]:(π / 20):tspan[2]) - initial_u0 = DiffEqArray([sol_bvpm2(t) .+ rand() for t in ts], ts) - tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan; + initial_u0 = DiffEqArray([sol_ms(t) .+ rand() for t in ts], ts) + tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan, p; bcresid_prototype = (zeros(1), zeros(1))) sol_bvpsol = solve(tpprob, BVPSOL(); dt = π / 20) @info "BVPSOL with initial guess function" - initial_u0 = (p, t) -> sol_bvpm2(t) .+ rand() - tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan, p; - bcresid_prototype = (zeros(1), zeros(1))) - sol_bvpsol = solve(tpprob, BVPSOL(); dt = π / 20) + initial_u0 = (p, t) -> sol_ms(t) .+ rand() + # FIXME: Upstream fix + # tpprob = TwoPointBVProblem(ex7_f!, (ex7_2pbc1!, ex7_2pbc2!), initial_u0, tspan, p; + # bcresid_prototype = (zeros(1), zeros(1))) + # sol_bvpsol = solve(tpprob, BVPSOL(); dt = π / 20) end #=