1

我正在尝试在 python 中编写 N 体模拟代码,并成功地使用越级近似方法成功地生成了一个涉及太阳、地球和木星的系统,如下所示。
太阳、地球、木星系统

但是,当我尝试为 N 个质量相同且速度为零的物体扩展相同的代码时,我没有得到系统形成的预期结果。取而代之的是,在最初相互吸引后身体散开的地方会产生以下情况。 在此处输入图像描述

无论使用多少初始粒子,都会复制相同的模式。

在此处输入图像描述

第二张图片只是第一张图片的放大版,显示他们最初是相互吸引的。

让我相信错误一定在于我的初始条件:

N = 3
mass = 1e30
R = 1e10
V = np.zeros([N,3])
M = np.full([N],mass)
P = np.random.uniform(-R, R, (N,3))
epsilon = 0.1 * R

加速度计算:

def calc_acceleration(position, mass, softening):
    
    G = 6.67 * 10**(-11)
    
    N = position.shape[0] # N = number of rows in particle_positions array
    acceleration = np.zeros([N,3])
    
    #print(N)
    for i in range(N):
        #print(i)
        for j in range(N):
            if i != j:
                #print("j", j)
                dx = position[i,0] - position[j,0]
                dy = position[i,1] - position[j,1]
                dz = position[i,2] - position[j,2]
                
                #print(dx,dy,dz)
                
                inv_r3 = ((dx**2 + dy**2 + dz**2 + softening**2)**(-1.5))
                
                acceleration[i,0] += - G * mass[j] * dx * inv_r3
                acceleration[i,1] += - G * mass[j] * dy * inv_r3
                acceleration[i,2] += - G * mass[j] * dz * inv_r3

    return(acceleration)

蛙跳功能:

def calc_next_v_half(position, mass, velocity, softening, dt):
    half_velocity = np.zeros_like(velocity)
    half_velocity = velocity + calc_acceleration(position, mass, softening) * dt/2
    return(half_velocity)
       

def calc_next_position(position, mass, velocity, dt):
    next_position = np.zeros_like(position)
    
    next_position = position + velocity * dt
    
    return(next_position)

实际程序功能:

def programe(position, mass, velocity, softening, time, dt):
    
    no_of_time_steps = (round(time/dt))

    all_positions = np.full((no_of_time_steps, len(mass), 3), 0.0)
    all_velocities = []
    
    kinetic_energy = []
    potential_energy = []
    total_energy = []
        
        
    for i in range(no_of_time_steps):
        all_positions[i] = position
        all_velocities.append(velocity)

        'leap frog'
        velocity = calc_next_v_half(position, mass, velocity, softening, dt)    
        position = calc_next_position(position, mass, velocity, dt)    
        velocity = calc_next_v_half(position, mass, velocity, softening, dt)
        

    return(all_positions, all_velocities, kinetic_energy, potential_energy, total_energy)
4

1 回答 1

0

问题在于,只要系统远离任何奇点,辛方法只有它们的特殊性质。对于引力系统来说,如果它是分层的,就像在太阳、行星和卫星的太阳系中一样,所有轨道都具有低偏心率。

然而,如果你考虑一个具有大约相同质量物体的“星团”,你不会得到开普勒椭圆,并且非常接近的相遇的可能性变得相当高。当您的零速度初始条件导致所有恒星向共同重心初始自由落体时,您的详细图片中也可以看出这一点。

由于势能下降到一个奇点,动能随着距离的减小而增加,因此近距离遇到等于高速。使用像跳跃-Verlet 方法中的恒定步长,采样率变得太小而无法代表曲线,完全捕捉摆动。严重违反了能量守恒,并且在近距离接触之外保持高速,导致系统的非物理爆炸。

于 2021-10-21T11:10:55.623 回答