Mercurial > repos > public > sbplib_julia
view src/SbpOperators/readoperator.jl @ 767:210d3f58bd56 operator_storage_array_of_table
Make signature of read_stencil_set conform to signature of get_stencil_set
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Wed, 14 Jul 2021 23:22:34 +0200 |
parents | 7624a1350ece |
children | 7c87a33963c5 |
line wrap: on
line source
using TOML export read_stencil_set export get_stencil_set export parse_stencil export read_D2_operator export read_stencil export read_stencils export read_tuple export get_stencil export get_stencils export get_tuple function read_D2_operator(fn; order) operators = TOML.parsefile(fn)["order$order"] D2 = operators["D2"] H = operators["H"] e = operators["e"] d1 = operators["d1"] # Create inner stencil innerStencil = get_stencil(operators, "D2", "inner_stencil") # Create boundary stencils boundarySize = length(D2["closure_stencils"]) closureStencils = Vector{typeof(innerStencil)}() # TBD: is the the right way to get the correct type? for i ∈ 1:boundarySize closureStencils = (closureStencils..., get_stencil(operators, "D2", "closure_stencils", i; center=i)) end # TODO: Get rid of the padding here. Any padding should be handled by the consturctor accepting the stencils. eClosure = Stencil(pad_tuple(toml_string_array_to_tuple(Float64, e["closure"]), boundarySize)..., center=1) dClosure = Stencil(pad_tuple(toml_string_array_to_tuple(Float64, d1["closure"]), boundarySize)..., center=1) q_tuple = pad_tuple(toml_string_array_to_tuple(Float64, H["closure"]), boundarySize) quadratureClosure = Vector{typeof(innerStencil)}() for i ∈ 1:boundarySize quadratureClosure = (quadratureClosure..., Stencil(q_tuple[i], center=1)) end d2 = SbpOperators.D2( innerStencil, closureStencils, eClosure, dClosure, quadratureClosure, even ) return d2 end """ read_stencil_set(fn; filters) Picks out a stencil set from the given toml file based on some filters. If more than one set matches the filters an error is raised. The stencil set is not parsed beyond the inital toml parse. To get usable stencils use the `parse_stencil` functions on the fields of the stencil set. """ read_stencil_set(fn; filters...) = get_stencil_set(TOML.parsefile(fn), filters...) """ get_stencil_set(parsed_toml; filters...) Same as `read_stencil_set` but works on already parsed TOML. """ function get_stencil_set(parsed_toml; filters...) matches = findall(parsed_toml["stencil_set"]) do set for (key, val) ∈ filters if set[string(key)] != val return false end end return true end if length(matches) != 1 throw(ArgumentError("filters must pick out a single stencil set")) end i = matches[1] return parsed_toml["stencil_set"][i] end function parse_stencil(toml) check_stencil_toml(toml) if toml isa Array weights = Float64.(parse_rational.(toml)) return CenteredStencil(weights...) end weights = Float64.(parse_rational.(toml["s"])) return Stencil(weights..., center = toml["c"]) end function check_stencil_toml(toml) if !(toml isa Dict || toml isa Vector{String}) throw(ArgumentError("the TOML for a stecil must be a vector of strings or a table.")) end if toml isa Vector{String} return end if !(haskey(toml, "s") && haskey(toml, "c")) throw(ArgumentError("the table form of a stencil must have fields `s` and `c`.")) end if !(toml["s"] isa Vector{String}) throw(ArgumentError("a stencil must be specified as a vector of strings.")) end if !(toml["c"] isa Int) throw(ArgumentError("the center of a stencil must be specified as an integer.")) end end """ read_stencil(fn, path...; [center]) Read a stencil at `path` from the file with name `fn`. If a center is specified the given element of the stecil is set as the center. See also: [`read_stencils`](@ref), [`read_tuple`](@ref), [`get_stencil`](@ref). # Examples ``` read_stencil(sbp_operators_path()*"standard_diagonal.toml", "order2", "D2", "inner_stencil") read_stencil(sbp_operators_path()*"standard_diagonal.toml", "order2", "d1", "closure"; center=1) ``` """ read_stencil(fn, path...; center=nothing) = get_stencil(TOML.parsefile(fn), path...; center=center) """ read_stencils(fn, path...; centers) Read stencils at `path` from the file `fn`. Centers of the stencils are specified as a tuple or array in `centers`. See also: [`read_stencil`](@ref), [`read_tuple`](@ref), [`get_stencils`](@ref). """ read_stencils(fn, path...; centers) = get_stencils(TOML.parsefile(fn), path...; centers=centers) """ read_tuple(fn, path...) Read tuple at `path` from the file `fn`. See also: [`read_stencil`](@ref), [`read_stencils`](@ref), [`get_tuple`](@ref). """ read_tuple(fn, path...) = get_tuple(TOML.parsefile(fn), path...) """ get_stencil(parsed_toml, path...; center=nothing) Same as [`read_stencil`](@ref)) but takes already parsed toml. """ get_stencil(parsed_toml, path...; center=nothing) = get_stencil(parsed_toml[path[1]], path[2:end]...; center=center) function get_stencil(parsed_toml; center=nothing) @assert parsed_toml isa Vector{String} stencil_weights = Float64.(parse_rational.(parsed_toml)) width = length(stencil_weights) if isnothing(center) center = div(width,2)+1 end return Stencil(stencil_weights..., center=center) end """ get_stencils(parsed_toml, path...; centers) Same as [`read_stencils`](@ref)) but takes already parsed toml. """ get_stencils(parsed_toml, path...; centers) = get_stencils(parsed_toml[path[1]], path[2:end]...; centers=centers) function get_stencils(parsed_toml; centers) @assert parsed_toml isa Vector{Vector{String}} @assert length(centers) == length(parsed_toml) stencils = () for i ∈ 1:length(parsed_toml) stencil = get_stencil(parsed_toml[i], center = centers[i]) stencils = (stencils..., stencil) end return stencils end """ get_tuple(parsed_toml, path...) Same as [`read_tuple`](@ref)) but takes already parsed toml. """ get_tuple(parsed_toml, path...) = get_tuple(parsed_toml[path[1]], path[2:end]...) function get_tuple(parsed_toml) @assert parsed_toml isa Vector{String} t = Tuple(Float64.(parse_rational.(parsed_toml))) return t end function get_rationals() end # TODO: Probably should be deleted once we have gotten rid of read_D2_operator() function toml_string_array_to_tuple(::Type{T}, arr::AbstractVector{String}) where T return Tuple(T.(parse_rational.(arr))) end function parse_rational(str) expr = Meta.parse(replace(str, "/"=>"//")) return eval(:(Rational($expr))) end function pad_tuple(t::NTuple{N, T}, n::Integer) where {N,T} if N >= n return t else return pad_tuple((t..., zero(T)), n) end end sbp_operators_path() = (@__DIR__) * "/operators/" export sbp_operators_path