0

这可能是一个数学问题,也是一个编程问题,但是当在下面的代码中将扭曲设置为高值(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 定律:

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

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

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

4

2 回答 2

2

正如@Beta 和@tom10 已经暗示的那样,您的集成方案很糟糕。积分时间步长是时间self.warp单位,即self.warp自从您使用物理单位以来的秒数。这不是做事的方式。您应该首先通过以某种计算单位表示每个项来将方程转换为无量纲格式。例如,Stefan-Boltzmann 常数和self.power可以用单位来测量,其中常数为1。然后你应该确定物体的特征时间,例如温度达到一定程度的平衡时间。如果有很多这样的对象,你应该找到所有特征时间中最小的一个,并将其作为时间的度量单位。那么积分时间步长应该比特征时间小大约一个数量级,否则您将完全错过微分方程的正确解并最终导致剧烈振荡。

现在发生的事情的例子:让我们拿一个 1 公斤的铁球。表面积为 3,05.10^(-3) m^2,辐射加热/冷却功率高达 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+ 单位的时间步长与解决方案的时间尺度(即系统达到几乎平衡状态所需的时间)相比如何。

于 2013-10-16T11:55:50.453 回答
0

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

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

于 2013-10-24T15:54:17.560 回答