Skip to content

Commit 5946ea9

Browse files
authored
Merge pull request #350 from FourierFlows/ncc/clarify
Fixes bug in `parsevalsum`/`parsevalsum2`
2 parents 36afbfc + 7e61a44 commit 5946ea9

File tree

3 files changed

+39
-18
lines changed

3 files changed

+39
-18
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
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.10.2"
9+
version = "0.10.3"
1010

1111
[deps]
1212
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
@@ -24,7 +24,7 @@ CUDA = "1, 2.4.2, 3.0.0 - 3.6.4, 3.7.1, 4"
2424
DocStringExtensions = "0.8, 0.9"
2525
FFTW = "1"
2626
Interpolations = "0.12, 0.13, 0.14"
27-
JLD2 = "^0.1, 0.2, 0.3, 0.4"
27+
JLD2 = "0.1, 0.2, 0.3, 0.4"
2828
Reexport = "0.2, 1"
2929
julia = "1.6"
3030

src/utils.jl

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,21 @@ end
9797
"""
9898
parsevalsum2(uh, grid)
9999
100-
Return `Σ |uh|²` on the `grid`, which is equal to the domain integral of `u`. More specifically,
101-
it returns
100+
Return `Σ |uh|²` on the `grid`, which is equal to the domain integral `u` squared.
101+
For example on a 2D grid, `parsevalsum2` returns
102+
102103
```math
103-
\\sum_{𝐤} |û_{𝐤}|² L_x L_y = \\int u(𝐱)² \\, 𝖽x 𝖽y \\,,
104+
\\sum_{𝐤} |û_{𝐤}|² L_x L_y = \\iint u² \\, 𝖽x 𝖽y \\,,
104105
```
106+
105107
where ``û_{𝐤} =`` `uh` `` / (n_x e^{i 𝐤 ⋅ 𝐱₀})``. The elements of the vector ``𝐱₀`` are the
106108
left-most position in each direction, e.g., for a 2D grid `(grid.x[1], grid.y[1])`.
107109
"""
108110
function parsevalsum2(uh, grid::TwoDGrid)
109-
if size(uh, 1) == grid.nkr # uh is in conjugate symmetric form
110-
U = sum(abs2, uh[1, :]) # k=0 modes
111-
U += 2*sum(abs2, uh[2:end, :]) # sum k>0 modes twice
111+
if size(uh, 1) == grid.nkr # uh is in conjugate symmetric form
112+
U = sum(abs2, uh[1, :]) # k=0 modes
113+
U += sum(abs2, uh[grid.nkr, :]) # k=nx/2 modes
114+
U += 2 * sum(abs2, uh[2:grid.nkr-1, :]) # sum twice for 0 < k < nx/2 modes
112115
else # count every mode once
113116
U = sum(abs2, uh)
114117
end
@@ -119,9 +122,10 @@ function parsevalsum2(uh, grid::TwoDGrid)
119122
end
120123

121124
function parsevalsum2(uh, grid::OneDGrid)
122-
if size(uh, 1) == grid.nkr # uh is conjugate symmetric
123-
U = sum(abs2, CUDA.@allowscalar uh[1]) # k=0 modes
124-
U += @views 2 * sum(abs2, uh[2:end]) # sum k>0 modes twice
125+
if size(uh, 1) == grid.nkr # uh is conjugate symmetric
126+
U = sum(abs2, CUDA.@allowscalar uh[1]) # k=0 mode
127+
U += sum(abs2, CUDA.@allowscalar uh[grid.nkr]) # k=nx/2 mode
128+
U += @views 2 * sum(abs2, uh[2:grid.nkr-1]) # sum twice for 0 < k < nx/2 modes
125129
else # count every mode once
126130
U = sum(abs2, uh)
127131
end
@@ -134,17 +138,20 @@ end
134138
"""
135139
parsevalsum(uh, grid)
136140
137-
Return `real(Σ uh)` on the `grid`, i.e.
141+
Return `real(Σ uh)` on the `grid`, i.e.,
142+
138143
```math
139144
ℜ [ \\sum_{𝐤} û_{𝐤} L_x L_y ] \\,,
145+
140146
```
141147
where ``û_{𝐤} =`` `uh` `` / (n_x e^{i 𝐤 ⋅ 𝐱₀})``. The elements of the vector ``𝐱₀`` are the
142148
left-most position in each direction, e.g., for a 2D grid `(grid.x[1], grid.y[1])`.
143149
"""
144150
function parsevalsum(uh, grid::TwoDGrid)
145-
if size(uh, 1) == grid.nkr # uh is conjugate symmetric
146-
U = sum(uh[1, :]) # k=0 modes
147-
U += 2*sum(uh[2:end, :]) # sum k>0 modes twice
151+
if size(uh, 1) == grid.nkr # uh is conjugate symmetric
152+
U = sum(uh[1, :]) # k = 0 modes
153+
U += sum(uh[grid.nkr, :]) # k = nx/2 modes
154+
U += 2 * sum(uh[2:grid.nkr-1, :]) # sum twice for 0 < k < nx/2 modes
148155
else # count every mode once
149156
U = sum(uh)
150157
end
@@ -155,9 +162,10 @@ function parsevalsum(uh, grid::TwoDGrid)
155162
end
156163

157164
function parsevalsum(uh, grid::OneDGrid)
158-
if size(uh, 1) == grid.nkr # uh is conjugate symmetric
159-
U = uh[1] # k=0 mode
160-
U += 2*sum(uh[2:end]) # sum k>0 modes twice
165+
if size(uh, 1) == grid.nkr # uh is conjugate symmetric
166+
U = uh[1] # k=0 mode
167+
U += uh[grid.nkr] # k=nx/2 mode
168+
U += 2 * sum(uh[2:grid.nkr-1]) # sum twice for 0 < k < nx/2 modes
161169
else # count every mode once
162170
U = sum(uh)
163171
end

test/runtests.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,13 @@ for dev in devices
267267
@test test_parsevalsums(f1, g; realvalued=false) # Real valued f with fft
268268
@test test_parsevalsums(f2, g; realvalued=false) # Complex valued f with fft
269269

270+
f3 = randn(eltype(g), (g.nx, g.ny))
271+
@test test_parsevalsums(f3, g; realvalued=true) # Real valued f with rfft
272+
@test test_parsevalsums(f3, g; realvalued=false) # Real valued f with fft
273+
274+
f4 = randn(Complex{eltype(g)}, (g.nx, g.ny))
275+
@test test_parsevalsums(f4, g; realvalued=false) # Complex valued f with fft
276+
270277
@test test_jacobian(sinkl1, sinkl1, 0*sinkl1, g) # Test J(a, a) = 0
271278
@test test_jacobian(sinkl1, sinkl2, Jsinkl1sinkl2, g) # Test J(sin1, sin2) = Jsin1sin2
272279
@test test_jacobian(expkl1, expkl2, Jexpkl1expkl2, g) # Test J(exp1, exp2) = Jexp1exps2
@@ -279,7 +286,13 @@ for dev in devices
279286
@test test_parsevalsums(f1, g; realvalued=true) # Real valued f with rfft
280287
@test test_parsevalsums(f1, g; realvalued=false) # Real valued f with fft
281288

289+
f2 = randn(eltype(g), (g.nx,))
290+
@test test_parsevalsums(f2, g; realvalued=true) # Real valued f with rfft
291+
@test test_parsevalsums(f2, g; realvalued=false) # Real valued f with fft
282292

293+
f3 = randn(Complex{eltype(g)}, (g.nx,))
294+
@test test_parsevalsums(f3, g; realvalued=false) # Complex valued f with fft
295+
283296
# Radial spectrum tests. Note that ahρ = ∫ ah ρ dθ.
284297
n = 128; δ = n/10 # Parameters
285298
ahkl_isotropic(k, l) = exp(-(k^2 + l^2) / 2δ^2) # a = exp(-ρ²/2δ²)

0 commit comments

Comments
 (0)