comparison src/SbpOperators/readoperator.jl @ 864:9a2776352c2a

Merge operator_storage_array_of_table
author Jonatan Werpers <jonatan@werpers.com>
date Wed, 19 Jan 2022 11:08:43 +0100
parents 568058183791
children 06c510d40ebb 7bf3121c6864
comparison
equal deleted inserted replaced
858:5088de9b6d65 864:9a2776352c2a
1 using TOML 1 using TOML
2 2
3 export read_D2_operator 3 export read_stencil_set
4 export read_stencil 4 export get_stencil_set
5 export read_stencils
6 export read_tuple
7 5
8 export get_stencil 6 export parse_stencil
9 export get_stencils 7 export parse_scalar
10 export get_tuple 8 export parse_tuple
11 9
12 function read_D2_operator(fn; order) 10 export sbp_operators_path
13 operators = TOML.parsefile(fn)["order$order"]
14 D2 = operators["D2"]
15 H = operators["H"]
16 e = operators["e"]
17 d1 = operators["d1"]
18 11
19 # Create inner stencil
20 innerStencil = get_stencil(operators, "D2", "inner_stencil")
21 12
22 # Create boundary stencils 13 """
23 boundarySize = length(D2["closure_stencils"]) 14 read_stencil_set(filename; filters)
24 closureStencils = Vector{typeof(innerStencil)}() # TBD: is the the right way to get the correct type?
25 for i ∈ 1:boundarySize
26 closureStencils = (closureStencils..., get_stencil(operators, "D2", "closure_stencils", i; center=i))
27 end
28 # TODO: Get rid of the padding here. Any padding should be handled by the consturctor accepting the stencils.
29 eClosure = Stencil(pad_tuple(toml_string_array_to_tuple(Float64, e["closure"]), boundarySize)..., center=1)
30 dClosure = Stencil(pad_tuple(toml_string_array_to_tuple(Float64, d1["closure"]), boundarySize)..., center=1)
31 15
32 q_tuple = pad_tuple(toml_string_array_to_tuple(Float64, H["closure"]), boundarySize) 16 Picks out a stencil set from a TOML file based on some key-value
33 quadratureClosure = Vector{typeof(innerStencil)}() 17 filters. If more than one set matches the filters an error is raised. The
34 for i ∈ 1:boundarySize 18 returned stencil set contains parsed TOML intended for functions like
35 quadratureClosure = (quadratureClosure..., Stencil(q_tuple[i], center=1)) 19 `parse_scalar` and `parse_stencil`.
20
21 The stencil set is not parsed beyond the inital TOML parse. To get usable
22 stencils use the `parse_stencil` functions on the fields of the stencil set.
23
24 The reason for this is that since stencil sets are intended to be very
25 general, and currently do not include any way to specify how to parse a given
26 section, the exact parsing is left to the user.
27
28 For more information see [Operator file format](@ref) in the documentation.
29
30 See also [`sbp_operators_path`](@ref), [`get_stencil_set`](@ref), [`parse_stencil`](@ref), [`parse_scalar`](@ref), [`parse_tuple`](@ref),.
31 """
32 read_stencil_set(filename; filters...) = get_stencil_set(TOML.parsefile(filename); filters...)
33
34 """
35 get_stencil_set(parsed_toml; filters...)
36
37 Picks out a stencil set from an already parsed TOML based on some key-value
38 filters.
39
40 See also [`read_stencil_set`](@ref).
41 """
42 function get_stencil_set(parsed_toml; filters...)
43 matches = findall(parsed_toml["stencil_set"]) do set
44 for (key, val) ∈ filters
45 if set[string(key)] != val
46 return false
47 end
48 end
49
50 return true
36 end 51 end
37 52
38 d2 = SbpOperators.D2( 53 if length(matches) != 1
39 innerStencil, 54 throw(ArgumentError("filters must pick out a single stencil set"))
40 closureStencils, 55 end
41 eClosure,
42 dClosure,
43 quadratureClosure,
44 even
45 )
46 56
47 return d2 57 i = matches[1]
58 return parsed_toml["stencil_set"][i]
59 end
60
61 """
62 parse_stencil(parsed_toml)
63
64 Accepts parsed TOML and reads it as a stencil.
65
66 See also [`read_stencil_set`](@ref), [`parse_scalar`](@ref), [`parse_tuple`](@ref).
67 """
68 function parse_stencil(parsed_toml)
69 check_stencil_toml(parsed_toml)
70
71 if parsed_toml isa Array
72 weights = parse_rational.(parsed_toml)
73 return CenteredStencil(weights...)
74 end
75
76 weights = parse_rational.(parsed_toml["s"])
77 return Stencil(weights..., center = parsed_toml["c"])
78 end
79
80 """
81 parse_stencil(T, parsed_toml)
82
83 Parses the input as a stencil with element type `T`.
84 """
85 parse_stencil(T, parsed_toml) = Stencil{T}(parse_stencil(parsed_toml))
86
87 function check_stencil_toml(parsed_toml)
88 if !(parsed_toml isa Dict || parsed_toml isa Vector{String})
89 throw(ArgumentError("the TOML for a stencil must be a vector of strings or a table."))
90 end
91
92 if parsed_toml isa Vector{String}
93 return
94 end
95
96 if !(haskey(parsed_toml, "s") && haskey(parsed_toml, "c"))
97 throw(ArgumentError("the table form of a stencil must have fields `s` and `c`."))
98 end
99
100 if !(parsed_toml["s"] isa Vector{String})
101 throw(ArgumentError("a stencil must be specified as a vector of strings."))
102 end
103
104 if !(parsed_toml["c"] isa Int)
105 throw(ArgumentError("the center of a stencil must be specified as an integer."))
106 end
107 end
108
109 """
110 parse_scalar(parsed_toml)
111
112 Parse a scalar, represented as a string or a number in the TOML, and return it as a `Rational`
113
114 See also [`read_stencil_set`](@ref), [`parse_stencil`](@ref) [`parse_tuple`](@ref).
115 """
116 function parse_scalar(parsed_toml)
117 try
118 return parse_rational(parsed_toml)
119 catch e
120 throw(ArgumentError("must be a number or a string representing a number."))
121 end
122 end
123
124 """
125 parse_tuple(parsed_toml)
126
127 Parse an array as a tuple of scalars.
128
129 See also [`read_stencil_set`](@ref), [`parse_stencil`](@ref), [`parse_scalar`](@ref).
130 """
131 function parse_tuple(parsed_toml)
132 if !(parsed_toml isa Array)
133 throw(ArgumentError("argument must be an array"))
134 end
135 return Tuple(parse_scalar.(parsed_toml))
48 end 136 end
49 137
50 138
51 """ 139 """
52 read_stencil(fn, path...; [center]) 140 parse_rational(parsed_toml)
53 141
54 Read a stencil at `path` from the file with name `fn`. 142 Parse a string or a number as a rational.
55 If a center is specified the given element of the stecil is set as the center.
56
57 See also: [`read_stencils`](@ref), [`read_tuple`](@ref), [`get_stencil`](@ref).
58
59 # Examples
60 ```
61 read_stencil(sbp_operators_path()*"standard_diagonal.toml", "order2", "D2", "inner_stencil")
62 read_stencil(sbp_operators_path()*"standard_diagonal.toml", "order2", "d1", "closure"; center=1)
63 ```
64 """ 143 """
65 read_stencil(fn, path...; center=nothing) = get_stencil(TOML.parsefile(fn), path...; center=center) 144 function parse_rational(parsed_toml)
66 145 if parsed_toml isa String
67 """ 146 expr = Meta.parse(replace(parsed_toml, "/"=>"//"))
68 read_stencils(fn, path...; centers) 147 return eval(:(Rational($expr)))
69 148 else
70 Read stencils at `path` from the file `fn`. 149 return Rational(parsed_toml)
71 Centers of the stencils are specified as a tuple or array in `centers`.
72
73 See also: [`read_stencil`](@ref), [`read_tuple`](@ref), [`get_stencils`](@ref).
74 """
75 read_stencils(fn, path...; centers) = get_stencils(TOML.parsefile(fn), path...; centers=centers)
76
77 """
78 read_tuple(fn, path...)
79
80 Read tuple at `path` from the file `fn`.
81
82 See also: [`read_stencil`](@ref), [`read_stencils`](@ref), [`get_tuple`](@ref).
83 """
84 read_tuple(fn, path...) = get_tuple(TOML.parsefile(fn), path...)
85
86 """
87 get_stencil(parsed_toml, path...; center=nothing)
88
89 Same as [`read_stencil`](@ref)) but takes already parsed toml.
90 """
91 get_stencil(parsed_toml, path...; center=nothing) = get_stencil(parsed_toml[path[1]], path[2:end]...; center=center)
92 function get_stencil(parsed_toml; center=nothing)
93 @assert parsed_toml isa Vector{String}
94 stencil_weights = Float64.(parse_rational.(parsed_toml))
95
96 width = length(stencil_weights)
97
98 if isnothing(center)
99 center = div(width,2)+1
100 end 150 end
101
102 return Stencil(stencil_weights..., center=center)
103 end 151 end
104 152
105 """ 153 """
106 get_stencils(parsed_toml, path...; centers) 154 sbp_operators_path()
107 155
108 Same as [`read_stencils`](@ref)) but takes already parsed toml. 156 Calculate the path for the operators folder with included stencil sets.
157
158 See also [`read_stencil_set`](@ref)
109 """ 159 """
110 get_stencils(parsed_toml, path...; centers) = get_stencils(parsed_toml[path[1]], path[2:end]...; centers=centers)
111 function get_stencils(parsed_toml; centers)
112 @assert parsed_toml isa Vector{Vector{String}}
113 @assert length(centers) == length(parsed_toml)
114
115 stencils = ()
116 for i ∈ 1:length(parsed_toml)
117 stencil = get_stencil(parsed_toml[i], center = centers[i])
118 stencils = (stencils..., stencil)
119 end
120
121 return stencils
122 end
123
124 """
125 get_tuple(parsed_toml, path...)
126
127 Same as [`read_tuple`](@ref)) but takes already parsed toml.
128 """
129 get_tuple(parsed_toml, path...) = get_tuple(parsed_toml[path[1]], path[2:end]...)
130 function get_tuple(parsed_toml)
131 @assert parsed_toml isa Vector{String}
132 t = Tuple(Float64.(parse_rational.(parsed_toml)))
133 return t
134 end
135
136 # TODO: Probably should be deleted once we have gotten rid of read_D2_operator()
137 function toml_string_array_to_tuple(::Type{T}, arr::AbstractVector{String}) where T
138 return Tuple(T.(parse_rational.(arr)))
139 end
140
141 function parse_rational(str)
142 expr = Meta.parse(replace(str, "/"=>"//"))
143 return eval(:(Rational($expr)))
144 end
145
146 function pad_tuple(t::NTuple{N, T}, n::Integer) where {N,T}
147 if N >= n
148 return t
149 else
150 return pad_tuple((t..., zero(T)), n)
151 end
152 end
153
154 sbp_operators_path() = (@__DIR__) * "/operators/" 160 sbp_operators_path() = (@__DIR__) * "/operators/"
155 export sbp_operators_path