I have a rectangle defined by mesh = RectangleMesh(Point(0.0, 0.0), Point(5.0, 0.1), 200, 200, "right/left")
. The top boundary is marked as 3 and the bottom boundary is marked as 4. The problem is to find the unit tangent vectors to the top and the bottom boundaries and then interpolate those unit tangent vectors to the interior nodes which we will call the “interior tangent vectors”.
In the below MWE, I am able to successfully calculate the unit tangent vectors to the top and bottom boundaries. However, when I am trying to interpolate those to the interior nodes, there are two problems:
- The direction of the interior tangent vectors are random. That is, some are pointing in the positive X direction while some are pointing in the negative X direction. But the tangent vectors at the top and the bottom boundaries are all oriented in the negative X direction.
- The magnitude of the tangent vectors on the top and the bottom boundaries before interpolation are 1. But after interpolation, the magnitudes are no longer 1 on the surface as well as on the boundaries.
MWE:
from dolfin import *
# Creating Rectangular mesh #
mesh = RectangleMesh(Point(0.0, 0.0), Point(5.0, 0.1), 200, 200, "right/left")
# Defining the boundaries of the rectangle #
class bottom(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and near(x[1], 0, tol)
class top(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and near(x[1], 0.1, tol)
class left(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and near(x[0], 0, tol)
class right(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and near(x[0], 5.0, tol)
# Defining boundary markers, surface and boundary measures #
boundary_markers = MeshFunction("size_t", mesh, mesh.topology().dim()-1, 0)
surface_markers = MeshFunction("size_t", mesh, mesh.topology().dim(), 0)
top().mark(boundary_markers, 3)
bottom().mark(boundary_markers, 4)
left().mark(boundary_markers, 1)
right().mark(boundary_markers, 2)
ds_custom = Measure("ds", domain=mesh, subdomain_data=boundary_markers)
dx_custom = Measure("dx", domain=mesh, subdomain_data=surface_markers)
# Finding unit tangent vectors to the top and bottom boundaries #
n = FacetNormal(mesh)
t = as_vector([-n[1], n[0]])
V = VectorFunctionSpace(mesh, "CG", 1)
u = TrialFunction(V)
v = TestFunction(V)
a = inner(u,v)*ds_custom(3) + inner(u,v)*ds_custom(4)
l = inner(t, v)*ds_custom(3) + inner(-t,v)*ds_custom(4)
A = assemble(a, keep_diagonal=True)
L = assemble(l)
A.ident_zeros()
tangent_boundary = Function(V)
solve(A, tangent_boundary.vector(), L)
tangent_boundary.rename('tangent_boundary','tangent_boundary')
File("tangent_boundary.pvd") << tangent_boundary
# Interpolating the unit tangent vectors on the top and bottom boundaries to the surface #
u1 = TrialFunction(V)
v1 = TestFunction(V)
a1 = inner(u1,v1)*dx_custom()
l1 = inner(tangent_boundary, v1)*ds_custom(3) + inner(tangent_boundary, v1)*ds_custom(4)
A1 = assemble(a1, keep_diagonal=True)
L1 = assemble(l)
A1.ident_zeros()
tangent_surface = Function(V)
solve(A1, tangent_surface.vector(), L1)
tangent_surface.rename('tangent_surface','tangent_surface')
File("tangent_surface.pvd") << tangent_surface
Results from Paraview:
- Unit tangent vectors on the top and bottom boundaries (just showing a few glyphs):
- Non-unit tangent vectors with different orientations when interpolated to the surface:
I want unit tangent vectors on the surface with all vectors oriented in the direction of the unit tangent vectors defined on the top and the bottom boundaries as shown in Result 1.
I am not sure what I am missing or doing wrong here.
Please advise.
Thanks in advance!