如何解决常微分方程组解的数值不稳定性

时间:2018-12-11 15:19:24

标签: numerical-methods differential-equations approximation runge-kutta

我一直在努力寻求以下常微分方程组的数值解:

倾斜午餐中空气在空中运动的方程式:
(显然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)),但将其用作{{1} }变小了,theta也变小了,我从给定的迭代sin(theta)中得到了一个数值误差,这很可能是因为-1.IND00太小了,我试图使theta消失从像theta这样的小正角到像0.00001-0.00001)这样的小负角,但是似乎if(fabs(theta)<0.00001) theta = -0.00001陷入了这个负值,有人指示吗?如何解决这种数值不稳定性?

1 个答案:

答案 0 :(得分:0)

使用反余弦或正弦函数来确定点的角度是个坏主意。得到

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 ])

,因此您不需要任何角度或尝试通过将其减小到速度矢量的角度来减弱速度分量的耦合。现在,您可以插入您选择的集成方法,将其用作矢量值系统的方法。