我正处于创建使用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)
答案 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。