1. 一维稳态热传导有限差分建模与验证

问题定义与离散格式

考虑一根长度 L = 1 m 的均质导热棒,导热系数 k = 1 W/(m·K),无内热源。左端 x = 0 保持定温 T₀ = 100 °C,右端 x = L 保持定温 T_L = 0 °C。控制方程为:

d²T/dx² = 0,  0 < x < L
T(0) = T₀,  T(L) = T_L

解析解为线性分布 T(x) = T₀ + (T_L − T₀)·x/L。有限差分法将区间等分为 N 个单元,节点间距 Δx = L/N,内部节点 i = 1…N−1 采用中心差分:

(T_{i−1} − 2T_i + T_{i+1}) / Δx² = 0
⇒ T_{i−1} − 2T_i + T_{i+1} = 0

边界节点 T_0 = T₀、T_N = T_L 直接代入,形成三对角线性方程组 A·T = b。由于方程是线性的且边界为第一类(Dirichlet)条件,离散解在节点上应精确等于解析解——这是验证格式与边界处理正确性的关键判据。

均质导热棒 L = 1 m,k = 1 W/(m·K),无内热源 i=0 i=1 i=2 i=3 i=4 i=N 左端 Dirichlet T₀ = 100 °C 右端 Dirichlet T_N = 0 °C 内部节点中心差分模板(i = 1…N−1) T_{i−1} − 2T_i + T_{i+1} = 0 三对角方程组 A·T = b 解析解:T(x) = 100 − 100x(线性分布)

Python 实现:组装与求解

下面给出完整可运行代码。核心步骤:生成节点坐标、组装三对角系数矩阵、施加 Dirichlet 边界、用 numpy.linalg.solve 求解,并与解析解逐点比较。

import numpy as np

def solve_1d_steady(N, L=1.0, T0=100.0, TL=0.0):
    """一维稳态热传导有限差分求解,返回节点坐标与温度。"""
    dx = L / N
    x = np.linspace(0.0, L, N + 1)
    n_int = N - 1                      # 内部未知量个数

    # 组装三对角矩阵 A (n_int × n_int) 与右端向量 b
    A = np.zeros((n_int, n_int))
    b = np.zeros(n_int)
    for i in range(n_int):
        A[i, i] = -2.0
        if i > 0:
            A[i, i - 1] = 1.0
        if i < n_int - 1:
            A[i, i + 1] = 1.0
    # 边界贡献移入右端项
    b[0]   -= T0      # 左边界 T_0 已知
    b[-1]  -= TL      # 右边界 T_N 已知

    T_int = np.linalg.solve(A, b)
    T = np.empty(N + 1)
    T[0], T[-1] = T0, TL
    T[1:-1] = T_int
    return x, T

def analytic(x, L=1.0, T0=100.0, TL=0.0):
    return T0 + (TL - T0) * x / L

# 验证:不同网格密度下的最大节点误差
for N in [4, 8, 16, 32]:
    x, T = solve_1d_steady(N)
    err = np.max(np.abs(T - analytic(x)))
    print(f"N={N:3d}  dx={1.0/N:.4f}  max|T_num - T_exact| = {err:.3e}")

预期输出(示例运行结果,非实测):

N=  4  dx=0.2500  max|T_num - T_exact| = 0.000e+00
N=  8  dx=0.1250  max|T_num - T_exact| = 0.000e+00
N= 16  dx=0.0625  max|T_num - T_exact| = 0.000e+00
N= 32  dx=0.0312  max|T_num - T_exact| = 0.000e+00
节点误差为机器精度量级(约 1e-14 以下)说明离散格式与边界处理正确。若出现非零误差,优先检查:① 边界项是否从矩阵移入右端;② 内部节点索引是否覆盖 1…N−1;③ 矩阵对角是否为 −2、邻对角是否为 +1。

边界条件处理的两种写法对比

除上述“消元法”(把边界值移到右端)外,也可保留完整 (N+1)×(N+1) 矩阵并对边界行直接置单位行。两种写法结果一致,但后者更易扩展到 Neumann 或 Robin 边界。下表给出关键差异:

写法矩阵规模边界行处理适用场景
消元法(N−1)×(N−1)边界值移入 b纯 Dirichlet,追求最小规模
完整矩阵法(N+1)×(N+1)边界行置单位行,b 置边界值混合边界、便于统一扩展

完整矩阵法核心片段:

A = np.zeros((N + 1, N + 1))
b = np.zeros(N + 1)
for i in range(1, N):
    A[i, i-1], A[i, i], A[i, i+1] = 1.0, -2.0, 1.0
A[0, 0] = 1.0;  b[0] = T0
A[N, N] = 1.0;  b[N] = TL
T = np.linalg.solve(A, b)

精度验证与判据

对第一类边界的一维稳态问题,中心差分格式在节点上无截断误差累积,数值解应与解析解在机器精度内一致。验证时建议同时检查:

  • 节点最大绝对误差:应 ≤ 1e-12(双精度)。
  • 线性度:相邻节点温差应恒为 (T_L − T₀)/N,可用 np.diff(T) 检查其标准差。
  • 能量守恒:通过任一截面的热流 q = −k·dT/dx 应处处相等。
若把边界条件误写成“边界节点也参与中心差分”(即对 i=0 使用 T_{−1}),会引入虚拟节点并导致解偏移。第一类边界必须显式固定边界节点值,不得让其成为未知量。