2016-02-22 30 views
1

我目前正在使用RK4算法對相當深奧的系統進行物理仿真。Python:捕捉double_scalars中的運行時溢出

它涉及奇點(例如r - > 0),並在其中一個方程中被這個半徑分開。 會有奇點,我需要程序在發生這種情況後停止進一步的計算。一旦程序變得過於接近奇點,我已經建立了一個>中斷操作,但有時用戶可能不會選擇足夠好的閾值在無窮大出現之前發生。該閾值的值不能事先確定 - 系統在動態中顯着混亂。我決定嘗試捕捉異常(具體來說,RuntimeWarning:在double_scalars中遇到溢出),以便用戶知道他們選擇的奇異性閾值太低。

for i in range(indices - 1): 
    try: 
     if((theta0 == 0 or theta0 == pi) and i == 0): 
      print('Unstable or stable equilibrium chosen as initial value. Please change the initial angle.') 
      flag = True 
      break 
     if(variables[i][0] <= (singularitythreshold * r0)): 
      print('The trajectory came within the threshold for identifying a singularity (%.5f%%). The program has finished early to avoid infinities.' % (singularitythreshold * r0 * 100)) 
      break 
     k1 = step * RKaccel(variables[i], times[i]) 
     k2 = step * RKaccel(variables[i] + k1/2, times[i] + step/2) 
     k3 = step * RKaccel(variables[i] + k2/2, times[i] + step/2) 
     k4 = step * RKaccel(variables[i] + k3, times[i] + step) 

     variables[i + 1] = variables[i] + k1/6 + k2/3 + k3/3 + k4/6 
    except RuntimeWarning: 
     print('A Runtime Warning was triggered, indicating infinities as r -> 0. Increase the singularity threshold.') 
     flag = True 
     print('Plotting procedures have been abandoned to avoid nonsensical data.') 
     break 

我已經通過關於如何處理此類問題(包括seterr和seterrfunc)10+的帖子閱讀,但我似乎無法得到它的權利。它從不觸發異常。

計算髮生在RKaccel中,我不認爲這個函數與捕獲錯誤有關,所以我沒有包含它(大量討厭的方程)。但是,我已經包含了印刷的特定警告:

/tmpw0ojdH.py:35: RuntimeWarning: overflow encountered in double_scalars 
    radiusdotdot = ((radius/(1 + mu)) * ((thetadot) ** 2)) + (((g * cos(theta)) - (g * mu))/(1 + mu)) 
/tmpw0ojdH.py:36: RuntimeWarning: overflow encountered in double_scalars 
    thetadotdot = - ((g * sin(theta))/radius) - (2 * ((radiusdot) * (thetadot))/radius) 

回答

1

我已解決了我的問題。關鍵是玩seterr()。通過添加

seterr(all = 'raise') 

和改變

except RuntimeWarning: 

except FloatingPointError: 

我的異常被觸發,並全部是固定的。希望這有助於未來的人。