From b9e3097861a816256e7cfb59f8346b595f3369d0 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Tue, 22 Feb 2022 22:28:39 +0100 Subject: [PATCH] Give the people what they want. --- src/PointEval/PointEvalHandler.jl | 15 +++++++----- src/utils.jl | 38 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/PointEval/PointEvalHandler.jl b/src/PointEval/PointEvalHandler.jl index 50eb8c5c20..0eafe87cab 100644 --- a/src/PointEval/PointEvalHandler.jl +++ b/src/PointEval/PointEvalHandler.jl @@ -278,15 +278,15 @@ end struct PointIterator{PH<:PointEvalHandler} ph::PH current_idx::ScalarWrapper{Int} - nodes::Vector{Int} - coords::Vector{Vec{2,Float64}} + nodes::FlexibleVector{Int} + coords::FlexibleVector{Vec{2,Float64}} end function PointIterator(ph::PointEvalHandler{G}) where {D,C,T,G<:Grid{D,C,T}} - @assert isconcretetype(C) # Check mate MixedDofHandler - N = nnodes_per_cell(ph.grid) + # @assert isconcretetype(C) # Check mate MixedDofHandler + N = nnodes_per_cell(ph.grid, 1) idx = ScalarWrapper(0) - nodes = zeros(Int, N) - coords = zeros(Vec{D,T}, N) + nodes = FlexibleVector(zeros(Int, N)) + coords = FlexibleVector(zeros(Vec{D,T}, N)) return PointIterator(ph, idx, nodes, coords) end @@ -299,7 +299,10 @@ function Base.iterate(p::PointIterator, state = 1) # Update stuff p.current_idx[] = state cid = cellid(p) + N = nnodes_per_cell(p.ph.grid, cid) + resize!(p.nodes, N) cellnodes!(p.nodes, p.ph.grid, cid) + resize!(p.coords, N) cellcoords!(p.coords, p.ph.grid, cid) return (p, state + 1) end diff --git a/src/utils.jl b/src/utils.jl index a938da45de..f04e96d97d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -23,3 +23,41 @@ end Base.copy(s::ScalarWrapper{T}) where {T} = ScalarWrapper{T}(copy(s.x)) copy!!(x, y) = copyto!(resize!(x, length(y)), y) # Future.copy! + + +# TODO: Maybe move to Compat.jl, maybe make it possible to wrap the full +# struct to also generate error paths in setproperty! +macro Const(field) + if VERSION >= v"1.8.0-DEV.1148" + Expr(:const, esc(field)) + else + return esc(field) + end +end + +# Vector with a fast resize! +mutable struct FlexibleVector{T} <: AbstractVector{T} + @Const buf::Vector{T} ■■ Missing reference: buf + len::Int + max_len::Int + FlexibleVector(buf::Vector{T}) where T = new{T}(buf, length(buf), length(buf)) +end +Base.IndexStyle(::Type{<:FlexibleVector}) = IndexLinear() +Base.size(v::FlexibleVector) = (v.len, ) +Base.@propagate_inbounds function Base.getindex(v::FlexibleVector, i::Int) + @boundscheck checkbounds(v, i) + return @inbounds v.buf[i] ■ Missing reference: buf +end +Base.@propagate_inbounds function Base.setindex!(v::FlexibleVector, val, i::Int) + @boundscheck checkbounds(v, i) + @inbounds setindex!(v.buf, val, i) + return v +end +function Base.resize!(v::FlexibleVector, l::Int) + if v.max_len < l + resize!(v.buf, l) ■ Missing reference: buf + v.max_len = l + end + v.len = l + return v +end