numerical-methods - 如何解决常微分方程组解的数值不稳定性
问题描述
我一直在尝试获得以下常微分方程组的数值解:
倾斜午餐中身体在空气中的运动方程:(
显然 LaTeX 不适用于堆栈溢出)
u'= -F(u, theta, t)*cos(theta)
v'= -F(v, theta, t)*sin(theta)-mg
通过 Runge-Kutta-Fehlberg 算法,但在计算过程中我必须计算 theta,即由下式计算
arccos(u/sqrt(u^2+v^2)) or arcsin(v/sqrt(u^2+v^2)),
但最终theta
变得太小了,我需要它来解决函数F( v, theta, t)
并找到V = sqrt(v^2 + u^2)
我使用的值V = (v/sin(theta))
,但是随着theta
变小sin(theta)
,我从给定的迭代中得到一个数值错误-1.IND00
,这可能是因为theta
太小了,我试图使theta
从一个小的正角(如)0.00001
变为一个小的负角,但似乎被困在这个负值中,有没有人知道如何解决这个数值不稳定性? -0.00001
if(fabs(theta)<0.00001) theta = -0.00001
theta
解决方案
使用反余弦或正弦函数来确定点的角度是一个坏主意。要得到
theta = arg ( u + i*v)
利用
theta = atan2(v,u).
这仍然存在它在负半轴上跳跃的问题,即对于v=0, u<0
。这可以通过制作theta
第三个动态变量来解决,因此
theta' = Im( (u'+i*v')/(u+i*v) ) = (u*v' - u'*v) / (u^2+v^2)
但实际上,带有空气摩擦的自由落体方程最容易实现为
def friction(vx, vy):
v = hypot(vx, vy)
return k*v
def freefall_ode(t, u):
rx, ry, vx, vy = u
f=friction(vx, vy)
ax = -f*vx
ay = -f*vy - g
return array([ vx, vy, ax, ay ])
这样您就不需要任何角度或试图通过将速度分量减小到速度矢量的角度来削弱速度分量的耦合。您现在可以将其插入您选择的集成方法中,用作向量值系统的方法。
推荐阅读
- github-api - 如何通过 GitHub API 获取集锦数据?
- database - wordpress中空格的字符编码:显示为?黑色钻石
- javascript - 在 Express/Node 中多次使用相同的查询参数
- r - 创建与 dplyr 中因子级别相等的新变量集
- python - 带有颜色条的数据框图在 Jupyter Notebook 中不显示 x 图例
- redirect - 如何将 HTTPS://example.com 重定向到 www.example.com==
- bash - Add flutter to environment path (Bash)
- java - 消除布尔值作为方法参数的设计思想
- azure - 通过 ARM 模板在存储帐户中部署多个容器
- java - Eclipse 自动完成刺激