不可控制的模拟振荡

时间:2013-10-15 18:43:30

标签: python math simulation physics game-physics

这可能是一个数学问题,因为它是一个编程问题,但是当我将类warp设置为高值(1000+)时,我的类方法“update()”似乎遇到了严重的温度振荡下面的代码。为简单起见,所有温度均为开尔文。

(我不是专业的程序员。这种格式可能很不愉快。)

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

使用的法则是计算黑体热损失的Stefan-Boltzmann定律:

温度 - =(发射率* Sigma * SurfaceArea *(Temp ^ 4-Amb ^ 4))/ SpecificHeat)

这是从KSP插件移植的,以便更快地进行调试。 Object.update()每秒调用50次。

是否有解决方案可以防止这些极端振荡,而不涉及每步执行多次代码?

2 个答案:

答案 0 :(得分: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等于5 kW时,当温度达到2319 K时,辐射功率等于内部辐射功率,这就是平衡温度。在低温下,辐射加热/冷却可以忽略不计,只有内部加热才能达到11,1 K / s的温度。如果warp为1000+,则第一次积分步骤会导致温度达到11100 K或更高,这会使平衡超过5次。现在,辐射能量比内部加热高几个数量级,并且导致巨大的冷却速率 - 乘以1000+,最终得到负温度。然后循环以更高和更高的绝对温度重复,直到你超出浮点运算的范围。

以下是您的提示:如果self.power保持不变,则等式具有解析解。找到它(或使用像Maple或Mathematica这样的工具为你找到它),然后绘制解决方案。了解1000+单位的时间步长与解决方案的时间尺度的比较,即系统达到近乎平衡状态所需的时间。

答案 1 :(得分:0)

我猜KSP = Kerbal Space Platform,所以我认为这是游戏物理中的一个问题。如果是这样,也许具有相同定性行为的近似就足够了。也许从初始温度开始并降至环境温度的指数曲线就足够了。通过匹配初始时的热传递来选择衰减常数。

有时近似值足够好。我不知道这是否是其中一种情况。