単振動の方程式は次のとおりです。
x¨+ωx=0\ ddot x + \ omega x = 0バツ¨+ωx _=0
ソリューションはする必要があります
x(t)= Acos(ωt− ϕ)v(t)=x˙(t)= −Aωsin(ωt− ϕ)\ begin {aligned} x(t)&= A \ cos (\ omega t- \ phi)\\ v(t)&= \ dot x(t)= -A \ omega \ sin(\ omega t- \ phi)\ end {aligned}x (t )v (t)=Acos (ωt _−ϕ )=バツ˙(t)=-ω _ _sin (ωt _−ϕ)
SciMLによる解法は
using OrdinaryDiffEq, Plots
ω = 1 #输入\omega然后按tab可打出ω
x₀ = [0.0] #输入\_0 然后按tab可打出下标₀
dx₀ = [π/2] #\pi tab
tspan = (0.0, 2π)
ϕ = atan((dx₀[1]/ω)/x₀[1])
A = √(x₀[1]^2 + dx₀[1]^2)
#
function f(ddu,du,u,ω,t)
ddu .= -ω^2 * u
end
# 创建二阶ODE问题
prob = SecondOrderODEProblem(f, dx₀, x₀, tspan, ω)
sol = solve(prob, DPRKN6())
#Plot
plot(sol, vars=[2,1], linewidth=2, title ="简谐振动", label = ["x" "dx"])
plot!(t->A*cos(ω*t-ϕ), lw=3, ls=:dash, label="解析解 x")
plot!(t->-A*ω*sin(ω*t-ϕ), lw=3, ls=:dash, label="解析解 dx")
savefig("ode_7.png")
結果を図に示します
その中にDPRKN6
は、ルンゲクッタ法を使用し、次数6の補間を使用する、効率的ですが不正確なソルバーがあります。精度が足りないと感じた場合は、代わりに使用できますDPRKN12
。名前が示すように、12次の補間がありますが、比較的遅くなります。
ルンゲクッタ法について