一维泊松方程的有限元方法实现与理论分析
有限元方法作为求解偏微分方程的重要数值技术,其核心思想是将连续问题离散化为有限自由度系统。本文以典型的一维泊松方程为例,系统阐述有限元方法的理论基础和Python实现细节,揭示其数学本质与计算特性。
问题描述与微分方程
考虑定义在区间Ω=[0,L]\Omega = [0,L]Ω=[0,L]上的一维泊松方程边值问题:
{−d2udx2=f(x),x∈(0,L)u(0)=0,u(L)=0 \begin{cases} -\dfrac{d^2u}{dx^2} = f(x), & x \in (0,L) \\ u(0) = 0, \quad u(L) = 0 \end{cases} ⎩⎨⎧−dx2d2u=f(x),u(0)=0,u(L)=0x∈(0,L)
其中u(x)u(x)u(x)是未知场函数,f(x)f(x)f(x)为给定的源项。该方程在热传导、弹性力学等领域具有广泛应用,其解析解可通过两次积分得到:
uexact(x)=−∫0x(∫0ξf(η)dη)dξ+C1x+C2 u_{exact}(x) = -\int_0^x \left( \int_0^\xi f(\eta) d\eta \right) d\xi + C_1x + C_2 uexact(x)=−∫0x(∫0ξf(η)dη)dξ+C1x+C2
当f(x)=1f(x)=1f(x)=1时,解析解简化为uexact(x)=−12x2+L2xu_{exact}(x) = -\frac{1}{2}x^2 + \frac{L}{2}xuexact(x)=−21x2+2Lx,这一特例将作为我们验证数值解正确性的基准。
弱形式推导与变分原理
经典微分形式要求解具有二阶导数,这限制了解的适用范围。通过引入弱形式,我们可以放宽对解的光滑性要求。选择测试函数空间v∈V={v∈H1(Ω)∣v(0)=v(L)=0}v \in \mathcal{V} = \{ v \in H^1(\Omega) | v(0)=v(L)=0 \}v∈V={v∈H1(Ω)∣v(0)=v(L)=0},其中H1H^1H1为一阶Sobolev空间。
将微分方程乘以测试函数vvv并在域内积分:
−∫0Lvd2udx2dx=∫0Lvfdx -\int_0^L v \frac{d^2u}{dx^2} dx = \int_0^L v f dx −∫0Lvdx2d2udx=∫0Lvfdx
应用分部积分法则处理二阶导数项:
∫0Ldvdxdudxdx−[vdudx]0L=∫0Lvfdx \int_0^L \frac{dv}{dx} \frac{du}{dx} dx - \left[ v \frac{du}{dx} \right]_0^L = \int_0^L v f dx ∫0Ldxdvdxdudx−[vdxdu]0L=∫0Lvfdx
由于vvv在边界处为零,自然得到弱形式表述:
a(u,v)=ℓ(v),∀v∈V a(u,v) = \ell(v), \quad \forall v \in \mathcal{V} a(u,v)=ℓ(v),∀v∈V
其中双线性形式a(u,v)=∫0Ldudxdvdxdxa(u,v) = \int_0^L \frac{du}{dx} \frac{dv}{dx} dxa(u,v)=∫0Ldxdudxdvdx,线性形式ℓ(v)=∫0Lvfdx\ell(v) = \int_0^L v f dxℓ(v)=∫0Lvfdx。这种形式只需解uuu具有一阶导数,显著扩展了容许解空间。
有限元离散化过程
将求解域Ω\OmegaΩ离散为nnn个子区间(单元),节点坐标为x0=0,x1,...,xn=Lx_0=0, x_1, ..., x_n=Lx0=0,x1,...,xn=L。定义有限元空间Vh⊂V\mathcal{V}_h \subset \mathcal{V}Vh⊂V由分段线性函数组成:
Vh={vh∈C0(Ω)∣vh∣[xi,xi+1]∈P1,vh(0)=vh(L)=0} \mathcal{V}_h = \{ v_h \in C^0(\Omega) | v_h|_{[x_i,x_{i+1}]} \in \mathbb{P}_1, v_h(0)=v_h(L)=0 \} Vh={vh∈C0(Ω)∣vh∣[xi,xi+1]∈P1,vh(0)=vh(L)=0}
其中P1\mathbb{P}_1P1表示一次多项式空间。引入形函数Ni(x)N_i(x)Ni(x)(又称"帐篷函数"):
Ni(x)={x−xi−1hi−1,x∈[xi−1,xi]xi+1−xhi,x∈[xi,xi+1]0,其他 N_i(x) = \begin{cases} \frac{x-x_{i-1}}{h_{i-1}}, & x \in [x_{i-1},x_i] \\ \frac{x_{i+1}-x}{h_i}, & x \in [x_i,x_{i+1}] \\ 0, & \text{其他} \end{cases} Ni(x)=⎩⎨⎧hi−1x−xi−1,hixi+1−x,0,x∈[xi−1,xi]x∈[xi,xi+1]其他
近似解表示为形函数的线性组合:
uh(x)=∑j=1n−1ujNj(x) u_h(x) = \sum_{j=1}^{n-1} u_j N_j(x) uh(x)=j=1∑n−1ujNj(x)
将uhu_huh代入弱形式,并取vh=Niv_h=N_ivh=Ni,得到离散方程组:
∑j=1n−1uj∫0LdNidxdNjdxdx=∫0LNifdx,i=1,...,n−1 \sum_{j=1}^{n-1} u_j \int_0^L \frac{dN_i}{dx} \frac{dN_j}{dx} dx = \int_0^L N_i f dx, \quad i=1,...,n-1 j=1∑n−1uj∫0LdxdNidxdNjdx=∫0LNifdx,i=1,...,n−1
这对应于线性代数系统Ku=FK\mathbf{u} = \mathbf{F}Ku=F,其中:
Kij=∫0LdNidxdNjdxdx,Fi=∫0LNifdx K_{ij} = \int_0^L \frac{dN_i}{dx} \frac{dN_j}{dx} dx, \quad F_i = \int_0^L N_i f dx Kij=∫0LdxdNidxdNjdx,Fi=∫0LNifdx
单元矩阵计算与组装策略
对于均匀网格hi=hh_i = hhi=h,典型单元[xi,xi+1][x_i,x_{i+1}][xi,xi+1]上的局部形函数为:
N1e(ξ)=1−ξ/h,N2e(ξ)=ξ/h N_1^e(\xi) = 1-\xi/h, \quad N_2^e(\xi) = \xi/h N1e(ξ)=1−ξ/h,N2e(ξ)=ξ/h
其导数矩阵为:
dN1edx=−1h,dN2edx=1h \frac{dN_1^e}{dx} = -\frac{1}{h}, \quad \frac{dN_2^e}{dx} = \frac{1}{h} dxdN1e=−h1,dxdN2e=h1
因此单元刚度矩阵为:
ke=∫xixi+1[dN1edxdN2edx][dN1edxdN2edx]dx=1h[1−1−11] k^e = \int_{x_i}^{x_{i+1}} \begin{bmatrix} \frac{dN_1^e}{dx} \\ \frac{dN_2^e}{dx} \end{bmatrix} \begin{bmatrix} \frac{dN_1^e}{dx} & \frac{dN_2^e}{dx} \end{bmatrix} dx = \frac{1}{h}\begin{bmatrix} 1 & -1 \\ -1 & 1 \end{bmatrix} ke=∫xixi+1[dxdN1edxdN2e][dxdN1edxdN2e]dx=h1[1−1−11]
单元载荷向量采用梯形公式近似:
fe≈h2[f(xi)f(xi+1)] f^e \approx \frac{h}{2} \begin{bmatrix} f(x_i) \\ f(x_{i+1}) \end{bmatrix} fe≈2h[f(xi)f(xi+1)]
全局矩阵通过直接刚度法组装,每个单元贡献叠加到对应全局位置。例如3节点2单元系统:
K=1h[1−10−12−10−11],F=h2[f(x0)f(x0)+2f(x1)+f(x2)f(x2)] K = \frac{1}{h}\begin{bmatrix} 1 & -1 & 0 \\ -1 & 2 & -1 \\ 0 & -1 & 1 \end{bmatrix}, \quad F = \frac{h}{2}\begin{bmatrix} f(x_0) \\ f(x_0)+2f(x_1)+f(x_2) \\ f(x_2) \end{bmatrix} K=h11−10−12−10−11,F=2hf(x0)f(x0)+2f(x1)+f(x2)f(x2)
边界条件处理与求解
Dirichlet边界条件u(0)=u(L)=0u(0)=u(L)=0u(0)=u(L)=0通过修改矩阵系统实现。设总自由度为n+1n+1n+1,则:
- 划去对应于固定节点的行列(第1行/列和第n+1行/列)
- 修改右端项:Fi←Fi−Ki,1u0−Ki,n+1un+1F_i \leftarrow F_i - K_{i,1}u_0 - K_{i,n+1}u_{n+1}Fi←Fi−Ki,1u0−Ki,n+1un+1
剩余系统Kreduint=FredK_{red}\mathbf{u}_{int} = \mathbf{F}_{red}Kreduint=Fred通过直接法或迭代法求解。最终解向量在边界点补零。
Python实现与数值验证
以下完整实现采用NumPy进行矩阵运算,支持常数或函数形式的源项:
import numpy as np
import matplotlib.pyplot as pltdef solve_poisson_fem(L=1.0, n_elements=4, f=1.0):"""求解一维泊松方程 -u'' = f 在[0,L]区间,边界条件u(0)=u(L)=0参数:L : 区域长度n_elements : 单元数量f : 源项(常数或函数)"""# 1. 离散化nodes = np.linspace(0, L, n_elements + 1)h = L / n_elements# 2. 初始化全局矩阵K = np.zeros((n_elements + 1, n_elements + 1))F = np.zeros(n_elements + 1)# 3. 组装单元矩阵for i in range(n_elements):# 单元节点编号node1 = inode2 = i + 1# 单元刚度矩阵 (线性单元)ke = np.array([[1/h, -1/h], [-1/h, 1/h]])# 单元载荷向量if callable(f):# 如果f是函数,使用高斯积分fe = np.array([f((nodes[node1] + nodes[node2])/2) * h/2,f((nodes[node1] + nodes[node2])/2) * h/2])else:# 如果f是常数fe = np.array([f * h/2, f * h/2])# 组装到全局矩阵K[np.ix_([node1, node2], [node1, node2])] += keF[[node1, node2]] += fe# 4. 施加边界条件 (u0=0, un=0)# 划去第一行/列和最后一行/列K_reduced = K[1:-1, 1:-1]F_reduced = F[1:-1] - K[1:-1, 0] * 0 - K[1:-1, -1] * 0# 5. 求解方程组u_interior = np.linalg.solve(K_reduced, F_reduced)u = np.zeros(n_elements + 1)u[1:-1] = u_interiorreturn nodes, u# 解析解 (用于验证)
def exact_solution(x, L=1.0, f=1.0):return -0.5 * f * x**2 + 0.5 * f * L * x# 计算数值解和解析解
L = 1.0
n_elements = 4
nodes, u_fem = solve_poisson_fem(L, n_elements, f=1.0)# 生成解析解
x_exact = np.linspace(0, L, 100)
u_exact = exact_solution(x_exact, L)# 可视化
plt.figure(figsize=(10, 6))
plt.plot(nodes, u_fem, 'ro-', label='FEM Solution')
plt.plot(x_exact, u_exact, 'b-', label='Exact Solution')
plt.xlabel('x')
plt.ylabel('u(x)')
plt.title(f'1D Poisson Equation FEM Solution (Elements={n_elements})')
plt.legend()
plt.grid(True)
plt.show()# 输出数值解
print("节点坐标:", nodes)
print("有限元解:", u_fem)
验证结果表明,当f(x)=1f(x)=1f(x)=1,L=1L=1L=1,4单元离散时,数值解与解析解在节点处完全一致:
节点坐标: [0. 0.25 0.5 0.75 1. ]
有限元解: [0. 0.09375 0.125 0.09375 0. ]
理论分析与扩展方向
有限元方法的收敛性由Céa引理保证:
∥u−uh∥H1≤Cinfvh∈Vh∥u−vh∥H1 \|u - u_h\|_{H^1} \leq C \inf_{v_h \in \mathcal{V}_h} \|u - v_h\|_{H^1} ∥u−uh∥H1≤Cvh∈Vhinf∥u−vh∥H1
对于线性元,能量范数误差满足O(h)O(h)O(h)收敛率,L2L^2L2范数误差为O(h2)O(h^2)O(h2)。实际计算中可通过Richardson外推或后验误差估计量化误差。
扩展方向包括:
- 高阶单元:采用二次/三次形函数提升精度
- 自适应网格:基于误差指示器动态优化网格分布
- 非线性问题:引入Newton-Raphson迭代方案
- 多维扩展:三角形/四边形单元处理二维问题
有限元方法通过其严谨的数学基础和灵活的离散化策略,成为工程数学中不可或缺的数值工具,其实现过程完美体现了"从连续到离散"的计算数学哲学。