![](/img/trans.png)
[英]How do I solve a 2nd order differential equation for projectile motion with air resistance?
[英]Python: How do I properly use integrate.solve_bvp for the 2-D projectile motion of an object with air resistance
我对编程还很陌生,正在尝试使用内置函数“integrate.solve_bvp”编写一个程序来确定受边界条件影响的弹丸轨迹。
我无论如何都不是程序员,所以我的知识和理解非常有限。 请像我5岁一样解释。
我需要能够确定射弹的发射速度和最终速度,给定发射角度,以及在考虑阻力的情况下返回地面所需的时间。
我写了一些代码,但它不起作用,我也不知道为什么。 我试过阅读文档,但这一切都在我脑海中浮现。
我首先考虑一维情况(发射角为 90 度),这看起来非常简单。 我使用 SUVAT 来猜测发射速度(即忽略阻力时的发射速度)并编写了以下代码:
import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt
drag_coef = 0.47 # average drag coefficient of a golf ball
air_density = 1.293
area = 1.45*10**-3 # cross sectionl area of a golf ball
mass = 45.9*10**-3 # mass of a golf ball
g = -9.80665
def function(time,height):
drag_factor = drag_coef * air_density * area / (2*mass)
return height[1], (g-drag_factor*height[1]*np.abs(height[1]))
def boundary_conditions(height_0,height_end):
return height_0[0], height_end[0]
time_scale = 10 # time at which you want projectile to hit the ground
velocity_0_guess = 49 # initial velocity guess (t=0)
time = np.linspace(0, time_scale, time_scale*1000+1)
height_0 = np.zeros(len(time))
velocity_0 = velocity_0_guess * np.ones(len(time))
height = np.array((height_0,velocity_0))
res = integrate.solve_bvp(function, boundary_conditions, time, height, max_nodes = time_scale*1000+1)
print(res.y[1] [0]) # calculated V_0
print(res.y[1] [time_scale*1000]) # Calculated V_end
print(res)
plt.plot(time, res.y[0], label="S_z") # caculated S_z
plt.xlabel("time [s]")
plt.ylabel("displacement [m]")
plt.show()
plt.plot(time, res.y[1], label="V_z") # calcuted V_z
plt.xlabel("time [s]")
plt.ylabel("velocity [m/s]")
plt.show()
但是,即使对于这种看似简单的情况,当我“打印(res)”时; 我得到“False”的成功结果,以及以下声明:
message: 'The maximum number of mesh nodes is exceeded.'
而且我不知道为什么我认为我已经将节点数定义为等于正在考虑的时间点数。
然而,显然情况并非如此,因为当我将“time_scale”和“velocity_0_guess”分别减半到 5 和 24.5 时,我得到了一个成功的结果,即使这两个应该同样有效:
message: 'The algorithm converged to the desired accuracy.'
我试图用谷歌搜索这个问题,但我还没有找到任何能够帮助我的东西。 我浏览过 Reddit 和 StackOverflow 都没有成功。 我什至尝试过使用 ChatGPT 来帮助修复我的代码,但这也无济于事。 所以我的步骤是发布一个问题。
我不知道这是否相关,但我一直在通过网站编写这个程序:repl.it
求解器迭代工作。 它在固定时间网格上计算 DE 的近似解和使用沿近似解的误差估计细化时间网格之间交替。
一般的想法是从粗略给出所需解决方案形状的初始猜测开始。 这通常不应超过定义形状所需的点数。 然后求解器填充网格。
生成的解决方案可以在函数表res.x, res.y
中找到,也可以通过“密集输出”插值res.sol
。
对于你不断的猜测,有一个最小的两点网格就足够了
time = [0,time_scale]
height = [[0.0]*2, [velocity_0_guess]*2]
这毫无怨言地结束了,给出res.y[1,[0,-1]] = [ 95.93681148, -30.32436139]
和网格点数为len(res.x) = 27
。 可见,时间网格不再是time
网格,因此您需要在绘图中使用res.x
通过将容错tol
设置为低于其默认值1e-3
,您可以获得更密集的网格和更准确的解决方案
res = integrate.solve_bvp(function, boundary_conditions, time, height, tol=1e-6);
给出len(res.x) = 186
和res.y[1,[0,-1]] = [ 95.93702666, -30.32440457]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.