From 1c57c6a2be1610095c3f40facf949f318c6263a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Wed, 6 Oct 2021 10:45:04 +0200 Subject: [PATCH 01/13] DofHandler with any <:AbstractGrid --- src/Dofs/DofHandler.jl | 4 ++-- src/iterators.jl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 01d5f2b931..5ab688937c 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -11,7 +11,7 @@ abstract type AbstractDofHandler end Construct a `DofHandler` based on the grid `grid`. """ -struct DofHandler{dim,C,T} <: AbstractDofHandler +struct DofHandler{dim,T,G<:AbstractGrid{dim}} <: AbstractDofHandler field_names::Vector{Symbol} field_dims::Vector{Int} # TODO: field_interpolations can probably be better typed: We should at least require @@ -21,7 +21,7 @@ struct DofHandler{dim,C,T} <: AbstractDofHandler cell_dofs::Vector{Int} cell_dofs_offset::Vector{Int} closed::ScalarWrapper{Bool} - grid::Grid{dim,C,T} + grid::G ndofs::ScalarWrapper{Int} end diff --git a/src/iterators.jl b/src/iterators.jl index 382232ea75..cd270265a9 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -33,7 +33,7 @@ struct CellIterator{dim,C,T,DH<:Union{AbstractDofHandler,Nothing}} dh::Union{DH,Nothing} celldofs::Vector{Int} - function CellIterator{dim,C,T}(dh::Union{DofHandler{dim,C,T},MixedDofHandler{dim,T,G},Nothing}, cellset::Union{AbstractVector{Int},Nothing}, flags::UpdateFlags) where {dim,C,T,G} + function CellIterator{dim,C,T}(dh::Union{DofHandler{dim,T,G},MixedDofHandler{dim,T,G},Nothing}, cellset::Union{AbstractVector{Int},Nothing}, flags::UpdateFlags) where {dim,C,T,G} isconcretetype(C) || _check_same_celltype(dh.grid, cellset) N = nnodes_per_cell(dh.grid, cellset === nothing ? 1 : first(cellset)) cell = ScalarWrapper(0) @@ -56,8 +56,8 @@ end CellIterator(grid::Grid{dim,C,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,C,T} = CellIterator{dim,C,T}(grid, cellset, flags) -CellIterator(dh::DofHandler{dim,C,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,C,T} = - CellIterator{dim,C,T}(dh, cellset, flags) +CellIterator(dh::DofHandler{dim,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,C,T} = + CellIterator{dim,getcelltype(dh.grid),T}(dh, cellset, flags) CellIterator(dh::MixedDofHandler{dim,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,T} = CellIterator{dim,getcelltype(dh.grid),T}(dh, cellset, flags) From 1f3795d0141f94498fa7745594b90121ca5d19ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Wed, 6 Oct 2021 11:03:09 +0200 Subject: [PATCH 02/13] cellnodes, cellcoords! fallback dispatches --- src/Dofs/DofHandler.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 5ab688937c..b56b0034ed 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -288,6 +288,23 @@ function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::Grid{dim,C}, i::In end return global_coords end + +function cellnodes!(global_nodes::Vector{Int}, grid::AbstractGrid{dim}, i::Int) where {dim} + C = getcelltype(grid) + @assert length(global_nodes) == nnodes(C) + for j in 1:nnodes(C) + global_nodes[j] = getcells(grid, i).nodes[j] ##TODO getnodes(::AbstractCell); only vertices(::AbstractCell) available + end + return global_nodes +end + +function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::AbstractGrid{dim}, i::Int) where {dim,T} + C = getcelltype(grid) + @assert length(global_coords) == nnodes(C) + global_coords .= getcoordinates(grid, i) + return global_coords +end + cellcoords!(global_coords::Vector{<:Vec}, dh::DofHandler, i::Int) = cellcoords!(global_coords, dh.grid, i) function celldofs(dh::DofHandler, i::Int) From b04728dd93301ab4aa83a271ded366c8ff38d631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Mon, 11 Oct 2021 23:24:36 +0200 Subject: [PATCH 03/13] added test for subtyping <:AbstractGrid and using it with DofHandler --- src/Dofs/DofHandler.jl | 2 +- test/runtests.jl | 1 + test/test_abstractgrid.jl | 90 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 test/test_abstractgrid.jl diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index b56b0034ed..dd165274d7 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -25,7 +25,7 @@ struct DofHandler{dim,T,G<:AbstractGrid{dim}} <: AbstractDofHandler ndofs::ScalarWrapper{Int} end -function DofHandler(grid::Grid) +function DofHandler(grid::AbstractGrid) isconcretetype(getcelltype(grid)) || error("Grid includes different celltypes. Use MixedDofHandler instead of DofHandler") DofHandler(Symbol[], Int[], Interpolation[], BCValues{Float64}[], Int[], Int[], ScalarWrapper(false), grid, Ferrite.ScalarWrapper(-1)) end diff --git a/test/runtests.jl b/test/runtests.jl index 1662eccdb6..686e985da5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,6 +16,7 @@ include("test_assemble.jl") include("test_dofs.jl") include("test_constraints.jl") include("test_grid_dofhandler_vtk.jl") +include("test_abstractgrid.jl") include("test_mixeddofhandler.jl") include("test_l2_projection.jl") # include("test_notebooks.jl") diff --git a/test/test_abstractgrid.jl b/test/test_abstractgrid.jl new file mode 100644 index 0000000000..8662fd0d56 --- /dev/null +++ b/test/test_abstractgrid.jl @@ -0,0 +1,90 @@ +@testset "AbstractGrid" begin + + struct SmallGrid{dim,N,C<:Ferrite.AbstractCell} <: Ferrite.AbstractGrid{dim} + nodes_test::Vector{NTuple{dim,Float64}} + cells_test::NTuple{N,C} + end + + Ferrite.getcells(grid::SmallGrid) = grid.cells_test + Ferrite.getcells(grid::SmallGrid, v::Union{Int, Vector{Int}}) = grid.cells_test[v] + Ferrite.getncells(grid::SmallGrid{dim,N}) where {dim,N} = N + Ferrite.getcelltype(grid::SmallGrid) = eltype(grid.cells_test) + Ferrite.getcelltype(grid::SmallGrid, i::Int) = typeof(grid.cells_test[i]) + + Ferrite.getnodes(grid::SmallGrid) = grid.nodes_test + Ferrite.getnodes(grid::SmallGrid, v::Union{Int, Vector{Int}}) = grid.nodes_test[v] + Ferrite.getnnodes(grid::SmallGrid) = length(grid.nodes_test) + Ferrite.nnodes_per_cell(grid::SmallGrid, i::Int=1) = Ferrite.nnodes(grid.cells_test[i]) + Ferrite.n_faces_per_cell(grid::SmallGrid) = nfaces(eltype(grid.cells_test)) + function Ferrite.getcoordinates!(x::Vector{Vec{dim,T}}, grid::SmallGrid, cell::Int) where {dim,T} + for i in 1:length(x) + x[i] = Vec{dim,T}(grid.nodes_test[grid.cells_test[cell].nodes[i]]) + end + end + function Ferrite.getcoordinates(grid::SmallGrid{dim}, cell::Int) where dim + nodeidx = grid.cells_test[cell].nodes + return [Vec{dim,Float64}(grid.nodes_test[i]) for i in nodeidx]::Vector{Vec{dim,Float64}} + end + + nodes = [(-1.0,-1.0); (0.0,-1.0); (1.0,-1.0); (-1.0,0.0); (0.0,0.0); (1.0,0.0); (-1.0,1.0); (0.0,1.0); (1.0,1.0)] + cells = (Quadrilateral((1,2,5,4)), Quadrilateral((2,3,6,5)), Quadrilateral((4,5,8,7)), Quadrilateral((5,6,9,8))) + subtype_grid = SmallGrid(nodes,cells) + reference_grid = generate_grid(Quadrilateral, (2,2)) + + ip = Lagrange{2, RefCube, 1}() + qr = QuadratureRule{2, RefCube}(2) + cellvalues = CellScalarValues(qr, ip); + + dhs = [DofHandler(grid) for grid in (subtype_grid, reference_grid)] + u1 = Vector{Float64}(undef, 9) + u2 = Vector{Float64}(undef, 9) + ∂Ω = union(getfaceset.((reference_grid, ), ["left", "right", "top", "bottom"])...) + dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) + + function doassemble!(cellvalues::CellScalarValues{dim}, K::SparseMatrixCSC, dh::DofHandler) where {dim} + n_basefuncs = getnbasefunctions(cellvalues) + Ke = zeros(n_basefuncs, n_basefuncs) + fe = zeros(n_basefuncs) + f = zeros(ndofs(dh)) + assembler = start_assemble(K, f) + for cellid in 1:getncells(dh.grid) + fill!(Ke, 0) + fill!(fe, 0) + coords = getcoordinates(dh.grid, cellid) + reinit!(cellvalues, coords) + for q_point in 1:getnquadpoints(cellvalues) + dΩ = getdetJdV(cellvalues, q_point) + for i in 1:n_basefuncs + v = shape_value(cellvalues, q_point, i) + ∇v = shape_gradient(cellvalues, q_point, i) + fe[i] += v * dΩ + for j in 1:n_basefuncs + ∇u = shape_gradient(cellvalues, q_point, j) + Ke[i, j] += (∇v ⋅ ∇u) * dΩ + end + end + end + assemble!(assembler, celldofs(dh,cellid), fe, Ke) + end + return K, f + end + + for (dh,u) in zip(dhs,(u1,u2)) + push!(dh, :u, 1) + close!(dh) + ch = ConstraintHandler(dh) + add!(ch, dbc) + close!(ch) + update!(ch, 0.0) + K = create_sparsity_pattern(dh); + K, f = doassemble!(cellvalues, K, dh); + apply!(K, f, ch) + sol = K \ f + u .= sol + end + + @test Ferrite.ndofs_per_cell(dhs[1]) == Ferrite.ndofs_per_cell(dhs[2]) + @test Ferrite.celldofs(dhs[1],3) == Ferrite.celldofs(dhs[2],3) + @test Ferrite.ndofs(dhs[1]) == Ferrite.ndofs(dhs[2]) + @test isapprox(us[1],us[2],atol=1e-18) +end From d1f62cd8a36fa3c53f63dc3d6c9a4788e4fea8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Tue, 12 Oct 2021 00:15:21 +0200 Subject: [PATCH 04/13] relax isapprox in abstractgrid test --- test/test_abstractgrid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_abstractgrid.jl b/test/test_abstractgrid.jl index 8662fd0d56..3959b532bf 100644 --- a/test/test_abstractgrid.jl +++ b/test/test_abstractgrid.jl @@ -86,5 +86,5 @@ @test Ferrite.ndofs_per_cell(dhs[1]) == Ferrite.ndofs_per_cell(dhs[2]) @test Ferrite.celldofs(dhs[1],3) == Ferrite.celldofs(dhs[2],3) @test Ferrite.ndofs(dhs[1]) == Ferrite.ndofs(dhs[2]) - @test isapprox(us[1],us[2],atol=1e-18) + @test isapprox(us[1],us[2],atol=1e-8) end From 49ce28b2855ec2e7787323a268c84f80ae9b7d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Tue, 12 Oct 2021 00:20:01 +0200 Subject: [PATCH 05/13] change isapprox variable names --- test/test_abstractgrid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_abstractgrid.jl b/test/test_abstractgrid.jl index 3959b532bf..78992481c5 100644 --- a/test/test_abstractgrid.jl +++ b/test/test_abstractgrid.jl @@ -86,5 +86,5 @@ @test Ferrite.ndofs_per_cell(dhs[1]) == Ferrite.ndofs_per_cell(dhs[2]) @test Ferrite.celldofs(dhs[1],3) == Ferrite.celldofs(dhs[2],3) @test Ferrite.ndofs(dhs[1]) == Ferrite.ndofs(dhs[2]) - @test isapprox(us[1],us[2],atol=1e-8) + @test isapprox(u1,u2,atol=1e-8) end From 7d0caab3249da2af49ea4aa1cbc7132fb7535292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Wed, 6 Oct 2021 10:45:04 +0200 Subject: [PATCH 06/13] DofHandler with any <:AbstractGrid --- src/Dofs/DofHandler.jl | 4 ++-- src/iterators.jl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 070b10d481..533dbec6fc 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -9,7 +9,7 @@ Operates slightly faster than [`MixedDofHandler`](@docs). Supports: - `Grid`s with a single concrete cell type. - One or several fields on the whole domaine. """ -struct DofHandler{dim,C,T} <: AbstractDofHandler +struct DofHandler{dim,T,G<:AbstractGrid{dim}} <: AbstractDofHandler field_names::Vector{Symbol} field_dims::Vector{Int} # TODO: field_interpolations can probably be better typed: We should at least require @@ -19,7 +19,7 @@ struct DofHandler{dim,C,T} <: AbstractDofHandler cell_dofs::Vector{Int} cell_dofs_offset::Vector{Int} closed::ScalarWrapper{Bool} - grid::Grid{dim,C,T} + grid::G ndofs::ScalarWrapper{Int} end diff --git a/src/iterators.jl b/src/iterators.jl index 16877ba910..a643158fbb 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -41,7 +41,7 @@ struct CellIterator{dim,C,T,DH<:Union{AbstractDofHandler,Nothing}} dh::Union{DH,Nothing} celldofs::Vector{Int} - function CellIterator{dim,C,T}(dh::Union{DofHandler{dim,C,T},MixedDofHandler{dim,T,G},Nothing}, cellset::Union{AbstractVector{Int},Nothing}, flags::UpdateFlags) where {dim,C,T,G} + function CellIterator{dim,C,T}(dh::Union{DofHandler{dim,T,G},MixedDofHandler{dim,T,G},Nothing}, cellset::Union{AbstractVector{Int},Nothing}, flags::UpdateFlags) where {dim,C,T,G} isconcretetype(C) || _check_same_celltype(dh.grid, cellset) N = nnodes_per_cell(dh.grid, cellset === nothing ? 1 : first(cellset)) cell = ScalarWrapper(0) @@ -64,8 +64,8 @@ end CellIterator(grid::Grid{dim,C,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,C,T} = CellIterator{dim,C,T}(grid, cellset, flags) -CellIterator(dh::DofHandler{dim,C,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,C,T} = - CellIterator{dim,C,T}(dh, cellset, flags) +CellIterator(dh::DofHandler{dim,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,C,T} = + CellIterator{dim,getcelltype(dh.grid),T}(dh, cellset, flags) CellIterator(dh::MixedDofHandler{dim,T}, cellset::Union{AbstractVector{Int},Nothing}=nothing, flags::UpdateFlags=UpdateFlags()) where {dim,T} = CellIterator{dim,getcelltype(dh.grid),T}(dh, cellset, flags) From 41b77dec7ae296ab327eb03404aa316202c6abe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Wed, 6 Oct 2021 11:03:09 +0200 Subject: [PATCH 07/13] cellnodes, cellcoords! fallback dispatches --- src/Dofs/DofHandler.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 533dbec6fc..76a6101991 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -321,6 +321,23 @@ function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::Grid{dim,C}, i::In end return global_coords end + +function cellnodes!(global_nodes::Vector{Int}, grid::AbstractGrid{dim}, i::Int) where {dim} + C = getcelltype(grid) + @assert length(global_nodes) == nnodes(C) + for j in 1:nnodes(C) + global_nodes[j] = getcells(grid, i).nodes[j] ##TODO getnodes(::AbstractCell); only vertices(::AbstractCell) available + end + return global_nodes +end + +function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::AbstractGrid{dim}, i::Int) where {dim,T} + C = getcelltype(grid) + @assert length(global_coords) == nnodes(C) + global_coords .= getcoordinates(grid, i) + return global_coords +end + cellcoords!(global_coords::Vector{<:Vec}, dh::DofHandler, i::Int) = cellcoords!(global_coords, dh.grid, i) function celldofs(dh::DofHandler, i::Int) From ce17bdd60a8a0e3c8481a57030b4dde5faabc637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Mon, 11 Oct 2021 23:24:36 +0200 Subject: [PATCH 08/13] added test for subtyping <:AbstractGrid and using it with DofHandler --- src/Dofs/DofHandler.jl | 2 +- test/runtests.jl | 1 + test/test_abstractgrid.jl | 90 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 test/test_abstractgrid.jl diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 76a6101991..4f8c5a82c6 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -23,7 +23,7 @@ struct DofHandler{dim,T,G<:AbstractGrid{dim}} <: AbstractDofHandler ndofs::ScalarWrapper{Int} end -function DofHandler(grid::Grid) +function DofHandler(grid::AbstractGrid) isconcretetype(getcelltype(grid)) || error("Grid includes different celltypes. Use MixedDofHandler instead of DofHandler") DofHandler(Symbol[], Int[], Interpolation[], BCValues{Float64}[], Int[], Int[], ScalarWrapper(false), grid, Ferrite.ScalarWrapper(-1)) end diff --git a/test/runtests.jl b/test/runtests.jl index d03a4e64b4..def659697e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,6 +16,7 @@ include("test_assemble.jl") include("test_dofs.jl") include("test_constraints.jl") include("test_grid_dofhandler_vtk.jl") +include("test_abstractgrid.jl") include("test_mixeddofhandler.jl") include("test_l2_projection.jl") include("test_pointevaluation.jl") diff --git a/test/test_abstractgrid.jl b/test/test_abstractgrid.jl new file mode 100644 index 0000000000..8662fd0d56 --- /dev/null +++ b/test/test_abstractgrid.jl @@ -0,0 +1,90 @@ +@testset "AbstractGrid" begin + + struct SmallGrid{dim,N,C<:Ferrite.AbstractCell} <: Ferrite.AbstractGrid{dim} + nodes_test::Vector{NTuple{dim,Float64}} + cells_test::NTuple{N,C} + end + + Ferrite.getcells(grid::SmallGrid) = grid.cells_test + Ferrite.getcells(grid::SmallGrid, v::Union{Int, Vector{Int}}) = grid.cells_test[v] + Ferrite.getncells(grid::SmallGrid{dim,N}) where {dim,N} = N + Ferrite.getcelltype(grid::SmallGrid) = eltype(grid.cells_test) + Ferrite.getcelltype(grid::SmallGrid, i::Int) = typeof(grid.cells_test[i]) + + Ferrite.getnodes(grid::SmallGrid) = grid.nodes_test + Ferrite.getnodes(grid::SmallGrid, v::Union{Int, Vector{Int}}) = grid.nodes_test[v] + Ferrite.getnnodes(grid::SmallGrid) = length(grid.nodes_test) + Ferrite.nnodes_per_cell(grid::SmallGrid, i::Int=1) = Ferrite.nnodes(grid.cells_test[i]) + Ferrite.n_faces_per_cell(grid::SmallGrid) = nfaces(eltype(grid.cells_test)) + function Ferrite.getcoordinates!(x::Vector{Vec{dim,T}}, grid::SmallGrid, cell::Int) where {dim,T} + for i in 1:length(x) + x[i] = Vec{dim,T}(grid.nodes_test[grid.cells_test[cell].nodes[i]]) + end + end + function Ferrite.getcoordinates(grid::SmallGrid{dim}, cell::Int) where dim + nodeidx = grid.cells_test[cell].nodes + return [Vec{dim,Float64}(grid.nodes_test[i]) for i in nodeidx]::Vector{Vec{dim,Float64}} + end + + nodes = [(-1.0,-1.0); (0.0,-1.0); (1.0,-1.0); (-1.0,0.0); (0.0,0.0); (1.0,0.0); (-1.0,1.0); (0.0,1.0); (1.0,1.0)] + cells = (Quadrilateral((1,2,5,4)), Quadrilateral((2,3,6,5)), Quadrilateral((4,5,8,7)), Quadrilateral((5,6,9,8))) + subtype_grid = SmallGrid(nodes,cells) + reference_grid = generate_grid(Quadrilateral, (2,2)) + + ip = Lagrange{2, RefCube, 1}() + qr = QuadratureRule{2, RefCube}(2) + cellvalues = CellScalarValues(qr, ip); + + dhs = [DofHandler(grid) for grid in (subtype_grid, reference_grid)] + u1 = Vector{Float64}(undef, 9) + u2 = Vector{Float64}(undef, 9) + ∂Ω = union(getfaceset.((reference_grid, ), ["left", "right", "top", "bottom"])...) + dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) + + function doassemble!(cellvalues::CellScalarValues{dim}, K::SparseMatrixCSC, dh::DofHandler) where {dim} + n_basefuncs = getnbasefunctions(cellvalues) + Ke = zeros(n_basefuncs, n_basefuncs) + fe = zeros(n_basefuncs) + f = zeros(ndofs(dh)) + assembler = start_assemble(K, f) + for cellid in 1:getncells(dh.grid) + fill!(Ke, 0) + fill!(fe, 0) + coords = getcoordinates(dh.grid, cellid) + reinit!(cellvalues, coords) + for q_point in 1:getnquadpoints(cellvalues) + dΩ = getdetJdV(cellvalues, q_point) + for i in 1:n_basefuncs + v = shape_value(cellvalues, q_point, i) + ∇v = shape_gradient(cellvalues, q_point, i) + fe[i] += v * dΩ + for j in 1:n_basefuncs + ∇u = shape_gradient(cellvalues, q_point, j) + Ke[i, j] += (∇v ⋅ ∇u) * dΩ + end + end + end + assemble!(assembler, celldofs(dh,cellid), fe, Ke) + end + return K, f + end + + for (dh,u) in zip(dhs,(u1,u2)) + push!(dh, :u, 1) + close!(dh) + ch = ConstraintHandler(dh) + add!(ch, dbc) + close!(ch) + update!(ch, 0.0) + K = create_sparsity_pattern(dh); + K, f = doassemble!(cellvalues, K, dh); + apply!(K, f, ch) + sol = K \ f + u .= sol + end + + @test Ferrite.ndofs_per_cell(dhs[1]) == Ferrite.ndofs_per_cell(dhs[2]) + @test Ferrite.celldofs(dhs[1],3) == Ferrite.celldofs(dhs[2],3) + @test Ferrite.ndofs(dhs[1]) == Ferrite.ndofs(dhs[2]) + @test isapprox(us[1],us[2],atol=1e-18) +end From 5654f665f8569d8605a4edba2ddb0cfe28e3e003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Tue, 12 Oct 2021 00:15:21 +0200 Subject: [PATCH 09/13] relax isapprox in abstractgrid test --- test/test_abstractgrid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_abstractgrid.jl b/test/test_abstractgrid.jl index 8662fd0d56..3959b532bf 100644 --- a/test/test_abstractgrid.jl +++ b/test/test_abstractgrid.jl @@ -86,5 +86,5 @@ @test Ferrite.ndofs_per_cell(dhs[1]) == Ferrite.ndofs_per_cell(dhs[2]) @test Ferrite.celldofs(dhs[1],3) == Ferrite.celldofs(dhs[2],3) @test Ferrite.ndofs(dhs[1]) == Ferrite.ndofs(dhs[2]) - @test isapprox(us[1],us[2],atol=1e-18) + @test isapprox(us[1],us[2],atol=1e-8) end From c28ba14fd806b211326ce59aab6663955317948f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Tue, 12 Oct 2021 00:20:01 +0200 Subject: [PATCH 10/13] change isapprox variable names --- test/test_abstractgrid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_abstractgrid.jl b/test/test_abstractgrid.jl index 3959b532bf..78992481c5 100644 --- a/test/test_abstractgrid.jl +++ b/test/test_abstractgrid.jl @@ -86,5 +86,5 @@ @test Ferrite.ndofs_per_cell(dhs[1]) == Ferrite.ndofs_per_cell(dhs[2]) @test Ferrite.celldofs(dhs[1],3) == Ferrite.celldofs(dhs[2],3) @test Ferrite.ndofs(dhs[1]) == Ferrite.ndofs(dhs[2]) - @test isapprox(us[1],us[2],atol=1e-8) + @test isapprox(u1,u2,atol=1e-8) end From 340193ccd48221b195efee1829a51ffc05831829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Fri, 22 Apr 2022 08:49:35 +0200 Subject: [PATCH 11/13] update cellcoords! and cellnodes --- src/Dofs/DofHandler.jl | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 4f8c5a82c6..ede5000a11 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -302,8 +302,8 @@ function celldofs!(global_dofs::Vector{Int}, dh::DofHandler, i::Int) return global_dofs end -function cellnodes!(global_nodes::Vector{Int}, grid::Grid{dim,C}, i::Int) where {dim,C} - nodes = grid.cells[i].nodes +function cellnodes!(global_nodes::Vector{Int}, grid::AbstractGrid{dim}, i::Int) where {dim,C} + nodes = getcells(grid,i).nodes N = length(nodes) @assert length(global_nodes) == N for j in 1:N @@ -312,32 +312,16 @@ function cellnodes!(global_nodes::Vector{Int}, grid::Grid{dim,C}, i::Int) where return global_nodes end -function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::Grid{dim,C}, i::Int) where {dim,C,T} - nodes = grid.cells[i].nodes +function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::AbstractGrid{dim}, i::Int) where {dim,C,T} + nodes = getcells(grid,i).nodes N = length(nodes) @assert length(global_coords) == N for j in 1:N - global_coords[j] = grid.nodes[nodes[j]].x + global_coords[j] = getnodes(grid.nodes,nodes[j]).x end return global_coords end -function cellnodes!(global_nodes::Vector{Int}, grid::AbstractGrid{dim}, i::Int) where {dim} - C = getcelltype(grid) - @assert length(global_nodes) == nnodes(C) - for j in 1:nnodes(C) - global_nodes[j] = getcells(grid, i).nodes[j] ##TODO getnodes(::AbstractCell); only vertices(::AbstractCell) available - end - return global_nodes -end - -function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::AbstractGrid{dim}, i::Int) where {dim,T} - C = getcelltype(grid) - @assert length(global_coords) == nnodes(C) - global_coords .= getcoordinates(grid, i) - return global_coords -end - cellcoords!(global_coords::Vector{<:Vec}, dh::DofHandler, i::Int) = cellcoords!(global_coords, dh.grid, i) function celldofs(dh::DofHandler, i::Int) From f1f8a80e78e0fd42ab57a7cecf150844723a7844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Fri, 22 Apr 2022 08:54:09 +0200 Subject: [PATCH 12/13] typo --- src/Dofs/DofHandler.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index ede5000a11..9bd07b9fd3 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -317,7 +317,7 @@ function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::AbstractGrid{dim}, N = length(nodes) @assert length(global_coords) == N for j in 1:N - global_coords[j] = getnodes(grid.nodes,nodes[j]).x + global_coords[j] = getnodes(grid,nodes[j]).x end return global_coords end From 5f5d25b34fca20dadd86e69f455785780541f97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hler?= Date: Fri, 22 Apr 2022 09:21:23 +0200 Subject: [PATCH 13/13] add working, general version of cellcoords --- src/Dofs/DofHandler.jl | 2 +- test/test_abstractgrid.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 9bd07b9fd3..50a7120ad3 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -317,7 +317,7 @@ function cellcoords!(global_coords::Vector{Vec{dim,T}}, grid::AbstractGrid{dim}, N = length(nodes) @assert length(global_coords) == N for j in 1:N - global_coords[j] = getnodes(grid,nodes[j]).x + global_coords[j] = getcoordinates(getnodes(grid,nodes[j])) end return global_coords end diff --git a/test/test_abstractgrid.jl b/test/test_abstractgrid.jl index 78992481c5..89b3136ecf 100644 --- a/test/test_abstractgrid.jl +++ b/test/test_abstractgrid.jl @@ -10,6 +10,7 @@ Ferrite.getncells(grid::SmallGrid{dim,N}) where {dim,N} = N Ferrite.getcelltype(grid::SmallGrid) = eltype(grid.cells_test) Ferrite.getcelltype(grid::SmallGrid, i::Int) = typeof(grid.cells_test[i]) + Ferrite.getcoordinates(x::NTuple{dim,Float64}) where dim = Vec{dim,Float64}(x) Ferrite.getnodes(grid::SmallGrid) = grid.nodes_test Ferrite.getnodes(grid::SmallGrid, v::Union{Int, Vector{Int}}) = grid.nodes_test[v]