我正在用Python模拟Sun-Earth-Rocket系统,并且到目前为止一直在使用Runge-Kutta 4th Order方法。效果很好,但是我现在尝试实现RKF45方法,以便在每次迭代时都能找到最佳的时间步长。
火箭感觉到的加速度是:
def acc(r):
return ((-6.6726e-11)*(mS)/abs(np.dot((r-rs),(r-rs)))**1.5)*(r-rs) + ((-6.6726e-11)*(mE)/abs(np.dot((r-re),(r-re)))**1.5)*(r-re)
其中mS是太阳的质量,rS是太阳的位置(0,0),r是火箭的位置。
到目前为止,我一直在使用的RK4方程是:
k1v = acc(r)
k1r = v
k2v = acc(r + k1r*(a/2))
k2r = v + (a/2) * k1v
k3v = acc(r + k2r*(a/2))
k3r = v + k2v * (a/2)
k4v = acc(r + k3r*a)
k4r = v + k3v * a
v = v + (a/6) * (k1v + 2*k2v + 2*k3v + k4v) #update v
r = r + (a/6) * (k1r + 2*k2r + 2*k3r + k4r) #update r
我在线上找到了包含RKF45方程的本文,该方程的形式仅预期能求解一个ODE。由于必须同时求解r和v,因此我尝试像上面的RK4方程一样将它们分解。
http://maths.cnam.fr/IMG/pdf/RungeKuttaFehlbergProof.pdf
我的实现如下:
k1v = a * acc(r)
k1r = a * v
k2v = a * acc(r + k1r/4)
k2r = a * (v + k1v*a/4)
k3v = a * acc(r + k1r*(3/32) + k2r*(9/32))
k3r = a * (v + (3/8)*a*k2v)
k4v = a * acc(r + (1932/2197)*k1r - (7200/2197)*k2r + (7296/2197)*k3r)
k4r = a * (v + (12/13)*a*k3v)
k5v = a * acc(r + (439/216)*k1r - 8*k2r + (3680/513)*k3r - (845/4104)*k4r)
k5r = a * (v + a*k4v)
k6v = a * acc(r - (8/27)*k1r + 2*k2r - (3544/2565)*k3r + (1859/4104)*k4r - (11/40)*k5r)
k6r = a * (v + (a/2)*k5v)
v = v + (16/135)*k1v + (6656/12825)*k3v + (28561/56430)*k4v - (9/50)*k5v + (2/55)*k6v
r = r + (16/135)*k1r + (6656/12825)*k3r + (28561/56430)*k4r - (9/50)*k5r + (2/55)*k6r
您会注意到,在链接的论文中,有些方程式也给出了RK4解决方案。我注意到当上面显示的RK4方程为我的火箭提供的路径与本文中的RK4方程截然不同时,出现了一个问题。同样,RK5给出了更“错误”的路径。 (当我说错了时,我的意思是我已经计算出想要的路径所需的发射速度。将这个发射速度输入新的RK4和RK5方程式时,我没有得到所需的路径)
我的问题是,这些方程式正确吗,它们是否已正确实施?我没有足够的经验来发现任何错误,因此我们将不胜感激。