You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

绕黑洞恒星轨道计算代码转solve_ivp(DOP853)结果异常求助

问题:DOP853积分方法求解黑洞周围恒星轨道时结果异常

我正在开发Python代码计算银河系中心黑洞周围的恒星轨道,实现了包含流体阻力与引力相互作用的气体盘模型。采用四阶Runge-Kutta(RK4)方法求解运动微分方程时结果正常,但改用SciPy库的solve_ivp函数的DOP853方法后,得到的螺旋轨道不符合物理规律。

代码实现

################################################### Imports section #########################################################
import numpy as np
import matplotlib.pyplot as plt
from scipy.constants import G, parsec, year, c
from astropy.constants import M_sun
from scipy.integrate import solve_ivp


# Computing the velocity components of the gaseous disk
def gas_velocity_keplerian_disc(x, y):

    """
    Computes the gas velocity components in Keplerian motion around the black hole.
    Assumes the gas follows a circular orbit in the x-y plane.
    :param x, y: position of the star from the black hole in the x-y plane [m]
    :param m_bh: mass of the black hole [kg]
    :return: velocity components (vx_gas, vy_gas) in the x-y plane [m/s]
    """

    dist = np.sqrt(x**2 + y**2)

    # Magnitude of velocity for a gas particle in a circular orbit
    v_gas_mag = np.sqrt(G * m_bh / dist)

    # Components of velocity assuming the gas moves in a circular orbit in the x-y plane
    vx_gas = -y / dist * v_gas_mag
    vy_gas = x / dist * v_gas_mag

    return vx_gas, vy_gas

# Function to calculate acceleration
def acceleration(t, state, m, c_d, R, ro, h, R_disc):
    x, y, z, vx, vy, vz = state

    dist = np.sqrt(x**2 + y**2 + z**2)

    ax_grav = -G * m_bh * x / dist**3
    ay_grav = -G * m_bh * y / dist**3
    az_grav = -G * m_bh * z / dist**3

    # Check if z is close to +- h/2
    if -h/2 < z and z < h/2:
        # Hydrodynamical drag force components
        vx_gas, vy_gas = gas_velocity_keplerian_disc(x, y)

        vx_rel = vx - vx_gas
        vy_rel = vy - vy_gas
        vz_rel = vz

        v_rel_mag = np.sqrt(vx_rel**2 + vy_rel**2 + vz_rel**2)

        ax_drag = -0.5 * c_d * ro0 * np.pi * R**2 * v_rel_mag * vx_rel / m
        ay_drag = -0.5 * c_d * ro0 * np.pi * R**2 * v_rel_mag * vy_rel / m
        az_drag = -0.5 * c_d * ro0 * np.pi * R**2 * v_rel_mag * vz_rel / m
        print("Hydrodynamic drag force applied.")

    else:
        ax_drag, ay_drag, az_drag = 0.0, 0.0, 0.0
        print("Hydrodynamic drag force not applied.")

    # Total acceleration
    ax = ax_grav + ax_drag
    ay = ay_grav + ay_drag
    az = az_grav + az_drag

    return [vx, vy, vz, ax, ay, az]

# Event function to terminate integration when the distance from the black hole falls below 100 gravitational radii
def event(t, state, m, c_d, R, ro, h, R_disc):
    x, y, z, vx, vy, vz = state

    distance_from_bh = np.sqrt(x**2 + y**2 + z**2)
    return distance_from_bh - 100 * r_grav

event.terminal = True  # Terminate integration when the event is triggered
event.direction = -1   # Trigger the event only when crossing from positive to negative

############################################# Black hole's information section ##############################################
# Black hole info (in SI units)
m_bh = 4.31e6 * M_sun.value  # Mass of the black hole in kg
x_bh, y_bh, z_bh = 0.0, 0.0, 0.0
vx_bh, vy_bh, vz_bh = 0.0, 0.0, 0.0

############################################## Additional parameters definition #############################################
r_grav = (G * m_bh) / c**2
r_bondi = (2 * G * m_bh) / c**2

################################################# Initial conditions ########################################################
# Time range
tstart, tstop = 2000 * year, 2200 * year  # Integration time range in years
t_span = (tstart, tstop)
t_eval = np.linspace(tstart, tstop, 1000)

# Initial conditions of a star (in meters and km/s)
initial_state = np.array([-129598458359999.98, -117255748040000.0, 253025561560000.03,
                          -1325901.2, 723308.2, -449334.5])

#initial_state = np.array([1e14, 0.0, 0.0, 0.0, 1e6, 0.0])

# Disk information
c_d = 1
ro0 = 1e-14  #default 1e-11!!!
h = 2e20
R_disc = 1e20
# Shakura-Sunyaev disk parameters
alpha = 0.3  # typical value for the viscosity parameter
M_dot = 1e-6 * M_sun.value / year  # mass accretion rate per year

# Orbiting object info (dust particle)
# R = 696340e3  # Radius of star in meters
R = 2.0   # Radius of dust particle in meters
m = 0.028    # Mass of the dust particle in kg

# Solve the initial value problem with event function
sol = solve_ivp(acceleration, t_span, initial_state, method='DOP853',
                rtol=1e-10, atol=1e-10, args=(m, c_d, R, ro0, h, R_disc), events=event)

结果对比

  • RK4方法预期结果:轨道符合天体物理规律,呈现正常的受引力与阻力作用的运动轨迹
  • DOP853方法实际结果:出现不符合物理规律的螺旋轨道

恳请帮忙排查代码错误并修正。


内容的提问来源于stack exchange,提问作者Kristýna Janoušková

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:15:11