comparison test/testSbpOperators.jl @ 649:351937390162 feature/volume_and_boundary_operators

Clean up testSbpOperators (remove some redundat tests, remove todos and fix use of Parity)
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Fri, 15 Jan 2021 14:09:53 +0100
parents 27b4bcb22154
children 538ccbaeb1f8 e14627e79a54 5ff162f3ed72
comparison
equal deleted inserted replaced
648:d6edde60909b 649:351937390162
9 import Sbplib.SbpOperators.Stencil 9 import Sbplib.SbpOperators.Stencil
10 import Sbplib.SbpOperators.VolumeOperator 10 import Sbplib.SbpOperators.VolumeOperator
11 import Sbplib.SbpOperators.volume_operator 11 import Sbplib.SbpOperators.volume_operator
12 import Sbplib.SbpOperators.BoundaryOperator 12 import Sbplib.SbpOperators.BoundaryOperator
13 import Sbplib.SbpOperators.boundary_operator 13 import Sbplib.SbpOperators.boundary_operator
14 import Sbplib.SbpOperators.Parity 14 import Sbplib.SbpOperators.even
15 import Sbplib.SbpOperators.odd
15 16
16 17
17 @testset "SbpOperators" begin 18 @testset "SbpOperators" begin
18 19
19 @testset "Stencil" begin 20 @testset "Stencil" begin
119 closure_stencils = (Stencil(1/2 .* (1.,1.),center=1),Stencil((0.,1.),center=2)) 120 closure_stencils = (Stencil(1/2 .* (1.,1.),center=1),Stencil((0.,1.),center=2))
120 g_1D = EquidistantGrid(11,0.,1.) 121 g_1D = EquidistantGrid(11,0.,1.)
121 g_2D = EquidistantGrid((11,12),(0.,0.),(1.,1.)) 122 g_2D = EquidistantGrid((11,12),(0.,0.),(1.,1.))
122 g_3D = EquidistantGrid((11,12,10),(0.,0.,0.),(1.,1.,1.)) 123 g_3D = EquidistantGrid((11,12,10),(0.,0.,0.),(1.,1.,1.))
123 @testset "Constructors" begin 124 @testset "Constructors" begin
124 #TODO: How are even and odd in SbpOperators.Parity exposed? Currently constructing even as Parity(1) 125 @testset "1D" begin
125 @testset "1D" begin 126 op = VolumeOperator(inner_stencil,closure_stencils,(11,),even)
126 op = VolumeOperator(inner_stencil,closure_stencils,(11,),Parity(1)) 127 @test op == VolumeOperator(g_1D,inner_stencil,closure_stencils,even)
127 @test op == VolumeOperator(g_1D,inner_stencil,closure_stencils,Parity(1)) 128 @test op == volume_operator(g_1D,inner_stencil,closure_stencils,even,1)
128 @test op == volume_operator(g_1D,inner_stencil,closure_stencils,Parity(1),1)
129 @test op isa TensorMapping{T,1,1} where T 129 @test op isa TensorMapping{T,1,1} where T
130 end 130 end
131 @testset "2D" begin 131 @testset "2D" begin
132 op_x = volume_operator(g_2D,inner_stencil,closure_stencils,Parity(1),1) 132 op_x = volume_operator(g_2D,inner_stencil,closure_stencils,even,1)
133 op_y = volume_operator(g_2D,inner_stencil,closure_stencils,Parity(1),2) 133 op_y = volume_operator(g_2D,inner_stencil,closure_stencils,even,2)
134 Ix = IdentityMapping{Float64}((11,)) 134 Ix = IdentityMapping{Float64}((11,))
135 Iy = IdentityMapping{Float64}((12,)) 135 Iy = IdentityMapping{Float64}((12,))
136 @test op_x == VolumeOperator(inner_stencil,closure_stencils,(11,),Parity(1))⊗Iy 136 @test op_x == VolumeOperator(inner_stencil,closure_stencils,(11,),even)⊗Iy
137 @test op_y == Ix⊗VolumeOperator(inner_stencil,closure_stencils,(12,),Parity(1)) 137 @test op_y == Ix⊗VolumeOperator(inner_stencil,closure_stencils,(12,),even)
138 @test op_x isa TensorMapping{T,2,2} where T 138 @test op_x isa TensorMapping{T,2,2} where T
139 @test op_y isa TensorMapping{T,2,2} where T 139 @test op_y isa TensorMapping{T,2,2} where T
140 end 140 end
141 @testset "3D" begin 141 @testset "3D" begin
142 op_x = volume_operator(g_3D,inner_stencil,closure_stencils,Parity(1),1) 142 op_x = volume_operator(g_3D,inner_stencil,closure_stencils,even,1)
143 op_y = volume_operator(g_3D,inner_stencil,closure_stencils,Parity(1),2) 143 op_y = volume_operator(g_3D,inner_stencil,closure_stencils,even,2)
144 op_z = volume_operator(g_3D,inner_stencil,closure_stencils,Parity(1),3) 144 op_z = volume_operator(g_3D,inner_stencil,closure_stencils,even,3)
145 Ix = IdentityMapping{Float64}((11,)) 145 Ix = IdentityMapping{Float64}((11,))
146 Iy = IdentityMapping{Float64}((12,)) 146 Iy = IdentityMapping{Float64}((12,))
147 Iz = IdentityMapping{Float64}((10,)) 147 Iz = IdentityMapping{Float64}((10,))
148 @test op_x == VolumeOperator(inner_stencil,closure_stencils,(11,),Parity(1))⊗Iy⊗Iz 148 @test op_x == VolumeOperator(inner_stencil,closure_stencils,(11,),even)⊗Iy⊗Iz
149 @test op_y == Ix⊗VolumeOperator(inner_stencil,closure_stencils,(12,),Parity(1))⊗Iz 149 @test op_y == Ix⊗VolumeOperator(inner_stencil,closure_stencils,(12,),even)⊗Iz
150 @test op_z == Ix⊗Iy⊗VolumeOperator(inner_stencil,closure_stencils,(10,),Parity(1)) 150 @test op_z == Ix⊗Iy⊗VolumeOperator(inner_stencil,closure_stencils,(10,),even)
151 @test op_x isa TensorMapping{T,3,3} where T 151 @test op_x isa TensorMapping{T,3,3} where T
152 @test op_y isa TensorMapping{T,3,3} where T 152 @test op_y isa TensorMapping{T,3,3} where T
153 @test op_z isa TensorMapping{T,3,3} where T 153 @test op_z isa TensorMapping{T,3,3} where T
154 end 154 end
155 end 155 end
156 156
157 @testset "Sizes" begin 157 @testset "Sizes" begin
158 @testset "1D" begin 158 @testset "1D" begin
159 op = volume_operator(g_1D,inner_stencil,closure_stencils,Parity(1),1) 159 op = volume_operator(g_1D,inner_stencil,closure_stencils,even,1)
160 @test range_size(op) == domain_size(op) == size(g_1D) 160 @test range_size(op) == domain_size(op) == size(g_1D)
161 end 161 end
162 162
163 @testset "2D" begin 163 @testset "2D" begin
164 op_x = volume_operator(g_2D,inner_stencil,closure_stencils,Parity(1),1) 164 op_x = volume_operator(g_2D,inner_stencil,closure_stencils,even,1)
165 op_y = volume_operator(g_2D,inner_stencil,closure_stencils,Parity(1),2) 165 op_y = volume_operator(g_2D,inner_stencil,closure_stencils,even,2)
166 @test range_size(op_y) == domain_size(op_y) == 166 @test range_size(op_y) == domain_size(op_y) ==
167 range_size(op_x) == domain_size(op_x) == size(g_2D) 167 range_size(op_x) == domain_size(op_x) == size(g_2D)
168 end 168 end
169 @testset "3D" begin 169 @testset "3D" begin
170 op_x = volume_operator(g_3D,inner_stencil,closure_stencils,Parity(1),1) 170 op_x = volume_operator(g_3D,inner_stencil,closure_stencils,even,1)
171 op_y = volume_operator(g_3D,inner_stencil,closure_stencils,Parity(1),2) 171 op_y = volume_operator(g_3D,inner_stencil,closure_stencils,even,2)
172 op_z = volume_operator(g_3D,inner_stencil,closure_stencils,Parity(1),3) 172 op_z = volume_operator(g_3D,inner_stencil,closure_stencils,even,3)
173 @test range_size(op_z) == domain_size(op_z) == 173 @test range_size(op_z) == domain_size(op_z) ==
174 range_size(op_y) == domain_size(op_y) == 174 range_size(op_y) == domain_size(op_y) ==
175 range_size(op_x) == domain_size(op_x) == size(g_3D) 175 range_size(op_x) == domain_size(op_x) == size(g_3D)
176 end 176 end
177 end 177 end
178 178
179 # TODO: Test for other dimensions? 179 op_x = volume_operator(g_2D,inner_stencil,closure_stencils,even,1)
180 op_x = volume_operator(g_2D,inner_stencil,closure_stencils,Parity(1),1) 180 op_y = volume_operator(g_2D,inner_stencil,closure_stencils,odd,2)
181 op_y = volume_operator(g_2D,inner_stencil,closure_stencils,Parity(-1),2)
182 v = zeros(size(g_2D)) 181 v = zeros(size(g_2D))
183 Nx = size(g_2D)[1] 182 Nx = size(g_2D)[1]
184 Ny = size(g_2D)[2] 183 Ny = size(g_2D)[2]
185 for i = 1:Nx 184 for i = 1:Nx
186 v[i,:] .= i 185 v[i,:] .= i
194 @testset "Application" begin 193 @testset "Application" begin
195 @test op_x*v ≈ rx rtol = 1e-14 194 @test op_x*v ≈ rx rtol = 1e-14
196 @test op_y*v ≈ ry rtol = 1e-14 195 @test op_y*v ≈ ry rtol = 1e-14
197 end 196 end
198 197
199 # TODO: Test for other dimensions?
200 @testset "Regions" begin 198 @testset "Regions" begin
201 @test (op_x*v)[Index(1,Lower),Index(3,Interior)] ≈ rx[1,3] rtol = 1e-14 199 @test (op_x*v)[Index(1,Lower),Index(3,Interior)] ≈ rx[1,3] rtol = 1e-14
202 @test (op_x*v)[Index(2,Lower),Index(3,Interior)] ≈ rx[2,3] rtol = 1e-14 200 @test (op_x*v)[Index(2,Lower),Index(3,Interior)] ≈ rx[2,3] rtol = 1e-14
203 @test (op_x*v)[Index(6,Interior),Index(3,Interior)] ≈ rx[6,3] rtol = 1e-14 201 @test (op_x*v)[Index(6,Interior),Index(3,Interior)] ≈ rx[6,3] rtol = 1e-14
204 @test (op_x*v)[Index(10,Upper),Index(3,Interior)] ≈ rx[10,3] rtol = 1e-14 202 @test (op_x*v)[Index(10,Upper),Index(3,Interior)] ≈ rx[10,3] rtol = 1e-14
215 213
216 @test_throws BoundsError (op_y*v)[Index(3,Interior),Index(10,Upper)] 214 @test_throws BoundsError (op_y*v)[Index(3,Interior),Index(10,Upper)]
217 @test_throws BoundsError (op_y*v)[Index(3,Interior),Index(3,Lower)] 215 @test_throws BoundsError (op_y*v)[Index(3,Interior),Index(3,Lower)]
218 end 216 end
219 217
220 # TODO: Test for other dimensions?
221 @testset "Inferred" begin 218 @testset "Inferred" begin
222 @inferred apply(op_x, v,1,1) 219 @inferred apply(op_x, v,1,1)
223 @inferred apply(op_x, v, Index(1,Lower),Index(1,Lower)) 220 @inferred apply(op_x, v, Index(1,Lower),Index(1,Lower))
224 @inferred apply(op_x, v, Index(6,Interior),Index(1,Lower)) 221 @inferred apply(op_x, v, Index(6,Interior),Index(1,Lower))
225 @inferred apply(op_x, v, Index(11,Upper),Index(1,Lower)) 222 @inferred apply(op_x, v, Index(11,Upper),Index(1,Lower))
237 Lx = 3.5 234 Lx = 3.5
238 Ly = 3. 235 Ly = 3.
239 g_1D = EquidistantGrid(121, 0.0, Lx) 236 g_1D = EquidistantGrid(121, 0.0, Lx)
240 g_2D = EquidistantGrid((121,123), (0.0, 0.0), (Lx, Ly)) 237 g_2D = EquidistantGrid((121,123), (0.0, 0.0), (Lx, Ly))
241 238
242 # TODO: These areant really constructors. Better name?
243 @testset "Constructors" begin 239 @testset "Constructors" begin
244 @testset "1D" begin 240 @testset "1D" begin
245 Dₓₓ = SecondDerivative(g_1D,op.innerStencil,op.closureStencils) 241 Dₓₓ = SecondDerivative(g_1D,op.innerStencil,op.closureStencils)
246 @test Dₓₓ == SecondDerivative(g_1D,op.innerStencil,op.closureStencils,1) 242 @test Dₓₓ == SecondDerivative(g_1D,op.innerStencil,op.closureStencils,1)
247 @test Dₓₓ isa VolumeOperator 243 @test Dₓₓ isa VolumeOperator
283 # 4th order interior stencil, 2nd order boundary stencil, 279 # 4th order interior stencil, 2nd order boundary stencil,
284 # implies that L*v should be exact for monomials up to order 3. 280 # implies that L*v should be exact for monomials up to order 3.
285 @testset "4th order" begin 281 @testset "4th order" begin
286 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4) 282 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4)
287 Dₓₓ = SecondDerivative(g_1D,op.innerStencil,op.closureStencils) 283 Dₓₓ = SecondDerivative(g_1D,op.innerStencil,op.closureStencils)
288 # TODO: high tolerances for checking the "exact" differentiation 284 # NOTE: high tolerances for checking the "exact" differentiation
289 # due to accumulation of round-off errors/cancellation errors? 285 # due to accumulation of round-off errors/cancellation errors?
290 @test Dₓₓ*monomials[1] ≈ zeros(Float64,size(g_1D)...) atol = 5e-10 286 @test Dₓₓ*monomials[1] ≈ zeros(Float64,size(g_1D)...) atol = 5e-10
291 @test Dₓₓ*monomials[2] ≈ zeros(Float64,size(g_1D)...) atol = 5e-10 287 @test Dₓₓ*monomials[2] ≈ zeros(Float64,size(g_1D)...) atol = 5e-10
292 @test Dₓₓ*monomials[3] ≈ monomials[1] atol = 5e-10 288 @test Dₓₓ*monomials[3] ≈ monomials[1] atol = 5e-10
293 @test Dₓₓ*monomials[4] ≈ monomials[2] atol = 5e-10 289 @test Dₓₓ*monomials[4] ≈ monomials[2] atol = 5e-10
294 @test Dₓₓ*v ≈ vₓₓ rtol = 5e-4 norm = l2 290 @test Dₓₓ*v ≈ vₓₓ rtol = 5e-4 norm = l2
295 end 291 end
296 end 292 end
297 293
298 @testset "2D" begin 294 @testset "2D" begin
299 l2(v) = sqrt(prod(spacing(g_2D))*sum(v.^2)); 295 l2(v) = sqrt(prod(spacing(g_2D))*sum(v.^2));
300 binomials = () 296 binomials = ()
301 maxOrder = 4; 297 maxOrder = 4;
302 for i = 0:maxOrder-1 298 for i = 0:maxOrder-1
320 # 4th order interior stencil, 2nd order boundary stencil, 316 # 4th order interior stencil, 2nd order boundary stencil,
321 # implies that L*v should be exact for binomials up to order 3. 317 # implies that L*v should be exact for binomials up to order 3.
322 @testset "4th order" begin 318 @testset "4th order" begin
323 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4) 319 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4)
324 Dyy = SecondDerivative(g_2D,op.innerStencil,op.closureStencils,2) 320 Dyy = SecondDerivative(g_2D,op.innerStencil,op.closureStencils,2)
325 # TODO: high tolerances for checking the "exact" differentiation 321 # NOTE: high tolerances for checking the "exact" differentiation
326 # due to accumulation of round-off errors/cancellation errors? 322 # due to accumulation of round-off errors/cancellation errors?
327 @test Dyy*binomials[1] ≈ zeros(Float64,size(g_2D)...) atol = 5e-9 323 @test Dyy*binomials[1] ≈ zeros(Float64,size(g_2D)...) atol = 5e-9
328 @test Dyy*binomials[2] ≈ zeros(Float64,size(g_2D)...) atol = 5e-9 324 @test Dyy*binomials[2] ≈ zeros(Float64,size(g_2D)...) atol = 5e-9
329 @test Dyy*binomials[3] ≈ evalOn(g_2D,(x,y)->1.) atol = 5e-9 325 @test Dyy*binomials[3] ≈ evalOn(g_2D,(x,y)->1.) atol = 5e-9
330 @test Dyy*binomials[4] ≈ evalOn(g_2D,(x,y)->y) atol = 5e-9 326 @test Dyy*binomials[4] ≈ evalOn(g_2D,(x,y)->y) atol = 5e-9
334 end 330 end
335 end 331 end
336 332
337 @testset "Laplace" begin 333 @testset "Laplace" begin
338 g_1D = EquidistantGrid(101, 0.0, 1.) 334 g_1D = EquidistantGrid(101, 0.0, 1.)
339 #TODO: It's nice to verify that 3D works somewhere at least, but perhaps should keep 3D tests to a minimum to avoid
340 # long run time for test?
341 g_3D = EquidistantGrid((51,101,52), (0.0, -1.0, 0.0), (1., 1., 1.)) 335 g_3D = EquidistantGrid((51,101,52), (0.0, -1.0, 0.0), (1., 1., 1.))
342 # TODO: These areant really constructors. Better name?
343 @testset "Constructors" begin 336 @testset "Constructors" begin
344 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4) 337 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4)
345 @testset "1D" begin 338 @testset "1D" begin
346 L = Laplace(g_1D, op.innerStencil, op.closureStencils) 339 L = Laplace(g_1D, op.innerStencil, op.closureStencils)
347 @test L == SecondDerivative(g_1D, op.innerStencil, op.closureStencils) 340 @test L == SecondDerivative(g_1D, op.innerStencil, op.closureStencils)
384 # 4th order interior stencil, 2nd order boundary stencil, 377 # 4th order interior stencil, 2nd order boundary stencil,
385 # implies that L*v should be exact for binomials up to order 3. 378 # implies that L*v should be exact for binomials up to order 3.
386 @testset "4th order" begin 379 @testset "4th order" begin
387 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4) 380 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4)
388 L = Laplace(g_3D,op.innerStencil,op.closureStencils) 381 L = Laplace(g_3D,op.innerStencil,op.closureStencils)
389 # TODO: high tolerances for checking the "exact" differentiation 382 # NOTE: high tolerances for checking the "exact" differentiation
390 # due to accumulation of round-off errors/cancellation errors? 383 # due to accumulation of round-off errors/cancellation errors?
391 @test L*polynomials[1] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9 384 @test L*polynomials[1] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9
392 @test L*polynomials[2] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9 385 @test L*polynomials[2] ≈ zeros(Float64, size(g_3D)...) atol = 5e-9
393 @test L*polynomials[3] ≈ polynomials[1] atol = 5e-9 386 @test L*polynomials[3] ≈ polynomials[1] atol = 5e-9
394 @test L*polynomials[4] ≈ polynomials[2] atol = 5e-9 387 @test L*polynomials[4] ≈ polynomials[2] atol = 5e-9
709 @testset "BoundaryRestriction" begin 702 @testset "BoundaryRestriction" begin
710 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4) 703 op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4)
711 g_1D = EquidistantGrid(11, 0.0, 1.0) 704 g_1D = EquidistantGrid(11, 0.0, 1.0)
712 g_2D = EquidistantGrid((11,15), (0.0, 0.0), (1.0,1.0)) 705 g_2D = EquidistantGrid((11,15), (0.0, 0.0), (1.0,1.0))
713 706
714 # TODO: These areant really constructors. Better name?
715 @testset "Constructors" begin 707 @testset "Constructors" begin
716 @testset "1D" begin 708 @testset "1D" begin
717 e_l = BoundaryRestriction(g_1D,op.eClosure,Lower()) 709 e_l = BoundaryRestriction(g_1D,op.eClosure,Lower())
718 @test e_l == BoundaryRestriction(g_1D,op.eClosure,CartesianBoundary{1,Lower}()) 710 @test e_l == BoundaryRestriction(g_1D,op.eClosure,CartesianBoundary{1,Lower}())
719 @test e_l == BoundaryOperator(g_1D,op.eClosure,Lower()) 711 @test e_l == BoundaryOperator(g_1D,op.eClosure,Lower())
743 u = fill(3.124) 735 u = fill(3.124)
744 736
745 @test (e_l*v)[] == v[1] 737 @test (e_l*v)[] == v[1]
746 @test (e_r*v)[] == v[end] 738 @test (e_r*v)[] == v[end]
747 @test (e_r*v)[1] == v[end] 739 @test (e_r*v)[1] == v[end]
748 @test e_l'*u == [u[]; zeros(10)]
749 @test e_r'*u == [zeros(10); u[]]
750 end 740 end
751 741
752 @testset "2D" begin 742 @testset "2D" begin
753 e_w = BoundaryRestriction(g_2D, op.eClosure, CartesianBoundary{1,Lower}()) 743 e_w = BoundaryRestriction(g_2D, op.eClosure, CartesianBoundary{1,Lower}())
754 e_e = BoundaryRestriction(g_2D, op.eClosure, CartesianBoundary{1,Upper}()) 744 e_e = BoundaryRestriction(g_2D, op.eClosure, CartesianBoundary{1,Upper}())
760 750
761 @test e_w*v == v[1,:] 751 @test e_w*v == v[1,:]
762 @test e_e*v == v[end,:] 752 @test e_e*v == v[end,:]
763 @test e_s*v == v[:,1] 753 @test e_s*v == v[:,1]
764 @test e_n*v == v[:,end] 754 @test e_n*v == v[:,end]
765
766
767 g_x = rand(11)
768 g_y = rand(15)
769
770 G_w = zeros(Float64, (11,15))
771 G_w[1,:] = g_y
772
773 G_e = zeros(Float64, (11,15))
774 G_e[end,:] = g_y
775
776 G_s = zeros(Float64, (11,15))
777 G_s[:,1] = g_x
778
779 G_n = zeros(Float64, (11,15))
780 G_n[:,end] = g_x
781
782 @test e_w'*g_y == G_w
783 @test e_e'*g_y == G_e
784 @test e_s'*g_x == G_s
785 @test e_n'*g_x == G_n
786 end 755 end
787 end 756 end
788 end 757 end
789 758
790 @testset "NormalDerivative" begin 759 @testset "NormalDerivative" begin
841 @test d_e*v ≈ -v∂x[end,:] atol = 1e-13 810 @test d_e*v ≈ -v∂x[end,:] atol = 1e-13
842 @test d_s*v ≈ v∂y[:,1] atol = 1e-13 811 @test d_s*v ≈ v∂y[:,1] atol = 1e-13
843 @test d_n*v ≈ -v∂y[:,end] atol = 1e-13 812 @test d_n*v ≈ -v∂y[:,end] atol = 1e-13
844 end 813 end
845 end 814 end
846 815 end
847 #TODO: Need to check this? Tested in BoundaryOperator. If so, the old test 816
848 # below should be fixed. 817 end
849 @testset "Transpose" begin
850 # op = read_D2_operator(sbp_operators_path()*"standard_diagonal.toml"; order=4)
851 # d_x_l = zeros(Float64, size(g_2D)[1])
852 # d_x_u = zeros(Float64, size(g_2D)[1])
853 # for i ∈ eachindex(d_x_l)
854 # d_x_l[i] = op.dClosure[i-1]
855 # d_x_u[i] = op.dClosure[length(d_x_u)-i]
856 # end
857 # d_y_l = zeros(Float64, size(g_2D)[2])
858 # d_y_u = zeros(Float64, size(g_2D)[2])
859 # for i ∈ eachindex(d_y_l)
860 # d_y_l[i] = op.dClosure[i-1]
861 # d_y_u[i] = op.dClosure[length(d_y_u)-i]
862 # end
863 # function prod_matrix(x,y)
864 # G = zeros(Float64, length(x), length(y))
865 # for I ∈ CartesianIndices(G)
866 # G[I] = x[I[1]]*y[I[2]]
867 # end
868 #
869 # return G
870 # end
871 # g_x = [1,2,3,4.0,5]
872 # g_y = [5,4,3,2,1.0,11]
873 #
874 # G_w = prod_matrix(d_x_l, g_y)
875 # G_e = prod_matrix(d_x_u, g_y)
876 # G_s = prod_matrix(g_x, d_y_l)
877 # G_n = prod_matrix(g_x, d_y_u)
878 #
879 # @test d_w'*g_y ≈ G_w
880 # @test_broken d_e'*g_y ≈ G_e
881 # @test d_s'*g_x ≈ G_s
882 # @test_broken d_n'*g_x ≈ G_n
883 end
884 end
885
886 end