comparison test/SbpOperators/volumeops/laplace/laplace_test.jl @ 924:12e8e431b43c feature/laplace_opset

Start restructuring Laplace making it more minimal.
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Mon, 21 Feb 2022 13:12:47 +0100
parents 6a4d36eccf39
children 47425442bbc5
comparison
equal deleted inserted replaced
923:88bf50821cf5 924:12e8e431b43c
2 2
3 using Sbplib.SbpOperators 3 using Sbplib.SbpOperators
4 using Sbplib.Grids 4 using Sbplib.Grids
5 using Sbplib.LazyTensors 5 using Sbplib.LazyTensors
6 using Sbplib.RegionIndices 6 using Sbplib.RegionIndices
7 using Sbplib.StaticDicts
8 7
8 # Default stencils (4th order)
9 operator_path = sbp_operators_path()*"standard_diagonal.toml" 9 operator_path = sbp_operators_path()*"standard_diagonal.toml"
10 # Default stencils (4th order)
11 stencil_set = read_stencil_set(operator_path; order=4) 10 stencil_set = read_stencil_set(operator_path; order=4)
12 inner_stencil = parse_stencil(stencil_set["D2"]["inner_stencil"]) 11 inner_stencil = parse_stencil(stencil_set["D2"]["inner_stencil"])
13 closure_stencils = parse_stencil.(stencil_set["D2"]["closure_stencils"]) 12 closure_stencils = parse_stencil.(stencil_set["D2"]["closure_stencils"])
14 e_closure = parse_stencil(stencil_set["e"]["closure"])
15 d_closure = parse_stencil(stencil_set["d1"]["closure"])
16 quadrature_interior = parse_scalar(stencil_set["H"]["inner"])
17 quadrature_closure = parse_tuple(stencil_set["H"]["closure"])
18 13
19 @testset "Laplace" begin 14 @testset "Laplace" begin
20 g_1D = EquidistantGrid(101, 0.0, 1.) 15 g_1D = EquidistantGrid(101, 0.0, 1.)
21 g_3D = EquidistantGrid((51,101,52), (0.0, -1.0, 0.0), (1., 1., 1.)) 16 g_3D = EquidistantGrid((51,101,52), (0.0, -1.0, 0.0), (1., 1., 1.))
22 @testset "Constructors" begin 17 @testset "Constructors" begin
23 18
24 @testset "1D" begin 19 @testset "1D" begin
25 Δ = laplace(g_1D, inner_stencil, closure_stencils) 20 Δ = laplace(g_1D, inner_stencil, closure_stencils)
26 H = inner_product(g_1D, quadrature_interior, quadrature_closure) 21 @test Laplace(g_1D, stencil_set) == Laplace(Δ, stencil_set)
27 Hi = inverse_inner_product(g_1D, quadrature_interior, quadrature_closure) 22 @test Laplace(g_1D, stencil_set) isa TensorMapping{T,1,1} where T
28
29 (id_l, id_r) = boundary_identifiers(g_1D)
30
31 e_l = boundary_restriction(g_1D, e_closure,id_l)
32 e_r = boundary_restriction(g_1D, e_closure,id_r)
33 e_dict = StaticDict(id_l => e_l, id_r => e_r)
34
35 d_l = normal_derivative(g_1D, d_closure,id_l)
36 d_r = normal_derivative(g_1D, d_closure,id_r)
37 d_dict = StaticDict(id_l => d_l, id_r => d_r)
38
39 H_l = inner_product(boundary_grid(g_1D,id_l), quadrature_interior, quadrature_closure)
40 H_r = inner_product(boundary_grid(g_1D,id_r), quadrature_interior, quadrature_closure)
41 Hb_dict = StaticDict(id_l => H_l, id_r => H_r)
42
43 L = Laplace(g_1D, operator_path; order=4)
44 @test L == Laplace(Δ, H, Hi, e_dict, d_dict, Hb_dict)
45 @test L isa TensorMapping{T,1,1} where T
46 @inferred Laplace(Δ, H, Hi, e_dict, d_dict, Hb_dict)
47 # REVIEW: The tests above seem very tied to the implementation. Is
48 # it important that the components of the operator set are stored
49 # in static dicts? Is something like below better?
50 #
51 # ```
52 # L = Laplace(g_1D, operator_path; order=4)
53 # @test L isa TensorMapping{T,1,1} where T
54 # @test boundary_restriction(L,id_l) == boundary_restriction(g_1D, e_closure,id_l)
55 # ...
56 # ```
57 # I guess this is more or less simply a reorganization of the test and skipping testing for the struct layout
58 end 23 end
59 @testset "3D" begin 24 @testset "3D" begin
60 Δ = laplace(g_3D, inner_stencil, closure_stencils) 25 Δ = laplace(g_3D, inner_stencil, closure_stencils)
61 H = inner_product(g_3D, quadrature_interior, quadrature_closure) 26 @test Laplace(g_3D, stencil_set) == Laplace(Δ,stencil_set)
62 Hi = inverse_inner_product(g_3D, quadrature_interior, quadrature_closure) 27 @test Laplace(g_3D, stencil_set) isa TensorMapping{T,3,3} where T
63
64 (id_l, id_r, id_s, id_n, id_b, id_t) = boundary_identifiers(g_3D)
65 e_l = boundary_restriction(g_3D, e_closure,id_l)
66 e_r = boundary_restriction(g_3D, e_closure,id_r)
67 e_s = boundary_restriction(g_3D, e_closure,id_s)
68 e_n = boundary_restriction(g_3D, e_closure,id_n)
69 e_b = boundary_restriction(g_3D, e_closure,id_b)
70 e_t = boundary_restriction(g_3D, e_closure,id_t)
71 e_dict = StaticDict(id_l => e_l, id_r => e_r,
72 id_s => e_s, id_n => e_n,
73 id_b => e_b, id_t => e_t)
74
75 d_l = normal_derivative(g_3D, d_closure,id_l)
76 d_r = normal_derivative(g_3D, d_closure,id_r)
77 d_s = normal_derivative(g_3D, d_closure,id_s)
78 d_n = normal_derivative(g_3D, d_closure,id_n)
79 d_b = normal_derivative(g_3D, d_closure,id_b)
80 d_t = normal_derivative(g_3D, d_closure,id_t)
81 d_dict = StaticDict(id_l => d_l, id_r => d_r,
82 id_s => d_s, id_n => d_n,
83 id_b => d_b, id_t => d_t)
84
85 H_l = inner_product(boundary_grid(g_3D,id_l), quadrature_interior, quadrature_closure)
86 H_r = inner_product(boundary_grid(g_3D,id_r), quadrature_interior, quadrature_closure)
87 H_s = inner_product(boundary_grid(g_3D,id_s), quadrature_interior, quadrature_closure)
88 H_n = inner_product(boundary_grid(g_3D,id_n), quadrature_interior, quadrature_closure)
89 H_b = inner_product(boundary_grid(g_3D,id_b), quadrature_interior, quadrature_closure)
90 H_t = inner_product(boundary_grid(g_3D,id_t), quadrature_interior, quadrature_closure)
91 Hb_dict = StaticDict(id_l => H_l, id_r => H_r,
92 id_s => H_s, id_n => H_n,
93 id_b => H_b, id_t => H_t)
94
95 L = Laplace(g_3D, operator_path; order=4)
96 @test L == Laplace(Δ,H,Hi,e_dict,d_dict,Hb_dict)
97 @test L isa TensorMapping{T,3,3} where T
98 @inferred Laplace(Δ,H,Hi,e_dict,d_dict,Hb_dict)
99 end 28 end
100 end
101
102 # REVIEW: Is this testset misplaced? Should it really be inside the "Laplace" testset?
103 @testset "laplace" begin
104 @testset "1D" begin
105 L = laplace(g_1D, inner_stencil, closure_stencils)
106 @test L == second_derivative(g_1D, inner_stencil, closure_stencils)
107 @test L isa TensorMapping{T,1,1} where T
108 end
109 @testset "3D" begin
110 L = laplace(g_3D, inner_stencil, closure_stencils)
111 @test L isa TensorMapping{T,3,3} where T
112 Dxx = second_derivative(g_3D, inner_stencil, closure_stencils, 1)
113 Dyy = second_derivative(g_3D, inner_stencil, closure_stencils, 2)
114 Dzz = second_derivative(g_3D, inner_stencil, closure_stencils, 3)
115 @test L == Dxx + Dyy + Dzz
116 @test L isa TensorMapping{T,3,3} where T
117 end
118 end
119
120 @testset "inner_product" begin
121 L = Laplace(g_3D, operator_path; order=4)
122 @test inner_product(L) == inner_product(g_3D, quadrature_interior, quadrature_closure)
123 end
124
125 @testset "inverse_inner_product" begin
126 L = Laplace(g_3D, operator_path; order=4)
127 @test inverse_inner_product(L) == inverse_inner_product(g_3D, quadrature_interior, quadrature_closure)
128 end
129
130 @testset "boundary_restriction" begin
131 L = Laplace(g_3D, operator_path; order=4)
132 (id_l, id_r, id_s, id_n, id_b, id_t) = boundary_identifiers(g_3D)
133 @test boundary_restriction(L, id_l) == boundary_restriction(g_3D, e_closure,id_l)
134 @test boundary_restriction(L, id_r) == boundary_restriction(g_3D, e_closure,id_r)
135 @test boundary_restriction(L, id_s) == boundary_restriction(g_3D, e_closure,id_s)
136 @test boundary_restriction(L, id_n) == boundary_restriction(g_3D, e_closure,id_n)
137 @test boundary_restriction(L, id_b) == boundary_restriction(g_3D, e_closure,id_b)
138 @test boundary_restriction(L, id_t) == boundary_restriction(g_3D, e_closure,id_t)
139
140 ids = boundary_identifiers(g_3D)
141 es = boundary_restriction(L, ids)
142 @test es == (boundary_restriction(L, id_l),
143 boundary_restriction(L, id_r),
144 boundary_restriction(L, id_s),
145 boundary_restriction(L, id_n),
146 boundary_restriction(L, id_b),
147 boundary_restriction(L, id_t));
148 @test es == boundary_restriction(L, ids...)
149 end
150
151 @testset "normal_derivative" begin
152 L = Laplace(g_3D, operator_path; order=4)
153 (id_l, id_r, id_s, id_n, id_b, id_t) = boundary_identifiers(g_3D)
154 @test normal_derivative(L, id_l) == normal_derivative(g_3D, d_closure,id_l)
155 @test normal_derivative(L, id_r) == normal_derivative(g_3D, d_closure,id_r)
156 @test normal_derivative(L, id_s) == normal_derivative(g_3D, d_closure,id_s)
157 @test normal_derivative(L, id_n) == normal_derivative(g_3D, d_closure,id_n)
158 @test normal_derivative(L, id_b) == normal_derivative(g_3D, d_closure,id_b)
159 @test normal_derivative(L, id_t) == normal_derivative(g_3D, d_closure,id_t)
160
161 ids = boundary_identifiers(g_3D)
162 ds = normal_derivative(L, ids)
163 @test ds == (normal_derivative(L, id_l),
164 normal_derivative(L, id_r),
165 normal_derivative(L, id_s),
166 normal_derivative(L, id_n),
167 normal_derivative(L, id_b),
168 normal_derivative(L, id_t));
169 @test ds == normal_derivative(L, ids...)
170 end
171
172 @testset "boundary_quadrature" begin
173 L = Laplace(g_3D, operator_path; order=4)
174 (id_l, id_r, id_s, id_n, id_b, id_t) = boundary_identifiers(g_3D)
175 @test boundary_quadrature(L, id_l) == inner_product(boundary_grid(g_3D, id_l), quadrature_interior, quadrature_closure)
176 @test boundary_quadrature(L, id_r) == inner_product(boundary_grid(g_3D, id_r), quadrature_interior, quadrature_closure)
177 @test boundary_quadrature(L, id_s) == inner_product(boundary_grid(g_3D, id_s), quadrature_interior, quadrature_closure)
178 @test boundary_quadrature(L, id_n) == inner_product(boundary_grid(g_3D, id_n), quadrature_interior, quadrature_closure)
179 @test boundary_quadrature(L, id_b) == inner_product(boundary_grid(g_3D, id_b), quadrature_interior, quadrature_closure)
180 @test boundary_quadrature(L, id_t) == inner_product(boundary_grid(g_3D, id_t), quadrature_interior, quadrature_closure)
181
182 ids = boundary_identifiers(g_3D)
183 H_gammas = boundary_quadrature(L, ids)
184 @test H_gammas == (boundary_quadrature(L, id_l),
185 boundary_quadrature(L, id_r),
186 boundary_quadrature(L, id_s),
187 boundary_quadrature(L, id_n),
188 boundary_quadrature(L, id_b),
189 boundary_quadrature(L, id_t));
190 @test H_gammas == boundary_quadrature(L, ids...)
191 end 29 end
192 30
193 # Exact differentiation is measured point-wise. In other cases 31 # Exact differentiation is measured point-wise. In other cases
194 # the error is measured in the l2-norm. 32 # the error is measured in the l2-norm.
195 @testset "Accuracy" begin 33 @testset "Accuracy" begin
205 43
206 # 2nd order interior stencil, 1st order boundary stencil, 44 # 2nd order interior stencil, 1st order boundary stencil,
207 # implies that L*v should be exact for binomials up to order 2. 45 # implies that L*v should be exact for binomials up to order 2.
208 @testset "2nd order" begin 46 @testset "2nd order" begin
209 stencil_set = read_stencil_set(operator_path; order=2) 47 stencil_set = read_stencil_set(operator_path; order=2)
210 inner_stencil = parse_stencil(stencil_set["D2"]["inner_stencil"]) 48 Δ = Laplace(g_3D, stencil_set)
211 closure_stencils = parse_stencil.(stencil_set["D2"]["closure_stencils"]) 49 @test Δ*polynomials[1] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9
212 L = laplace(g_3D, inner_stencil, closure_stencils) 50 @test Δ*polynomials[2] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9
213 @test L*polynomials[1] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9 51 @test Δ*polynomials[3] ≈ polynomials[1] atol = 5e-9
214 @test L*polynomials[2] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9 52 @test Δ*v ≈ Δv rtol = 5e-2 norm = l2
215 @test L*polynomials[3] ≈ polynomials[1] atol = 5e-9
216 @test L*v ≈ Δv rtol = 5e-2 norm = l2
217 end 53 end
218 54
219 # 4th order interior stencil, 2nd order boundary stencil, 55 # 4th order interior stencil, 2nd order boundary stencil,
220 # implies that L*v should be exact for binomials up to order 3. 56 # implies that L*v should be exact for binomials up to order 3.
221 @testset "4th order" begin 57 @testset "4th order" begin
222 stencil_set = read_stencil_set(operator_path; order=4) 58 stencil_set = read_stencil_set(operator_path; order=4)
223 inner_stencil = parse_stencil(stencil_set["D2"]["inner_stencil"]) 59 Δ = Laplace(g_3D, stencil_set)
224 closure_stencils = parse_stencil.(stencil_set["D2"]["closure_stencils"])
225 L = laplace(g_3D, inner_stencil, closure_stencils)
226 # NOTE: high tolerances for checking the "exact" differentiation 60 # NOTE: high tolerances for checking the "exact" differentiation
227 # due to accumulation of round-off errors/cancellation errors? 61 # due to accumulation of round-off errors/cancellation errors?
228 @test L*polynomials[1] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9 62 @test Δ*polynomials[1] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9
229 @test L*polynomials[2] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9 63 @test Δ*polynomials[2] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9
230 @test L*polynomials[3] ≈ polynomials[1] atol = 5e-9 64 @test Δ*polynomials[3] ≈ polynomials[1] atol = 5e-9
231 @test L*polynomials[4] ≈ polynomials[2] atol = 5e-9 65 @test Δ*polynomials[4] ≈ polynomials[2] atol = 5e-9
232 @test L*v ≈ Δv rtol = 5e-4 norm = l2 66 @test Δ*v ≈ Δv rtol = 5e-4 norm = l2
233 end 67 end
234 end 68 end
235 end 69 end
70
71 @testset "laplace" begin
72 @testset "1D" begin
73 Δ = laplace(g_1D, inner_stencil, closure_stencils)
74 @test Δ == second_derivative(g_1D, inner_stencil, closure_stencils)
75 @test Δ isa TensorMapping{T,1,1} where T
76 end
77 @testset "3D" begin
78 Δ = laplace(g_3D, inner_stencil, closure_stencils)
79 @test Δ isa TensorMapping{T,3,3} where T
80 Dxx = second_derivative(g_3D, inner_stencil, closure_stencils, 1)
81 Dyy = second_derivative(g_3D, inner_stencil, closure_stencils, 2)
82 Dzz = second_derivative(g_3D, inner_stencil, closure_stencils, 3)
83 @test Δ == Dxx + Dyy + Dzz
84 @test Δ isa TensorMapping{T,3,3} where T
85 end
86 end
87