学习了《不动点迭代法数值求解方程》以及《微分方程离散化》之后,所有的知识就已经齐备。我们可以尝试使用不动点迭代法来求解泊松方程了,下面以一维泊松方程为例,最后附以二维泊松方程的离散化。


泊松方程

泊松方程是一个重要的椭圆形偏微分方程,广泛应用于物理和数学领域。泊松方程以法国数学家和物理学家 Siméon Denis Poisson 的名字命名。泊松方程在电势场、引力场、热传导、流体力学等领域中都有广泛的应用。例如,在电势场、引力场中,泊松方程可以用来描述电势、引力势满足的方程。在热传导中,泊松方程可以用来表示温度分布。在流体力学中,泊松方程可以用来描述速度势或压力场。

通常泊松方程表示为

这里 代表的是拉普拉斯算子 为已知函数,而 为未知函数。当 时,就会变成一个齐次方程,被称为拉普拉斯方程

泊松方程可以用格林函数法,也可以使用分离变量法、特征线法求解,还可以使用其他数值方法求解,如有限差分法、有限元法、谱方法等。下面介绍 Mathematica 数值求解一维泊松方程作为示例。


Mathematica 数值求解一维泊松方程

考虑一个更普遍的形式:

并考虑常微分方程或偏微分方程的“第一类边界条件”——狄利克雷边界条件(Dirichlet boundary condition):

该方程有解析解,使用 Mathematica 的 DSolve[] 函数可以求出该方程的解析解:

In[]:=
1
2
3
uSol = DSolveValue[{
u''[x] + u'[x] + u[x] + x == 0, u[0] == 0, u[1] == 0
}, u[x], {x, 0, 1}]
Out[]:=

使用前面讲的离散化方法,将 写成差分形式,一阶导使用:

二阶导使用:

这样微分方程变为:


不动点迭代法需要找出 这样的形式进行迭代,因此我们求解出

In[]:=
1
2
3
Solve[(u[i + 1] - 2 u[i] + u[i - 1])/h^2 + 
(u[i + 1] - u[i - 1])/(2 h) + u[i] + x == 0,
u[i]] // Simplify
Out[]:=

我们可以使用这个式子迭代求解。将 x 的范围从 0 到 1 分割成 100 份:

In[]:=
1
2
3
4
h = 0.01;
n = Floor[1/h]
xGrid = Range[0, 1, h];
uu = Table[0., n+1];

u 的解用 uu 表示,迭代的初始值均为 0,当然也可以设置为其它值。但要注意的是边界条件为狄利克雷边界条件,,在 Mathematica 中 uu[[1]],uu[[-1]] 代表这两个值。下面的计算中,边界条件这两个值保持不变。


In[]:=
1
2
Do[uu[[2 ;; -2]] = (-2 h^2 xGrid[[2 ;; -2]] + (h - 2) uu[[;; -3]] 
- (h + 2) uu[[3 ;;]])/(2 (h^2 - 2)), 10000]

迭代了 10000 次,下面画出了解析解和数值解的对比。作为演示故意少迭代了几次,使数值解看起来和解析解有一定的误差,当然迭代次数变多之后误差会变小。

In[]:=
1
2
Show[{ListPlot[Transpose[{xGrid, uu}]],
Plot[uSol[x], {x, 0, 1}, PlotStyle -> Red]}]
Out[]:=

离散化

对于二维的泊松方程

采用二阶导差分形式可以得到:

以后讲到二维偏微分方程(特别是数值求解 纳维-斯托克斯(Navier-Stokes)方程)时,会继续使用该形式。