Skip to content

Commit 00b8ab3

Browse files
authored
Merge pull request #294 from apaloczy/master
Fix potential energy calculation bug in `MultiLayerQG.energies`
2 parents 37d93a5 + 43bfa28 commit 00b8ab3

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "GeophysicalFlows"
22
uuid = "44ee3b1c-bc02-53fa-8355-8e347616e15e"
33
license = "MIT"
44
authors = ["Navid C. Constantinou <[email protected]>", "Gregory L. Wagner <[email protected]>", "and co-contributors"]
5-
version = "0.14.0"
5+
version = "0.14.1"
66

77
[deps]
88
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"

src/multilayerqg.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ The kinetic energy at the ``j``-th fluid layer is
916916
while the potential energy that corresponds to the interface ``j+1/2`` (i.e., the interface
917917
between the ``j``-th and ``(j+1)``-th fluid layer) is
918918
```math
919-
𝖯𝖤_{j+1/2} = \\int \\frac1{2} \\frac{f₀^2}{g'_{j+1/2}} (ψ_j - ψ_{j+1})^2 \\frac{𝖽x 𝖽y}{L_x L_y} = \\frac1{2} \\frac{f₀^2}{g'_{j+1/2}} \\sum_{𝐤} |ψ_j - ψ_{j+1}|², \\ j = 1, ..., n-1 .
919+
𝖯𝖤_{j+1/2} = \\int \\frac1{2} \\frac{f₀^2}{g'_{j+1/2} H} (ψ_j - ψ_{j+1})^2 \\frac{𝖽x 𝖽y}{L_x L_y} = \\frac1{2} \\frac{f₀^2}{g'_{j+1/2} H} \\sum_{𝐤} |ψ̂_j - ψ̂_{j+1}|², \\ j = 1, ..., n-1 .
920920
```
921921
"""
922922
function energies(vars, params, grid, sol)
@@ -934,7 +934,7 @@ function energies(vars, params, grid, sol)
934934
end
935935

936936
for j = 1:nlayers-1
937-
CUDA.@allowscalar PE[j] = 1 / (2 * grid.Lx * grid.Ly) * params.f₀^2 / params.g′[j] * parsevalsum(abs2.(vars.ψh[:, :, j+1] .- vars.ψh[:, :, j]), grid)
937+
CUDA.@allowscalar PE[j] = 1 / (2 * grid.Lx * grid.Ly * sum(params.H)) * params.f₀^2 / params.g′[j] * parsevalsum(abs2.(vars.ψh[:, :, j+1] .- vars.ψh[:, :, j]), grid)
938938
end
939939

940940
return KE, PE
@@ -956,7 +956,7 @@ function energies(vars, params::TwoLayerParams, grid, sol)
956956
CUDA.@allowscalar KE[j] = @views 1 / (2 * grid.Lx * grid.Ly) * parsevalsum(abs²∇𝐮h[:, :, j], grid) * params.H[j] / sum(params.H)
957957
end
958958

959-
PE = @views 1 / (2 * grid.Lx * grid.Ly) * params.f₀^2 / params.g′ * parsevalsum(abs2.(ψ2h .- ψ1h), grid)
959+
PE = @views 1 / (2 * grid.Lx * grid.Ly * sum(params.H)) * params.f₀^2 / params.g′ * parsevalsum(abs2.(ψ2h .- ψ1h), grid)
960960

961961
return KE, PE
962962
end

test/test_multilayerqg.jl

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -347,29 +347,31 @@ function test_mqg_energies(dev::Device=CPU();
347347

348348
x, y = gridpoints(gr)
349349
k₀, l₀ = 2π/gr.Lx, 2π/gr.Ly # fundamental wavenumbers
350-
351-
nlayers = 2 # these choice of parameters give the
352-
f₀, g = 1, 1 # desired PV-streamfunction relations
353-
H = [0.2, 0.8] # q1 = Δψ1 + 25*(ψ2-ψ1), and
354-
ρ = [4.0, 5.0] # q2 = Δψ2 + 25/4*(ψ1-ψ2).
355-
356-
prob = MultiLayerQG.Problem(nlayers, dev; nx, ny, Lx, Ly, f₀, g, H, ρ)
350+
nlayers = 2
357351

352+
f₀, g = 1, 1
353+
H = [2.5, 7.5] # sum(params.H) = 10
354+
ρ = [1.0, 2.0] # Make g′ = 1/2
355+
356+
prob = MultiLayerQG.Problem(nlayers, dev; nx, ny, Lx, Ly, f₀, g, H, ρ)
358357
sol, cl, pr, vs, gr = prob.sol, prob.clock, prob.params, prob.vars, prob.grid
359358

360-
ψ1, ψ2, q1, q2, ψ1x, ψ2x, q1x, q2x, Δψ2, Δq1, Δq2 = constructtestfields_2layer(gr)
359+
ψ = zeros(dev, eltype(gr), (gr.nx, gr.ny, nlayers))
360+
361+
CUDA.@allowscalar @views @. ψ[:, :, 1] = cos(2k₀ * x) * cos(2l₀ * y)
362+
CUDA.@allowscalar @views @. ψ[:, :, 2] = 1/2 * cos(2k₀ * x) * cos(2l₀ * y)
361363

362-
qf = zeros(dev, eltype(gr), (gr.nx, gr.ny, nlayers))
363-
CUDA.@allowscalar @views qf[:, :, 1] .= q1
364-
CUDA.@allowscalar @views qf[:, :, 2] .= q2
364+
MultiLayerQG.set_ψ!(prob, ψ)
365365

366-
MultiLayerQG.set_q!(prob, qf)
366+
KE1_calc = 1/4 # = H1/H
367+
KE2_calc = 3/4/4 # = H2/H/4
368+
PE_calc = 1/16/10 # = 1/16/H
367369

368370
KE, PE = MultiLayerQG.energies(prob)
369371

370-
return isapprox(KE[1], 61/640*1e-6, rtol=rtol_multilayerqg) &&
371-
isapprox(KE[2], 3*1e-6, rtol=rtol_multilayerqg) &&
372-
isapprox(PE[1], 1025/1152*1e-6, rtol=rtol_multilayerqg) &&
372+
return isapprox(KE[1], KE1_calc, rtol=rtol_multilayerqg) &&
373+
isapprox(KE[2], KE2_calc, rtol=rtol_multilayerqg) &&
374+
isapprox(PE[1], PE_calc, rtol=rtol_multilayerqg) &&
373375
MultiLayerQG.addforcing!(prob.timestepper.RHS₁, sol, cl.t, cl, vs, pr, gr)==nothing
374376
end
375377

0 commit comments

Comments
 (0)