Skip to content

Commit 9c5423c

Browse files
Merge pull request #116 from ErikQQY/qqy/bvp_working_precision
Add BVP precision diagram
2 parents a185b85 + f6ce3ed commit 9c5423c

File tree

4 files changed

+153
-4
lines changed

4 files changed

+153
-4
lines changed

Project.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DiffEqDevTools"
22
uuid = "f3b72e0c-5b89-59e1-b016-84e28bfd966d"
33
authors = ["Chris Rackauckas <[email protected]>"]
4-
version = "2.36.0"
4+
version = "2.37.0"
55

66
[deps]
77
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
@@ -28,6 +28,8 @@ SciMLBase = "1.74"
2828
julia = "1.6"
2929

3030
[extras]
31+
BoundaryValueDiffEq = "764a87c0-6b3e-53db-9096-fe964310641d"
32+
BVProblemLibrary = "ded0fc24-dfea-4565-b1d9-79c027d14d84"
3133
DelayDiffEq = "bcd4f6db-9728-5f36-b5f7-82caef46ccdb"
3234
DDEProblemLibrary = "f42792ee-6ffc-4e2a-ae83-8ee2f22de800"
3335
NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec"
@@ -42,4 +44,4 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
4244
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4345

4446
[targets]
45-
test = ["DelayDiffEq", "DDEProblemLibrary", "NonlinearSolve", "ODEProblemLibrary", "SDEProblemLibrary", "OrdinaryDiffEq", "ParameterizedFunctions", "Random", "StochasticDiffEq", "StochasticDelayDiffEq", "Plots", "Test"]
47+
test = ["BoundaryValueDiffEq", "BVProblemLibrary", "DelayDiffEq", "DDEProblemLibrary", "NonlinearSolve", "ODEProblemLibrary", "SDEProblemLibrary", "OrdinaryDiffEq", "ParameterizedFunctions", "Random", "StochasticDiffEq", "StochasticDelayDiffEq", "Plots", "Test"]

src/DiffEqDevTools.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Base: length
1111
import DiffEqBase: AbstractODEProblem, AbstractDDEProblem, AbstractDDEAlgorithm,
1212
AbstractODESolution, AbstractRODEProblem, AbstractSDEProblem,
1313
AbstractSDDEProblem, AbstractEnsembleProblem,
14-
AbstractDAEProblem, @def, ConvergenceSetup, DEAlgorithm,
14+
AbstractDAEProblem, AbstractBVProblem, @def, ConvergenceSetup, DEAlgorithm,
1515
ODERKTableau, AbstractTimeseriesSolution, ExplicitRKTableau,
1616
ImplicitRKTableau
1717

src/benchmark.jl

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,103 @@ function WorkPrecision(prob, alg, abstols, reltols, dts = nothing;
273273
return WorkPrecision(prob, abstols, reltols, errors, times, name, N)
274274
end
275275

276+
# Work precision information for a BVP
277+
function WorkPrecision(prob::AbstractBVProblem, alg, abstols, reltols, dts = nothing;
278+
name = nothing, appxsol = nothing, error_estimate = :final,
279+
numruns = 20, seconds = 2, kwargs...)
280+
N = length(abstols)
281+
errors = Vector{Float64}(undef, N)
282+
times = Vector{Float64}(undef, N)
283+
if name === nothing
284+
name = "WP-Alg"
285+
end
286+
287+
if haskey(kwargs, :prob_choice)
288+
_prob = prob[kwargs[:prob_choice]]
289+
elseif prob isa AbstractArray
290+
_prob = prob[1]
291+
else
292+
_prob = prob
293+
end
294+
295+
let _prob = _prob
296+
timeseries_errors = error_estimate TIMESERIES_ERRORS
297+
dense_errors = error_estimate DENSE_ERRORS
298+
for i in 1:N
299+
if dts === nothing
300+
sol = solve(_prob, alg; kwargs..., abstol = abstols[i],
301+
reltol = reltols[i], timeseries_errors = timeseries_errors,
302+
dense_errors = dense_errors)
303+
else
304+
sol = DiffEqBase.solve(_prob, alg; kwargs..., abstol = abstols[i],
305+
reltol = reltols[i], dt = dts[i],
306+
timeseries_errors = timeseries_errors,
307+
dense_errors = dense_errors)
308+
end
309+
310+
if haskey(kwargs, :prob_choice)
311+
cur_appxsol = appxsol[kwargs[:prob_choice]]
312+
elseif prob isa AbstractArray
313+
cur_appxsol = appxsol[1]
314+
else
315+
cur_appxsol = appxsol
316+
end
317+
318+
if cur_appxsol !== nothing
319+
errsol = appxtrue(sol, cur_appxsol)
320+
errors[i] = mean(errsol.errors[error_estimate])
321+
else
322+
errors[i] = mean(sol.errors[error_estimate])
323+
end
324+
325+
benchmark_f = let dts = dts, _prob = _prob, alg = alg, sol = sol,
326+
abstols = abstols, reltols = reltols, kwargs = kwargs
327+
328+
if dts === nothing
329+
if typeof(_prob) <: DAEProblem
330+
() -> @elapsed solve(_prob, alg;
331+
abstol = abstols[i],
332+
reltol = reltols[i],
333+
timeseries_errors = false,
334+
dense_errors = false, kwargs...)
335+
else
336+
() -> @elapsed solve(_prob, alg;
337+
abstol = abstols[i],
338+
reltol = reltols[i],
339+
timeseries_errors = false,
340+
dense_errors = false, kwargs...)
341+
end
342+
else
343+
if typeof(_prob) <: DAEProblem
344+
() -> @elapsed solve(_prob, alg;
345+
abstol = abstols[i],
346+
reltol = reltols[i],
347+
dt = dts[i],
348+
timeseries_errors = false,
349+
dense_errors = false, kwargs...)
350+
else
351+
() -> @elapsed solve(_prob, alg;
352+
abstol = abstols[i],
353+
reltol = reltols[i],
354+
dt = dts[i],
355+
timeseries_errors = false,
356+
dense_errors = false, kwargs...)
357+
end
358+
end
359+
end
360+
benchmark_f() # pre-compile
361+
362+
b_t = benchmark_f()
363+
if b_t > seconds
364+
times[i] = b_t
365+
else
366+
times[i] = mapreduce(i -> benchmark_f(), min, 2:numruns; init = b_t)
367+
end
368+
end
369+
end
370+
return WorkPrecision(prob, abstols, reltols, errors, times, name, N)
371+
end
372+
276373
# Work precision information for a nonlinear problem.
277374
function WorkPrecision(prob::NonlinearProblem, alg, abstols, reltols, dts = nothing; name = nothing, appxsol = nothing, error_estimate = :l2, numruns = 20, seconds = 2, kwargs...)
278375
isnothing(appxsol) && error("Must provide the real value as the \"appxsol\" kwarg.")
@@ -587,6 +684,33 @@ function WorkPrecisionSet(prob::AbstractEnsembleProblem, abstols, reltols, setup
587684
Int(trajectories))
588685
end
589686

687+
function WorkPrecisionSet(prob::AbstractBVProblem,
688+
abstols, reltols, setups;
689+
print_names = false, names = nothing, appxsol = nothing,
690+
error_estimate = :final,
691+
test_dt = nothing, kwargs...)
692+
N = length(setups)
693+
@assert names === nothing || length(setups) == length(names)
694+
wps = Vector{WorkPrecision}(undef, N)
695+
if names === nothing
696+
names = [_default_name(setup[:alg]) for setup in setups]
697+
end
698+
for i in 1:N
699+
print_names && println(names[i])
700+
_abstols = get(setups[i], :abstols, abstols)
701+
_reltols = get(setups[i], :reltols, reltols)
702+
_dts = get(setups[i], :dts, nothing)
703+
filtered_setup = filter(p -> p.first in DiffEqBase.allowedkeywords, setups[i])
704+
705+
wps[i] = WorkPrecision(prob, setups[i][:alg], _abstols, _reltols, _dts;
706+
appxsol = appxsol,
707+
error_estimate = error_estimate,
708+
name = names[i], kwargs..., filtered_setup...)
709+
end
710+
return WorkPrecisionSet(wps, N, abstols, reltols, prob, setups, names, error_estimate,
711+
nothing)
712+
end
713+
590714
function get_sample_errors(prob::AbstractRODEProblem, setup, test_dt = nothing;
591715
appxsol_setup = nothing,
592716
numruns, error_estimate = :final,

test/benchmark_tests.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
using OrdinaryDiffEq, DelayDiffEq, DiffEqDevTools, DiffEqBase, Test
1+
using OrdinaryDiffEq, DelayDiffEq, BoundaryValueDiffEq, DiffEqDevTools, DiffEqBase, Test
22
using ODEProblemLibrary: prob_ode_2Dlinear, prob_ode_linear
33
using DDEProblemLibrary: prob_dde_constant_1delay_ip
4+
using BVProblemLibrary: prob_bvp_linear_1
45

56
## Setup Tests
67

@@ -176,3 +177,25 @@ setups = [Dict(:alg => RadauIIA5()),
176177
Dict(:alg => RosShamp4())]
177178
shoot = Shootout(prob, setups; appxsol = TestSolution(sol))
178179
@test shoot.names == ["RadauIIA5", "RosShamp4"]
180+
181+
# BVP problem
182+
prob = prob_bvp_linear_1
183+
abstols = 1.0 ./ 10.0 .^ (2:3)
184+
reltols = 1.0 ./ 10.0 .^ (2:3)
185+
sol = solve(prob, Shooting(Tsit5()), abstol = 1e-14, reltol = 1e-14)
186+
test_sol = TestSolution(sol.t, sol.u)
187+
188+
setups = [Dict(:alg => MIRK4(), :dts => 1.0 ./ 5.0 .^ ((1:length(reltols)) .+ 1))
189+
Dict(:alg => MIRK5(), :dts => 1.0 ./ 5.0 .^ ((1:length(reltols)) .+ 1))]
190+
labels = ["MIRK4", "MIRK5"]
191+
192+
println("Test MIRK4 and MIRK5")
193+
wp = WorkPrecisionSet(prob,
194+
abstols,
195+
reltols,
196+
setups;
197+
approxsol = sol,
198+
names = labels,
199+
print_names = true)
200+
@test wp.names == ["MIRK4", "MIRK5"]
201+
println("BVP Done")

0 commit comments

Comments
 (0)