隐式法数值求解泊松方程
上次在《不动点迭代法数值求解泊松方程》和《不动点迭代法数值求解热传导方程》中讲到不动点迭代法效率特别低,这次讲在 Mathematica 中使用隐式法数值求解微分方程。该方法是一种通用数值算法,非线性方程组、常微分方程组、偏微分方程组、甚至刚性问题,无论是初值问题(initial value problem)还是边值问题(boundary value problem),都可以使用隐式法求解。如此精妙的算法我都舍不得分享😂
隐式法数值求解一维泊松方程
还是考虑普遍的形式:
并考虑边值条件:
将 x 的范围从 0 到 1 分割成 100 份:
In[]:=
1 | h = 0.01; |
边值条件,以及使用前面讲的离散化方法写出差分方程组:
In[]:=
1 | u[0] = 0; u[n] = 0; |
该方程组为非线性方程组,下面讲两种求解方法。第一种利用 NSolve[]
函数:
In[]:=
1 | NSolve[equations, Map[u, Range[1, n - 1]]] |
上面方程组不太难,所以可以使用 NSolve[]
函数求解。但是对于高度非线性的方程组来说,NSolve[]
无法给出解,所以下面讲第二种方法,利用 FindRoot[]
函数求解。FindRoot[]
函数需要猜测一个初始值,下次讲到牛顿法(Newton’s method)就知道为什么需要初始值。
In[]:=
1 | try = Table[{u[i], 0.5}, {i, 1, n - 1}]; |
Out[]:=
下面画出了解析解和数值解的对比:
In[]:=
1 | Show[{ListPlot[Transpose[{xGrid, Table[u[i], {i, 0, n}] /. sol}]], |
Out[]:=
隐式法数值求解二维泊松方程
考虑普遍的形式:
并考虑狄利克雷边界条件:
离散求解区域:
In[]:=
1 | dx = 0.02; |
边值条件,以及离散化形成差分方程组:
In[]:=
1 | equations = Flatten[ |
利用 FindRoot[]
函数求解:
In[]:=
1 | try = Flatten[Table[{u[i, j], 0.5}, {i, 1, nx}, {j, 1, ny}], 1]; |
Out[]:=
下面画出数值解:
In[]:=
1 | uuSol = Flatten[Table[{xGrid[[i]], yGrid[[j]], u[i, j] /. sol}, {i, nx}, {j, ny}], 1]; |
Out[]:=
牛顿法
FindRoot[]
函数内置了很多数值求解方程组的方法,可以使用 Method-> 指定。我们前面已经讲了二分法和不动点迭代法,下次介绍牛顿法(Newton’s method)。
请大家多多关注、点赞、收藏、转发,这一章绝对干货满满,以后会分享更多实用的算法。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Who Am I!
评论
ValineDisqus