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