2013-10-15 47 views
0

這可能是一個數學問題,儘管它是一個編程問題,但我似乎遇到嚴重的溫度振盪在我的類方法「更新()」當warp設置爲一個高值(1000 +)在下面的代碼。爲簡單起見,所有溫度都以開爾文爲單位不可控的模擬振盪

(我不是一個程序員的職業此格式可能是不愉快的。)

import math 

#Critical to the Stefan-Boltzmann equation. Otherwise known as Sigma 
BOLTZMANN_CONSTANT = 5.67e-8 

class GeneratorObject(object): 
    """Create a new object to run thermal simulation on.""" 
    def __init__(self, mass, emissivity, surfaceArea, material, temp=0, power=5000, warp=1): 
     self.tK = temp             #Temperature of the object.  
     self.mass = mass            #Mass of the object. 
     self.emissivity = emissivity         #Emissivity of the object. Always between 0 and 1. 
     self.surfaceArea = surfaceArea         #Emissive surface area of the object. 
     self.material = material          #Store the material name for some reason. 
     self.specificHeat = (0.45*1000)*self.mass      #Get the specific heat of the object in J/kg (Iron: 0.45*1000=450J/kg) 
     self.power = power            #Joules/Second (Watts) input. This is for heating the object. 
     self.warp = warp            #Warp Multiplier. This pertains to how KSP's warp multiplier works. 

    def update(self): 
     """Update the object's temperature according to it's properties.""" 
     #This method updates the object's temperature according to heat losses and other factors. 
     self.tK -= (((self.emissivity * BOLTZMANN_CONSTANT * self.surfaceArea * (math.pow(self.tK,4) - math.pow(30+273.15,4)))/self.specificHeat) - (self.power/self.specificHeat)) * self.warp 

使用的法律是計算黑體熱損失史蒂芬 - 玻耳茲曼定律:

溫度 - =(發射率*西格瑪*表面積*(溫度^ 4-Amb^4))/ SpecificHeat)

這是從KSP插件中移植出來的,用於快速調試。 Object.update()每秒被調用50次。

會不會有一個解決方案來防止這些不涉及每步執行代碼多次的極端振盪?

+1

時間間隔不應該是該方程中的一個因子嗎? – Beta

+0

我試圖模擬你所要求的,但找不到matlib包。 也可以啓動參數有幫助。 – MiooiM

+0

代替調用matlib,只需將self.specificHeat設置爲450.我忽略從代碼中去除額外的模塊。 Obj = GeneratorObject(100,0.93,10,「iron」,0,0,1)self.Warp大於500通常會導致超出範圍的錯誤。 – Calrizan

回答

2

您的整合方案很糟糕,已經被@Beta和@ tom10暗示了。積分時間步長爲self.warp個單位時間,即自您使用物理單位以來的self.warp秒。這不是事情的方式。您應該首先通過以某種計算單位表示每個術語來將方程轉換爲無量綱格式。例如,Stefan-Boltzmann常數和self.power可以以單位測量,其中常數爲1.然後,你應該確定物體的特徵時間,例如,溫度達到一定程度時的平衡時間。如果有很多這樣的對象,你應該找到所有特徵時間中最小的一個,並將其用作時間的度量單位。那麼積分時間步應該比特徵時間少一個數量級,否則你完全錯過了微分方程的正確解,並最終產生自然振盪。

現在發生的事情的例子:讓我們拿一個1公斤的鐵球。當表面積爲3,05.10 ^( - 3)平方公尺時,輻射加熱/冷卻功率高達1,73.10 ^( - 10)W/K^4。當self.power等於5kW時,當溫度達到2319K並且這是平衡溫度時,輻射功率等同於內部功率。在低溫下,輻射加熱/冷卻可忽略不計,而內部加熱只會以11.1 K/s的溫度速率結束。如果翹曲是1000+,則第一次積分步驟會產生11100 K或更高的溫度,這會使平衡點過沖5次。現在,輻射能量比內部加熱高几個數量級,並且會導致巨大的降溫速率 - 乘以1000+,最終會產生負溫度。然後,循環以更高和更高的絕對溫度重複,直到達到浮點運算範圍之外。

這裏給你一個提示:如果self.power保持不變,那麼方程就有一個解析解。找到它(或使用像Maple或Mathematica這樣的工具爲你找到它),然後繪製解決方案。瞭解1000多個單元的時間步長與解決方案的時間尺度的比較,即系統達到幾乎平衡狀態所需的時間。

+0

感謝您對此問題的幫助。我將以支持dt/dx的方式重寫它,並查看是否有可能兼容的解決方案,如RK4。 – Calrizan

0

我猜KSP = Kerbal空間平臺,所以我認爲這是遊戲物理中的一個問題。如果是這樣的話,那麼具有相同定性行爲的近似就足夠了。也許從初始溫度開始並下降到環境溫度的指數曲線就足夠了。通過匹配初始時間的熱傳遞來選擇衰減常數。

有時候近似是足夠好的。我不知道這是否是這種情況之一。