diff --git a/src/image.jl b/src/image.jl index eb4486707118feae875d74ce7556d731505a8df4..10e3740e74bc7a52896bf6bf2b43800a39fdaa5b 100644 --- a/src/image.jl +++ b/src/image.jl @@ -443,6 +443,66 @@ function project_l2_pixel!(u::FeFunction, img) return u end +""" + compute_local_error(u::FeFunction, img) + +Compute for every cell the squared L2-error between the mesh function `u` and +the image `img`. +Integrals are evaluated with a Lagrange quadrature rule with order dependent on +the current cell diameter. Image point evaluations use bilinear interpolations. +""" +function compute_local_error(u::FeFunction, img) + d = 2 + space = u.space + mesh = space.mesh + + nrdims = prod(space.size) + # number of element dofs (i.e. local dofs not counting codomain dimensions) + nldofs = ndofs(space.element) + + space_indicator = FeSpace(mesh, DP0(), (1,)) + err = FeFunction(space_indicator; name = "err") + + for cell in cells(mesh) + bind!(u, cell) + bind!(err, cell) + # cell map is assumed to be constant per cell + delmap = jacobian(elmap(mesh, cell), SA[0., 0.]) + delmapinv = inv(delmap) + intel = abs(det(delmap)) + + p = ceil(Int, diam(mesh, cell)) + qw, qx = quadrature_composite_lagrange_midpoint(p) + nqpts = length(qw) # number of quadrature points + + qphi = zeros(nrdims, nrdims, nldofs, nqpts) + dqphi = zeros(nrdims, d, nrdims, nldofs, nqpts) + for k in axes(qx, 2) + for r in 1:nrdims + qphi[r, r, :, k] .= evaluate_basis(space.element, SVector{d}(view(qx, :, k))) + dqphi[r, :, r, :, k] .= transpose(jacobian(x -> evaluate_basis(space.element, x), SVector{d}(view(qx, :, k)))) + end + end + + # quadrature points + for k in axes(qx, 2) + xhat = SVector{d}(view(qx, :, k)) + x = elmap(mesh, cell)(xhat) + + # TODO: support more dimensions, evaluate_bilinear needs rework + u_val = first(evaluate(u, xhat)) + img_val = evaluate_bilinear(img, x) + + err_val = qw[k] * (u_val - img_val)^2 * intel + + gdofs = space.dofmap[:, 1, cell] + err.data[gdofs] .= err_val + end + + end + return err +end + function save_csv(path, img::AbstractArray{<:Any,2}) df = DataFrame() for ci in CartesianIndices(img)