【问题标题】:Planetary orbit shown as linear graph using rk4使用 rk4 将行星轨道显示为线性图
【发布时间】:2021-06-13 05:03:09
【问题描述】:

我正在尝试使用 Runge-Kutta 4 方法模拟行星围绕恒星运行的轨道。在与导师交谈后,我的代码应该是正确的。但是,我没有生成预期的 2D 轨道图,而是生成线性图。这是我第一次使用solve_ivp 求解二阶微分。谁能解释为什么我的情节是错误的?

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# %% Define derivative function
def f(t, z):
    
    x = z[0] # Position x
    y = z[1] # Position y
    dx = z[2] # Velocity x
    dy = z[3] # Velocity y
    
    G = 6.674 * 10**-11 # Gravitational constant
    M = 2 # Mass of binary stars in solar masses
    c = 2*G*M 
    r = np.sqrt(y**2 + x**2) # Distance of planet from stars
    
    zdot = np.empty(6) # Array for integration solutions
    zdot[0] = x
    zdot[1] = y
    zdot[2] = dx # Velocity x
    zdot[3] = dy #Velocity y
    zdot[4] = (-c/(r**3))*(x) # Acceleration x
    zdot[5] = (-c/(r**3))*(y) # Acceleration y
    
    return zdot
# %% Define time spans, initial values, and constants
tspan = np.linspace(0., 10000., 100000000)
xy0 = [0.03, -0.2, 0.008, 0.046, 0.2, 0.3] # Initial positions x,y in R and velocities
# %% Solve differential equation
sol = solve_ivp(lambda t, z: f(t, z), [tspan[0], tspan[-1]], xy0, t_eval=tspan)
# %% Plot 
#plot
plt.grid()
plt.subplot(2, 2, 1)
plt.plot(sol.y[0],sol.y[1], color='b')
plt.subplot(2, 2, 2)
plt.plot(sol.t,sol.y[2], color='g')
plt.subplot(2, 2, 3)
plt.plot(sol.t,sol.y[4], color='r')
plt.show()

【问题讨论】:

    标签: python matplotlib scipy runge-kutta orbital-mechanics


    【解决方案1】:

    使用给定的 ODE 函数,您正在求解系统的第一个组件

    xdot = x
    ydot = y
    

    它具有众所周知的指数解决方案。由于指数因子在两个解中的长度相同,因此 xy 图将沿通过原点的直线移动。

    解决方案当然是用dx,dy 填充zdot[0:2],用ax,ayddx,ddy 填充zdot[2:4],或者你想命名加速的组件。那么初始状态也只有 4 个分量。或者您需要将位置和速度视为 3 维。


    您需要将单位放入常量中,并注意所有单位都使用相同的单位。引用的Gm^3/kg/s^2 中,因此您定义的任何M 都将在kg 中,任何长度在m 中,任何速度在m/s 中。在这种情况下,您的常量可能会显得非常小。

    无论代码中的注释说什么,都不会发生神奇的转换。您需要使用实际的转换计算来获得真实的数字。例如使用数字

    G       = 6.67408e-11 # m^3 s^-2 kg^-1
    AU      = 149.597e9 # m
    Msun    = 1.988435e30 # kg
    hour = 60*60 # seconds in an hour
    day = hour * 24 # seconds in one day
    year = 365.25*day # seconds in a year (not very astronomical)
    

    人们可以猜测,对于一个由两颗质量相等的恒星组成的合理双星系统,一个具有

    M = 2*Msun # now actually 2 sun masses
    x0 = 0.03*AU
    y0 = -0.2*AU
    vx0 = 0.008*AU/day
    vy0 = 0.046*AU/day
    

    对于只有 AU 作为单位有意义的位置,速度也可以在 AU/hour 中。通过https://math.stackexchange.com/questions/4033996/developing-keplers-first-lawCannot get RK4 to solve for position of orbiting body in Python,半径为R=0.2AU 的圆形轨道围绕2*M 的组合质量的速度为

    sqrt(2*M*G/R)=sqrt(4*Msun*G/(0.2*AU)) = 0.00320 * AU/hour = 0.07693 AU/day
    

    如果给定的速度实际上是在AU/day 中,这......不是太不合理。从https://math.stackexchange.com/questions/4050575/application-of-the-principle-of-conservation 调用计算来计算开普勒椭圆是否合理

    r0 = (x0**2+y0**2)**0.5
    dotr0 = (x0*vx0+y0*vy0)/r0
    L = x0*vy0-y0*vx0           # r^2*dotphi = L constant, L^2 = G*M_center*R
    dotphi0 = L/r0**2
    
    R = L**2/(G*2*M)
    wx = R/r0-1; wy = -dotr0*(R/(G*2*M))**0.5
    E = (wx*wx+wy*wy)**0.5; psi = m.atan2(wy,wx)
    print(f"half-axis R={R/AU} AU, eccentr. E={E}, init. angle psi={psi}")
    print(f"min. rad. = {R/(1+E)/AU} AU, max. rad. = {R/(1-E)/AU} AU")
    

    返回

    half-axis R=0.00750258 AU, eccentr. E=0.96934113, init. angle psi=3.02626659
    min. rad. = 0.00380969 AU, max. rad. = 0.24471174 AU
    

    这给出了一个极细的椭圆,这并不令人惊讶,因为初始速度几乎直接指向重心。

    orbit variants with half-day steps marked, lengths in AU

    如果交换速度分量,则会得到

    half-axis R=0.07528741 AU, eccentr. E=0.62778767, init. angle psi=3.12777251
    min. rad. = 0.04625137 AU, max. rad. = 0.20227006 AU
    

    这样比较平衡。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多