changeset 766:7624a1350ece operator_storage_array_of_table

Add parse_stencil
author Jonatan Werpers <jonatan@werpers.com>
date Sat, 13 Feb 2021 22:17:55 +0100
parents fdd48f6ace1c
children 210d3f58bd56
files src/SbpOperators/readoperator.jl test/testSbpOperators.jl
diffstat 2 files changed, 68 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/SbpOperators/readoperator.jl	Sun Feb 07 21:32:21 2021 +0100
+++ b/src/SbpOperators/readoperator.jl	Sat Feb 13 22:17:55 2021 +0100
@@ -3,6 +3,8 @@
 export read_stencil_set
 export get_stencil_set
 
+export parse_stencil
+
 export read_D2_operator
 export read_stencil
 export read_stencils
@@ -85,6 +87,40 @@
     return parsed_toml["stencil_set"][i]
 end
 
+function parse_stencil(toml)
+    check_stencil_toml(toml)
+
+    if toml isa Array
+        weights = Float64.(parse_rational.(toml))
+        return CenteredStencil(weights...)
+    end
+
+    weights = Float64.(parse_rational.(toml["s"]))
+    return Stencil(weights..., center = toml["c"])
+end
+
+function check_stencil_toml(toml)
+    if !(toml isa Dict || toml isa Vector{String})
+        throw(ArgumentError("the TOML for a stecil must be a vector of strings or a table."))
+    end
+
+    if toml isa Vector{String}
+        return
+    end
+
+    if !(haskey(toml, "s") && haskey(toml, "c"))
+        throw(ArgumentError("the table form of a stencil must have fields `s` and `c`."))
+    end
+
+    if !(toml["s"] isa Vector{String})
+        throw(ArgumentError("a stencil must be specified as a vector of strings."))
+    end
+
+    if !(toml["c"] isa Int)
+        throw(ArgumentError("the center of a stencil must be specified as an integer."))
+    end
+end
+
 """
     read_stencil(fn, path...; [center])
 
--- a/test/testSbpOperators.jl	Sun Feb 07 21:32:21 2021 +0100
+++ b/test/testSbpOperators.jl	Sat Feb 13 22:17:55 2021 +0100
@@ -107,6 +107,38 @@
         @test_throws ArgumentError get_stencil_set(parsed_toml; order = 4)
     end
 
+    @testset "parse_stencil" begin
+        toml = """
+            s1 = ["-1/12","4/3","-5/2","4/3","-1/12"]
+            s2 = {s = ["2", "-5", "4", "-1", "0", "0"], c = 1}
+            s3 = {s = ["1", "-2", "1", "0", "0", "0"], c = 2}
+            s4 = "not a stencil"
+            s5 = [-1, 4, 3]
+            s6 = {k = ["1", "-2", "1", "0", "0", "0"], c = 2}
+            s7 = {s = [-1, 4, 3], c = 2}
+            s8 = {s = ["1", "-2", "1", "0", "0", "0"], c = [2,2]}
+        """
+
+        @test parse_stencil(TOML.parse(toml)["s1"]) == CenteredStencil(-1/12, 4/3, -5/2, 4/3, -1/12)
+        @test parse_stencil(TOML.parse(toml)["s2"]) == Stencil(2., -5., 4., -1., 0., 0.; center=1)
+        @test parse_stencil(TOML.parse(toml)["s3"]) == Stencil(1., -2., 1., 0., 0., 0.; center=2)
+
+        @test_throws ArgumentError parse_stencil(TOML.parse(toml)["s4"])
+        @test_throws ArgumentError parse_stencil(TOML.parse(toml)["s5"])
+        @test_throws ArgumentError parse_stencil(TOML.parse(toml)["s6"])
+        @test_throws ArgumentError parse_stencil(TOML.parse(toml)["s7"])
+        @test_throws ArgumentError parse_stencil(TOML.parse(toml)["s8"])
+
+        stencil_set = get_stencil_set(parsed_toml; order = 4, test = 1)
+
+        @test parse_stencil.(stencil_set["D2"]["closure_stencils"]) == [
+            Stencil(    2.,    -5.,      4.,       -1.,     0.,     0.; center=1),
+            Stencil(    1.,    -2.,      1.,        0.,     0.,     0.; center=2),
+            Stencil(-4/43, 59/43, -110/43,   59/43, -4/43,     0.; center=3),
+            Stencil(-1/49,     0.,   59/49, -118/49, 64/49, -4/49; center=4),
+        ]
+    end
+
     @testset "get_stencil" begin
         @test get_stencil(parsed_toml, "order2", "D1", "inner_stencil") == Stencil(-1/2, 0., 1/2, center=2)
         @test get_stencil(parsed_toml, "order2", "D1", "inner_stencil", center=1) == Stencil(-1/2, 0., 1/2; center=1)