Skip to content

Commit 9d234b7

Browse files
committed
adds twodturb lamb dipole test
1 parent fae1da1 commit 9d234b7

File tree

4 files changed

+91
-40
lines changed

4 files changed

+91
-40
lines changed

src/utils.jl

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Returns a time-stepper type defined by the prefix 'stepper', timestep dt
2727
solution sol (used to construct variables with identical type and size as
2828
the solution vector), and grid g.
2929
"""
30-
function autoconstructtimestepper(stepper, dt, sol,
30+
function autoconstructtimestepper(stepper, dt, sol,
3131
g::AbstractGrid=ZeroDGrid(1))
3232
fullsteppername = Symbol(stepper, :TimeStepper)
3333
if stepper filteredsteppers
@@ -48,14 +48,14 @@ end
4848

4949

5050
"""
51-
@createarrays T dims a b c
51+
@createarrays T dims a b c
5252
5353
Create arrays of all zeros with element type T, size dims, and global names
5454
a, b, c (for example). An arbitrary number of arrays may be created.
5555
"""
5656
macro createarrays(T, dims, vars...)
5757
expr = Expr(:block)
58-
append!(expr.args,
58+
append!(expr.args,
5959
[:( $(esc(var)) = zeros($(esc(T)), $(esc(dims))); ) for var in vars])
6060
expr
6161
end
@@ -65,12 +65,12 @@ end
6565
This function returns an expression that defines a Composite Type
6666
of the AbstractVars variety.
6767
"""
68-
function structvarsexpr(name, physfields, transfields; soldims=2, vardims=2,
69-
parent=:AbstractVars)
70-
71-
physexprs = [:( $fld::Array{Float64,$vardims} )
68+
function structvarsexpr(name, physfields, transfields; soldims=2, vardims=2,
69+
parent=:AbstractVars)
70+
71+
physexprs = [:( $fld::Array{Float64,$vardims} )
7272
for fld in physfields]
73-
transexprs = [:( $fld::Array{Complex{Float64},$vardims} )
73+
transexprs = [:( $fld::Array{Complex{Float64},$vardims} )
7474
for fld in transfields]
7575

7676
if parent != nothing
@@ -88,7 +88,7 @@ function structvarsexpr(name, physfields, transfields; soldims=2, vardims=2,
8888
end
8989
end
9090
end
91-
91+
9292
expr
9393
end
9494

@@ -101,10 +101,10 @@ Return the fftwavenumber vector with length n and domain size L.
101101
fftwavenums(n::Int; L=1) = 2π/L*cat(1, 0:n/2, -n/2+1:-1)
102102

103103

104-
"""
104+
"""
105105
rms(q)
106106
107-
Return the root-mean-square of an array.
107+
Return the root-mean-square of an array.
108108
"""
109109
rms(q) = sqrt(mean(q.^2))
110110

@@ -152,7 +152,7 @@ function peaked_isotropic_spectrum(nx::Int, npeak::Real; ord=4.0, rms=1.0,
152152
end
153153

154154

155-
"""
155+
"""
156156
lambdipole(Ue, R, g; center=(x0, y0))
157157
158158
Return a 2D vorticity field corresponding to the Lamb Dipole with
@@ -170,7 +170,8 @@ function lambdipole(Ue::Real, R::Real, g::TwoDGrid; center=(nothing, nothing))
170170
end
171171

172172
# Wavenumber corresponding to radius R and the first bessel func zero.
173-
k = 3.8317 / R
173+
# k = 3.8317 / R
174+
k = 3.8317059702075123156 / R
174175
q0 = -2*Ue*k/SpecialFunctions.besselj(0, k*R)
175176

176177
r = sqrt.((g.X-xc).^2.0 + (g.Y-yc).^2.0)
@@ -183,12 +184,12 @@ function lambdipole(Ue::Real, R::Real, g::TwoDGrid; center=(nothing, nothing))
183184
end
184185

185186

186-
"""
187+
"""
187188
gaussianvortex(q0, R, G; center=(x0, y0))
188189
189190
Return a vorticity field with magnitude q0, radius R, and center at
190191
center[1], center[2] on a TwoDGrid g corresponding to a 'Gaussian vortex' with
191-
Gaussian streamfunction.
192+
Gaussian streamfunction.
192193
"""
193194
function gaussianvortex(q0::Real, R::Real, g::TwoDGrid;
194195
center=(nothing, nothing))
@@ -206,11 +207,11 @@ function gaussianvortex(q0::Real, R::Real, g::TwoDGrid;
206207
end
207208

208209

209-
"""
210+
"""
210211
rmsrand(g, rmsval)
211212
212213
Return an array of random numbers on a TwoDGrid normalized to have a
213-
specifed rms value.
214+
specifed rms value.
214215
"""
215216
function rmsrand(g::TwoDGrid, rmsval::Real)
216217
q = rand(g.nx, g.ny)
@@ -219,7 +220,7 @@ function rmsrand(g::TwoDGrid, rmsval::Real)
219220
end
220221

221222

222-
"""
223+
"""
223224
parsevalsum2(uh, g)
224225
225226
Calculate ∫u = Σ|uh|² on a 2D grid, where uh is the Fourier transform of u.
@@ -231,27 +232,27 @@ function parsevalsum2(uh, g::TwoDGrid)
231232

232233
if size(uh)[1] == g.nkr # uh is conjugate symmetric
233234
U = sum(abs2, uh[1, :]) # k=0 modes
234-
U += 2*sum(abs2, uh[2:end, :]) # sum k>0 modes twice
235+
U += 2*sum(abs2, uh[2:end, :]) # sum k>0 modes twice
235236
else # count every mode once
236237
U = sum(abs2, uh)
237238
end
238239

239240
norm*U
240241
end
241242

242-
"""
243+
"""
243244
parsevalsum(uh, g)
244245
245-
Calculate real(Σ uh) on a 2D grid. Accounts for DFT normalization,
246-
grid resolution, and whether or not uh is in a conjugate-symmetric form to
246+
Calculate real(Σ uh) on a 2D grid. Accounts for DFT normalization,
247+
grid resolution, and whether or not uh is in a conjugate-symmetric form to
247248
save memory.
248-
"""
249+
"""
249250
function parsevalsum(uh, g::TwoDGrid)
250251
norm = g.Lx*g.Ly/(g.nx^2*g.ny^2) # weird normalization for dft
251252

252253
if size(uh)[1] == g.nkr # uh is conjugate symmetric
253254
U = sum(uh[1, :]) # k=0 modes
254-
U += 2*sum(uh[2:end, :]) # sum k>0 modes twice
255+
U += 2*sum(uh[2:end, :]) # sum k>0 modes twice
255256
else # count every mode once
256257
U = sum(uh)
257258
end
@@ -298,13 +299,13 @@ end
298299
"""
299300
radialspectrum(ah, g; nr=nothing, nθ=nothing, refinement=4)
300301
301-
Returns aρ = ∫ ah(ρ,θ) ρ dρ dθ, the radial spectrum of ah known on the
302-
Cartesian wavenumber grid (k,l).
302+
Returns aρ = ∫ ah(ρ,θ) ρ dρ dθ, the radial spectrum of ah known on the
303+
Cartesian wavenumber grid (k,l).
303304
304-
aρ is found by intepolating ah onto a polar wavenumber grid (ρ,θ), and
305-
then integrating over θ to find aρ. The default resolution (n,m) for the
306-
polar wave number grid is n=refinement*maximum(nk,nl),
307-
m=refinement*maximum(nk,nl), where refinement=4 by default. If
305+
aρ is found by intepolating ah onto a polar wavenumber grid (ρ,θ), and
306+
then integrating over θ to find aρ. The default resolution (n,m) for the
307+
polar wave number grid is n=refinement*maximum(nk,nl),
308+
m=refinement*maximum(nk,nl), where refinement=4 by default. If
308309
ah is in conjugate symmetric form only the upper half plane in θ is
309310
represented on the polar grid.
310311
@@ -319,7 +320,7 @@ function radialspectrum(ah, g::TwoDGrid; n=nothing, m=nothing, refinement=4)
319320
θ = linspace(-π/2, π/2, m) # θ-grid from k=0 to max(kr)
320321
ahsh = fftshift(ah, 2) # shifted ah
321322
ksh = linspace(0, g.nkr-1, g.nkr)*2π/g.Lx
322-
else # ordinary form
323+
else # ordinary form
323324
θ = linspace(0, 2π, m) # θ grid
324325
ahsh = fftshift(ah, [1, 2]) # shifted ah
325326
ksh = linspace(-g.nk/2+1, g.nk/2, g.nk)*2π/g.Lx
@@ -348,7 +349,7 @@ function radialspectrum(ah, g::TwoDGrid; n=nothing, m=nothing, refinement=4)
348349
end
349350
ahρ[1] = ah[1, 1] # zeroth mode
350351

351-
ρ, ahρ
352+
ρ, ahρ
352353
end
353354

354355
# Moments and cumulants

test/runtests.jl

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ using Base.Test
77
# Run tests
88
tic()
99

10+
println("-- Core tests --")
11+
1012
@testset "Grid tests" begin
1113
include("test_grid.jl")
1214
end
@@ -19,20 +21,27 @@ end
1921
include("test_ifft.jl")
2022
end
2123

22-
@testset "TwoDTurb Stepper tests" begin
23-
include("test_timesteppers.jl")
24+
@testset "Utils tests" begin
25+
include("test_utils.jl")
2426
end
2527

26-
@testset "BarotropicQG Stepper tests" begin
27-
include("test_BarotropicQG_timesteppers.jl")
28+
@testset "Timestepper tests" begin
29+
include("test_timesteppers.jl")
2830
end
2931

30-
@testset "BarotropicQG Rossby wave test" begin
31-
include("test_BarotropicQG_RossbyWave.jl")
32+
# @testset "BarotropicQG Stepper tests" begin
33+
# include("test_BarotropicQG_timesteppers.jl")
34+
# end
35+
36+
println("-- Physics tests --")
37+
38+
@testset "Physics: TwoDTurb" begin
39+
include("test_twodturb.jl")
3240
end
3341

34-
@testset "Utils tests" begin
35-
include("test_utils.jl")
42+
@testset "Physics: BarotropicQG" begin
43+
include("test_barotropicqg.jl")
3644
end
3745

46+
3847
println("Total test time: ", toq())
File renamed without changes.

test/test_twodturb.jl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import FourierFlows.TwoDTurb
2+
3+
cfl(prob) = maximum([maximum(abs.(prob.vars.U)), maximum(abs.(prob.vars.V))]*
4+
prob.ts.dt/prob.grid.dx)
5+
6+
function lambdipoletest(n, dt; L=2π, Ue=1, Re=L/20, ν=0, nν=1, ti=L/Ue*0.01,
7+
nm=3, message=false)
8+
9+
nt = round(Int, ti/dt)
10+
11+
prob = TwoDTurb.InitialValueProblem(nx=n, Lx=L, ν=ν, nν=nν, dt=dt, stepper="FilteredRK4")
12+
x, y, q = prob.grid.X, prob.grid.Y, prob.vars.q # nicknames
13+
14+
q0 = FourierFlows.lambdipole(Ue, Re, prob.grid)
15+
TwoDTurb.set_q!(prob, q0)
16+
17+
xq = zeros(nm) # centroid of abs(q)
18+
Ue_m = zeros(nm) # measured dipole speed
19+
20+
# Step forward
21+
for i = 1:nm
22+
tic()
23+
stepforward!(prob, nt)
24+
TwoDTurb.updatevars!(prob)
25+
xq[i] = mean(abs.(q).*x) / mean(abs.(q))
26+
27+
if i > 1
28+
Ue_m[i] = (xq[i]-xq[i-1]) / ((nt-1)*dt)
29+
end
30+
31+
if message
32+
@printf(" step: %04d, t: %3.3f, time: %.3f, cfl: %.2f\n",
33+
prob.step, prob.t, toq(), cfl(prob))
34+
end
35+
end
36+
# println(Ue_m)
37+
# println(abs(Ue - mean(Ue_m[2:end]))/abs(Ue))
38+
isapprox(Ue, mean(Ue_m[2:end]), rtol=1e-2)
39+
end
40+
41+
@test lambdipoletest(256, 1e-3)

0 commit comments

Comments
 (0)