Dear all,
I am struggling with implementing Nitsche’s method. Given the Poisson equation
\nabla^2 u = f \textrm{ in } \Omega
u = u_D \textrm{ in } \partial \Omega
where \Omega is the unit square, I can succesfully solve this by implementing the boundary condition with Nitsche’s method, here is a minimal working example:
from __future__ import print_function
from fenics import *
import matplotlib.pyplot as plt
import argparse
import numpy as np
from mshr import *
import matplotlib.pyplot as plt
import meshio
import ufl as ufl
i, j = ufl.indices(2)
parser = argparse.ArgumentParser()
args = parser.parse_args()
xdmffile_u = XDMFFile("u.xdmf")
# Create mesh
channel = Rectangle(Point(0, 0), Point(1.0, 1.0))
domain = channel
alpha = Constant(10.0)
h = Constant(2.0)
mesh = generate_mesh(domain, 16)
n = FacetNormal(mesh)
V = FunctionSpace(mesh, 'P', 8)
O = VectorFunctionSpace(mesh, 'P', 8, dim=2)
u = Function(V)
u_D = Function(V)
v = TestFunction(V)
f = Function(V)
class u_expression(UserExpression):
def eval(self, values, x):
values[0] =cos(x[0])**2 + 2*sin(x[0]+x[1])**4
def value_shape(self):
return (1,)
class laplacian_u_expression(UserExpression):
def eval(self, values, x):
# values[0] = 6.0
values[0] = - 2 * (cos(2 * x[0]) - 4 * cos(2 * (x[0]+x[1])) + 4 * cos(4 * (x[0]+x[1])))
def value_shape(self):
return (1,)
f = interpolate(laplacian_u_expression(element=V.ufl_element()), V)
u_D = interpolate(u_expression(element=V.ufl_element()), V)
# Define variational problem
#this is the ordinary variational functional
F_0 = dot(grad(u), grad(v))*dx + f*v*dx + ( - n[i]*(u.dx(i)) * v ) * ds
#this is the term that enforces the BCs with Nitsche's method
F_BC = ( ( + alpha/h*(u - u_D ) ) * v + n[i]*(v.dx(i))*(u-u_D) ) * ds
F = F_0 + F_BC
solve(F == 0, u)
xdmffile_u.write(u, 0)
Notice that I added to the variational functional the terms \alpha/h (u - u_D) \, \nu \, ds and n^i \partial_i \nu (u - u_D) \, ds, where \alpha is the large-enough parameter in Nitsche’s method, h the radius of the smallest circle containing \Omega, and \nu the test function.
Now I would like to implement, with the same method, the BC
n^i \partial_i u = u_D \textrm{ on } \partial \Omega.
What are the terms that I should add to the variational functional to achieve this? And why?
Thank you !