This code computes the solution of Poisson equation with Neumann boundary conditions on the hemisphere using the mixed formulation. (The needed mesh file can be downloaded from here.) The code works great if the Neumann condition is homogeneous, but not if it is inhomogeneous. What am I doing wrong?
"""
Douglas N. Arnold 2014-03-03
This program solves the mixed Poisson equation
u = -grad p, -div u + c0 = -f, int p = 0
with Neumann (essential) boundary conditions on a hemispherical surface.
The constant c0 (equal to the mean value of f) is the Lagrange multiplier
to enforce the side condition that the mean value of p vanishes.
"""
from dolfin import *
from numpy import log
# forcing function
f = Expression("exp(-10.*(pow(x[0], 2) + pow(x[1]-1/sqrt(2.), 2) + pow(x[2]-1/sqrt(2.), 2)))")
mesh = Mesh("hemisphere_mesh.xml")
global_normal = Expression(("x[0]", "x[1]", "x[2]"))
mesh.init_cell_orientations(global_normal)
# finite element mesh and spaces
V0 = FunctionSpace(mesh, "RT", 3)
V1 = FunctionSpace(mesh, "DG", 2)
R = FunctionSpace(mesh, "Real", 0)
V = MixedFunctionSpace([V0, V1, R])
# essential boundary condition
def bdry(x, on_boundary):
return on_boundary
# homogeneous BC works
#bc = DirichletBC(V.sub(0), Constant((0., 0., 0.0)), bdry)
# but inhomogeneous does not (examine computed vector field at boundary)
bc = DirichletBC(V.sub(0), Constant((0., 0., 0.1)), bdry)
# trial and test functions
(u, p, c0) = TrialFunctions(V)
(v, q, c1) = TestFunctions(V)
# bilinear form, right hand side
a = (dot(u, v) - p*div(v) - div(u)*q + c0*q + p*c1) * dx
L = -f*q * dx
# assemble, solve
up = Function(V)
solve(a == L, up, bc)
(u, p, c0) = up.split()
up = project(u, VectorFunctionSpace(mesh, "CG", 1))
# plot the scalar variable
plot(up, interactive=True)