计算物理 · 课程汇报
从对流方程
到可信的数值解
以 Lorenz 系统为例
σ = 10ρ = 28β = 8/3
x₀x₀ + 10⁻⁵
t = 0.0|Δ| = 1.0e−5
目录
一段推导,四项检验
开场 · 现场演示
同一个方程,同一个初值,同一个求解器
参考解 rtol = 1e−13 所选 rtol
唯一的旋钮是相对容差 rtol。前一段贴合,之后各自脱钩,差到吸引子的尺度。
绪论
从 Boussinesq 方程到时间积分
绪论 · 物理图景
Rayleigh–Bénard 对流
底下的流体受热变轻想上浮,上面的冷流体想下沉。粘性和热扩散会抵抗这种翻动。
两股力量之比叫 Rayleigh 数:
- Ra 小于临界值 Rac:流体静止,热量只靠传导
- Ra 大于 Rac:静止失稳,长出一排对流卷
- 另一个无量纲数 Pr = ν/κ:动量与热量各自扩散的快慢之比
Saltzman(1962)、Lorenz(1963)只看一个方向上的二维卷。
绪论 · 出发点
Boussinesq 方程与流函数形式
Boussinesq 近似:密度只在浮力项里随温度变,其余地方当常数。
- 只看 X–Z 平面里的二维卷:令 \(u = -\partial_Z\psi,\ w = \partial_X\psi\),质量守恒自动满足
- 对动量方程取旋度,压力 p 消掉
- 温度拆成两份:\(T = \underbrace{T_0 + \Delta T\,(1 - Z/H)}_{\text{静止时的传导直线}} + \theta\)
剩下两个未知场:流函数 ψ(X, Z, t) 管流动,θ(X, Z, t) 是温度偏离传导直线的那部分。流体静止时 θ ≡ 0。
\(J(a,b) = \partial_X a\,\partial_Z b - \partial_Z a\,\partial_X b\),就是 \(\mathbf u\cdot\nabla b\)。这是 Lorenz 1963 的式 (17)–(18)。未知量是两个函数,所以是无穷维的。
绪论 · 怎么放进计算机
线方法:先空间离散,再时间积分
| 偏微分方程 | 第 1 步:空间离散 | 常微分方程组 | 第 2 步:时间推进 | |
|---|---|---|---|---|
| 一般形式 | 未知量是场,无穷维 | 选基函数或网格,只留 N 个数 | \(\dot{\mathbf u} = \mathbf f(\mathbf u),\ \mathbf u\in\mathbb R^N\) | \(\mathbf u_{n+1} = \Phi_h(\mathbf u_n)\) |
| 声场 FDTD | 波动方程 \(p_{tt} = c^2\nabla^2 p\) | 差分网格,N 动辄上百万 | 线性 | 蛙跳格式 |
| Lorenz | 二维 Boussinesq 对流 | 3 个 Fourier 模态,N = 3 | 非线性,3 行 | RK4(原理)· DOP853(实算) |
Lorenz 是线方法(method of lines)最小的例子:N = 3,小到每一步都能看清。
后面四段都落在第 2 步上:每一步的误差会怎样累积。
绪论 · 第 1 步 空间离散
三模 Fourier 截断:x、y、z 是模态振幅

把 ψ、θ 按满足边界条件的正弦展开(谱方法),Lorenz 只留三项:
- x:卷翻滚得多快,正负是转向
- y:上升流与下沉流之间的温差
- z:平均温度剖面弯离直线的程度,也就是对流额外运走的热:Nu = 1 + 2z/ρ
绪论 · 第 1 步 空间离散
Galerkin 投影:截断丢掉了什么
Galerkin 做法:把三项展开代入两条 PDE,乘以每个模态、在一个卷上积分,每个模态得到一条 ODE。线性项各回各的模态,要算的只有平流 J。取 H = 1,k = πa:
| 平流里相乘的两样 | 乘出来的空间花样 | 去向 |
|---|---|---|
| 卷 × 卷 \(J(\psi,\nabla^2\psi)\) | 0:单个模态的 \(\nabla^2\psi \propto \psi\) | \(\dot x\) 方程是线性的 |
| 卷 x × 温差 y | \(\tfrac{k\pi}{2}\sin 2\pi Z\),恰好是 z 的花样 | \(\dot z\) 里的 \(+xy\) |
| 卷 x × 剖面 z | \(k\pi\cos kX\,(\sin 3\pi Z - \sin\pi Z)\) | \(\sin\pi Z\) 回到 y:\(\dot y\) 里的 \(-xz\) \(\sin 3\pi Z\) 不在三个模态里,扔掉 |
截断就是扔掉 sin 3πZ 这一类高阶项。z 必须留:它是 x·y 直接生出来的。不留 z,方程只剩线性部分,ρ > 1 时振幅指数增长、停不下来。
绪论 · 得到的 ODE
Lorenz 方程逐项的物理意义
| 方程 | 项 | 物理过程 |
|---|---|---|
| \(\dot x = \sigma(y - x)\) | \(+\sigma y\) | 浮力:热的一侧轻、冷的一侧重,温差推着卷转 |
| \(-\sigma x\) | 粘性给翻滚刹车 | |
| \(\dot y = \rho x - y - xz\) | \(+\rho x\) | 卷把底部热流体搬上去、顶部冷流体搬下来,制造水平温差 |
| \(-y\) | 热扩散把水平温差抹平 | |
| \(-xz\) | 剖面中段已被拉平,同样的翻滚搬来的温差打了折扣 | |
| \(\dot z = xy - \beta z\) | \(+xy\) | 热的上升、冷的下沉,净效果是向上运热,把剖面拉弯 |
| \(-\beta z\) | 热扩散把剖面拉回直线 |
非线性只有标色的两项,都来自流体搬运温度(平流 u·∇θ)。时间以热扩散为单位,Lorenz 的 1 个时间单位约等于 H²/κ 的 1/15。
绪论 · 参数
经典参数 σ、β、ρ 的来由
- β = 8/3:宽度不同的卷各有各的失稳阈值 \(\mathrm{Ra}_c(a) = \pi^4(1+a^2)^3/a^2\),在 a² = 1/2 最低(27π⁴/4 ≈ 657.5)。取最先失稳的那种卷,β = 4/(1 + ½) = 8/3,卷宽 √2 H。
- σ = 10:和水同一量级(室温约 7)。它还得大于 β + 1 = 11/3,否则 C± 永远不会失稳,就没有后面的混沌。
- ρ = 28:Ra 是临界值的 28 倍。ρ 超过 \(\rho_H = \sigma(\sigma+\beta+3)/(\sigma-\beta-1) = 470/19 \approx 24.74\) 时 C± 失稳;Lorenz 取了一个稍高于它的整数。
三个数都出自 Lorenz 1963 原文,此后的文献几乎都沿用,后面所有实验也都用这一组。ρ_H 在 ① 里会再出现。
绪论 · 模型的边界
三模截断的适用范围
后面所有结论都关于这个数学对象,不涉及流体或天气的主张。
但有几个物理系统,化简后恰好就是这组方程:
- Malkus 水车:x 是转速,y、z 是桶中水量分布的一阶 Fourier 系数
- 热虹吸环:竖直圆环管里的对流,x 是环流速度
- 单模激光(Haken 1975):x 是光场,y 是极化,z 是粒子数反转
绪论 · 第 2 步 时间推进
时间积分:Euler、RK4 与自适应步长
def f(u): # 就是那三行方程 x, y, z = u return np.array([σ*(y-x), x*(ρ-z) - y, x*y - β*z]) u = u0 # 显式 Euler:一阶 for n in range(N): u = u + h * f(u) def rk4_step(u, h): # 经典 RK4:四阶 k1 = f(u) k2 = f(u + h/2 * k1) k3 = f(u + h/2 * k2) k4 = f(u + h * k3) return u + h/6 * (k1 + 2*k2 + 2*k3 + k4)
仓库里的 integrate.rk4_step 就是这几行(多一个时间参数)。后面的计算和现场演示都用 DOP853,只调 rtol。
| 积分器 | 步长怎么定 |
|---|---|
| RK4(原理) | 固定 h;h 减半,误差约缩小 16 倍 |
| DOP853(实算) | 8 阶;每步估计局部误差,按 rtol 自动调 h |
| DOP853,rtol = 1e-13 | 当作参考解 |
第 ① 部分
从不动点到 Lyapunov 指数
① 从不动点到 Lyapunov 指数 · 现场演示
约化 Rayleigh 数 ρ = Ra / Rac
开始对流24.74
定常卷失稳
① 从不动点到 Lyapunov 指数
令导数为零:静止导热与一对定常卷

- 原点 静止导热
- C± 定常卷:\(x = y = \pm\sqrt{\beta(\rho-1)},\ z = \rho-1\)
ρ = 28:(±8.49, ±8.49, 27)
原点附近扔掉二阶小量 xz、xy:
① 从不动点到 Lyapunov 指数
ρH = 24.74:一对复根穿过虚轴,定常卷站不住

在 C± 旁展开到一阶:\(\lambda^3 + a_2\lambda^2 + a_1\lambda + a_0 = 0\)
a₂ = σ+β+1,a₁ = β(σ+ρ),a₀ = 2σβ(ρ−1),全为正
没有正实根;要失稳,只能一对复根从 ±iω 穿过。代 λ = iω:
ρ = 28:那对复根 0.094 ± 10.19i
① 从不动点到 Lyapunov 指数
三维流 → 二维截面 → 一维映射

一个点是一步。越过门槛越少,落到对面越远,于是能连换好几次。
① 从不动点到 Lyapunov 指数
在任意一点展开:Jacobian 逐行求偏导
线性项求导得常数;xz、xy 求导留下 x、y、z,J 随轨道上的点变。
- 不动点上 J 是常数,看特征值:不动点与 Hopf 两页已经用过
- 沿轨道 J 每一点都不同,没有固定的本征方向:局部指数、边算边正交化
- 对角线 tr J = −(σ+1+β),与点无关:三个指数之和
① 从不动点到 Lyapunov 指数
局部 Lyapunov 指数:此刻、这个方向上拉得多快

由两样东西决定:轨道走到哪(J),扰动此刻指向哪(e)。
- 不是 J 的特征值:最大实部平均 1.65
- 窗口 τ 上平均 = 有限时间指数:τ = 0.5 标准差 2.60;τ → ∞ 收拢到 λ₁
① 从不动点到 Lyapunov 指数
Lyapunov 指数:定义与 Benettin 公式

定义(M′ = JM,M(0) = I):
计算:
λ = (+0.9038, −0.0004, −14.570)
线段按 eλ₁t,面积按 e(λ₁+λ₂)t,体积按 e(λ₁+λ₂+λ₃)t。
① 从不动点到 Lyapunov 指数
J 每点在变:Lyapunov 谱要边算边 QR 正交化

① 从不动点到 Lyapunov 指数
迹在正交换基下不变:三个指数之和 = tr J

Lorenz 的对角线 −σ、−1、−β 里没有变量:
tr J = −(σ+1+β) = −13.667
三个局部指数之和每一瞬间都是 −13.667。λ₂ = 0,于是 λ₃ = −13.67 − 0.90 = −14.57。
第 ② 部分
精度只换来对数时间
② 精度只换来对数时间 · 现场演示
从相差 ε 的两个初值出发
x₀ x₀ + ε t = 0.0|Δ| = 1e−6
换一个 ε 再跑一次,比较两次分开的时刻。
② 精度只换来对数时间
误差按 λ₁ 增长,到吸引子尺度饱和

吸引子上 16 个点 × 4 个随机方向,扰动 δ = 1e−9,全部用参考精度积分。
② 精度只换来对数时间 · 核心证据
可分辨时间对 ln(1/rtol) 是一条直线

| rtol | Tdiv |
|---|---|
| 1e−4 | 5.69 |
| 1e−6 | 10.62 |
| 1e−8 | 16.11 |
| 1e−10 | 20.71 |
| 1e−12 | 26.88 |
② 精度只换来对数时间
双精度下的预报极限
t > 41 时,
算出的已不是那个初值的轨道。
从 rtol = 1e−4 收紧到 1e−12,DOP853 的步数约多 10 倍,预报时间从 5.7 涨到 26.9。再要 20 个时间单位需要再收紧 8 个数量级,而双精度已经到头了。
第 ③ 部分
单条轨道不可信,统计量可信
③ 统计量不随 rtol 变
影随:数值轨道跟着另一条真解
直觉:局部误差很小的数值轨道,虽然不是你要的那条真解,可能紧跟着另一条初值稍有不同的真解。
那么画出来的蝴蝶是真的蝴蝶,只是不是"你那只"。
对一致双曲系统,这是定理(影随引理)。
影随只提示方向。真正的辩护必须可测量。
③ 统计量不随 rtol 变 · 中心实验
同一组数据:左边报废,右边完好

③ 统计量不随 rtol 变
不变密度同样不动

两条结论都写成了测试:
test_statistics.py::
test_lorenz_map_is_tolerance_independent
test_invariant_density_is_tolerance_independent
③ 统计量不随 rtol 变
教科书上的蝴蝶不是幻觉

红点是三个不动点:原点是鞍点,C± 各自是一叶的中心。
两叶间的切换是非周期的,而切换序列正是 Lorenz 映射编码的东西。
可信的是这个形状和它的统计,不是其中任何一条轨道。
第 ④ 部分
可信的判据随系统类型变
④ 判据随系统类型变
三类系统的验证判据
| 系统类型 | 可保的结构 | 验证手段 | 长时间单条轨道 |
|---|---|---|---|
| 保守(哈密顿) | 辛形式、不变量 | 监视能量有界;辛 / 分裂格式 | 可信(误差多项式增长,辛格式下线性) |
| 耗散、非混沌 | 收敛到吸引子 | 是否收敛到正确的稳态或极限环 | 可信 |
| 耗散、混沌 | 无 | 统计量对方法不敏感 | 不可信(超过 1/λ₁ 量级) |
混沌问题的验证协议:容差扫几个数量级、方法换几种,检查 λ₁、不变密度、Lorenz 映射是否稳定。第 ③ 部分就是在执行这套协议。
④ 判据随系统类型变
Poincaré 截面:周期、准周期、混沌

近邻收拢是第二行,刚性转动是第一行,指数散开是第三行。
④ 判据随系统类型变
哈密顿结构守三样,Lorenz 一样也没有
| 谐振子 | Lorenz | |
|---|---|---|
| 能量 H | (p² + q²)/2 守恒 | 无 |
| 相体积 | tr J = 0 | tr J = −13.667 |
| 辛形式 Ω | 一对 (q, p) | 3 维,配不成对 |
| Lyapunov 谱 | ±λ 成对,和为 0 | 和为 −13.67 |
没有不变量可查。
④ 判据随系统类型变
守恒系统里,精度换来成倍的时间

④ 判据随系统类型变
回到声学
表的第一行
无耗散波动方程是哈密顿系统。Yee 的 FDTD 格式里 E 与 H 在时间上交错半格,那就是蛙跳格式,也就是辛积分器。
FDTD 能长时间运行而不出现数值能量爆炸或人工衰减,原因在结构。
表的第三行
非线性声学、声致湍流一旦进入混沌,单次实现的波形不该当作可复现的预报。
该报告的是谱、相关函数、统计矩。
结论
守恒系统看不变量,混沌系统看统计量
- Lorenz 没有守恒量,体积以 tr J = −13.667 坍缩。
- 可预报时间被 λ₁ = 0.904 锁死在约 41 个时间单位,精度只换来对数的时间。
- 不变密度、Lorenz 映射对 rtol 不敏感。
全部数字与图都可复现,关键断言写成了测试:
uv sync --all-groups uv run pytest uv run lorenz63 info uv run lorenz63 figure all
备用
备用页
备用 · 绪论 · 时间推进
三个积分器:阶数、步长、误差估计
| RK4 | RK45 | DOP853 | |
|---|---|---|---|
| 阶数 p | 4 | 5 | 8 |
| 步长 | 固定,人给 | 自适应 | 自适应 |
| 误差估计 | 无 | 5 阶 − 4 阶 | 5 阶与 3 阶组合 |
| 每步 f 次数 | 4 | 6 | 12 |
RK45 即 scipy 的 Dormand–Prince 5(4);DOP853 是 Hairer–Wanner 的 8(5,3)。演示里的 DOP853 由 scipy 逐行移植。
err ≤ 1 接受,否则重算;下一步 \(h \leftarrow 0.9\,h\,\text{err}^{-1/p}\)。
步数 \(\propto \text{rtol}^{-1/p}\)。rtol 收紧 106 倍:
积分器决定代价;每 10 倍 rtol 换 2.55 个时间单位,由 λ₁ 决定。
备用 · ① 从不动点到 Lyapunov 指数
Lyapunov 函数:耗散但有界
方括号在椭球 \(\rho x^2 + y^2 + \beta(z-\rho)^2 = \beta\rho^2\) 之外为正,V 在那里单调下降。
所有轨道最终被困在一个有界区域里。
这是混沌,不是发散。
备用 · ① 从不动点到 Lyapunov 指数
不动点的本征结构决定吸引子形状

- 原点的不稳定方向 λ = +11.83
- 稳定 / 收缩方向
- C± 的不变平面 0.094 ± 10.19i
原点 +11.827723 −2.666667 −22.827723 一正二负 → 鞍点 C± −13.854578 +0.093956 ± 10.194505 i 收缩方向 + 向外旋的不变平面
备用 · ② 精度只换来对数时间
数值稳定性 ≠ Lyapunov 不稳定性
| 是什么的性质 | 由什么决定 | 步长能改变吗 | |
|---|---|---|---|
| 数值稳定性 | 方法 + 步长 | hλJ 是否落在稳定域内 | 能 |
| Lyapunov 指数 | 流本身 | 方程 | 不能 |
真解自己就在指数分离。步长变小只减少注入的误差量,这些误差随后照样按 eλt 放大。
备用 · ② 精度只换来对数时间
hλ:一步跨过模的几个时间尺度
线性化 \(\dot{\delta u} = J\,\delta u\),对角化后每个方向都是 \(\dot y = \lambda y\)。
\(R_\text{RK4}(z) = 1 + z + \tfrac{z^2}{2} + \tfrac{z^3}{6} + \tfrac{z^4}{24}\),是 \(e^z\) 的截断。
h·Re λ:一步里幅度的对数变化。h·Im λ:一步转过的弧度(C±:0.10,62 步一圈)。
最快的衰减模 λ = −21.85,时间尺度 0.046:
| h | hλ | 真解 \(e^{h\lambda}\) | RK4 \(R(h\lambda)\) |
|---|---|---|---|
| 0.01 | −0.22 | 0.8037 | 0.8037 |
| 0.05 | −1.09 | 0.335 | 0.346 |
| 0.12 | −2.62 | 0.073 | 0.78 |
| 0.15 | −3.28 | 0.038 | 2.03 |
备用 · ② 精度只换来对数时间
瓶颈是精度,不是稳定性

吸引子上采样的 Jacobian 谱:max |λJ| = 23.0,36.3% 的特征值实部为正。
备用 · ② 精度只换来对数时间
自适应:稳定域不变,守它的换成控制器
| 格式 | 负实轴交点 | 稳定上限 h |
|---|---|---|
| RK4 | −2.785 | 0.127 |
| RK45 | −3.31 | 0.151 |
| DOP853 | −6.39 | 0.293 |
R(z) 由 Butcher 表算出;上限 = 交点 / 21.85。与 rtol 无关。
DOP853 在吸引子上的最大步长,占稳定上限:
| rtol | 最大 h | 占上限 |
|---|---|---|
| 10⁻³ | 0.296 | 1.01 |
| 10⁻⁴ | 0.245 | 0.84 |
| 10⁻⁶ | 0.135 | 0.46 |
| 10⁻⁹ | 0.061 | 0.21 |
| 10⁻¹³ | 0.021 | 0.07 |
全文用的 10⁻⁴ 到 10⁻¹³ 都在稳定域里面:步长按精度选。
备用 · ② 精度只换来对数时间
衰减模走出了精度域,没走出稳定域

沿负实轴,rtol = 10⁻⁴:
| 精度域 | 衰减模 hλ | 稳定域 | |
|---|---|---|---|
| RK45 | −0.63 | −1.81 | −3.31 |
| DOP853 | −1.81 | −4.57 | −6.39 |
备用 · ② 精度只换来对数时间
阶数在精度定步长时才值钱

非刚性:h ∝ tol1/p,nfev ∝ s · tol−1/p
| 斜率 | −1/p | 误差 10⁻¹⁰ | |
|---|---|---|---|
| RK45 | −0.17 | −0.20 | 6100 次 |
| DOP853 | −0.10 | −0.125 | 1440 次 |
刚性:nfev ≈ s · |λ|T / 交点,与 tol、阶数都无关
| s / 交点 | 步数:心算 | 实测 | |
|---|---|---|---|
| RK45 | 1.81 | 3020 | 3025 |
| DOP853 | 1.88 | 1560 | 1567 |
备用 · ④ 判据随系统类型变
推论:混沌问题的收敛阶要在短窗口里验
常见做法:画"误差 vs 步长",期待一条 O(hp) 直线。
超过可预报时间后误差饱和到吸引子直径,图会变成一条水平线,看起来像格式失去了精度阶。
收敛阶必须在 t ≪ 1/λ₁ 的窗口内验证。
test_integrate.py::
test_tighter_tolerance_is_more_accurate_before_saturation
备用
数字汇总
| tr J | −13.6666666667 | 闭式 |
| C± | (±8.4853, ±8.4853, 27) | 闭式 |
| ρ_Hopf | 24.7368421053 | 闭式 |
| λ₁ / λ₂ / λ₃ | 0.9038 / −0.0004 / −14.5700 | T=2000 |
| Σλ − tr J | 2.17e−9 | 自洽检验 |
| D_KY | 2.062001 | λ 谱 |
| 倍增时间 | 0.767 | ln2/λ₁ |
| 双精度预报极限 | 40.76 | ln(10¹⁶)/λ₁ |
| λ₁(系综) | 0.8750 | 16 点 × 4 方向 |
| λ₁(容差斜率) | 0.8839 | T_div 拟合 |
| RK4 稳定步长上限 | 0.1253 | 仅衰减模 |
| Lorenz 映射厚度 | 8.6e−5 | z 值域比例 |
| 不变密度最大总变差 | 0.0099 | 三个 rtol |
| 有限时间 λ₁ 标准差 | 2.60 | 窗口 0.5 |