julia - 使用微分方程计算终端速度

标签 julia scientific-computing differentialequations.jl

我是 Juia lang 的新手,正在尝试使用 Julia 求解以下微分方程以找到球的终端速度。

F = - m * g - 1/2 rho * v² Cd * A

这是我编写的代码:

# Termal velocity of a falling ball

using DifferentialEquations
using Plots

g  = 9.8                # Accelaration of gravity
p  = 1.2                # Density of air
m  = 0.100              # A 100 g ball
r  = 0.10               # 10 cm radius
Cd = 0.5                # Drag coeficient for a small spherical object
y0 = 1000.0             # Initial height of the body (1000 m)
v0 = 10.0               # Initial velocity of the body (10 m/s^2, going up)
A  = pi*r^2;            # Cross-section area of the body;

u0 = [v0;y0]            # Initial Conditions
tspan = (0.0,5.0)       # Time span to solve for
p = [g;p;m;Cd;A]

function Terminal_Velocity(du,u,p,t)
 du[1] = u[1]                                                      # velocity 
 du[2] = -1.0 * p[1] - 0.5 * (p[2]/p[3]) * (u[1]^2) * p[4] * p[5]  # acceleration
end



prob = ODEProblem(Terminal_Velocity,u0,tspan,p)
sol = solve(prob)

plot(sol,vars=(0,1)) 

我认为问题在于我将 y0 作为加速度的初始条件而不是高度的初始条件。但我还不太理解语法。

我的起点是这篇文章:https://nbviewer.jupyter.org/github/JuliaLang/ODE.jl/blob/master/examples/Terminal_Velocity.ipynb

感谢您提前提供的帮助。

最佳答案

您的示例中有几个错误。其中大多数与编程不是很相关,而是与物理和数学相关。

您忽略了阻力项中的符号变化。此外,您在 F 方程中指定的阻力项还有一个额外的误差(额外的 1/m)。

您似乎混淆了速度和加速度。 du[2] 是加速度,因为它是速度 (u[2]) 的导数。您正在使用 u[1] 作为速度。

du[1] = u[1] 给出了 u[1] 的指数增长,你想要的是 du[1] = u[ 2] 表示位置受速度影响。

u0 = [v0;y0] 的顺序翻转,u[1]y 坐标,而 u [2] 是速度。

我看到的唯一编程错误是在选择要绘制的变量时使用基于 0 的索引。

解决以上几点后,您将得到:

using DifferentialEquations
using Plots

g  = 9.8                # Accelaration of gravity
p  = 1.2                # Density of air
m  = 0.100              # A 100 g ball
r  = 0.10               # 10 cm radius
Cd = 0.5                # Drag coeficient for a small spherical object
y0 = 1000.0             # Initial height of the body (1000 m)
v0 = 10.0               # Initial velocity of the body (10 m/s^2, going up)
A  = pi*r^2;            # Cross-section area of the body;

u0 = [y0;v0]            # Initial Conditions
tspan = (0.0,5.0)       # Time span to solve for
p = [g;p;m;Cd;A]

function Terminal_Velocity(du,u,p,t)
 du[1] = u[2]                                                      # velocity 
 du[2] = - p[1] - sign(u[2]) * 0.5 * (p[2]/p[3]) * (u[2]^2) * p[4] * p[5]  # acceleration
end

prob = ODEProblem(Terminal_Velocity,u0,tspan,p)
sol = solve(prob)

plt1 = plot(sol; vars=1) 
plt2 = plot(sol; vars=2) 
plot(plt1, plt2)

我们可以更进一步,使用回调来确保符号更改不会导致数字错误。

为此,请将 solve 行替换为

cond(u, t, i) = u[2]
callback = ContinuousCallback(cond, nothing)
sol = solve(prob; callback=callback)

关于julia - 使用微分方程计算终端速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58216794/

相关文章:

julia - Julia 中的 UndefVarError

garbage-collection - 手动调用 `gc()` 会导致立即执行所有 `finalizers` 吗?

ruby - Ruby 的稀疏矩阵库

通过规范值管理科学数据依赖图的python解决方案

python - 有没有办法告诉 jupyter notebook 是用哪个内核构建的?

c - 当我尝试从 C 中 unsafe_load 一个指针时,Julia 得到了错误的值

python - 有没有办法使用python进一步缩短稀疏解决时间?

julia - Julia中的抛物线偏微分方程

julia - 如何在DiscreteCallback中读取指定时间对应的值?

julia - 用于求解同步 ODE 的并行化代码 (DifferentialEquations.jl) - Julia