Quadrature rules

To numerically compute the integrals in the variational formulation, a quadrature rule is required. By default, Firedrake obtains a quadrature rule by estimating the polynomial degree of the integrands within a ufl.Form. Sometimes this estimate might be quite large, and a warning like this one will be raised:

tsfc:WARNING Estimated quadrature degree 13 more than tenfold greater than any argument/coefficient degree (max 1)

For integrals with very complicated nonlinearities, the estimated quadrature degree might be in the hundreds or thousands, rendering the integration prohibitively expensive, or leading to segfaults.

Specifying the quadrature rule in the variational formulation

To manually override the default, the quadrature degree can be prescribed on each integral Measure,

inner(sin(u)**4, v) * dx(degree=4)

Setting degree=4 means that the quadrature rule will be exact only for integrands of total polynomial degree up to 4. This, of course, will introduce a greater numerical error than the default.

For integrals that do not specify a quadrature degree, the default may be keyed as "quadrature_degree" in the form_compiler_parameters dictionary passed on to solve(), project(), or NonlinearVariationalProblem.

F = inner(grad(u), grad(v))*dx(degree=0) + inner(exp(u), v)*dx - inner(1, v)*dx

solve(F == 0, u, form_compiler_parameters={"quadrature_degree": 4})

In the example above, only the integrals with unspecified quadrature degree will be computed on a quadrature rule that exactly integrates polynomials of the degree set in form_compiler_parameters.

Another way to specify the quadrature rule is through the scheme keyword. This could be either a QuadratureRule, or a string. Supported string values are "default", "canonical", and "KMV". For more details see create_quadrature().

Lumped quadrature schemes

Spectral elements, such as Gauss-Legendre-Lobatto and KMV, may be used with lumped quadrature schemes to produce a diagonal mass matrix.

degree = 3
V = FunctionSpace(mesh, "KMV", degree)
u = TrialFunction(V)
v = TestFunction(V)

a = inner(u, v) * dx(scheme="KMV", degree=degree)

Note

To obtain the lumped mass matrix with scheme="KMV", the degree argument should match the degree of the FiniteElement.

The Quadrature space

It is possible to define a finite element Function on a quadrature rule. The "Quadrature" and "Boundary Quadrature" spaces are useful to interpolate data at quadrature points on cell interiors and cell boundaries, respectively.

Q = FunctionSpace(mesh, "Quadrature", degree=quad_degree, quad_scheme=quad_scheme)

The quad_scheme keyword argument again may be either QuadratureRule or a string. If a Function in the "Quadrature" space appears within an integral, Firedrake will automatically select the quadrature rule that corresponds to dx(degree=quad_degree, scheme=quad_scheme) to match the one associated with the quadrature space.

Specifying the quadrature for integral-type degrees of freedom

Finite element spaces with integral-type degrees of freedom support different quadrature rules. These are selected by passing a string to the "quad_scheme" keyword argument of the FiniteElement or FunctionSpace() constructors. For example, to construct a Crouzeix-Raviart space with degrees of freedom consisting of integrals along the edges computed from a 2-point average at the endpoints, one can set quad_scheme="KMV":

fe = FiniteElement("Crouzeix-Raviart", triangle, 1, variant="integral", quad_scheme="KMV")

Note

Finite elements with integral-type degrees of freedom only accept string values for quad_scheme, since it does not make sense to specify a concrete QuadratureRule when the degrees of freedom are defined on cell entities of different dimensions.