Projection

The projection_l2! function sets the dof values of an FEFunction from the L2-projection of a field onto its FESpace — typically to initialize a solution from an analytical expression, or to obtain the dofs of a lazy expression such as the limited field returned by linear_scaling_limiter.

Note that cell_mean is a specialized L2-projection onto the piecewise-constant space, used to compute the mean value of a field in each cell.

Bcube.projection_l2! — Function
projection_l2!(u::AbstractSingleFieldFEFunction, f, mesh::AbstractMesh)
projection_l2!(u::AbstractSingleFieldFEFunction, f, mesh::AbstractMesh, degree::Int)
projection_l2!(u::AbstractSingleFieldFEFunction, f, dΩ::Measure; mass = nothing)
projection_l2!(u::MultiFieldFEFunction, f, args...; mass = nothing)

Set the dof values of u — in place — from the L2-projection of f onto the FESpace of u, i.e. the dof values solve:

\[ ∫(u ⋅ v)dΩ = ∫(f ⋅ v)dΩ, ∀v\]

where v spans the test space associated with the FESpace of u. The integrals are evaluated with the quadrature rule of the cell Measure dΩ; for a discontinuous FESpace the mass matrix is block-diagonal and the projection is local to each cell.

When a mesh is provided instead of a measure, dΩ is built internally on CellDomain(mesh) with the quadrature degree degree — 2d+1 by default, where d is the degree of the FunctionSpace of u. This degree makes the integrals exact for products of two degree-d polynomials — e.g. f ⋅ v with f polynomial of degree d — which are of degree 2d.

Compared to the nodal initialization FEFunction(fes, mesh, f) — which requires a nodal FunctionSpace and simply evaluates f at the dof nodes — projection_l2! computes the L2-optimal dof values and accepts any lazy expression on any FESpace.

Arguments

  • u: the FEFunction whose dof values are computed (modified in place). It can also be a MultiFieldFEFunction, in which case f must be a tuple of lazy expressions (one per field) and the projection is applied field by field.
  • f: the field to project; it must be an AbstractLazy expression — e.g. a PhysicalFunction, an FEFunction or a combination of lazy operators — and not a plain Julia function.
  • mesh: the mesh on which the measure dΩ is built (it covers the whole CellDomain).
  • degree: the quadrature degree of the measure built from mesh (default 2d+1).
  • dΩ: the cell Measure used to evaluate both integrals.

Keyword arguments

  • mass: a precomputed matrix — or, better, a Factorization, e.g. obtained with factorize from LinearAlgebra — for the left-hand term $∫(u ⋅ v)dΩ$. This is useful when the projection is repeated with the same FESpace and measure, e.g. at each time step of an explicit scheme. Note that if u is a MultiFieldFEFunction, then mass must be a Tuple of the mass matrices of each FESpace constituting the MultiFESpace of u (and not the mass matrix of the whole MultiFESpace).

Returns

nothing: u is modified in place.

Examples

mesh = rectangle_mesh(20, 4)
fes = TrialFESpace(FunctionSpace(:Lagrange, 2), mesh) # continuous P2
u = FEFunction(fes)

# the measure is built internally, with the quadrature degree 2d+1 = 5
projection_l2!(u, PhysicalFunction(x -> x[1]^2 + x[2]^2), mesh)

# or explicitly, e.g. to share the same measure between several projections
dΩ = Measure(CellDomain(mesh), 5)
projection_l2!(u, PhysicalFunction(x -> x[1]^2 + x[2]^2), dΩ)
source