Mercurial > repos > public > sbplib_julia
comparison src/SbpOperators/stencil_set.jl @ 1019:3031ce7a4999 feature/stencil_set_type
Rename readoperator.jl to stencil_set.jl
| author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
|---|---|
| date | Tue, 22 Mar 2022 10:02:47 +0100 |
| parents | src/SbpOperators/readoperator.jl@5ec49dd2c7c4 |
| children | 3bb94ce74697 ec2a4d5dd8e8 |
comparison
equal
deleted
inserted
replaced
| 1018:5ec49dd2c7c4 | 1019:3031ce7a4999 |
|---|---|
| 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 parse_scalar(parsed_toml) | |
| 115 | |
| 116 Parse a scalar, represented as a string or a number in the TOML, and return it as a `Rational` | |
| 117 | |
| 118 See also [`read_stencil_set`](@ref), [`parse_stencil`](@ref) [`parse_tuple`](@ref). | |
| 119 """ | |
| 120 function parse_scalar(parsed_toml) | |
| 121 try | |
| 122 return parse_rational(parsed_toml) | |
| 123 catch e | |
| 124 throw(ArgumentError("must be a number or a string representing a number.")) | |
| 125 end | |
| 126 end | |
| 127 | |
| 128 """ | |
| 129 parse_tuple(parsed_toml) | |
| 130 | |
| 131 Parse an array as a tuple of scalars. | |
| 132 | |
| 133 See also [`read_stencil_set`](@ref), [`parse_stencil`](@ref), [`parse_scalar`](@ref). | |
| 134 """ | |
| 135 function parse_tuple(parsed_toml) | |
| 136 if !(parsed_toml isa Array) | |
| 137 throw(ArgumentError("argument must be an array")) | |
| 138 end | |
| 139 return Tuple(parse_scalar.(parsed_toml)) | |
| 140 end | |
| 141 | |
| 142 | |
| 143 """ | |
| 144 parse_rational(parsed_toml) | |
| 145 | |
| 146 Parse a string or a number as a rational. | |
| 147 """ | |
| 148 function parse_rational(parsed_toml) | |
| 149 if parsed_toml isa String | |
| 150 expr = Meta.parse(replace(parsed_toml, "/"=>"//")) | |
| 151 return eval(:(Rational($expr))) | |
| 152 else | |
| 153 return Rational(parsed_toml) | |
| 154 end | |
| 155 end | |
| 156 | |
| 157 """ | |
| 158 sbp_operators_path() | |
| 159 | |
| 160 Calculate the path for the operators folder with included stencil sets. | |
| 161 | |
| 162 See also [`StencilSet`](@ref), [`read_stencil_set`](@ref). | |
| 163 """ | |
| 164 sbp_operators_path() = (@__DIR__) * "/operators/" |
