32. Stokes Equation#
The Stokes equation is the basic model for incompressible fluids. While several terms of the advanced Navier-Stokes equations are skipped, the Stokes equation allows to study the difficulty of incompressibility constraints.
The unknown fields are
The Stokes equation is a system of equations
with a given force density
32.1. Variational Formulation#
The weak form is : Find
The pressure is defined up to a constant, and the divergence equation is satisfied for constant test-functions, anyway. Thus, we need the space
32.2. Finite Element Spaces#
We discretize the Stokes equation by different finite element spaces. For the velocity we use continuous,
We try different combinations of finite element spaces for
from ngsolve import *
from ngsolve.webgui import Draw
mesh = Mesh(unit_square.GenerateMesh(maxh=0.05))
Use continuous elements of order
V = VectorH1(mesh, order=2, dirichlet=".*")
Q = L2(mesh, order=0)
X = V * Q
def SolveStokes(X):
u,p = X.TrialFunction()
v,q = X.TestFunction()
a = BilinearForm(X)
a += (InnerProduct(grad(u),grad(v))+div(u)*q+div(v)*p)*dx
# a += -1e-10*p*q*dx
a.Assemble()
a.mat[X.components[0].ndof,X.components[0].ndof]+=-1 # fixing pressure in one point
f = LinearForm( (x-0.5)*v[1]*dx).Assemble()
gfu = GridFunction(X)
gfu.vec.data = a.mat.Inverse(X.FreeDofs()) * f.vec
return gfu
gfu = SolveStokes(X)
Draw (gfu.components[0], mesh, "velocity")
Draw (gfu.components[1], mesh, "pressure");
Try a
V = VectorH1(mesh, order=2, dirichlet=".*")
Q = L2(mesh, order=1)
X = V*Q
gfu = SolveStokes(X)
Draw (gfu.components[0], mesh, "velocity")
Draw (gfu.components[1], mesh, "pressure");
---------------------------------------------------------------------------
NgException Traceback (most recent call last)
Cell In[5], line 4
2 Q = L2(mesh, order=1)
3 X = V*Q
----> 4 gfu = SolveStokes(X)
5 Draw (gfu.components[0], mesh, "velocity")
6 Draw (gfu.components[1], mesh, "pressure");
Cell In[3], line 13, in SolveStokes(X)
10 f = LinearForm( (x-0.5)*v[1]*dx).Assemble()
12 gfu = GridFunction(X)
---> 13 gfu.vec.data = a.mat.Inverse(X.FreeDofs()) * f.vec
14 return gfu
NgException: UmfpackInverse: Numeric factorization failed.
V = VectorH1(mesh, order=2, dirichlet=".*")
V.SetOrder(TRIG,3)
V.Update()
Q = L2(mesh, order=1)
X = V*Q
gfu = SolveStokes(X)
Draw (gfu.components[0], mesh, "velocity")
Draw (gfu.components[1], mesh, "pressure");
The Taylor Hood element
V = VectorH1(mesh, order=2, dirichlet=".*")
Q = H1(mesh, order=1)
X = V*Q
gfu = SolveStokes(X)
Draw (gfu.components[0], mesh, "velocity")
Draw (gfu.components[1], mesh, "pressure");
We see that the pressure space must not be too rich, otherwise we obtain a singular system (or a bad solutions, in particular for the pressure).