2017-08-02 127 views
1

我有一個程序創建一個太陽系,整合直到相鄰行星之間發生近距離接觸(或直到10e + 9年),然後將兩個數據點寫入文件。當行星離得太近時,嘗試和除外行爲就會成爲一面旗幟。該過程重複16,000次。這一切都是通過導入模塊REBOUND完成的,該模塊是一個軟件包,它將顆粒在重力影響下的運動整合在一起。有效收集大量數據

for i in range(0,16000): 
    def P_dist(p1, p2): 
     x = sim.particles[p1].x - sim.particles[p2].x 
     y = sim.particles[p1].y - sim.particles[p2].y 
     z = sim.particles[p1].z - sim.particles[p2].z 
     dist = np.sqrt(x**2 + y**2 + z**2) 
     return dist 

    init_periods = [sim.particles[1].P,sim.particles[2].P,sim.particles[3].P,sim.particles[4].P,sim.particles[5].P] 

    try: 
     sim.integrate(10e+9*2*np.pi) 
    except rebound.Encounter as error: 
     print(error) 
     print(sim.t) 

    for j in range(len(init_periods)-1): 
     distance = P_dist(j, j+1) 
     print(j,":",j+1, '=', distance) 
     if distance <= .01: #returns the period ratio of the two planets that had the close enecounter and the inner orbital period between the two 
      p_r = init_periods[j+1]/init_periods[j] 
      with open('good.txt', 'a') as data: #opens a file writing the x & y values for the graph 
       data.write(str(math.log10(sim.t/init_periods[j]))) 
       data.write('\n') 
       data.write(str(p_r)) 
       data.write('\n') 

是否有近距離接觸主要取決於我分配的隨機值,而且隨機值也控制模擬運行的時間。例如,我選擇隨機值爲9.99的最大值,並且在大約11年+ 8年(大約14小時)發生了一次近距離相遇。隨機值的範圍是2-10,並且在下側更頻繁地發生近距離碰撞。每次迭代時,如果發生近距離碰撞,我的代碼將寫入文件,我相信這可能會花費大量的仿真時間。由於我的大部分模擬時間都是通過嘗試定位近距離接觸來消化的,所以我想通過找到一種方法來收集所需數據,而不必在每次迭代時追加到文件中。

因爲我試圖繪製從這個模擬收集的數據,創建兩個數組並輸出數據到那些更快?或者有沒有辦法只需寫入文件一次,當所有的16000次迭代完成?

sim是一個變量,它包含有關太陽系的所有信息。

這不是完整的代碼,我忽略了我創建太陽系的部分。

count = 0 
data = open('good.txt', 'a+') 
.... 
    if distance <= .01: 
     count+=1 
     while(count<=4570) 
      data.write(~~~~~~~) 
.... 
data.close() 
+1

你的想法是正確的,但邏輯錯誤。 while循環是無限的:進入循環時'count'爲1,並且它永遠不會改變。您只有一個循環,但有兩種退出方式:'j> = len(句號)'或'count> 4570'。將兩個條件都編碼到您的循環頭文件中,或者使用第二個條件從循環中「斷開」。 – Prune

回答

1

問題不在於你每次發現近距離遇到時都要寫信。這就是說,對於每次遭遇,你打開文件,寫一個輸出記錄,然後關閉文件。所有的開幕和附加是。試試這個,而不是:打開文件一次,並且只做一個寫入每條記錄。

# Near the top of the program 
data = open('good.txt', 'a') 
... 
    if distance <= .01: #returns the period ratio of the two planets that had the close enecounter and the inner orbital period between the two 
     # Write one output record 
     p_r = init_periods[j+1]/init_periods[j] 
     data.write(str(math.log10(sim.t/init_periods[j])) + '\n' + 
        str(p_r) + '\n') 
... 
data.close() 

這應該很好,因爲寫入將被緩存,並且通常會與下一次計算並行運行。

+0

太棒了,還有一個問題。我已決定將我的樣本量減少到4570個近距離接觸。由於每次迭代都不會發生近距離接觸,所以我想出了一種方法來保持程序運行,直到遇到4570個近距離接觸。 – dlsj

+1

這是一個陳述,而不是一個問題。可能缺少一兩句話? – Prune

+0

在我最近的文章編輯中,我上傳了一段類似於你的代碼。這是獲取我需要的大量數據的有效方法嗎? – dlsj