comparison src/SbpOperators/stencil_set.jl @ 1049:3bb94ce74697 feature/variable_derivatives

Merge default
author Jonatan Werpers <jonatan@werpers.com>
date Wed, 23 Mar 2022 12:54:45 +0100
parents src/SbpOperators/readoperator.jl@d24b331547f3 src/SbpOperators/readoperator.jl@3031ce7a4999
children 102ebdaf7c11
comparison
equal deleted inserted replaced
1048:86aa69ad3304 1049:3bb94ce74697
1 using TOML
2
3
4 """
5 StencilSet
6
7 A `StencilSet` contains a set of associated stencils. The stencils
8 are are stored in a table, and can be accesed by indexing into the `StencilSet`.
9 """
10 struct StencilSet
11 table
12 end
13 Base.getindex(set::StencilSet,I...) = set.table[I...]
14
15
16 """
17 read_stencil_set(filename; filters)
18
19 Creates a `StencilSet` from a TOML file based on some key-value
20 filters. If more than one set matches the filters an error is raised. The
21 table of the `StencilSet` is a parsed TOML intended for functions like
22 `parse_scalar` and `parse_stencil`.
23
24 The `StencilSet` table is not parsed beyond the inital TOML parse. To get usable
25 stencils use the `parse_stencil` functions on the fields of the stencil set.
26
27 The reason for this is that since stencil sets are intended to be very
28 general, and currently do not include any way to specify how to parse a given
29 section, the exact parsing is left to the user.
30
31 For more information see [Operator file format](@ref) in the documentation.
32
33 See also [`StencilSet`](@ref), [`sbp_operators_path`](@ref), [`get_stencil_set`](@ref), [`parse_stencil`](@ref), [`parse_scalar`](@ref), [`parse_tuple`](@ref).
34 """
35 read_stencil_set(filename; filters...) = StencilSet(get_stencil_set(TOML.parsefile(filename); filters...))
36
37
38 """
39 get_stencil_set(parsed_toml; filters...)
40
41 Picks out a stencil set from an already parsed TOML based on some key-value
42 filters.
43
44 See also [`read_stencil_set`](@ref).
45 """
46 function get_stencil_set(parsed_toml; filters...)
47 matches = findall(parsed_toml["stencil_set"]) do set
48 for (key, val) ∈ filters
49 if set[string(key)] != val
50 return false
51 end
52 end
53
54 return true
55 end
56
57 if length(matches) != 1
58 throw(ArgumentError("filters must pick out a single stencil set"))
59 end
60
61 i = matches[1]
62 return parsed_toml["stencil_set"][i]
63 end
64
65 """
66 parse_stencil(parsed_toml)
67
68 Accepts parsed TOML and reads it as a stencil.
69
70 See also [`read_stencil_set`](@ref), [`parse_scalar`](@ref), [`parse_tuple`](@ref).
71 """
72 function parse_stencil(parsed_toml)
73 check_stencil_toml(parsed_toml)
74
75 if parsed_toml isa Array
76 weights = parse_rational.(parsed_toml)
77 return CenteredStencil(weights...)
78 end
79
80 weights = parse_rational.(parsed_toml["s"])
81 return Stencil(weights..., center = parsed_toml["c"])
82 end
83
84 """
85 parse_stencil(T, parsed_toml)
86
87 Parses the input as a stencil with element type `T`.
88 """
89 parse_stencil(T, parsed_toml) = Stencil{T}(parse_stencil(parsed_toml))
90
91 function check_stencil_toml(parsed_toml)
92 if !(parsed_toml isa Dict || parsed_toml isa Vector{String})
93 throw(ArgumentError("the TOML for a stencil must be a vector of strings or a table."))
94 end
95
96 if parsed_toml isa Vector{String}
97 return
98 end
99
100 if !(haskey(parsed_toml, "s") && haskey(parsed_toml, "c"))
101 throw(ArgumentError("the table form of a stencil must have fields `s` and `c`."))
102 end
103
104 if !(parsed_toml["s"] isa Vector{String})
105 throw(ArgumentError("a stencil must be specified as a vector of strings."))
106 end
107
108 if !(parsed_toml["c"] isa Int)
109 throw(ArgumentError("the center of a stencil must be specified as an integer."))
110 end
111 end
112
113
114 """
115 parse_nested_stencil(parsed_toml)
116
117 Accept parsed TOML and read it as a nested tuple.
118
119 See also [`read_stencil_set`](@ref), [`parse_stencil`](@ref).
120 """
121 function parse_nested_stencil(parsed_toml)
122 if parsed_toml isa Array
123 weights = parse_stencil.(parsed_toml)
124 return CenteredNestedStencil(weights...)
125 end
126
127 center = parsed_toml["c"]
128 weights = parse_tuple.(parsed_toml["s"])
129 return NestedStencil(weights...; center)
130 end
131
132 """
133 parse_nested_stencil(T, parsed_toml)
134
135 Parse the input as a nested stencil with element type `T`.
136 """
137 parse_nested_stencil(T, parsed_toml) = NestedStencil{T}(parse_nested_stencil(parsed_toml))
138
139
140 """
141 parse_scalar(parsed_toml)
142
143 Parse a scalar, represented as a string or a number in the TOML, and return it as a `Rational`
144
145 See also [`read_stencil_set`](@ref), [`parse_stencil`](@ref) [`parse_tuple`](@ref).
146 """
147 function parse_scalar(parsed_toml)
148 try
149 return parse_rational(parsed_toml)
150 catch e
151 throw(ArgumentError("must be a number or a string representing a number."))
152 end
153 end
154
155 """
156 parse_tuple(parsed_toml)
157
158 Parse an array as a tuple of scalars.
159
160 See also [`read_stencil_set`](@ref), [`parse_stencil`](@ref), [`parse_scalar`](@ref).
161 """
162 function parse_tuple(parsed_toml)
163 if !(parsed_toml isa Array)
164 throw(ArgumentError("argument must be an array"))
165 end
166 return Tuple(parse_scalar.(parsed_toml))
167 end
168
169
170 """
171 parse_rational(parsed_toml)
172
173 Parse a string or a number as a rational.
174 """
175 function parse_rational(parsed_toml)
176 if parsed_toml isa String
177 expr = Meta.parse(replace(parsed_toml, "/"=>"//"))
178 return eval(:(Rational($expr)))
179 else
180 return Rational(parsed_toml)
181 end
182 end
183
184 """
185 sbp_operators_path()
186
187 Calculate the path for the operators folder with included stencil sets.
188
189 See also [`StencilSet`](@ref), [`read_stencil_set`](@ref).
190 """
191 sbp_operators_path() = (@__DIR__) * "/operators/"