@@ -48,107 +48,116 @@ sol2tqp(sol) = (sol.t, sol2q(sol), sol2p(sol))
4848#
4949sn(u, k) = Jacobi.sn(u, k^2) # the Jacobian sn function
5050
51- # Use PyPlot .
51+ # Use Plot .
5252#
53- using PyPlot
53+ using Plots
5454
55+ # Define the color list
5556colorlist = [
5657 "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
5758 "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf",
5859]
5960cc(k) = colorlist[mod1(k, length(colorlist))]
6061
61- # plot the sulution of a Hamiltonian problem
62- #
62+ # Function to plot the solution of a Hamiltonian problem
6363function plotsol(sol::ODESolution)
6464 local t, q, p
6565 t, q, p = sol2tqp(sol)
6666 local d = size(q)[2]
67+ p1 = plot(title="Solution", xlabel="t", grid=:on)
6768 for j in 1:d
6869 j_str = d > 1 ? "[$j]" : ""
69- plot( t, q[:,j], color=cc(2j-1), label="q$(j_str)", lw =1)
70- plot( t, p[:,j], color=cc(2j), label="p$(j_str)", lw =1, ls="--" )
70+ plot!(p1, t, q[:, j], color=cc(2j-1), label="q$(j_str)", linewidth =1)
71+ plot!(p1, t, p[:, j], color=cc(2j), label="p$(j_str)", linewidth =1, linestyle=:dash )
7172 end
72- grid(ls=":")
73- xlabel("t")
74- legend()
73+ return p1
7574end
7675
77- # plot the solution of a Hamiltonian problem on the 2D phase space
78- #
76+ # Function to plot the solution on the 2D phase space
7977function plotsol2(sol::ODESolution)
8078 local t, q, p
8179 t, q, p = sol2tqp(sol)
8280 local d = size(q)[2]
81+ p2 = plot(title="Phase Space", xlabel="q", ylabel="p", grid=:on)
8382 for j in 1:d
8483 j_str = d > 1 ? "[$j]" : ""
85- plot( q[:,j], p[:,j], color=cc(j), label="(q$(j_str),p$(j_str))", lw =1)
84+ plot!(p2, q[:, j], p[:, j], color=cc(j), label="(q$(j_str), p$(j_str))", linewidth =1)
8685 end
87- grid(ls=":")
88- xlabel("q")
89- ylabel("p")
90- legend()
86+ return p2
9187end
9288
93- # plot the energy of a Hamiltonian problem
94- #
89+ # Function to plot the energy of a Hamiltonian problem
9590function plotenergy(H, sol::ODESolution)
9691 local t, q, p
9792 t, q, p = sol2tqp(sol)
9893 local energy = [H(q[i,:], p[i,:], nothing) for i in 1:size(q)[1]]
99- plot(t, energy, label="energy", color="red", lw=1)
100- grid(ls=":")
101- xlabel("t")
102- legend()
103- local stdenergy_str = @sprintf("%.3e", std(energy))
104- title(" std(energy) = $stdenergy_str", fontsize=10)
94+ p3 = plot(t, energy, label="energy", color="red", linewidth=1, xlabel="t", title="Energy", grid=:on)
95+ stdenergy_str = @sprintf("%.3e", std(energy))
96+ title!("std(energy) = $stdenergy_str", fontsize=10)
97+ return p3
10598end
10699
107- # plot the numerical and exact solutions of a single pendulum
108- #
109- # Warning: Assume q(0) = 0, p(0) = 2k. (for the sake of laziness)
110- #
100+ # Function to compare the numerical and exact solutions of a single pendulum
111101function plotcomparison(k, sol::ODESolution)
112102 local t, q, p
113103 t, q, p = sol2tqp(sol)
114- local y = sin.(q/2)
115- local y_exact = k*sn.(t, k) # the exact solution
116-
117- plot(t, y, label="numerical", lw=1)
118- plot(t, y_exact, label="exact", lw=1, ls="--")
119- grid(ls=":")
120- xlabel("t")
121- ylabel("y = sin(q(t)/2)")
122- legend()
123- local error_str = @sprintf("%.3e", maximum(abs.(y - y_exact)))
124- title("maximum(abs(numerical - exact)) = $error_str", fontsize=10)
104+ local y = sin.(q / 2)
105+ local y_exact = k * sn.(t, k) # the exact solution
106+
107+ p4 = plot(t, y, label="numerical", linewidth=1, grid=:on, xlabel="t", ylabel="y = sin(q(t)/2)", title="Comparison")
108+ plot!(p4, t, y_exact, label="exact", linewidth=1, linestyle=:dash)
109+ error_str = @sprintf("%.3e", maximum(abs.(y - y_exact)))
110+ title!("maximum(abs(numerical - exact)) = $error_str", fontsize=10)
111+ return p4
125112end
126113
127- # plot solution and energy
128- #
114+ # Plot solution and energy
129115function plotsolenergy(H, integrator, Δt, sol::ODESolution)
130- local integrator_str = replace("$integrator", r"^[^.]*\." => "")
116+ integrator_str = replace("$integrator", r"^[^.]*\ \." => "")
131117
132- figure(figsize=(10,8))
118+ p1 = plotsol(sol)
119+ p2 = plotsol2(sol)
120+ p3 = plotenergy(H, sol)
133121
134- subplot2grid((21,20), ( 1, 0), rowspan=10, colspan=10)
135- plotsol(sol)
122+ suptitle = "===== $integrator_str, Δt = $Δt ====="
123+ plot(p1, p2, p3, layout=(3, 1), title=suptitle)
124+ end
136125
137- subplot2grid((21,20), ( 1,10), rowspan=10, colspan=10)
138- plotsol2(sol)
126+ # Solve a single pendulum
127+ function singlependulum(k, integrator, Δt; t0 = 0.0, t1 = 100.0)
128+ H(p, q, params) = p[1]^2 / 2 - cos(q[1]) + 1
129+ q0 = [0.0]
130+ p0 = [2k]
131+ prob = HamiltonianProblem(H, p0, q0, (t0, t1))
139132
140- subplot2grid((21,20), (11, 0), rowspan=10, colspan=10)
141- plotenergy(H, sol)
133+ integrator_str = replace("$integrator", r"^[^.]*\\." => "")
134+ @printf("%-25s", "$integrator_str:")
135+ sol = solve(prob, integrator, dt=Δt)
136+ @time sol = solve(prob, integrator, dt=Δt)
142137
143- suptitle("===== $integrator_str, Δt = $Δt =====")
138+ sleep(0.1)
139+
140+ p1 = plotsol(sol)
141+ p2 = plotsol2(sol)
142+ p3 = plotenergy(H, sol)
143+ p4 = plotcomparison(k, sol)
144+
145+ suptitle = "===== $integrator_str, Δt = $Δt ====="
146+ plot(p1, p2, p3, p4, layout=(2, 2), title=suptitle)
144147end
148+ ```
149+
150+ ## Tests
151+
152+ ```julia
153+ # Single pendulum
154+ using Plots
155+ using OrdinaryDiffEq
145156
146- # Solve a single pendulum
147- #
148157function singlependulum(k, integrator, Δt; t0 = 0.0, t1 = 100.0)
149- local H(p,q, params) = p[1]^2/ 2 - cos(q[1]) + 1
150- local q0 = [0.0]
151- local p0 = [2k]
158+ local H(p, q, params) = p[1]^2 / 2 - cos(q[1]) + 1 # Hamiltonian for single pendulum
159+ local q0 = [0.0] # Initial position
160+ local p0 = [2k] # Initial momentum
152161 local prob = HamiltonianProblem(H, p0, q0, (t0, t1))
153162
154163 local integrator_str = replace("$integrator", r"^[^.]*\." => "")
@@ -157,28 +166,17 @@ function singlependulum(k, integrator, Δt; t0 = 0.0, t1 = 100.0)
157166 @time local sol = solve(prob, integrator, dt=Δt)
158167
159168 sleep(0.1)
160- figure(figsize=(10,8))
161-
162- subplot2grid((21,20), ( 1, 0), rowspan=10, colspan=10)
163- plotsol(sol)
164-
165- subplot2grid((21,20), ( 1,10), rowspan=10, colspan=10)
166- plotsol2(sol)
167-
168- subplot2grid((21,20), (11, 0), rowspan=10, colspan=10)
169- plotenergy(H, sol)
170169
171- subplot2grid((21,20), (11,10), rowspan=10, colspan=10)
172- plotcomparison(k, sol)
170+ # Create plots using Plots.jl
171+ p1 = plot(sol.t, map(x -> x[1], sol.u), label="Position", title="Position vs Time")
172+ p2 = plot(sol.t, map(x -> x[2], sol.u), label="Momentum", title="Momentum vs Time")
173+ p3 = plot(sol.t, map(p -> H(p[1], p[2], nothing), sol.u), label="Energy", title="Energy vs Time")
174+ p4 = plot(sol.t, map(x -> x[1] - k, sol.u), label="Comparison", title="Comparison Plot")
173175
174- suptitle("===== $integrator_str, Δt = $Δt =====")
176+ # Combine all plots in a layout
177+ layout = @layout [a b; c d]
178+ plot(p1, p2, p3, p4, layout=layout, size=(1000, 800), title="===== $integrator_str, Δt = $Δt =====")
175179end
176- ```
177-
178- ## Tests
179-
180- ```julia
181- # Single pendulum
182180
183181k = rand()
184182integrator = VelocityVerlet()
@@ -189,8 +187,24 @@ singlependulum(k, integrator, Δt, t0=-20.0, t1=20.0)
189187```julia
190188# Two single pendulums
191189
192- H(q,p,param) = sum(p.^2/2 .- cos.(q) .+ 1)
193- q0 = pi*rand(2)
190+ using Plots
191+ using OrdinaryDiffEq
192+
193+ function plotsolenergy(H, integrator, Δt, sol::ODESolution)
194+ local integrator_str = replace("$integrator", r"^[^.]*\." => "")
195+
196+ # Create plots using Plots.jl
197+ p1 = plot(sol, label="Position", title="Position vs Time")
198+ p2 = plot(sol, label="Momentum", title="Momentum vs Time")
199+ p3 = plot(sol.t, map(p -> H(p[2], p[3], nothing), sol.u), label="Energy", title="Energy vs Time")
200+
201+ # Combine all plots in a layout
202+ layout = @layout [a b; c]
203+ plot(p1, p2, p3, layout=layout, size=(1000, 800), title="===== $integrator_str, Δt = $Δt =====")
204+ end
205+
206+ H(q, p, param) = sum(p.^2 / 2 .- cos.(q) .+ 1)
207+ q0 = pi * rand(2)
194208p0 = zeros(2)
195209t0, t1 = -20.0, 20.0
196210prob = HamiltonianProblem(H, q0, p0, (t0, t1))
@@ -257,4 +271,4 @@ singlependulum(k, SymplecticEuler(), Δt)
257271```julia, echo = false
258272using SciMLBenchmarks
259273SciMLBenchmarks.bench_footer(WEAVE_ARGS[:folder],WEAVE_ARGS[:file])
260- ```
274+ ```
0 commit comments