This is a numerical roundoff in the generated code (for the projection forms). Actually it is not that bad. One should maybe measure the error as w.vector()[:].norm('linf')/v.vector().norm('linf')
. One can also tweak form compiler parameters to get get some improvement.
>>> w = project(-grad( v ), VectorFunctionSpace(mesh, "CG", 2), form_compiler_parameters={})
>>> print w.vector()[:].norm('linf')/v.vector().norm('linf')
3.71706040551e-13
>>> w = project(-grad( v ), VectorFunctionSpace(mesh, "CG", 2), form_compiler_parameters={'precision': 17})
>>> print w.vector()[:].norm('linf')/v.vector().norm('linf')
3.30199902966e-13
>>> w = project(-grad( v ), VectorFunctionSpace(mesh, "CG", 2), form_compiler_parameters={'precision': 17, 'epsilon': 1e-20})
>>> print w.vector()[:].norm('linf')/v.vector().norm('linf')
1.3903806388e-13
>>> w = project(-grad( v ), VectorFunctionSpace(mesh, "CG", 2), form_compiler_parameters={'precision': 17, 'epsilon': 1e-20, 'representation': 'uflacs'})
>>> print w.vector()[:].norm('linf')/v.vector().norm('linf')
1.88949719446e-14