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

Compatible projections onto the boundary mesh

+2 votes

Hello,

I have been trying to find a way around the following problem:

Given a scalar field $ \omega $ defined in a 2D mesh, I wish to compute the form \( ( \nabla \times \omega ) \times \vec{n} \) on the boundary mesh, for the purpose of solving a 1D ODE further on.

$\nabla\times\omega\times\vec{n}$ along the boundary will be a DG function. I would expect to be able to reconstruct it exactly using DG basis functions along the boundary.

I have attempted to do this using CG and DG elements, as can be observed in the example code I have included below. Difficulties arise when considering the components of the normal vector $\vec{n}$ on the boundary mesh. I have had to define two expressions which correspond with the components of $\vec{n}$, such that I can compute the tangential component of $\nabla \times \omega$.

However, I have found that errors appear on the corners, probably because I do not distinguish between the different normal vectors of each adjacent element to the corner.

I would really appreciate if somebody could suggest a better way of carrying out this computation, as I am out of ideas at the moment. How can the components of the normal vector to the mesh be included in an integration along the boundary mesh?

Thank you very much.

Gonzalo

from dolfin import *

# Discretization parameters
p = 2
N = 20

# Arbitrary scalar field
w_exp = Expression('x[0]*sin(2*pi*x[0]*x[1])', degree = p)

# Generation of mesh
mesh = UnitSquareMesh(N,N,'left')
n = FacetNormal(mesh)
n_perp = as_vector((n[1], -n[0]))

# Definition of function spaces
W = FunctionSpace(mesh,'CG',p)
P = FunctionSpace(mesh,'DG',p)

# Interpolate scalar field
w = interpolate(w_exp, W)

# Integrate tangential component of curl w along the boundary
curlw_tang = dot(curl(w), n_perp)
integral_1 = dolfin.assemble(curlw_tang*ds)
print 'Integral of curlw_tang along boundary :: ' + str(integral_1)

# Initialize boundary mesh
boundary_mesh = BoundaryMesh(mesh, "exterior")   

# Initialize Discontinous Lagrange elements on boundary
P_b = FunctionSpace(boundary_mesh, 'DG', p)

# Project components of curlw onto P
curlw_x = project(curl(w)[0],P)
curlw_y = project(curl(w)[1],P)

# Project components of curlw onto P_b
curlw_x_b = interpolate(curlw_x, P_b)
curlw_y_b = interpolate(curlw_y, P_b)

# Define components of outwards facing normal vector as dolfin expressions
class n1_exp(Expression):
    def __init__(self, degree = 0):
        self.degree = degree

    def eval(self, value, x):
        if x[0] == 0: # Left boundary
            value[0] = -1
        elif x[0] == 1: # Right boundary
            value[0] = 1
        else:
            value[0] = 0        

class n2_exp(Expression):
    def __init__(self, degree = 0):
        self.degree = degree
    def eval(self, value, x):
        if x[1] == 0: # Lower boundary
            value[0] = -1
        elif x[1] == 1: # Upper boundary
            value[0] = 1
        else:
            value[0] = 0


n1_b = n1_exp(degree = 0)
n2_b = n2_exp(degree = 0)

# Integrate tangential component of w_b (defined in boundary mesh) along the boundary
curlw_tang_b = project(curlw_x_b*n2_b - curlw_y_b*n1_b, P_b)
integral_2 = dolfin.assemble(curlw_tang_b*dx)
print 'Integral of curlw_tang_b along boundary :: ' + str(integral_2)  
asked Mar 14, 2017 by gonzalogddiego FEniCS Novice (140 points)
edited Mar 15, 2017 by gonzalogddiego
...