|
| 1 | +# Pleiades benchmark |
| 2 | + |
| 3 | +```julia |
| 4 | +using LinearAlgebra, Statistics |
| 5 | +using DiffEqDevTools, ParameterizedFunctions, SciMLBase, OrdinaryDiffEq, Sundials, Plots |
| 6 | +using ModelingToolkit |
| 7 | +using ProbNumDiffEq |
| 8 | + |
| 9 | +# Plotting theme |
| 10 | +theme(:dao; |
| 11 | + markerstrokewidth=0.5, |
| 12 | + legend=:outertopright, |
| 13 | + bottom_margin=5Plots.mm, |
| 14 | + size = (1000, 400), |
| 15 | +) |
| 16 | +``` |
| 17 | + |
| 18 | +### Pleiades problem definition |
| 19 | + |
| 20 | +```julia |
| 21 | +# first-order ODE |
| 22 | +@fastmath function pleiades(du, u, p, t) |
| 23 | + v = view(u, 1:7) # x |
| 24 | + w = view(u, 8:14) # y |
| 25 | + x = view(u, 15:21) # x′ |
| 26 | + y = view(u, 22:28) # y′ |
| 27 | + du[15:21] .= v |
| 28 | + du[22:28] .= w |
| 29 | + @inbounds @simd ivdep for i in 1:14 |
| 30 | + du[i] = zero(eltype(u)) |
| 31 | + end |
| 32 | + @inbounds @simd ivdep for i in 1:7 |
| 33 | + @inbounds @simd ivdep for j in 1:7 |
| 34 | + if i != j |
| 35 | + r = ((x[i] - x[j])^2 + (y[i] - y[j])^2)^(3 / 2) |
| 36 | + du[i] += j * (x[j] - x[i]) / r |
| 37 | + du[7+i] += j * (y[j] - y[i]) / r |
| 38 | + end |
| 39 | + end |
| 40 | + end |
| 41 | +end |
| 42 | +x0 = [3.0, 3.0, -1.0, -3.0, 2.0, -2.0, 2.0] |
| 43 | +y0 = [3.0, -3.0, 2.0, 0, 0, -4.0, 4.0] |
| 44 | +dx0 = [0, 0, 0, 0, 0, 1.75, -1.5] |
| 45 | +dy0 = [0, 0, 0, -1.25, 1, 0, 0] |
| 46 | +u0 = [dx0; dy0; x0; y0] |
| 47 | +tspan = (0.0, 3.0) |
| 48 | +prob1 = ODEProblem(pleiades, u0, tspan) |
| 49 | + |
| 50 | +# second-order ODE |
| 51 | +function pleiades2(ddu, du, u, p, t) |
| 52 | + x = view(u, 1:7) |
| 53 | + y = view(u, 8:14) |
| 54 | + for i in 1:14 |
| 55 | + ddu[i] = zero(eltype(u)) |
| 56 | + end |
| 57 | + for i in 1:7, j in 1:7 |
| 58 | + if i != j |
| 59 | + r = ((x[i] - x[j])^2 + (y[i] - y[j])^2)^(3 / 2) |
| 60 | + ddu[i] += j * (x[j] - x[i]) / r |
| 61 | + ddu[7+i] += j * (y[j] - y[i]) / r |
| 62 | + end |
| 63 | + end |
| 64 | +end |
| 65 | +u0 = [x0; y0] |
| 66 | +du0 = [dx0; dy0] |
| 67 | +prob2 = SecondOrderODEProblem(pleiades2, du0, u0, tspan) |
| 68 | +probs = [prob1, prob2] |
| 69 | + |
| 70 | +ref_sol1 = solve(prob1, Vern9(), abstol=1/10^14, reltol=1/10^14, dense=false) |
| 71 | +ref_sol2 = solve(prob2, Vern9(), abstol=1/10^14, reltol=1/10^14, dense=false) |
| 72 | +ref_sols = [ref_sol1, ref_sol2] |
| 73 | + |
| 74 | +plot(ref_sol1, idxs=[(14+i,21+i) for i in 1:7], title="Pleiades Solution", legend=false) |
| 75 | +scatter!(ref_sol1.u[end][15:21], ref_sol1.u[end][22:end], color=1:7) |
| 76 | +``` |
| 77 | + |
| 78 | +## First-order ODE vs. second-order ODE |
| 79 | +```julia |
| 80 | +DENSE = false; |
| 81 | +SAVE_EVERYSTEP = false; |
| 82 | + |
| 83 | +_setups = [ |
| 84 | + "EK0(3) (1st order ODE)" => Dict(:alg => EK0(order=3, smooth=DENSE), :prob_choice => 1) |
| 85 | + "EK0(5) (1st order ODE)" => Dict(:alg => EK0(order=5, smooth=DENSE), :prob_choice => 1) |
| 86 | + "EK1(3) (1st order ODE)" => Dict(:alg => EK1(order=3, smooth=DENSE), :prob_choice => 1) |
| 87 | + "EK1(5) (1st order ODE)" => Dict(:alg => EK1(order=5, smooth=DENSE), :prob_choice => 1) |
| 88 | + "EK0(4) (2nd order ODE)" => Dict(:alg => EK0(order=4, smooth=DENSE), :prob_choice => 2) |
| 89 | + "EK0(6) (2nd order ODE)" => Dict(:alg => EK0(order=6, smooth=DENSE), :prob_choice => 2) |
| 90 | + "EK1(4) (2nd order ODE)" => Dict(:alg => EK1(order=4, smooth=DENSE), :prob_choice => 2) |
| 91 | + "EK1(6) (2nd order ODE)" => Dict(:alg => EK1(order=6, smooth=DENSE), :prob_choice => 2) |
| 92 | +] |
| 93 | + |
| 94 | +labels = first.(_setups) |
| 95 | +setups = last.(_setups) |
| 96 | + |
| 97 | +abstols = 1.0 ./ 10.0 .^ (6:11) |
| 98 | +reltols = 1.0 ./ 10.0 .^ (3:8) |
| 99 | + |
| 100 | +wp = WorkPrecisionSet( |
| 101 | + probs, abstols, reltols, setups; |
| 102 | + names = labels, |
| 103 | + #print_names = true, |
| 104 | + appxsol = ref_sols, |
| 105 | + dense = DENSE, |
| 106 | + save_everystep = SAVE_EVERYSTEP, |
| 107 | + numruns = 10, |
| 108 | + maxiters = Int(1e7), |
| 109 | + timeseries_errors = false, |
| 110 | + verbose = false, |
| 111 | +) |
| 112 | + |
| 113 | +plot(wp, color=[1 1 2 2 3 3 4 4], |
| 114 | + # xticks = 10.0 .^ (-16:1:5) |
| 115 | +) |
| 116 | +``` |
| 117 | + |
| 118 | + |
| 119 | +## Conclusion |
| 120 | + |
| 121 | +- If the problem is a second-order ODE, _implement it as a second-order ODE_! |
| 122 | + |
| 123 | + |
| 124 | +## Appendix |
| 125 | + |
| 126 | +Computer information: |
| 127 | +```julia |
| 128 | +using InteractiveUtils |
| 129 | +InteractiveUtils.versioninfo() |
| 130 | +``` |
| 131 | + |
| 132 | +Package Information: |
| 133 | +```julia |
| 134 | +using Pkg |
| 135 | +Pkg.status() |
| 136 | +``` |
| 137 | + |
| 138 | +And the full manifest: |
| 139 | +```julia |
| 140 | +Pkg.status(mode=Pkg.PKGMODE_MANIFEST) |
| 141 | +``` |
0 commit comments