Mercurial > repos > public > sbplib_julia
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 |