Skip to content

Commit a4bcb46

Browse files
authored
Merge pull request #282 from FourierFlows/ncc/fix-dealias-bug
Fix bug in `dealias!` functionality
2 parents 702c7fa + bc9af8d commit a4bcb46

File tree

4 files changed

+79
-61
lines changed

4 files changed

+79
-61
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ authors = ["Gregory L. Wagner <wagner.greg@gmail.com>", "Navid C. Constantinou <
66
description = "Tools for building fast, hackable, pseudospectral partial differential equation solvers on periodic domains."
77
documentation = "https://fourierflows.github.io/FourierFlowsDocumentation/stable/"
88
repository = "https://github.com/FourierFlows/FourierFlows.jl"
9-
version = "0.6.18"
9+
version = "0.6.19"
1010

1111
[deps]
1212
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ and [Navid C. Constantinou][] (@navidcy).
102102

103103
The code is citable via [zenodo](https://zenodo.org). Please cite as:
104104

105-
> Navid C. Constantinou & Gregory L. Wagner. (2021). FourierFlows/FourierFlows.jl: FourierFlows v0.6.18 (Version v0.6.18). Zenodo. [http://doi.org/10.5281/zenodo.1161724](http://doi.org/10.5281/zenodo.1161724)
105+
> Navid C. Constantinou & Gregory L. Wagner. (2021). FourierFlows/FourierFlows.jl: FourierFlows v0.6.19 (Version v0.6.19). Zenodo. [http://doi.org/10.5281/zenodo.1161724](http://doi.org/10.5281/zenodo.1161724)
106106
107107

108108

src/domains.jl

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -316,44 +316,47 @@ function getaliasedwavenumbers(nk, nkr, aliasfraction)
316316
end
317317

318318
"""
319-
dealias!(a, g, kalias)
319+
dealias!(a, grid, kalias)
320320
321-
Dealias array `a` on the grid `g` with aliased x-wavenumbers `kalias`.
321+
Dealias array `a` on the `grid` with aliased x-wavenumbers `kalias`.
322322
"""
323-
function dealias!(a, g::OneDGrid)
324-
kalias = size(a, 1) == g.nkr ? g.kralias : g.kalias
325-
dealias!(a, g, kalias)
323+
function dealias!(a, grid::OneDGrid)
324+
kalias = size(a, 1) == grid.nkr ? grid.kralias : grid.kalias
325+
dealias!(a, grid, kalias)
326326
return nothing
327327
end
328328

329-
function dealias!(a, g::OneDGrid, kalias)
329+
function dealias!(a, grid::OneDGrid, kalias)
330330
@views @. a[kalias, :] = 0
331331

332332
return nothing
333333
end
334334

335-
function dealias!(a, g::TwoDGrid)
336-
kalias = size(a, 1) == g.nkr ? g.kralias : g.kalias
337-
dealias!(a, g, kalias)
335+
function dealias!(a, grid::TwoDGrid)
336+
kalias = size(a, 1) == grid.nkr ? grid.kralias : grid.kalias
337+
dealias!(a, grid, kalias)
338338

339339
return nothing
340340
end
341341

342-
function dealias!(a, g::TwoDGrid, kalias)
343-
@views @. a[kalias, g.lalias, :] = 0
342+
function dealias!(a, grid::TwoDGrid, kalias)
343+
@views @. a[kalias, :, :] = 0
344+
@views @. a[:, grid.lalias, :] = 0
344345

345346
return nothing
346347
end
347348

348-
function dealias!(a, g::ThreeDGrid)
349-
kalias = size(a, 1) == g.nkr ? g.kralias : g.kalias
350-
dealias!(a, g, kalias)
349+
function dealias!(a, grid::ThreeDGrid)
350+
kalias = size(a, 1) == grid.nkr ? grid.kralias : grid.kalias
351+
dealias!(a, grid, kalias)
351352

352353
return nothing
353354
end
354355

355-
function dealias!(a, g::ThreeDGrid, kalias)
356-
@views @. a[kalias, g.lalias, g.malias, :] = 0
356+
function dealias!(a, grid::ThreeDGrid, kalias)
357+
@views @. a[kalias, :, :, :] = 0
358+
@views @. a[:, grid.lalias, :, :] = 0
359+
@views @. a[:, :, grid.malias, :] = 0
357360

358361
return nothing
359362
end

test/test_grid.jl

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,22 @@ testnz(g, nz) = isapprox(g.nz, nz)
66
function testdx(dev, g::Union{OneDGrid{T}, TwoDGrid{T}, ThreeDGrid{T}}) where T
77
dxgrid = @. g.x[2:end] - g.x[1:end-1]
88
dxones = ArrayType(dev)(g.dx*ones(T, size(dxgrid)))
9-
isapprox(dxgrid, dxones)
9+
10+
return isapprox(dxgrid, dxones)
1011
end
1112

1213
function testdy(dev, g::Union{TwoDGrid{T}, ThreeDGrid{T}}) where T
1314
dygrid = @. g.y[2:end] - g.y[1:end-1]
1415
dyones = ArrayType(dev)(g.dy*ones(T, size(dygrid)))
15-
isapprox(dygrid, dyones)
16+
17+
return isapprox(dygrid, dyones)
1618
end
1719

1820
function testdz(dev, g::ThreeDGrid{T}) where T
1921
dzgrid = @. g.z[2:end] - g.z[1:end-1]
2022
dzones = ArrayType(dev)(g.dz*ones(T, size(dzgrid)))
21-
isapprox(dzgrid, dzones)
23+
24+
return isapprox(dzgrid, dzones)
2225
end
2326

2427
testx(g) = isapprox(g.x[end]-g.x[1], g.Lx-g.dx)
@@ -35,7 +38,8 @@ function testwavenumberalignment(k, nx)
3538
mid = Int(nx/2)
3639
positives = k[2:mid]
3740
negatives = flippednegatives(k, mid)
38-
isapprox(reshape(positives, mid-1), reshape(negatives, mid-1))
41+
42+
return isapprox(reshape(positives, mid-1), reshape(negatives, mid-1))
3943
end
4044

4145
testk(g) = testwavenumberalignment(g.k, g.nx)
@@ -49,7 +53,8 @@ function testgridpoints(dev::Device, g::TwoDGrid{T}) where T
4953
dYgrid = @. Y[:, 2:end] - Y[:, 1:end-1]
5054
dXones = ArrayType(dev)(g.dx*ones(T, size(dXgrid)))
5155
dYones = ArrayType(dev)(g.dy*ones(T, size(dYgrid)))
52-
isapprox(dXgrid, dXones) && isapprox(dYgrid, dYones)
56+
57+
return isapprox(dXgrid, dXones) && isapprox(dYgrid, dYones)
5358
end
5459

5560
function testgridpoints(dev::Device, g::ThreeDGrid{T}) where T
@@ -60,63 +65,70 @@ function testgridpoints(dev::Device, g::ThreeDGrid{T}) where T
6065
dXones = ArrayType(dev)(g.dx*ones(T, size(dXgrid)))
6166
dYones = ArrayType(dev)(g.dy*ones(T, size(dYgrid)))
6267
dZones = ArrayType(dev)(g.dz*ones(T, size(dZgrid)))
63-
isapprox(dXgrid, dXones) && isapprox(dYgrid, dYones) && isapprox(dZgrid, dZones)
68+
69+
return isapprox(dXgrid, dXones) && isapprox(dYgrid, dYones) && isapprox(dZgrid, dZones)
6470
end
6571

66-
function testdealias(g::OneDGrid)
67-
T = typeof(g.Lx)
68-
fh = ones(Complex{T}, size(g.kr))
69-
dealias!(fh, g)
70-
kmax = round(maximum(g.kr)*2/3)
71-
CUDA.@allowscalar isapprox(sum(abs.(fh[g.kr .>= kmax])), 0)
72+
function testdealias(grid::OneDGrid)
73+
fh = ones(Complex{eltype(grid)}, size(grid.kr))
74+
dealias!(fh, grid)
75+
kmax = round(maximum(grid.kr)*2/3)
76+
77+
return CUDA.@allowscalar isapprox(sum(abs.(fh[grid.kr .>= kmax])), 0)
7278
end
7379

74-
function testdealias(g::TwoDGrid)
75-
T = typeof(g.Lx)
76-
fh = ones(Complex{T}, size(g.Krsq))
77-
dealias!(fh, g)
78-
kmax = round(maximum(g.kr)*2/3)
79-
lmax = floor(maximum(g.l)*2/3)
80+
function testdealias(grid::TwoDGrid)
81+
fh = ones(Complex{eltype(grid)}, size(grid.Krsq))
82+
dealias!(fh, grid)
83+
kmax = round(maximum(grid.kr)*2/3)
84+
lmax = floor(maximum(grid.l)*2/3)
8085

81-
temp = 0.0
82-
for j = 1:g.nl, i = 1:g.nkr
83-
if (CUDA.@allowscalar g.kr[i] >= kmax) & (CUDA.@allowscalar g.l[j] >= lmax || CUDA.@allowscalar g.l[j] < -lmax)
86+
temp = 0
87+
for j = 1:grid.nl, i = 1:grid.nkr
88+
if ((CUDA.@allowscalar grid.kr[i] >= kmax) ||
89+
(CUDA.@allowscalar grid.l[j] >= lmax || CUDA.@allowscalar grid.l[j] < -lmax))
8490
temp += abs.(fh[i, j]) #temp = sum of |fh| for aliased wavenumbers
8591
end
8692
end
87-
isapprox(temp, 0)
93+
94+
return isapprox(temp, 0)
8895
end
8996

90-
function testdealias(g::ThreeDGrid)
91-
T = typeof(g.Lx)
92-
fh = ones(Complex{T}, size(g.Krsq))
93-
dealias!(fh, g)
94-
kmax = round(maximum(g.kr)*2/3)
95-
lmax = floor(maximum(g.l)*2/3)
96-
mmax = floor(maximum(g.m)*2/3)
97-
98-
temp = 0.0
99-
for k = 1:g.nm, j = 1:g.nl, i = 1:g.nkr
100-
if (CUDA.@allowscalar g.kr[i] >= kmax ) & (CUDA.@allowscalar g.l[j] >= lmax || CUDA.@allowscalar g.l[j] < -lmax) & (CUDA.@allowscalar g.m[k] >= mmax || CUDA.@allowscalar g.m[k] < -mmax)
97+
function testdealias(grid::ThreeDGrid)
98+
fh = ones(Complex{eltype(grid)}, size(grid.Krsq))
99+
dealias!(fh, grid)
100+
kmax = round(maximum(grid.kr)*2/3)
101+
lmax = floor(maximum(grid.l)*2/3)
102+
mmax = floor(maximum(grid.m)*2/3)
103+
104+
temp = 0
105+
for k = 1:grid.nm, j = 1:grid.nl, i = 1:grid.nkr
106+
if ((CUDA.@allowscalar grid.kr[i] >= kmax ) ||
107+
(CUDA.@allowscalar grid.l[j] >= lmax || CUDA.@allowscalar grid.l[j] < -lmax) ||
108+
(CUDA.@allowscalar grid.m[k] >= mmax || CUDA.@allowscalar grid.m[k] < -mmax))
101109
temp += abs.(fh[i, j, k]) #temp = sum of |fh| for aliased wavenumbers
102110
end
103111
end
104-
isapprox(temp, 0)
112+
113+
return isapprox(temp, 0)
105114
end
106115

107116
function testtypedonedgrid(dev::Device, nx, Lx; T=Float64)
108-
gr = OneDGrid(nx, Lx, T=T)
109-
typeof(gr.dx)==T && typeof(gr.x[1])==T && typeof(gr.Lx)==T && eltype(gr) == T
117+
grid = OneDGrid(nx, Lx, T=T)
118+
119+
return typeof(grid.dx)==T && typeof(grid.x[1])==T && typeof(grid.Lx)==T && eltype(grid) == T
110120
end
111121

112122
function testtypedtwodgrid(dev::Device, nx, Lx, ny=Lx, Ly=Lx; T=Float64)
113-
gr = TwoDGrid(nx, Lx, ny, Ly, T=T)
114-
typeof(gr.dx)==T && typeof(gr.dy)==T && typeof(gr.x[1])==T && typeof(gr.y[1])==T && typeof(gr.Lx)==T && typeof(gr.Ly)==T && eltype(gr) == T
123+
grid = TwoDGrid(nx, Lx, ny, Ly, T=T)
124+
125+
return typeof(grid.dx)==T && typeof(grid.dy)==T && typeof(grid.x[1])==T && typeof(grid.y[1])==T && typeof(grid.Lx)==T && typeof(grid.Ly)==T && eltype(grid) == T
115126
end
116127

117128
function testtypedthreedgrid(dev::Device, nx, Lx, ny=nx, Ly=Lx, nz=nx, Lz=Lx; T=Float64)
118-
gr = ThreeDGrid(nx, Lx, ny, Ly, nz, Lz, T=T)
119-
typeof(gr.dx)==T && typeof(gr.dy)==T && typeof(gr.dz)==T && typeof(gr.x[1])==T && typeof(gr.y[1])==T && typeof(gr.z[1])==T && typeof(gr.Lx)==T && typeof(gr.Ly)==T && typeof(gr.Lz)==T && eltype(gr) == T
129+
grid = ThreeDGrid(nx, Lx, ny, Ly, nz, Lz, T=T)
130+
131+
return typeof(grid.dx)==T && typeof(grid.dy)==T && typeof(grid.dz)==T && typeof(grid.x[1])==T && typeof(grid.y[1])==T && typeof(grid.z[1])==T && typeof(grid.Lx)==T && typeof(grid.Ly)==T && typeof(grid.Lz)==T && eltype(grid) == T
120132
end
121133

122134
function testmakefilter(dev::Device, g::AbstractGrid)
@@ -125,7 +137,8 @@ function testmakefilter(dev::Device, g::AbstractGrid)
125137
G = typeof(g)
126138
nofilter = G<:OneDGrid ? filter[@. g.kr*g.dx/π < 0.65] : ( G<:TwoDGrid ? filter[@. sqrt((g.kr*g.dx/π)^2 + (g.l*g.dy/π)^2) < 0.65] : filter[@. sqrt((g.kr*g.dx/π)^2 + (g.l*g.dy/π)^2 + (g.m*g.dz/π)^2) < 0.65] )
127139
fullfilter = G<:OneDGrid ? filter[@. g.kr*g.dx/π > 0.999] : ( G<:TwoDGrid ? filter[@. sqrt((g.kr*g.dx/π)^2 + (g.l*g.dy/π)^2) > 0.999] : filter[@. sqrt((g.kr*g.dx/π)^2 + (g.l*g.dy/π)^2 + (g.m*g.dz/π)^2) > 0.999] )
128-
nofilter== zeros(dev, T, size(nofilter)) .+ 1 && isapprox(fullfilter, zeros(dev, T, size(fullfilter)), atol=1e-12)
140+
141+
return nofilter== zeros(dev, T, size(nofilter)) .+ 1 && isapprox(fullfilter, zeros(dev, T, size(fullfilter)), atol=1e-12)
129142
end
130143

131144
function test_plan_flows_fftrfft(::CPU; T=Float64)
@@ -137,7 +150,8 @@ function test_plan_flows_fftrfft(::CPU; T=Float64)
137150
typeof(FourierFlows.plan_flows_rfft(A(rand(T, (4,))))) <: FFTW.rFFTWPlan{T,-1,false,1} &&
138151
typeof(FourierFlows.plan_flows_rfft(A(rand(T, (4, 6))))) <: FFTW.rFFTWPlan{T,-1,false,2} &&
139152
typeof(FourierFlows.plan_flows_rfft(A(rand(T, (4, 6, 8))))) <: FFTW.rFFTWPlan{T,-1,false,3} &&
140-
FourierFlows.plan_flows_rfft(A(rand(T, (4, 6, 8))), [1, 2]).region == [1, 2])
153+
154+
return FourierFlows.plan_flows_rfft(A(rand(T, (4, 6, 8))), [1, 2]).region == [1, 2])
141155
end
142156

143157
function test_plan_flows_fftrfft(::GPU; T=Float64)
@@ -149,5 +163,6 @@ function test_plan_flows_fftrfft(::GPU; T=Float64)
149163
typeof(FourierFlows.plan_flows_rfft(A(rand(T, (4,))))) == CUDA.CUFFT.rCuFFTPlan{T,-1,false,1} &&
150164
typeof(FourierFlows.plan_flows_rfft(A(rand(T, (4, 6))))) == CUDA.CUFFT.rCuFFTPlan{T,-1,false,2} &&
151165
typeof(FourierFlows.plan_flows_rfft(A(rand(T, (4, 6, 8))))) == CUDA.CUFFT.rCuFFTPlan{T,-1,false,3} &&
152-
FourierFlows.plan_flows_rfft(A(rand(T, (4, 6, 8))), [1, 2]).region == [1, 2])
166+
167+
return FourierFlows.plan_flows_rfft(A(rand(T, (4, 6, 8))), [1, 2]).region == [1, 2])
153168
end

0 commit comments

Comments
 (0)