15 加热
目前为止,我们研究的系统都是真实存在于这个世界之上的系统。但是,在一般意义上,这些系统并不能被称为物理系统。在接下来的几章里,我们会实现一些真正的物理系统,例如热力系统——也就是在其中,各物体的温度会以热量的形式进行交换。
15.1 咖啡冷却问题
1977年,在Scientific American(《科学美国人》)中,Jearl Walker首次提出了咖啡冷却问题[1] 。从那开始,这个问题就变成了建模与仿真中的一个基础的例子。
下面是我对这个问题的改版:
我在上班前冲了一杯咖啡,手边还有牛奶。假设我希望这杯咖啡在我开车到办公室的时候尽可能的热,请问,我是应该现在就把牛奶加进去然后等着,还是在上班路上的某个时刻把牛奶加进去?
为了解决这个问题,我用放在不同容器里的咖啡和牛奶做了一次实验,并进行了一些测量[2]:
- 咖啡刚冲好的温度是90 °C,体积是300 mL。
- 牛奶的初始温度是5 °C,体积大约50 mL。
- 我车里的温度是22 °C。
- 装咖啡的杯子保温性能良好。30分钟后当我到办公室时,咖啡的温度会降到70 °C。
- 装牛奶的杯子并不能很好隔热。15分钟后,牛奶的温度会升至20 °C,很接近车内温度。
为了利用这些数据解决问题,我们需要了解一些热学的知识,并确定使用什么模型。
15.2 温度与热量
为了理解咖啡如何冷却(牛奶升温),我们需要一个热学的模型。温度是一个物体或者系统自带的属性,在国际标准单位中,温度的单位是摄氏度()。温度确定了一个物体究竟有有多热、有多冷,这些也与物体里的分子热运动相关。
当一个温度高的物体与温度低的物体的分子相遇,由于能量的转移,热的物体会变冷、冷的物体会变热。这个转移的能量就叫热量,在国际标准单位中,它的单位是焦耳(J)。
热量与温度相关,具体关系如下方公式(详情见http://www.modsimpy.com/thermass):
公式中,是转移的热量,
是温度的变化量,
是物体的热容。热容(热质量)确定了想要加热或者冷却这个物体单位温度需要的热量。在国际标准单位中,它的单位是焦耳每摄氏度(
)。
对于主要只由一种材料构成的物体,热质量有如下公式:
是物体的质量,
是构成物体材料的比热容(详情见http://modsimpy.com/specheat)。
我们可以用这些公式估算一杯咖啡的热质量。咖啡的比热容很接近水,为。假设咖啡的密度也接近水,为
,那么300 mL的咖啡就是300 g,热容就是1260 J/ °C。
咖啡从90 °C冷却到70 °C,变化的温度是20 °C,这就意味着有25200 J的热量从咖啡转移到周围的环境中(例如杯座和车中的空气)。
让你直观地感受一下这些热量吧:如果你能利用这所有热量来做功(实际上并不能[3]),你就能把一杯咖啡从海平面抬到8571 m的高度,这已经很接近珠穆朗玛峰的8848 m了。
假设杯子的重量小于咖啡,且其材料的比热容也很小。这样,我们就可以忽略杯子的热质量。而对于那些热质量很大的杯子,例如陶瓷杯,我们就需要一个分别计算咖啡和杯子温度的模型。
15.3 热传递
在像咖啡冷却问题这样的情况中,热量从一个物体转移到另一个的方法有三种(详情见http://modsimpy.com/transfer):
- 热传导:当两个温度不同的物体互相接触时,高温度物体快速运动的分子把它的动能传递给低温度物体里低速运动的分子。
- 热对流:气体或者液体里的分子运动时都携带着热量。流体流动有很多原因,可以是外部作用例如搅拌,也可以是内部作用例如温度的变化。比如说,你应该听说过热的空气会上升,这就是一种“自然热对流”。
- 热辐射:当物体分子由于热能而运动时,它们会放出电磁辐射。辐射能量的多少取决于物体的温度及表面材质。
对于车里的一杯咖啡,热辐射的影响要远远小于热传导和热对流,所以我们可以忽视它。
热对流实际上是一个很复杂的过程,因为它涉及三维空间内的流体流动。但是在本问题中我们可以采取一种简单的模型——“牛顿冷却定律”。
15.4 牛顿冷却定律
定律表明:当物体与周围环境存在温度差时,物体温度的变化率与温度差成比例。
这里的,是物体的温度,也是时间
的函数;
是环境的温度,
是一个常数,用来表示系统与环境进行热交换的快慢。
这个定律是个典型的模型:它在一些情况下可以很好地近似,但在其他情况下则不行。
比如说,如果发生热传递中的主要机制是热传导,牛顿冷却定律是“正确的”,也就是说 不随温度改变而改变。并且有时我们可以通过材料的性质和物体的形状估计
。
如果这个主要机制是热对流, 就取决于温度了,但是牛顿冷却定律依然有用,至少在温度变化不剧烈的时候。这种情况下
通常需要通过实验测得,因为它取决于空气的流动、蒸发等因素。
而如果主要机制是热辐射时,定律就完全失效了。这种情况下物体会处于太空或者真空里,物体的温度也会很高(几百摄氏度)。
然而,对于咖啡冷却问题,牛顿冷却定律是可以胜任的。
15.5 代码实现
开始之前,先暂时忘掉牛奶专注咖啡。我会创建一个State类的实例来表示初始温度:
init = State(T=90)
和一个System类的实例来储存参数:
coffee = System(init=init,
volume=300,
r=0.01,
T_env=22,
t_0=0,
t_end=30,
dt=1)
所有参数的值都来源于问题描述。我随便挑了一个r的值,待会我们会指出如何估计出它的值。
dt是我们用来模拟冷却过程的时间间隔。严格来说,牛顿冷却定律是一个微分方程,但在时间差较短的情况下我们可以用一个非微分方程代替它:
这里 是一个很小的时间间隔,
是这个时间间隔里温度的变化量。
注意:我用 表示温度的变化量,但是在一些地方你可能也会看见
用来表示物体与环境的温度差。为了减少混淆,我会避免再次这样使用它。
现在我们可以写出一个更新函数:
def update_func(state, t, system):
r, T_env, dt = system.r, system.T_env, system.dt
T = state.T
T += -r * (T - T_env) * dt
return State(T=T)
就像之前的更新函数一样,这个函数接收一个State类,一个时间变量,一个System类。
如果我们运行
update_func(init, 0, coffee)
可以看出,一分钟后咖啡的温度是89.3 °C,所以温度下降的速度大约是0.7 °C/min,至少在这个 下。
这里有一个run_simulation函数,可以模拟从t_0到t_end的一系列时间间隔:
def run_simulation(system, update_func):
init = system.init
t_0, t_end, dt = system.t_0, system.t_end, system.dt
frame = TimeFrame(columns=init.index)
frame.row[t_0] = init
ts = linrange(t_0, t_end, dt)
for t in ts:
frame.row[t+dt] = update_func(frame.row[t], t, system)
return frame
这个函数很像run_simulation之前的版本。
有一个区别是它用linrange来生成一列从t_0到t_end以dt为间隔的数组。数组并不包括t_end,所以最后一个值是t_end - dt。
可以运行:
results = run_simulation(coffee, update_func)
函数的返回值是TimeFrame类,每一行是一个时间间隔,只有一列,为T。30分钟后温度降至72.3 °C,略高于问题描述的70 °C。我们可以通过不断试错逐步调整 ,但是下一章会有一个更简单的方法。
首先我想把所有东西集成到一个函数里:
def make_system(T_init, r, volume, t_end):
init = State(T=T_init)
return System(init=init,
r=r,
volume=volume,
temp=T_init,
t_0=0,
t_end=t_end,
dt=1,
T_env=22)
make_system接受参数并把它们传给一个System类。现在我们可以像这样进行仿真:
coffee = make_system(T_init=90, r=0.01,volume=300, t_end=30)
results = run_simulation(coffee, update_func)
在阅读下一章之前,你可以阅读一下本章的notebook,并且做做其中的练习题。关于下载、运行代码的说明,请阅读Section 0.4。
本书的中文翻译由南开大学医学院智能医学工程专业2018级、2019级的师生完成,方便后续学生学习《Python仿真建模》课程。翻译人员(排名不分前后):薛淏源、金钰、张雯、张莹睿、赵子雨、李翀、慕振墺、许靖云、李文硕、尹瀛寰、沈纪辰、迪力木拉、樊旭波、商嘉文、赵旭、连煦、杨永新、樊一诺、刘志鑫、彭子豪、马碧婷、吴晓玲、常智星、陈俊帆、高胜寒、韩志恒、刘天翔、张艺潇、刘畅。
整理校订由刘畅完成,如果您发现有翻译不当或者错误,请邮件联系changliu@nankai.edu.cn。
本书中文版不用于商业用途,供大家自由使用。
未经允许,请勿转载。