See for instance: Error control: Computing convergence rates — FEniCSx tutorial
or:
Test problem 1: Channel flow (Poiseuille flow) — FEniCSx tutorial
ref
import numpy as np
def u_exact(x):
values = np.zeros((2, x.shape[1]), dtype=PETSc.ScalarType)
values[0] = 4*x[1]*(1.0 - x[1])
return values
u_ex = Function(V)
u_ex.interpolate(u_exact)
L2_error = form(dot(u_ - u_ex, u_ - u_ex)*dx)
# do stuff
# ....
for i in range(num_steps):
# Solve problem
#....
# Compute error at current time-step
error_L2 = np.sqrt(mesh.comm.allreduce(assemble_scalar(L2_error), op=MPI.SUM))
I would also like to note that you do not need the project functionality for computing the error “pointwise”, i.e.
could be handled with dolfinx.fem.Expression
and interpolate, see for instance: Problem with grad and interpolate - #2 by dokken
I am also not sure why you do not just call
error_normalized = (u_ref - u_approx) / u_ref
error_total = sqrt(assemble(inner(error_normalized, error_normalized) * dx))
in DOLFIN, or the equivalent version of it in DOLFINx.