有限元学习有限元法求解偏微分方程之FEniCS入门讲解
bxplosionFEniCS入门讲解(求解泊松方程)
FEniCS
是一个有限元法求解偏微分方程的开源计算平台。
- 泊松方程
- 将泊松方程转化成(弱)变分形式
- 求解微分方程边值问题(1维泊松方程)
- 求解2维泊松方程
ParaView
中查看解
泊松方程
第一个例子自然是求解著名的泊松方程。
将泊松方程转化成(弱)变分形式
首先:对泊松方程两边都乘上测试函数,然后对全域积分。
这里需要说明一下试探函数
和测试函数
的概念。
测试函数,定义为:
试探函数,定义为:
然后,对上面这个变分方程进行变换
左边是双线性形式,右边是线性形式:
于是得到标准的变分问题:寻求,满足
这就是和前面的泊松问题等价的变分问题。
求解微分方程边值问题(1维泊松方程)
有了前面的准备,现在可以写代码求解了。
第一步:为求解域创建网格,并定义函数空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from dolfin import *
nel = 20
xmin = 0 xmax = 1
p = 2
mesh = IntervalMesh(nel,xmin,xmax)
V = FunctionSpace(mesh,"CG",p)
|
第二步:定义已提供的表达式
1 2 3
| u0 = Constant(0) f = Constant(-1) g = Constant(1)
|
第三步:创建和应用Dirichlet
边界条件
1 2 3 4 5
| def dirichlet_boundary(x, on_boundary): return on_boundary and abs(x[0]) < DOLFIN_EPS
bc = DirichletBC(V,u0,dirichlet_boundary)
|
第四步:定义变分问题
1 2 3 4 5
| u = TrialFunction(V) v = TestFunction(V)
a = inner(grad(u),grad(v))*dx L = f*v*dx+g*v*ds
|
第五步:求解并绘图
1 2 3 4 5 6
| u = Function(V) solve(a == L, u, bc)
plot(u)
|
求解2维泊松方程
-
(一个单位矩阵)
- (Dirichlet边界)
- (Neumann边界)
- (法向导数)
-
(源项)
类似地,也分五步求解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from dolfin import *
mesh = UnitSquareMesh(32, 32) V = FunctionSpace(mesh, "Lagrange", 1)
u0 = Constant(0.0) f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=2) g = Expression("sin(5*x[0])", degree=2)
def boundary(x): return x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS bc = DirichletBC(V, u0, boundary)
u = TrialFunction(V) v = TestFunction(V) a = inner(grad(u), grad(v))*dx L = f*v*dx + g*v*ds
u = Function(V) solve(a == L, u, bc) plot(u)
|
ParaView
中查看解
1 2 3
| file = File("poisson.pvd") file << u
|
【结束】