使用python绘制地球轨道图的问题

使用python绘制地球轨道图的问题,python,python-3.x,matplotlib,Python,Python 3.x,Matplotlib,我正在尝试使用辛积分器编写SI中的地球轨道代码,我的尝试如下: import numpy as np import matplotlib.pyplot as plt #Set parameters G = 6.67348e-11 mEar = 5.972e24 mSun = 1.989e30 def earth_orbit(x0, y0, vx0, vy0, N): dt = 1/N #timestep pos_arr = np.zero

我正在尝试使用辛积分器编写SI中的地球轨道代码,我的尝试如下:

import numpy as np
import matplotlib.pyplot as plt

#Set parameters
G = 6.67348e-11
mEar = 5.972e24
mSun = 1.989e30

def earth_orbit(x0, y0, vx0, vy0, N):
    dt = 1/N                    #timestep
    pos_arr = np.zeros((N,2))   #empty array to store position
    vel_arr = np.zeros((N,2))   #empty array to store velocities

    #Initial conditions
#     x0 = x
#     y0 = y
#     vx0 = vx
#     vy0 = vy
    pos_arr[0] = (x0,y0)        #set the intial positions in the array
    vel_arr[0] = (vx0,vy0)      #set the initial velocities in the array

    #Implement Verlet Algorithm
    for k in range (N-1):
        pos_arr[k+1] = pos_arr[k] + vel_arr[k]*dt                       #update positions
        force = -G * mSun * mEar * pos_arr[k+1] / (np.linalg.norm(pos_arr[k+1])**3)   #force calculation 
        vel_arr[k+1] = vel_arr[k] + (force/mEar) * dt                     #update velocities

    #Plot:
    plt.plot(pos_arr, 'go', markersize = 1, label = 'Earth trajectory')
#     plt.plot(0,0,'yo', label = 'Sun positon')                  # yellow marker
#     plt.plot(pos_arr[0],'bo', label = 'Earth initial positon')  # dark blue marker
    plt.axis('equal')
    plt.xlabel ('x')
    plt.ylabel ('y')

    return pos_arr, vel_arr

earth_orbit(149.59787e9, 0, 0, 29800, 1000)
输出为2个点,我无法确定这是单位问题还是计算问题?

显示轨迹
pos_arr
在其列中包含
x
y
坐标。为了显示整个轨迹,可以使用plt.plot(pos_arr[:,0],pos_arr[:,1])。我更愿意使用
plt.plot(*pos\u arr.T)
作为较短的备选方案。显示轨迹的线必须替换为:

plt.plot(*pos_arr.T,'g',label='Earth track')
更改时间步长 此处时间步()选择为
1/N
,其中
N
是迭代次数。因此,模拟的总持续时间等于
timestep*N=1秒
!对于
N=1000
,您可以尝试使用
timestep=3600*12
(半天),使总持续时间略少于1.5年。我建议将
duration
作为函数
earth\u orbit
的参数传递,然后将
timestep
设置为
duration/N

def地球轨道(x0,y0,vx0,vy0,N=1000,持续时间=3.15e7):
dt=持续时间/N
...

正如评论中所说,这不是Verlet算法,而是辛欧拉算法。不同之处在于初始化,但与更精确的参考解决方案和多个步长相比,顺序2与1的差异将非常明显

对时间循环进行短暂更改,以确保速度处于蛙跳Verlet所需的半程步长,如下所示:

def force(pos):返回-G*mSun*mEar*pos_arr[k+1]/(np.linalg.norm(pos_arr[k+1])**3)力计算
pos_arr[0]=(x0,y0)#设置阵列中的初始位置
vel_arr[0]=(vx0,vy0)#设置阵列中的初始速度
水平角[0]+=(力(位置角[0])/mEar)*(0.5*dt)#对半时速度进行校正
#Verlet算法的实现
对于范围(N-1)内的k:
pos_arr[k+1]=pos_arr[k]+vel_arr[k]*dt#更新位置
水平角[k+1]=水平角[k]+(力(位置角[k+1])/mEar)*dt#更新速度

请注意,这不是Verlet算法,而是辛欧拉算法。不同之处在于,对于Leapfrog Verlet,您需要将
vel_arr[0]
提升到时间
dt/2
的速度。