I’m trying to evaluate the dot product of a tensor with the surface normal on a curved boundary.
import dolfin as df
import mshr as ms
import matplotlib.pyplot as plt
circle = ms.Circle(df.Point(0,0), 1.0, 18)
mesh = ms.generate_mesh(circle, 18)
bmesh = df.BoundaryMesh(mesh, 'exterior')
TFS = df.TensorFunctionSpace(bmesh, 'P', 1)
sigma = df.Function(TFS)
sigma.interpolate(df.Expression(
(('x[0]','x[0]*x[1]'),('x[0]*x[1]','x[1]')),
degree=1))
VFS = df.VectorFunctionSpace(bmesh, 'P', 1)
normal = df.interpolate(
df.Expression(
('x[0]/sqrt(x[0]*x[0]+x[1]*x[1])',
'x[1]/sqrt(x[0]*x[0]+x[1]*x[1])'),
degree=1), VFS)
ex = df.interpolate(df.Constant((1,0)), VFS)
ey = df.interpolate(df.Constant((0,1)), VFS)
force = df.project(df.dot(sigma, normal), VFS)
fx = df.project(df.dot(sigma, ex), VFS)
fy = df.project(df.dot(sigma, ey), VFS)
force_exact = df.interpolate(
df.Expression(
('x[0]*(x[0]+x[1]*x[1])/sqrt(x[0]*x[0]+x[1]*x[1])',
'x[1]*(x[0]*x[0]+x[1])/sqrt(x[0]*x[0]+x[1]*x[1])'),
degree=1), VFS)
fx_exact = df.interpolate(
df.Expression(('x[0]', 'x[0]*x[1]'), degree=1), VFS)
fy_exact = df.interpolate(
df.Expression(('x[0]*x[1]', 'x[1]'), degree=1), VFS)
err = force.compute_vertex_values() - force_exact.compute_vertex_values()
err_x = fx.compute_vertex_values() - fx_exact.compute_vertex_values()
err_y = fy.compute_vertex_values() - fy_exact.compute_vertex_values()
fig, (ax1, ax2, ax3) = plt.subplots(1,3, figsize=(12,5))
ax1.hist(err)
ax2.hist(err_x)
ax3.hist(err_y)
plt.show()
This produces the figure
The errors when evaluating the dot product of the tensor with a constant vector are at machine precision while the errors when the tensor is dotted with a non-constant vector (in this case the surface normal of a curved boundary) are way large.
Why is this? Am I doing a mistake or is this the best that one can obtain?