4. 有限差分法离散一维泊松方程

一维泊松方程的标准形式为

−u″(x) = f(x),  x ∈ (0, L),  u(0) = a,  u(L) = b

其中 f(x) 是已知源项,u(x) 是待求函数,a、b 为两端狄利克雷边界值。本节围绕“如何把连续的微分方程变成可计算的代数方程组”展开:先推导三点差分格式,再分析截断误差,然后处理边界条件,最后用一个可手算的算例走通全流程。全文约定 x 轴向右为正,网格节点从左到右编号 i = 0, 1, …, N,步长 h = L/N,节点坐标 xi = i·h。

一、三点差分格式的推导

在内部节点 xi 处,把 u(xi±h) 分别做泰勒展开:

u(xi+h) = ui + h·u′i + h²/2·u″i + h³/6·u‴i + h⁴/24·u⁗i + …

u(xi−h) = ui − h·u′i + h²/2·u″i − h³/6·u‴i + h⁴/24·u⁗i − …

两式相加,一阶导数项与三阶导数项相消,得到二阶中心差分:

u″i = (ui−1 − 2ui + ui+1) / h² + O(h²)

代入 −u″ = f,得到内部节点的三点差分方程:

−ui−1 + 2ui − ui+1 = h²·fi,  i = 1, 2, …, N−1

每个内部节点只与左右相邻节点耦合,因此 N−1 个未知量 u1…uN−1 构成一个三对角线性方程组。写成矩阵形式为 A·U = F,其中 A 的主对角线全为 2,次对角线与超对角线全为 −1,右端项 Fi = h²·fi,边界值 u0 = a、uN = b 移到右端后并入 F1 与 FN−1。该矩阵严格对角占优,方程组有唯一解,可用追赶法(Thomas 算法)以 O(N) 复杂度求解。

二、截断误差分析

把上面两式相减可得一阶导数中心差分,而二阶导数的截断误差需保留到四阶项。将两式相加后除以 h²:

(ui−1 − 2ui + ui+1)/h² = u″i + h²/12·u⁗i + O(h⁴)

因此局部截断误差 τi = h²/12·u⁗(ξi),格式具有二阶精度。这带来两个实用结论:其一,步长减半时误差约缩小为原来的四分之一,可用“网格加密误差比接近 4”来验证实现是否正确;其二,误差与解的四阶导数成正比,若源项 f 变化剧烈或解曲率大,粗网格上的误差会明显偏大,需要更细的网格或更高阶格式。

验证技巧:用同一算例分别取 h 与 h/2 计算,若最大节点误差之比接近 4,说明差分格式与边界处理实现基本正确;若比值接近 2 或 1,往往意味着边界条件处理有误或右端项缩放(h² 因子)写错。

三、边界条件的处理

狄利克雷边界最简单:u0、uN 已知,直接移入右端项,不参与求解。例如 i = 1 的方程变为 2u1 − u2 = h²f1 + a,i = N−1 的方程变为 −uN−2 + 2uN−1 = h²fN−1 + b。

若边界给定的是导数(诺伊曼条件),则需引入虚拟节点。以左端 u′(0) = g 为例,在 x0 处用中心差分 u′(0) ≈ (u1 − u−1)/(2h) = g,得 u−1 = u1 − 2hg。再对 i = 0 写三点方程 −u−1 + 2u0 − u1 = h²f0,消去 u−1 后得到 2u0 − 2u1 = h²f0 − 2hg。这样边界节点也进入方程组,矩阵仍保持三对角结构,只是首行元素变为 (2, −2)。这种虚拟节点法保持二阶精度,优于把边界导数用单侧一阶差分硬代入的做法。

四、简单算例

取 L = 1,f(x) = 1,边界 u(0) = 0、u(1) = 0。该问题的解析解为 u(x) = x(1−x)/2,便于对照误差。取 N = 4,则 h = 0.25,h² = 0.0625,内部节点 i = 1, 2, 3,右端项均为 0.0625。

方程组为:

2u1 − u2        = 0.0625 + 0 = 0.0625
−u1 + 2u2 − u3  = 0.0625
       −u2 + 2u3 = 0.0625 + 0 = 0.0625

由对称性 u1 = u3,代入解得 u2 = 0.09375,u1 = u3 = 0.078125。与解析解对比:x = 0.25 处精确值 0.09375,x = 0.5 处精确值 0.125。可见节点值存在偏差,最大误差出现在中点,约 0.03125。若把 N 加密到 8,h² 变为 0.015625,误差应约降为原来的四分之一,这正是二阶收敛的体现。

三点差分格式:节点耦合与边界处理 u₀=a x₀ u₁ x₁ u₂ x₂ u₃ x₃ u₄=b x₄ −uᵢ₋₁ + 2uᵢ − uᵢ₊₁ = h²fᵢ 狄利克雷边界(已知值) u₀ = a 直接移入右端项 i=1: 2u₁ − u₂ = h²f₁ + a i=N−1: −uₙ₋₂ + 2uₙ₋₁ = h²fₙ₋₁ + b 边界节点不进入未知量 诺伊曼边界(虚拟节点) u′(0)=g ⇒ u₋₁ = u₁ − 2hg 代入 i=0 方程消去 u₋₁ 得 2u₀ − 2u₁ = h²f₀ − 2hg 矩阵首行变为 (2, −2),仍三对角

从算例可以看出,离散求解的完整链条是:确定网格与步长 → 组装三对角矩阵与右端项 → 处理边界 → 用追赶法求解 → 与解析解或加密网格结果对比验证。实际编程时,右端项务必乘上 h²,边界值务必正确并入首末方程,这两处是最常见的错误来源。截断误差分析则告诉我们:当结果与参考解偏差较大时,优先检查网格是否足够细,而不是盲目怀疑算法本身。