Python 3.x Runge Kutta简单的轨道

时间:2018-03-23 13:37:13

标签: python-3.x runge-kutta orbital-mechanics

我正处于创建使用Runge-Kutta方法绘制轨道的程序的早期阶段,并且想在2D中绘制轨道,但是,无论初始条件是什么,我都得到一条直线。我见过类似的问题,但它没有解决我的问题。为什么会这样?

import numpy as np
import matplotlib.pyplot as mpl
def derX(vx):
    return vx

def derY(vy):
    return vy

def derVx(x,y):
    return -(G*M*x)/((x**2 + y**2)**(3/2))

def timestep(x,k1,k2,k3,k4):
    return x + (step/6)*(k1 + 2*k2 +2*k3 + k4)

G=6.67408E-11 #m^3/kg s^2
M=5.972E24 #kg, mass of Earth
step=100 #seconds
x=4596194 #initial conditions in m and m/s
y=4596194
vx=-6646
vy=6646
t=0
T=3600
bodyx = 444 #stationary body position metres
bodyy = 444
tarray=[]
xarray=[]
yarray=[]
vxarray=[]
vyarray=[]
while t<T:
    k1 = np.zeros(4)
    k2 = np.zeros(4)
    k3 = np.zeros(4)
    k4 = np.zeros(4)
    tarray.append(t)
    xarray.append(x)
    yarray.append(y)
    vxarray.append(vx)
    vyarray.append(vy)
    x = bodyx - x
    y = bodyy - y
    k1[0]=derX(vx)
    k1[1]=derY(vy)
    k1[2]=derVx(x,y)
    k1[3]=derVx(y,x)


    k2[0]=derX(vx+(step/2)*k1[2])
    k2[1]=derY(vy+(step/2)*k1[3])
    k2[2]=derVx(x+(step/2)*k1[0],y+(step/2)*k1[1])
    k2[3]=derVx(y+(step/2)*k1[1],x+(step/2)*k1[0])


    k3[0]=derX(vx+(step/2)*k2[2])
    k3[1]=derY(vy+(step/2)*k2[3])
    k3[2]=derVx(x+(step/2)*k2[0],y+(step/2)*k2[1])
    k3[3]=derVx(y+(step/2)*k2[1],x+(step/2)*k2[0])


    k4[0]=derX(vx+step*k3[2])
    k4[1]=derY(vy+step*k3[3])
    k4[2]=derVx(x+step*k3[0],y+step*k3[1])
    k4[3]=derVx(y+step*k3[1],vx+step*k3[0])

    t=t+step
    x=timestep(x,k1[0],k2[0],k3[0],k4[0])
    y=timestep(x,k1[1],k2[1],k3[1],k4[1])
    vx=timestep(x,k1[2],k2[2],k3[2],k4[2])
    vy=timestep(x,k1[3],k2[3],k3[3],k4[3])

mpl.plot(xarray, yarray)

1 个答案:

答案 0 :(得分:0)

v的计算中存在虚假的k4[3]

timestep的来电有x作为参数,应该是y, vx, vy

另一个错误似乎是差异计算

x = bodyx - x
y = bodyy - y

您还可以更改绝对位置。力方向也相反。

将其更改为

diffx = x - bodyx
diffy = y - bodyy

并在力计算中使用这些相对位置。

要进行比较,内置程序会生成scipy.integrate.odeint数据

G=6.67408E-11 #m^3/kg s^2
M=5.972E24 #kg, mass of Earth

bodyx = 444 #stationary body position metres
bodyy = 444

def system(u,t):
    x,y,vx,vy = u
    x -= bodyx
    y -= bodyy
    f = -(G*M)/((x**2 + y**2)**(1.5))
    return [ vx, vy, f*x, f*y ]

x0=4596194 #initial conditions in m and m/s
y0=4596194
vx0=-6646
vy0=6646
u0 = [ x0, y0, vx0, vy0 ]

T= np.linspace(0,3600,36+1)

sol = odeint(system, u0, T)

mpl.plot(sol[:,0], sol[:,1]); mpl.show()

给出一个很好的弯曲弓,约为完整轨道的1/4。