単振動の微分方程式を解くSciML

単振動の方程式は次のとおりです。

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次の補間がありますが、比較的遅くなります。

ルンゲクッタ法について

おすすめ

転載: blog.csdn.net/m0_37816922/article/details/123747619