Skip to content
Snippets Groups Projects
Commit 5c46c0c8 authored by Stephan Hilb's avatar Stephan Hilb
Browse files

partly refactor mesh interface

The mesh interface is a mess. I probably won't have time to clean it up
before implementing refinement though, sadly.
parent 1f220c07
No related branches found
No related tags found
No related merge requests found
...@@ -31,41 +31,38 @@ end ...@@ -31,41 +31,38 @@ end
function FeSpace(mesh, el::P1, size_=(1,)) function FeSpace(mesh, el::P1, size_=(1,))
# special case for P1: dofs correspond to vertices # special case for P1: dofs correspond to vertices
rdims = prod(size_) rdims = prod(size_)
ncells = size(mesh.cells, 2) dofmap = Array{Int, 3}(undef, rdims, 3, ncells(mesh))
dofmap = Array{Int, 3}(undef, rdims, 3, ncells) for i in CartesianIndices((rdims, 3, ncells(mesh)))
for i in CartesianIndices((rdims, 3, ncells))
dofmap[i] = rdims * (mesh.cells[i[2], i[3]] - 1) + i[1] dofmap[i] = rdims * (mesh.cells[i[2], i[3]] - 1) + i[1]
end end
return FeSpace{typeof(mesh), typeof(el), size_}( return FeSpace{typeof(mesh), typeof(el), size_}(
mesh, el, dofmap, rdims * size(mesh.vertices, 2)) mesh, el, dofmap, rdims * nvertices(mesh))
end end
function FeSpace(mesh, el::DP0, size_=(1,)) function FeSpace(mesh, el::DP0, size_=(1,))
# special case for DP1: dofs correspond to cells # special case for DP1: dofs correspond to cells
rdims = prod(size_) rdims = prod(size_)
ncells = size(mesh.cells, 2) dofmap = Array{Int, 3}(undef, rdims, 1, ncells(mesh))
dofmap = Array{Int, 3}(undef, rdims, 1, ncells) for i in CartesianIndices((rdims, 1, ncells(mesh)))
for i in CartesianIndices((rdims, 1, ncells))
dofmap[i] = rdims * (i[3] - 1) + i[1] dofmap[i] = rdims * (i[3] - 1) + i[1]
end end
return FeSpace{typeof(mesh), typeof(el), size_}( return FeSpace{typeof(mesh), typeof(el), size_}(
mesh, el, dofmap, rdims * ncells) mesh, el, dofmap, rdims * ncells(mesh))
end end
function FeSpace(mesh, el::DP1, size_=(1,)) function FeSpace(mesh, el::DP1, size_=(1,))
# special case for DP1: dofs correspond to vertices # special case for DP1: dofs correspond to vertices
rdims = prod(size_) rdims = prod(size_)
ncells = size(mesh.cells, 2) dofmap = Array{Int, 3}(undef, rdims, 3, ncells(mesh))
dofmap = Array{Int, 3}(undef, rdims, 3, ncells) for i in LinearIndices((rdims, 3, ncells(mesh)))
for i in LinearIndices((rdims, 3, ncells))
dofmap[i] = i dofmap[i] = i
end end
return FeSpace{typeof(mesh), typeof(el), size_}( return FeSpace{typeof(mesh), typeof(el), size_}(
mesh, el, dofmap, rdims * 3 * ncells) mesh, el, dofmap, rdims * 3 * ncells(mesh))
end end
Base.show(io::IO, ::MIME"text/plain", x::FeSpace) = Base.show(io::IO, ::MIME"text/plain", x::FeSpace) =
print("$(nameof(typeof(x))), $(nameof(typeof(x.element))) elements, size $(x.size), $(x.ndofs) dofs") 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 function Base.getproperty(obj::FeSpace{<:Any, <:Any, S}, sym::Symbol) where S
if sym === :size if sym === :size
...@@ -75,6 +72,8 @@ function Base.getproperty(obj::FeSpace{<:Any, <:Any, S}, sym::Symbol) where S ...@@ -75,6 +72,8 @@ function Base.getproperty(obj::FeSpace{<:Any, <:Any, S}, sym::Symbol) where S
end end
end end
ndofs(space::FeSpace) = space.ndofs
# evaluate at local point # evaluate at local point
@inline function evaluate(space::FeSpace, ldofs, xloc) @inline function evaluate(space::FeSpace, ldofs, xloc)
bv = evaluate_basis(space.element, xloc) bv = evaluate_basis(space.element, xloc)
...@@ -97,7 +96,7 @@ struct FeFunction{Sp,Ld} ...@@ -97,7 +96,7 @@ struct FeFunction{Sp,Ld}
end end
function FeFunction(space; name=string(gensym("f"))) function FeFunction(space; name=string(gensym("f")))
data = Vector{Float64}(undef, space.ndofs) data = Vector{Float64}(undef, ndofs(space))
ldata = zero(MVector{prod(space.size) * ndofs(space.element)}) ldata = zero(MVector{prod(space.size) * ndofs(space.element)})
return FeFunction(space, data, name, ldata) return FeFunction(space, data, name, ldata)
end end
...@@ -116,13 +115,14 @@ function interpolate!(dst::FeFunction, ::P1, expr::Function; params...) ...@@ -116,13 +115,14 @@ function interpolate!(dst::FeFunction, ::P1, expr::Function; params...)
params = NamedTuple(params) params = NamedTuple(params)
space = dst.space space = dst.space
mesh = space.mesh mesh = space.mesh
for cell in axes(mesh.cells, 2) for cell in cells(mesh)
for f in params for f in params
bind!(f, cell) bind!(f, cell)
end end
for eldof in axes(mesh.cells, 1)
xid = mesh.cells[eldof, cell] vertices = mesh.vertices[:, mesh.cells[:, cell]]
x = SArray{Tuple{ndims_domain(mesh)}}(mesh.vertices[:, xid]) for eldof in 1:nvertices_cell(mesh)
x = SArray{Tuple{ndims_domain(mesh)}}(vertices[:, eldof])
xloc = SA[0. 1. 0.; 0. 0. 1.][:, eldof] xloc = SA[0. 1. 0.; 0. 0. 1.][:, eldof]
opvalues = map(f -> evaluate(f, xloc), params) opvalues = map(f -> evaluate(f, xloc), params)
...@@ -137,10 +137,11 @@ function interpolate!(dst::FeFunction, ::DP0, expr::Function; params...) ...@@ -137,10 +137,11 @@ function interpolate!(dst::FeFunction, ::DP0, expr::Function; params...)
params = NamedTuple(params) params = NamedTuple(params)
space = dst.space space = dst.space
mesh = space.mesh mesh = space.mesh
for cell in axes(mesh.cells, 2) for cell in cells(mesh)
for f in params for f in params
bind!(f, cell) bind!(f, cell)
end end
vertices = mesh.vertices[:, mesh.cells[:, cell]] vertices = mesh.vertices[:, mesh.cells[:, cell]]
centroid = SArray{Tuple{ndims_domain(mesh)}}(mean(vertices, dims = 2)) centroid = SArray{Tuple{ndims_domain(mesh)}}(mean(vertices, dims = 2))
lcentroid = SA[1/3, 1/3] lcentroid = SA[1/3, 1/3]
...@@ -186,7 +187,7 @@ end ...@@ -186,7 +187,7 @@ end
function sample(f::FeFunction) function sample(f::FeFunction)
mesh = f.mapper.mesh mesh = f.mapper.mesh
for cell in axes(mesh.cells, 2) for cell in cells(mesh)
vertices = mesh.vertices[:, mesh.cells[:, cell]] vertices = mesh.vertices[:, mesh.cells[:, cell]]
I0 = floor.(Int, vec(minimum(vertices, dims = 2))) I0 = floor.(Int, vec(minimum(vertices, dims = 2)))
I1 = ceil.(Int, vec(maximum(vertices, dims = 2))) I1 = ceil.(Int, vec(maximum(vertices, dims = 2)))
......
export init_grid, save export init_grid, save
using WriteVTK using WriteVTK
using StaticArrays: SVector
# 2d, simplex grid # 2d, simplex grid
struct Mesh struct Mesh
...@@ -14,6 +15,18 @@ Base.show(io::IO, ::MIME"text/plain", f::Mesh) = ...@@ -14,6 +15,18 @@ Base.show(io::IO, ::MIME"text/plain", f::Mesh) =
ndims_domain(::Mesh) = 2 ndims_domain(::Mesh) = 2
ndims_space(::Mesh) = 2 ndims_space(::Mesh) = 2
nvertices_cell(::Mesh) = 3 nvertices_cell(::Mesh) = 3
nvertices(x::Mesh) = size(x.vertices, 2)
ncells(x::Mesh) = size(x.cells, 2)
cells(x::Mesh) = axes(x.cells, 2)
#function Base.getproperty(obj::Mesh, sym::Symbol)
# if sym === :vertices
# return reinterpret(SVector{ndims_space(obj), Float64}, vec(obj.vertices))
# else
# return getfield(obj, sym)
# end
#end
function init_grid(m::Int, n::Int = m, v0 = (0., 0.), v1 = (1., 1.)) function init_grid(m::Int, n::Int = m, v0 = (0., 0.), v1 = (1., 1.))
r1 = LinRange(v0[1], v1[1], m + 1) r1 = LinRange(v0[1], v1[1], m + 1)
......
...@@ -74,11 +74,11 @@ function assemble(space::FeSpace, a, l; params...) ...@@ -74,11 +74,11 @@ function assemble(space::FeSpace, a, l; params...)
I = Float64[] I = Float64[]
J = Float64[] J = Float64[]
V = Float64[] V = Float64[]
b = zeros(space.ndofs) b = zeros(ndofs(space))
gdof = LinearIndices((nrdims, space.ndofs)) gdof = LinearIndices((nrdims, ndofs(space)))
# mesh cells # mesh cells
for cell in axes(mesh.cells, 2) for cell in cells(mesh)
foreach(f -> bind!(f, cell), opparams) foreach(f -> bind!(f, cell), opparams)
# cell map is assumed to be constant per cell # cell map is assumed to be constant per cell
delmap = jacobian(x -> elmap(mesh, cell, x), SA[0., 0.]) delmap = jacobian(x -> elmap(mesh, cell, x), SA[0., 0.])
...@@ -116,7 +116,7 @@ function assemble(space::FeSpace, a, l; params...) ...@@ -116,7 +116,7 @@ function assemble(space::FeSpace, a, l; params...)
end end
end end
ngdofs = space.ndofs ngdofs = ndofs(space)
A = sparse(I, J, V, ngdofs, ngdofs) A = sparse(I, J, V, ngdofs, ngdofs)
return A, b return A, b
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment