Hi, as an alternative to Kent's answer consider the following. You might get a meaningful answer from errornorm
even if the exact solution is not an Expression
. It can be sufficient that it is represented in some higher order space. You can compute expansion coefficients of such a function manually and sympy
has tools to speed up the process.
from sympy import symbols, lambdify, besselj
from scipy.special import jv as scipy_besselj
from dolfin import *
mesh = UnitCubeMesh(20, 20, 20)
# Space where the exact solution is represented
Ve = FunctionSpace(mesh, 'DG', 4)
dof_x = Ve.dofmap().tabulate_all_coordinates(mesh).reshape((-1, 3))
X, Y, Z = dof_x[:, 0], dof_x[:, 1], dof_x[:, 2]
# Suppose the solution is besselj(1, x[0]) + besselj(2, x[1]) + besselj(3, x[2])
x, y, z = symbols('x, y, z')
u = besselj(1, x) + besselj(2, y) + besselj(3, z)
u_lambda = lambdify([x, y, z], u, {'besselj': scipy_besselj})
# Interpolate manually
timer = Timer('eval')
timer.start()
u_values = u_lambda(X, Y, Z)
print 'Evaluated %d dofs in % s' % (Ve.dim(), timer.stop())
# Exact solution in Ve
u = Function(Ve)
u.vector()[:] = u_values
# Solution space and the hypot. numerical solution
V = FunctionSpace(mesh, 'CG', 1)
uh = interpolate(Constant(1), V)
print errornorm(u, uh)
Code above evaluates u_lamba
1.68 million times. On my machine this takes about 3.5 seconds.