N 体模拟开始时的能量激增

问题描述

我正在尝试使用 n 体模拟来模拟球状星团的坍塌,从一个点开始,该点在固定半径球体的随机位置生成的所有物体的初始速度均为 0,我正在研究形成平衡系统所需的时间。然而,当粒子最初靠近在一起时运行我的代码时,势能会出现很大的激增。有没有办法避免这种情况?我正在使用跳蛙近似来计算粒子的后续速度和位置。

enter image description here

enter image description here

初始条件

sun_mass = 1.989e30


N = 50
mass = 25 * sun_mass
M = np.full([N],mass)    
R = 3.086e+16          # 1pc
epsilon = 0.1 * R
collision_radius = 7e8
V = np.zeros([N,3])
P = np.zeros([N,3])

t = 50000000 * 365 * 24 * 60 * 60
dt = 18000000 * 24 * 60 * 60



print(t/dt)

np.random.seed(54321)



for i in range(N):
    
    #M[i] = np.random.uniform(sun_mass,100*sun_mass,1)
    
    phi = np.random.uniform(0,(2*np.pi))
    costheta = np.random.uniform(-1,1)
    u = np.random.uniform(0,1)
    
    theta = np.arccos( costheta )
    r = R * (u) **(1/3)
    
    
    x = r * np.sin( theta) * np.cos( phi )
    y = r * np.sin( theta) * np.sin( phi )
    z = r * np.cos( theta )

    P[i] = (x,y,z)

运行程序的代码

def programe(position,mass,veLocity,softening,time,dt,R,collision_radius):
    
    #print(len(mass))
    no_of_time_steps = (round(time/dt))

    #all_positions = np.full((no_of_time_steps,len(mass),3),0.0)
    all_positions = []
    all_veLocities = []
    #print(all_positions)
    #print(len(all_positions[0]))
    kinetic_energy = []
    potential_energy = []
    total_energy = []
    
    #prevIoUs_veLocity = calc_prevIoUs_half_veLocity(veLocity,calc_acceleration(position,softening),dt)
        
    for i in range(no_of_time_steps):
        
        position,veLocity = detect_collisions(position,collision_radius)
        
        #all_positions[i] = position
        all_positions.append(position)
        all_veLocities.append(veLocity)
    
        'graph'
        plots = np.round(np.linspace(0,no_of_time_steps,num=500))
        for k in range(len(plots)):
            if i == plots[k]:
                print("test")
                #print(i)
                graph(position,i,k)
        
        'energies'
        kinetic_energy.append(calc_kinetic_energy(veLocity,mass))
        potential_energy.append(calc_potential_energy(position,mass))
        total_energy.append(calc_total_energy(position,mass))
        
        'leap frog'
        veLocity = calc_next_v_half(position,dt)    
        position = calc_next_position(position,dt)    
        veLocity = calc_next_v_half(position,dt)
        

    #columns_to_delete = len(all_veLocities)
    #print(no_of_time_steps)
    #print(len(kinetic_energy),len(potential_energy),len(total_energy))
    
    
    all_positions = np.array(all_positions)
    all_veLocities = np.array(all_veLocities)
    #print(all_positions)
    graphing(all_positions,all_veLocities,kinetic_energy,potential_energy,total_energy,R)
    #print(len(mass))

    return(all_positions,total_energy)
        

跳跃功能

'LeapFrog functions'

'acceleration Calculation'
def calc_acceleration(position,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) #,print(acceleration))

def calc_prevIoUs_half_veLocity(veLocity,acceleration,dt):
    prevIoUs_veLocity = np.zero_like(veLocity)
    
    prevIoUs_veLocity = veLocity - acceleration * dt/2
    return(prevIoUs_veLocity)

def calc_next_v_half(position,dt):
    half_veLocity = np.zeros_like(veLocity)
    half_veLocity = veLocity + calc_acceleration(position,softening) * dt/2
    return(half_veLocity)
    
def calc_next_veLocity(position,dt):
    next_veLocity = np.zeros_like(veLocity)
    
    next_veLocity = veLocity + calc_acceleration(position,softening) * dt
    
    return(next_veLocity)


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

使用的其他功能

def calc_CoM(position,mass):
        sumMR = np.zeros(3)
        sumM = 0.0
        position = np.array(position)
        for i in range(len(mass)):
            sumM += mass[i]
            sumMR += mass[i] * position[i]
        return(sumMR / sumM)


def calc_total_mass2(mass):
    total_mass = 0.0
    print((mass[0]))
    for i in range(len(mass)):
        total_mass += mass[i]
    return(total_mass)

def calc_total_mass(mass):
    total_mass = sum(mass)
    return(total_mass)

def calc_CoM_seperation(position,i):
    new_mass = np.array(mass) 
    new_pos = np.array(position)
    new_mass[i] = 0.0
    new_pos[i] = 0.0
    position = np.array(position)
    r = np.linalg.norm(calc_CoM(new_pos,new_mass) - position[i])
    return(r)

def calc_seperation(p1,p2):
    return np.linalg.norm(p1-p2)
    

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)