From 3994a26701f2792f89ad38c2b05dcbac5495e4e5 Mon Sep 17 00:00:00 2001 From: Xiansheng Cai Date: Thu, 22 Sep 2022 22:47:56 -0400 Subject: [PATCH] Now AbstractGrid{T}<:AbstractArray{T,1}; implemented eltype. --- src/grid/composite.jl | 2 +- src/grid/simple.jl | 158 ++++++++++++++++++++++-------------------- 2 files changed, 83 insertions(+), 77 deletions(-) diff --git a/src/grid/composite.jl b/src/grid/composite.jl index 6216f01..0c273c3 100644 --- a/src/grid/composite.jl +++ b/src/grid/composite.jl @@ -30,7 +30,7 @@ create Composite grid from panel and subgrids. if the boundary grid point of two neighbor subgrids are too close, they will be combined in the whole grid. """ -struct Composite{T<:AbstractFloat,PG,SG} <: SimpleG.ClosedGrid +struct Composite{T<:AbstractFloat,PG,SG} <: SimpleG.ClosedGrid{T} bound::SVector{2,T} size::Int grid::Vector{T} diff --git a/src/grid/simple.jl b/src/grid/simple.jl index 2fc912d..d0a1c6a 100644 --- a/src/grid/simple.jl +++ b/src/grid/simple.jl @@ -20,9 +20,9 @@ const invvandermonde = BaryChebTools.invvandermonde All Grids are derived from AbstractGrid; ClosedGrid has bound[1], bound[2] == grid[1], grid[end], while OpenGrid has bound[1]= grid.grid[end] - if grid.size!=1 - return grid.size-1 + if grid.size != 1 + return grid.size - 1 else return 1 end end - result = searchsortedfirst(grid.grid, x)-1 + result = searchsortedfirst(grid.grid, x) - 1 return Base.floor(Int, result) end Base.length(grid::AbstractGrid) = grid.size -Base.size(grid::AbstractGrid) = grid.size +Base.size(grid::AbstractGrid) = (grid.size,) +Base.size(grid::AbstractGrid, I::Int) = grid.size + Base.show(io::IO, grid::AbstractGrid) = print(io, grid.grid) Base.view(grid::AbstractGrid, inds...) where {N} = Base.view(grid.grid, inds...) # set is not allowed for grids @@ -103,9 +105,13 @@ Base.getindex(grid::AbstractGrid, i) = grid.grid[i] Base.firstindex(grid::AbstractGrid) = 1 Base.lastindex(grid::AbstractGrid) = grid.size # iterator -Base.iterate(grid::AbstractGrid) = (grid.grid[1],1) -Base.iterate(grid::AbstractGrid, state) = (state>=grid.size) ? nothing : (grid.grid[state+1],state+1) +Base.iterate(grid::AbstractGrid) = (grid.grid[1], 1) +Base.iterate(grid::AbstractGrid, state) = (state >= grid.size) ? nothing : (grid.grid[state+1], state + 1) +# Base.IteratorSize +Base.IteratorSize(::Type{AbstractGrid{T}}) where {T} = Base.HasLength() +Base.IteratorEltype(::Type{AbstractGrid{T}}) where {T} = Base.HasEltype() +Base.eltype(::Type{AbstractGrid{T}}) where {T} = eltype(T) """ struct Uniform{T<:AbstractFloat} <: ClosedGrid @@ -121,29 +127,29 @@ Uniform grid generated on [bound[1], bound[2]] with N points #Constructor: - function Uniform{T}(bound, size) where {T<:AbstractFloat} """ -struct Uniform{T<:AbstractFloat} <: ClosedGrid +struct Uniform{T<:AbstractFloat} <: ClosedGrid{T} bound::SVector{2,T} size::Int grid::Vector{T} weight::Vector{T} -""" - function Uniform{T}(bound, N) where {T<:AbstractFloat} + """ + function Uniform{T}(bound, N) where {T<:AbstractFloat} -create Uniform grid. -""" + create Uniform grid. + """ function Uniform{T}(bound, N) where {T<:AbstractFloat} Ntot = N - 1 - interval = (bound[2]-bound[1])/Ntot - grid = bound[1] .+ Vector(1:N) .* interval .- ( interval ) + interval = (bound[2] - bound[1]) / Ntot + grid = bound[1] .+ Vector(1:N) .* interval .- (interval) weight = similar(grid) for i in 1:N - if i==1 - weight[1] = 0.5*(grid[2]-grid[1]) - elseif i==N - weight[end] = 0.5*(grid[end]-grid[end-1]) + if i == 1 + weight[1] = 0.5 * (grid[2] - grid[1]) + elseif i == N + weight[end] = 0.5 * (grid[end] - grid[end-1]) else - weight[i] = 0.5*(grid[i+1]-grid[i-1]) + weight[i] = 0.5 * (grid[i+1] - grid[i-1]) end end return new{T}(bound, N, grid, weight) @@ -159,11 +165,11 @@ grid point smaller than x. return 1 for xgrid[end]. """ function Base.floor(grid::Uniform{T}, x) where {T} - result = (x-grid.grid[1])/(grid.grid[end]-grid.grid[1])*(grid.size-1)+1 - if result <1 + result = (x - grid.grid[1]) / (grid.grid[end] - grid.grid[1]) * (grid.size - 1) + 1 + if result < 1 return 1 elseif result >= grid.size - return grid.size-1 + return grid.size - 1 else return Base.floor(Int, result) end @@ -184,23 +190,23 @@ BaryCheb grid generated on [bound[1], bound[2]] with order N. #Constructor: - function BaryCheb{T}(bound, size) where {T<:AbstractFloat} """ -struct BaryCheb{T<:AbstractFloat} <: OpenGrid +struct BaryCheb{T<:AbstractFloat} <: OpenGrid{T} bound::SVector{2,T} size::Int grid::Vector{T} weight::Vector{T} invVandermonde::Matrix{T} -""" - function BaryCheb{T}(bound, N) where {T<:AbstractFloat} + """ + function BaryCheb{T}(bound, N) where {T<:AbstractFloat} -create BaryCheb grid. -""" + create BaryCheb grid. + """ function BaryCheb{T}(bound, N) where {T<:AbstractFloat} order = N - x, w =barychebinit(order) + x, w = barychebinit(order) grid = zeros(T, N) a, b = bound[1], bound[2] - weight = (b - a) / 2 .* w + weight = (b - a) / 2 .* w grid = (a + b) / 2 .+ (b - a) / 2 .* x invVandermonde = inv(transpose(vandermonde(x))) @@ -209,10 +215,10 @@ create BaryCheb grid. function BaryCheb{T}(bound, N, invVandermonde) where {T<:AbstractFloat} # use given Vandermonde matrix, useful for composite grid that has many BaryCheb subgrids with same order order = N - x, w =barychebinit(order) + x, w = barychebinit(order) grid = zeros(T, N) a, b = bound[1], bound[2] - weight = (b - a) / 2 .* w + weight = (b - a) / 2 .* w grid = (a + b) / 2 .+ (b - a) / 2 .* x return new{T}(bound, N, grid, weight, invVandermonde) end @@ -232,23 +238,23 @@ GaussLegendre grid generated on [bound[1], bound[2]] with order N. #Constructor: - function GaussLegendre{T}(bound, size) where {T<:AbstractFloat} """ -struct GaussLegendre{T<:AbstractFloat} <: OpenGrid +struct GaussLegendre{T<:AbstractFloat} <: OpenGrid{T} bound::SVector{2,T} size::Int grid::Vector{T} weight::Vector{T} -""" - function GaussLegendre{T}(bound, N) where {T<:AbstractFloat} + """ + function GaussLegendre{T}(bound, N) where {T<:AbstractFloat} -create GaussLegendre grid. -""" + create GaussLegendre grid. + """ function GaussLegendre{T}(bound, N) where {T<:AbstractFloat} order = N x, w = gausslegendre(order) grid = zeros(T, N) a, b = bound[1], bound[2] - weight = (b - a) / 2 .* w + weight = (b - a) / 2 .* w grid = (a + b) / 2 .+ (b - a) / 2 .* x return new{T}(bound, N, grid, weight) @@ -276,7 +282,7 @@ On [0, 1], a typical d2s Log grid looks like #Constructor: - function Log{T}(bound, size, minterval, d2s) where {T<:AbstractFloat} """ -struct Log{T<:AbstractFloat} <: ClosedGrid +struct Log{T<:AbstractFloat} <: ClosedGrid{T} bound::SVector{2,T} size::Int grid::Vector{T} @@ -285,39 +291,39 @@ struct Log{T<:AbstractFloat} <: ClosedGrid λ::T d2s::Bool -""" - function Log{T}(bound, N, minterval, d2s) where {T<:AbstractFloat} + """ + function Log{T}(bound, N, minterval, d2s) where {T<:AbstractFloat} -create Log grid. -""" + create Log grid. + """ function Log{T}(bound, N, minterval, d2s) where {T<:AbstractFloat} grid = zeros(T, N) - M = N-2 - λ = (minterval/(bound[2]-bound[1]))^(1.0/M) + M = N - 2 + λ = (minterval / (bound[2] - bound[1]))^(1.0 / M) if d2s for i in 1:M - grid[i+1] = bound[1] + (bound[2]-bound[1])*λ^(M+1-i) + grid[i+1] = bound[1] + (bound[2] - bound[1]) * λ^(M + 1 - i) end else for i in 2:M+1 - grid[i] = bound[2] - (bound[2]-bound[1])*λ^(i-1) + grid[i] = bound[2] - (bound[2] - bound[1]) * λ^(i - 1) end end grid[1] = bound[1] grid[end] = bound[2] weight = similar(grid) for i in 1:N - if i==1 - weight[1] = 0.5*(grid[2]-grid[1]) - elseif i==N - weight[end] = 0.5*(grid[end]-grid[end-1]) + if i == 1 + weight[1] = 0.5 * (grid[2] - grid[1]) + elseif i == N + weight[end] = 0.5 * (grid[end] - grid[end-1]) else - weight[i] = 0.5*(grid[i+1]-grid[i-1]) + weight[i] = 0.5 * (grid[i+1] - grid[i-1]) end end - return new{T}(bound, N, grid,weight, λ, d2s) + return new{T}(bound, N, grid, weight, λ, d2s) end end @@ -334,23 +340,23 @@ function Base.floor(grid::Log{T}, x) where {T} if x <= grid.grid[1] return 1 elseif x >= grid.grid[end] - return grid.size-1 + return grid.size - 1 end - a,b=grid.bound[1],grid.bound[2] + a, b = grid.bound[1], grid.bound[2] if grid.d2s - i = Base.floor( log((x-a)/(b-a))/log(grid.λ) ) - if i > grid.size-2 + i = Base.floor(log((x - a) / (b - a)) / log(grid.λ)) + if i > grid.size - 2 result = 1 else - result = grid.size-i-1 + result = grid.size - i - 1 end else - i = Base.floor( log((b-x)/(b-a))/log(grid.λ) ) - if i > grid.size-2 - result = grid.size-1 + i = Base.floor(log((b - x) / (b - a)) / log(grid.λ)) + if i > grid.size - 2 + result = grid.size - 1 else - result = i+1 + result = i + 1 end end @@ -358,7 +364,7 @@ function Base.floor(grid::Log{T}, x) where {T} end @inline function denseindex(grid::Log) - return [(grid.d2s) ? 1 : grid.size, ] + return [(grid.d2s) ? 1 : grid.size,] end end