Select Git revision
function.jl 9.80 KiB
using Statistics: mean
using StaticArrays: SA, SArray, MVector, MMatrix
export FeSpace, Mapper, FeFunction, P1, DP0, DP1
export interpolate!, sample, bind!, evaluate, integrate, nabla
# Finite Elements
struct P1 end
struct DP0 end
struct DP1 end
ndofs(::P1) = 3
ndofs(::DP0) = 1
ndofs(::DP1) = 3
# FIXME: should be static vectors
# evaluate all (1-dim) local basis functions against x
evaluate_basis(::P1, x) = SA[1 - x[1] - x[2], x[1], x[2]]
evaluate_basis(::DP0, x) = SA[1]
evaluate_basis(::DP1, x) = evaluate_basis(P1(), x)
# non-mixed
# scalar elements
struct FeSpace{M, Fe, S}
mesh::M
element::Fe
dofmap::Array{Int, 3} # (rdim, eldof, cell) -> gdof
ndofs::Int # = maximum(dofmap)
end
function FeSpace(mesh, el::P1, size_=(1,))
# special case for P1: dofs correspond to vertices
rdims = prod(size_)
dofmap = Array{Int, 3}(undef, rdims, 3, ncells(mesh))
for i in CartesianIndices((rdims, 3, ncells(mesh)))
dofmap[i] = rdims * (mesh.cells[i[2], i[3]] - 1) + i[1]
end
return FeSpace{typeof(mesh), typeof(el), size_}(
mesh, el, dofmap, rdims * nvertices(mesh))
end
function FeSpace(mesh, el::DP0, size_=(1,))
# special case for DP1: dofs correspond to cells
rdims = prod(size_)
dofmap = Array{Int, 3}(undef, rdims, 1, ncells(mesh))
for i in CartesianIndices((rdims, 1, ncells(mesh)))
dofmap[i] = rdims * (i[3] - 1) + i[1]
end
return FeSpace{typeof(mesh), typeof(el), size_}(
mesh, el, dofmap, rdims * ncells(mesh))
end
function FeSpace(mesh, el::DP1, size_=(1,))
# special case for DP1: dofs correspond to vertices
rdims = prod(size_)
dofmap = Array{Int, 3}(undef, rdims, 3, ncells(mesh))
for i in LinearIndices((rdims, 3, ncells(mesh)))
dofmap[i] = i
end
return FeSpace{typeof(mesh), typeof(el), size_}(
mesh, el, dofmap, rdims * 3 * ncells(mesh))
end
Base.show(io::IO, ::MIME"text/plain", x::FeSpace) =
print("$(nameof(typeof(x))), $(nameof(typeof(x.element))) elements, size $(x.size), $(ndofs(x)) dofs")
function Base.getproperty(obj::FeSpace{<:Any, <:Any, S}, sym::Symbol) where S
if sym === :size
return S
else