This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Iterative solver for 2D Stokes equation with weak boundary condition

0 votes

I have a simple Stokes equation with a weak boundary condition on the pressure on one frontier. The code runs and results are satisfying when using a direct solver but when using an iterative solver (I took the example demo_stokes-iterative.py that runs on many other geometries) it does not converge anymore.

mesh = Mesh("Mesh2D.xml")
File("maillage2D.pvd")<<mesh

Define function spaces

V1 = FiniteElement("Lagrange",mesh.ufl_cell(),2)
V2 = FiniteElement("Lagrange",mesh.ufl_cell(),2)
P = FiniteElement("Lagrange",mesh.ufl_cell(),1)
M = MixedElement([[V1,V2], P])
W = FunctionSpace(mesh, M)

Np = 10
Lp = 2.5
Rp = 0.5
Lr = 8
Rr = 4

P0 = -1.
nu=1.
tol = 1e-6

Boundaries

def b1(x, on_boundary): return on_boundary and near(x[1], -Rp, tol)
def b2(x, on_boundary): return on_boundary and near(x[0], Lp, tol) and (x[1]<=-Rp)
def b3(x,on_boundary): return on_boundary and near(x[1], -Rr,tol)
def b4(x, on_boundary): return on_boundary and near(x[0], Lp+Lr, tol)
def b5(x,on_boundary): return on_boundary and near(x[1], Rr, tol)
def b6(x,on_boundary): return on_boundary and near(x[0],Lp,tol) and (x[1]>=Rp)
def b7(x, on_boundary): return on_boundary and near(x[1], Rp, tol)
def b8(x,on_boundary): return on_boundary and near (x[0], 0, tol)
def bound(x,on_boundary): return on_boundary

No-slip boundary condition for velocity

noslip = project(Constant((0.0, 0.0)), W.sub(0).collapse())
bc1 = DirichletBC(W.sub(0), noslip, b1)
bc7 = DirichletBC(W.sub(0), noslip, b7)

slip boundary condition for velocity u.n = 0

slip = project(Constant(0.), W.sub(0).sub(0).collapse())
bc2 = DirichletBC(W.sub(0).sub(0), slip, b2)
bc6 = DirichletBC(W.sub(0).sub(0),slip, b6)

collect boundary conditions

bcs = [bc1,bc2,bc6,bc7]

class fsi_boundary(SubDomain):
def inside(self, x,on_boundary):
return on_boundary and near(x[0], 0, tol)

define measure dsS

fsimarkers = FacetFunction("size_t", mesh)
fsimarkers.set_all(0)
fsibound = fsi_boundary()
fsibound.mark(fsimarkers, 8)
dsS = Measure('ds', domain=mesh, subdomain_data = fsimarkers)

Define variational problem

normal = project(Constant((1.,0.)), W.sub(0).collapse())
(u, p) = TrialFunctions(W)
(v, q) = TestFunctions(W)
w= Function(W)
f = Constant((0.0, 0.0))
a = nuinner(sym(grad(u)), sym(grad(v)))dx - pdiv(v)dx + qdiv(u)dx
L = inner(f, v)dx + Constant(P0) dot(v,normal)*dsS(8)

Form for use in constructing preconditioner matrix

b = inner(sym(grad(u)), sym(grad(v)))dx +pq*dx

Assemble system

A, bb = assemble_system(a, L, bcs)

Assemble preconditioner system

P, btmp = assemble_system(b, L, bcs)

Create Krylov solver and AMG preconditioner

solver = KrylovSolver(krylov_method, "amg")

Associate operator (A) and preconditioner matrix (P)

solver.set_operators(A, P)

Solve

solver.solve(w.vector(), bb)

Get sub-functions

u, p = w.split(True)

asked Jul 6, 2017 by jfromdalembert FEniCS Novice (120 points)
...