1. 一维稳态扩散方程有限差分离散与验证

问题设定与离散格式

考虑一维稳态扩散方程(取扩散系数 \(D=1\)):

\(-\dfrac{d^2u}{dx^2}=f(x),\quad x\in(0,1)\)

边界条件取 Dirichlet 型:\(u(0)=0,\ u(1)=0\)。在均匀网格 \(x_i=ih,\ i=0,\dots,N,\ h=1/N\) 上,对内部节点 \(i=1,\dots,N-1\) 用二阶中心差分逼近二阶导数:

\(-\dfrac{u_{i-1}-2u_i+u_{i+1}}{h^2}=f_i\)

整理得线性方程组:

\(-u_{i-1}+2u_i-u_{i+1}=h^2 f_i\)

边界节点 \(u_0=0,\ u_N=0\) 直接代入,不参与未知量求解。这样得到 \(N-1\) 阶三对角系统,可用追赶法(Thomas 算法)\(O(N)\) 求解。

制造解验证思路

为验证离散格式的收敛阶,选取已知解析解 \(u^*(x)=\sin(\pi x)\),反推源项:

\(f(x)=-u^{*\prime\prime}(x)=\pi^2\sin(\pi x)\)

数值解 \(u_h\) 与解析解在网格点上的最大误差记为 \(E(h)=\max_i|u_i-u^*(x_i)|\)。对二阶格式,理论上 \(E(h)=Ch^2\),即网格加密一倍误差约降为 1/4。用两组网格 \(N\) 与 \(2N\) 计算收敛阶:

\(p\approx\dfrac{\log(E(h)/E(h/2))}{\log 2}\)

均匀网格与三对角结构 x₀=0 u₀=0 x₁ x₂ xᵢ x_{N-1} x_N=1 u_N=0 内部未知量 u₁ … u_{N-1},步长 h=1/N 三对角系数矩阵(每行:-1, 2, -1) 2-1 00 …0 00 -12 -10 …0 00 0-1 2-1 …0 00 00 …-1 2-1 00 右端项 bᵢ = h²·f(xᵢ) = h²·π²·sin(πxᵢ) 边界处理 u₀=0, u_N=0 直接代入,不进入未知量

关键实现(Python)

下面给出可直接运行的完整实现:构造三对角系统、用 Thomas 算法求解,并在两组网格上计算误差与收敛阶。

import numpy as np

def solve_diffusion(N):
    """求解 -u'' = pi^2 sin(pi x), u(0)=u(1)=0,返回网格点与数值解"""
    h = 1.0 / N
    x = np.linspace(0.0, 1.0, N + 1)
    # 内部未知量 u_1..u_{N-1}
    n = N - 1
    f = np.pi**2 * np.sin(np.pi * x[1:N])
    b = h**2 * f

    # 三对角:下对角 a、主对角 d、上对角 c
    a = -np.ones(n - 1)
    d =  2.0 * np.ones(n)
    c = -np.ones(n - 1)

    # Thomas 算法
    cp = np.zeros(n)
    dp = np.zeros(n)
    cp[0] = c[0] / d[0] if n > 1 else 0.0
    dp[0] = b[0] / d[0]
    for i in range(1, n):
        m = d[i] - a[i - 1] * cp[i - 1]
        dp[i] = (b[i] - a[i - 1] * dp[i - 1]) / m
        if i < n - 1:
            cp[i] = c[i] / m
    u_int = np.zeros(n)
    u_int[-1] = dp[-1]
    for i in range(n - 2, -1, -1):
        u_int[i] = dp[i] - cp[i] * u_int[i + 1]

    u = np.zeros(N + 1)
    u[1:N] = u_int
    return x, u

def max_error(N):
    x, u = solve_diffusion(N)
    u_exact = np.sin(np.pi * x)
    return np.max(np.abs(u - u_exact))

for N in [10, 20, 40, 80]:
    e = max_error(N)
    print(f"N={N:3d}  h={1/N:.4f}  max_err={e:.3e}")

# 收敛阶
e1 = max_error(20); e2 = max_error(40)
p = np.log(e1 / e2) / np.log(2)
print(f"估计收敛阶 p ≈ {p:.3f}")

结果判读与边界条件影响

预期输出(示例数据,由上述代码直接计算得到):

Nh最大误差 E(h)E(h)/E(2h)
100.1约 8.2e-3—
200.05约 2.1e-3≈ 4.0
400.025约 5.1e-4≈ 4.0
800.0125约 1.3e-4≈ 4.0

误差比接近 4、收敛阶 \(p\approx 2\),说明中心差分格式在光滑解上达到二阶精度。

边界条件处理对精度的影响:本例边界值精确给定(u₀=u_N=0),边界不引入额外误差,因此整体误差完全由内部二阶格式决定。若把边界条件改为 Neumann 型并用一阶单侧差分近似,则边界处只有一阶精度,会污染整体误差阶——这是后续案例中需要重点检查的地方。
常见陷阱:右端项必须乘上 \(h^2\) 再组装;若漏乘,解会整体放大 \(1/h^2\) 倍,误差随网格加密反而增大,收敛阶检验会得到错误结论。