Source code for firedrake.norms
from ufl import inner, div, grad, curl, dx
from firedrake.assemble import assemble
from firedrake import function
from firedrake.logging import warning
from firedrake.petsc import PETSc
__all__ = ['errornorm', 'norm']
[docs]
@PETSc.Log.EventDecorator()
def errornorm(u, uh, norm_type="L2", degree_rise=None, mesh=None):
"""Compute the error :math:`e = u - u_h` in the specified norm.
:arg u: a :class:`.Function` or UFL expression containing an "exact" solution
:arg uh: a :class:`.Function` containing the approximate solution
:arg norm_type: the type of norm to compute, see :func:`.norm` for
details of supported norm types.
:arg degree_rise: ignored.
:arg mesh: an optional mesh on which to compute the error norm
(currently ignored).
"""
urank = len(u.ufl_shape)
uhrank = len(uh.ufl_shape)
if urank != uhrank:
raise RuntimeError("Mismatching rank between u and uh")
if not isinstance(uh, function.Function):
raise ValueError("uh should be a Function, is a %r", type(uh))
if isinstance(u, function.Function):
degree_u = u.function_space().ufl_element().degree()
degree_uh = uh.function_space().ufl_element().degree()
if degree_uh > degree_u:
warning("Degree of exact solution less than approximation degree")
return norm(u - uh, norm_type=norm_type, mesh=mesh)
[docs]
@PETSc.Log.EventDecorator()
def norm(v, norm_type="L2", mesh=None):
r"""Compute the norm of ``v``.
:arg v: a ufl expression (:class:`~.ufl.classes.Expr`) to compute the norm of
:arg norm_type: the type of norm to compute, see below for
options.
:arg mesh: an optional mesh on which to compute the norm
(currently ignored).
Available norm types are:
- Lp :math:`||v||_{L^p} = (\int |v|^p)^{\frac{1}{p}} \mathrm{d}x`
- H1 :math:`||v||_{H^1}^2 = \int (v, v) + (\nabla v, \nabla v) \mathrm{d}x`
- Hdiv :math:`||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\nabla\cdot v, \nabla \cdot v) \mathrm{d}x`
- Hcurl :math:`||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\nabla \wedge v, \nabla \wedge v) \mathrm{d}x`
"""
typ = norm_type.lower()
p = 2
if typ == 'l2':
expr = inner(v, v)
elif typ.startswith('l'):
try:
p = int(typ[1:])
if p < 1:
raise ValueError
except ValueError:
raise ValueError("Don't know how to interpret %s-norm" % norm_type)
expr = inner(v, v)
elif typ == 'h1':
expr = inner(v, v) + inner(grad(v), grad(v))
elif typ == "hdiv":
expr = inner(v, v) + inner(div(v), div(v))
elif typ == "hcurl":
expr = inner(v, v) + inner(curl(v), curl(v))
else:
raise RuntimeError("Unknown norm type '%s'" % norm_type)
return assemble((expr**(p/2))*dx)**(1/p)