非线性变分问题之FEniCS求解
非线性变分问题之FEniCS求解
bxplosion【本文仅是视频中Markdown文件内容,不包括视频中讲解】
如果你希望和我一样Win10上安装FEniCS,建议采用Win10 + WSL2 + Ubuntu。
非线性变分问题之FEniCS求解
- 第1讲 有限元法求解偏微分方程之FEniCS入门讲解
- (上一讲)第2讲 混合形式泊松方程之FEniCS求解
本讲要点
- 非线性变分问题的表述
- 变分问题的离散化
- 求解非线性泊松方程
非线性变分问题
前面2讲都是线性偏微分方程。变换得到线性变分问题:寻求\(u\in V\),满足 \[ a(u, v) = L(v) \qquad \forall v\in \hat{V} \] 类似地,非线性变分问题表述为:寻求\(u\in V\),满足 \[ \textcolor{red}{F(u; v)} = 0 \qquad \forall v\in \hat{V} \] 我们的目标是:将这个非线性的变分问题,从局部转换为线性问题。
变分问题的离散化
要解决上面这个目标,首先不妨将变分问题离散化,这样可以看清楚之间的关系。
我们通过限制一对离散的试探和测试空间来离散化此变分问题,寻求\(\textcolor{red}{u\in V_h} \subset V\),满足 \[ F(u_h; v) = 0 \qquad \forall \textcolor{red}{v\in \hat{V}_h} \subset \hat{V} \] 其中,\(F(\textcolor{red}{u_h;}v)\)是一个半线性形式,分号后的参数中是线性的。
可将离散试探函数\(u_h\)展开为(同时离散测试函数\(v\)可取): \[ \boxed{u_h = \sum^N_{j=1} U_j\phi_j} \\ v = \hat{\phi}_i,\quad i=1,\dots,N \] 其中:\(\{\phi_j\}^N_{j=1}\)是离散试探空间\(V_h\)的基底;\(\{\hat{\phi}_i\}^N_{i=1}\)则是离散测试空间\(\hat{V}_h\)的基底。
带入到前面这个离散化变分问题,得到一个关于N元变量非线性方程组: \[ b_i(U_1,\dots,U_N)\overset{\Delta}{=}F(u_h; \hat{\phi}_i) = 0,\quad i=1,\dots,N \] 或写成矢量方程的形式: \[ b(U)=0 \] 可用牛顿法或牛顿法的某些变体来求解这种非线性方程组。为此,要计算雅可比矩阵\(A=b'\)。
我们注意到,如果半线性形式\(F\)对\(u\)是可微的,那么雅可比矩阵\(A\)的各项可以写出: \[ A_{ij}(u_h)=\frac{\partial b_i(U)}{\partial U_i}=\frac{\partial}{\partial U_i}F(u_h;\hat{\phi}_i)=F'(u_h;\hat{\phi}_i)\phi_j\overset{\Delta}{=}F'(u_h;\textcolor{red}{\phi_j,\hat{\phi}_i}) \] 我们注意到:对每个固定的\(u_h\),\(a=F'(u_h;\cdot,\cdot)\)是双线性形式,并且\(L=F(u_h;\cdot)\)是线性形式。
因此,在每次牛顿迭代中,我们都是求解标准形式的线性变分问题:需求\(\textcolor{red}{\delta u \in V_{h,0}}\),满足 \[ a(\delta u,v) = L(v) \qquad \forall v\in \hat{V}_h \\ a(\delta u,v) = F'(u_h;\delta u,v) \\ L(v) = -F(u_h;v) \] 其中,\(\delta u\)是每次迭代的更新增量;\(V_{h,0}=\{v-w:v,w\in V_h\}\)。
【结论】
- 1)线性变分问题,在离散化后,就是求解一个线性方程组。
- 2)非线性变分问题,在离散化后,得到非线性方程组。可用牛顿法时,每次迭代的更新增量,实际上就是一个线性变分问题。
非线性泊松方程的求解
例如,考虑以下非线性泊松方程 \[ -\nabla\cdot[\textcolor{red}{(1+u)}\nabla u] = f \quad \text{in } \Omega \\ u|_{\Gamma_D}=u_0 \qquad \text{ on } \Gamma_D\\ \left.\frac{\partial u}{\partial n}\right|_{\Gamma_N}=g \qquad \text{ on } \Gamma_N \] 首先,按第1讲的套路,变换成 变分方程: \[ \int_\Omega (1+u)\nabla u \cdot \nabla v dx = \int_\Omega f v dx + \int_{\Gamma_N} (1+u)g v ds \] 写成前面非线性变分问题形式的等式左边: \[ \boxed{F(u;v) = \int_\Omega (1+u)\nabla u \cdot \nabla v dx - \int_\Omega f v dx - \int_{\Gamma_N} (1+u)g v ds} \] 输入函数,域和边界的设定:
- \(\Omega=[0,1]×[0,1]\) (一个单位矩形)
- \(\Gamma_D=\{(1,y)\subset\partial \Omega\}\)(Dirichlet边界)
- \(\Gamma_N=\{(x,0)\cup(x,1)\cup(0,y)\subset\partial \Omega\}\) (Neumann边界)
- \(g=0\) (法向导数)
- \(f=x\sin(y)\) (源项)
于是就可以写代码求解了
1 | from dolfin import * |
END