avatar

Xiaojun Wu

Ph.D. Candidate, HKUST(GZ)
Affiliate LLM Researcher, IDEA Research
wuxiaojun@idea.edu.cn & wuxiaojun@pku.edu.cn & xwu647@connect.hkust-gz.edu.cn


← Blog

python数学建模实践

Python 微分方程(五):热量为什么会自己摊平?

在知乎查看原文

阅读 知乎未公开 收藏 29 点赞 6

互动数据为 2026-09-13 的知乎数据快照;阅读量未在当前可用的知乎公开接口中提供。

上一章我们看的是稳态问题:

两头条件都给定,空间曲线怎么连起来。

这一章再往前一步,把时间加回来。

一根两头固定温度的热棒,为什么中间一块热斑会慢慢散开,最后整根棒都变平?

先给一句人话答案:

每个点都在和左右邻居交换热量,所以高的地方会往低的地方流。

这就是热传导方程最核心的直觉。

偏微分方程的英文是 partial differential equation,简称 PDE。
先别急着背,它只是说:

未知量不只随一个自变量变,而是会同时随空间和时间变。

这一节的 takeaway:PDE 的难点不是更花哨,而是变量从一个方向变成了两个方向。

0. 先看最小故事

想象一根长度固定的细杆:

  • 两端温度被钉死为 0
  • 中间一开始有一个热包
  • 热包会慢慢往两边摊开

我们想问的不是“某个点现在多热”,而是:

整根杆在每个位置、每个时刻到底多热?

这就不是一条曲线了,而是一张“温度场”。

这一节的 takeaway:PDE 不是单条时间曲线,而是“位置 + 时间”的二维变化。

1. 变量和方程

把温度写成 u(x, t):

  • x 表示空间位置
  • t 表示时间
  • u 表示这个位置、这个时间的温度

一维热传导方程写成:

 \frac{\partial u}{\partial t} = \alpha \frac{\partial^2 u}{\partial x^2}

这里:

  • u_t 代表温度随时间怎么变
  • u_xx 代表空间上弯得有多厉害
  • alpha 是热扩散系数,越大说明热摊得越快

这个方程的人话版本是:

哪里比周围高,热量就会往外摊。

边界条件通常是:

 u(0,t)=0,\qquad u(L,t)=0

也就是两端温度固定。

初始条件是:

 u(x,0)=u_0(x)

也就是一开始那根杆上,温度分布长什么样。

这一节的 takeaway:热方程把“空间上的弯曲”直接变成“时间上的变化速度”。

2. 最小可用例子

如果一开始中间有一个热包,左右两端是冷的,那么直觉上会发生三件事:

  1. 中间先降温
  2. 两边先升温
  3. 最后整条曲线越来越平

这其实就是“高温向低温扩散”。

所以热方程不是在追求某个最优值,而是在描述:

温度如何自动摊平。

这一节的 takeaway:热传导的最小工作例子,就是一个中间热、两端冷的杆。

3. 为什么要离散化

PDE 直接在连续空间上算,通常不好手算。
但电脑最擅长的事情是:

把连续东西切成一格一格,再反复更新。

所以最常见的做法是有限差分。

有限差分的英文是 finite difference。
它的人话版本是:

用邻居之间的差,去近似导数。

对于二阶导数,有一个最常用的近似:

 \frac{\partial^2 u}{\partial x^2}\approx \frac{u_{i+1}-2u_i+u_{i-1}}{\Delta x^2}

这句话很重要,因为它告诉我们:

一个点未来怎么变,只由它左右两个邻居决定。

这一节的 takeaway:PDE 进电脑的第一步,通常是把空间切成网格。

4. 让时间一步步走

把上面的近似代回热方程,就得到显式更新公式:

 u_i^{n+1} = u_i^n + r\left(u_{i+1}^n - 2u_i^n + u_{i-1}^n\right)

其中:

 r = \alpha \frac{\Delta t}{\Delta x^2}

这里 r 不是什么新术语,你可以先把它理解成:

时间步长和空间步长拼出来的稳定参数。

如果 r 太大,数值解会炸掉;
如果 r 足够小,曲线就会稳稳地摊平。

最常见的显式格式里,稳定性通常要求:

 r \le \frac{1}{2}

这一节的 takeaway:PDE 不只是“能不能算”,还要看“步长会不会把结果算炸”。

5. 代码怎么写

热方程可以直接用 numpy 做网格更新。

import numpy as np

L = 1.0          # 杆长
alpha = 0.15     # 热扩散系数
nx = 51          # 空间网格点数
dx = L / (nx - 1)

# 选一个稳定的时间步长
r = 0.45
dt = r * dx * dx / alpha

x = np.linspace(0, L, nx)
u = np.exp(-80 * (x - 0.5) ** 2)  # 初始热包
u[0] = 0.0
u[-1] = 0.0

for _ in range(n_steps):
    u_new = u.copy()
    u_new[1:-1] = u[1:-1] + r * (u[2:] - 2 * u[1:-1] + u[:-2])
    u_new[0] = 0.0
    u_new[-1] = 0.0
    u = u_new

这段代码里最关键的是这一行:

u_new[1:-1] = u[1:-1] + r * (u[2:] - 2 * u[1:-1] + u[:-2])

它把“左右邻居”这个物理事实,直接变成了数组切片。

所以这类 PDE 代码的本质不是神秘算法,而是:

把公式翻译成网格上的邻居计算。

这一节的 takeaway:热方程的核心更新,只是在每个网格点上看左右邻居。

6. 结果怎么看

这个模型的结果应该有三个很清楚的特征:

  • 热包会变矮
  • 热量会向两边摊开
  • 最后曲线会越来越平

如果你看到局部温度越来越尖,或者数值突然振荡,通常就是:

  • 时间步长太大
  • 空间网格太粗
  • 稳定条件没满足

所以 PDE 不只是“有没有算出图”,而是:

图像是不是符合扩散直觉。

这一节的 takeaway:结果是否合理,第一眼看扩散形状,第二眼看稳定性。


7. 一个实用判断

遇到热方程这类 PDE 时,可以先问三个小问题:

  1. 我是不是已经把空间离散成网格了
  2. 时间步长是不是足够小
  3. 边界条件是不是写对了

如果这三件事都对,热包一般会按预期慢慢散开。

如果这三件事有一个错了,图就可能会炸。

这一节的 takeaway:PDE 的第一层验算,不是高级分析,而是网格、步长和边界。

8. 小结

这一篇压成一句话就是:

偏微分方程描述的是“空间 + 时间”上的变化,热传导方程的数值实现,最常见的方法就是把空间切成网格,再按时间一步步更新。

如果只记五句话,就记这五句:

  • PDE 是 partial differential equation
  • u(x,t) 同时依赖空间和时间
  • 热方程告诉你哪里高温会往哪里摊
  • 有限差分就是把导数换成邻居差
  • 稳定性比“能不能写出代码”更重要

到这里,我们已经把微分方程从“一个起点往前推”,写到了“边界条件在两头”和“空间时间一起变”。 后面如果再扩,就可以继续往反应扩散、波动方程,或者更贴近建模竞赛的耦合系统去写。

参考


© 2025 Xiaojun Wu. All rights reserved. Powered by Jekyll and Minimal Light theme.