@@ -9,37 +9,8 @@ using ClimaCorePlots, Plots
9
9
10
10
# Reference paper: https://rmets.onlinelibrary.wiley.com/doi/pdf/10.1002/qj.2105
11
11
12
- # min_λx = 2 * (x_max / x_elem) / upsampling_factor # this should include npoly
13
- # min_λz = 2 * (FT( / z_)elem) / upsampling_factor
14
- # min_λx = 2 * π / max_kx = x_max / max_ikx
15
- # min_λz = 2 * π / max_kz = 2 * z_max / max_ikz
16
- # max_ikx = x_max / min_λx = upsampling_factor * x_elem / 2
17
- # max_ikz = 2 * z_max / min_λz = upsampling_factor * z_elem
18
- function ρfb_init_coefs! (:: Type{FT} , params) where {FT}
19
- (; max_ikz, max_ikx, x_max, z_max, unit_integral) = params
20
- (; ρfb_init_array, ᶜρb_init_xz) = params
21
- # Since the coefficients are for a modified domain of height 2 * z_max, the
22
- # unit integral over the domain must be multiplied by 2 to ensure correct
23
- # normalization. On the other hand, ᶜρb_init is assumed to be 0 outside of
24
- # the "true" domain, so the integral of
25
- # ᶜintegrand (`ᶜintegrand = ᶜρb_init / ᶜfourier_factor`) should not be modified.
26
- # where `ᶜfourier_factor = exp(im * (kx * x + kz * z))`.
27
- @inbounds begin
28
- Threads. @threads for ikx in (- max_ikx): max_ikx
29
- for ikz in (- max_ikz): max_ikz
30
- kx:: FT = 2 * π / x_max * ikx
31
- kz:: FT = 2 * π / (2 * z_max) * ikz
32
- ρfb_init_array[ikx + max_ikx + 1 , ikz + max_ikz + 1 ] =
33
- sum (ᶜρb_init_xz) do nt
34
- (; ρ, x, z) = nt
35
- ρ / exp (im * (kx * x + kz * z))
36
- end / unit_integral
37
-
38
- end
39
- end
40
- end
41
- return nothing
42
- end
12
+ include (" intertial_gravity_wave_utils.jl" )
13
+ import . InertialGravityWaveUtils as IGWU
43
14
44
15
# Constants for switching between different experiment setups
45
16
const is_small_scale = true
@@ -191,7 +162,7 @@ function postprocessing(sol, output_dir)
191
162
for iframe in (1 , length (sol. t))
192
163
t = sol. t[iframe]
193
164
Y = sol. u[iframe]
194
- linear_solution! (Y_lin, lin_cache, t)
165
+ IGWU . linear_solution! (Y_lin, lin_cache, t, FT )
195
166
println (" Error norms at time t = $t :" )
196
167
for (name, f) in
197
168
((:ρ′ , ρ′), (:T′ , T′), (:u′ , u′), (:v′ , v′), (:w′ , w′))
@@ -213,11 +184,12 @@ function postprocessing(sol, output_dir)
213
184
(:wprime , w′, is_small_scale ? 0.0042 : 0.0014 ),
214
185
)
215
186
anims = [Animation () for _ in 1 : (3 * length (anim_vars))]
187
+ @info " Creating animation with $(length (sol. t)) frames."
216
188
@inbounds begin
217
189
@progress " Animations" for iframe in 1 : length (sol. t)
218
190
t = sol. t[iframe]
219
191
Y = sol. u[iframe]
220
- linear_solution! (Y_lin, lin_cache, t)
192
+ IGWU . linear_solution! (Y_lin, lin_cache, t, FT )
221
193
for (ivar, (_, f, lim)) in enumerate (anim_vars)
222
194
var = f (Y)
223
195
var_lin = f (Y_lin)
@@ -307,10 +279,27 @@ function linear_solution_cache(ᶜlocal_geometry, ᶠlocal_geometry)
307
279
ᶜz = ᶜlocal_geometry. coordinates. z
308
280
ᶠz = ᶠlocal_geometry. coordinates. z
309
281
ρfb_init_array_params = ρfb_init_coefs_params ()
310
- @time " ρfb_init_coefs!" ρfb_init_coefs! (FT, ρfb_init_array_params)
311
- (; ρfb_init_array) = ρfb_init_array_params
282
+ @time " ρfb_init_coefs!" IGWU. ρfb_init_coefs! (FT, ρfb_init_array_params)
283
+ (; ρfb_init_array, ᶜρb_init_xz, unit_integral) = ρfb_init_array_params
284
+ max_ikx, max_ikz = (size (ρfb_init_array) .- 1 ) .÷ 2
312
285
ᶜp₀ = @. p₀ (ᶜz)
313
286
return (;
287
+ # globals
288
+ R_d,
289
+ ᶜ𝔼_name,
290
+ x_max,
291
+ z_max,
292
+ p_0,
293
+ cp_d,
294
+ cv_d,
295
+ grav,
296
+ T_tri,
297
+ u₀,
298
+ δ,
299
+ cₛ²,
300
+ f,
301
+ ρₛ,
302
+ ᶜinterp,
314
303
# coordinates
315
304
ᶜx = ᶜlocal_geometry. coordinates. x,
316
305
ᶠx = ᶠlocal_geometry. coordinates. x,
@@ -331,10 +320,10 @@ function linear_solution_cache(ᶜlocal_geometry, ᶠlocal_geometry)
331
320
332
321
# Fourier coefficients of Bretherton transform of initial perturbation
333
322
ρfb_init_array,
334
-
335
- # Fourier transform factors
336
- ᶜfourier_factor = Fields . Field (Complex{FT}, axes (ᶜlocal_geometry)) ,
337
- ᶠfourier_factor = Fields . Field (Complex{FT}, axes (ᶠlocal_geometry)) ,
323
+ unit_integral,
324
+ ᶜρb_init_xz,
325
+ max_ikx ,
326
+ max_ikz ,
338
327
339
328
# Bretherton transform of final perturbation
340
329
ᶜpb = Fields. Field (FT, axes (ᶜlocal_geometry)),
@@ -354,97 +343,3 @@ function linear_solution_cache(ᶜlocal_geometry, ᶠlocal_geometry)
354
343
ᶜT = Fields. Field (FT, axes (ᶜlocal_geometry)),
355
344
)
356
345
end
357
-
358
- function linear_solution! (Y, lin_cache, t)
359
- (; ᶜx, ᶠx, ᶜz, ᶠz, ᶜp₀, ᶜρ₀, ᶜu₀, ᶜv₀, ᶠw₀) = lin_cache
360
- (; ᶜbretherton_factor_pρ) = lin_cache
361
- (; ᶜbretherton_factor_uvwT, ᶠbretherton_factor_uvwT) = lin_cache
362
- (; ρfb_init_array, ᶜfourier_factor, ᶠfourier_factor) = lin_cache
363
- (; ᶜpb, ᶜρb, ᶜub, ᶜvb, ᶠwb, ᶜp, ᶜρ, ᶜu, ᶜv, ᶠw, ᶜT) = lin_cache
364
-
365
- ᶜpb .= FT (0 )
366
- ᶜρb .= FT (0 )
367
- ᶜub .= FT (0 )
368
- ᶜvb .= FT (0 )
369
- ᶠwb .= FT (0 )
370
- max_ikx, max_ikz = (size (ρfb_init_array) .- 1 ) .÷ 2
371
- @inbounds for ikx in (- max_ikx): max_ikx, ikz in (- max_ikz): max_ikz
372
- kx = 2 * π / x_max * ikx
373
- kz = 2 * π / (2 * z_max) * ikz
374
-
375
- # Fourier coefficient of ᶜρb_init (for current kx and kz)
376
- ρfb_init = ρfb_init_array[ikx + max_ikx + 1 , ikz + max_ikz + 1 ]
377
-
378
- # Fourier factors, shifted by u₀ * t along the x-axis
379
- @. ᶜfourier_factor = exp (im * (kx * (ᶜx - u₀ * t) + kz * ᶜz))
380
- @. ᶠfourier_factor = exp (im * (kx * (ᶠx - u₀ * t) + kz * ᶠz))
381
-
382
- # roots of a₁(s)
383
- p₁ = cₛ² * (kx^ 2 + kz^ 2 + δ^ 2 / 4 ) + f^ 2
384
- q₁ = grav * kx^ 2 * (cₛ² * δ - grav) + cₛ² * f^ 2 * (kz^ 2 + δ^ 2 / 4 )
385
- α² = p₁ / 2 - sqrt (p₁^ 2 / 4 - q₁)
386
- β² = p₁ / 2 + sqrt (p₁^ 2 / 4 - q₁)
387
- α = sqrt (α²)
388
- β = sqrt (β²)
389
-
390
- # inverse Laplace transform of s^p/((s^2 + α^2)(s^2 + β^2)) for p ∈ -1:3
391
- if α == 0
392
- L₋₁ = (β² * t^ 2 / 2 - 1 + cos (β * t)) / β^ 4
393
- L₀ = (β * t - sin (β * t)) / β^ 3
394
- else
395
- L₋₁ =
396
- (- cos (α * t) / α² + cos (β * t) / β²) / (β² - α²) + 1 / (α² * β²)
397
- L₀ = (sin (α * t) / α - sin (β * t) / β) / (β² - α²)
398
- end
399
- L₁ = (cos (α * t) - cos (β * t)) / (β² - α²)
400
- L₂ = (- sin (α * t) * α + sin (β * t) * β) / (β² - α²)
401
- L₃ = (- cos (α * t) * α² + cos (β * t) * β²) / (β² - α²)
402
-
403
- # Fourier coefficients of Bretherton transforms of final perturbations
404
- C₁ = grav * (grav - cₛ² * (im * kz + δ / 2 ))
405
- C₂ = grav * (im * kz - δ / 2 )
406
- pfb = - ρfb_init * (L₁ + L₋₁ * f^ 2 ) * C₁
407
- ρfb =
408
- ρfb_init *
409
- (L₃ + L₁ * (p₁ + C₂) + L₋₁ * f^ 2 * (cₛ² * (kz^ 2 + δ^ 2 / 4 ) + C₂))
410
- ufb = ρfb_init * L₀ * im * kx * C₁ / ρₛ
411
- vfb = - ρfb_init * L₋₁ * im * kx * f * C₁ / ρₛ
412
- wfb = - ρfb_init * (L₂ + L₀ * (f^ 2 + cₛ² * kx^ 2 )) * grav / ρₛ
413
-
414
- # Bretherton transforms of final perturbations
415
- @. ᶜpb += real (pfb * ᶜfourier_factor)
416
- @. ᶜρb += real (ρfb * ᶜfourier_factor)
417
- @. ᶜub += real (ufb * ᶜfourier_factor)
418
- @. ᶜvb += real (vfb * ᶜfourier_factor)
419
- @. ᶠwb += real (wfb * ᶠfourier_factor)
420
- # The imaginary components should be 0 (or at least very close to 0).
421
- end
422
-
423
- # final state
424
- @. ᶜp = ᶜp₀ + ᶜpb * ᶜbretherton_factor_pρ
425
- @. ᶜρ = ᶜρ₀ + ᶜρb * ᶜbretherton_factor_pρ
426
- @. ᶜu = ᶜu₀ + ᶜub * ᶜbretherton_factor_uvwT
427
- @. ᶜv = ᶜv₀ + ᶜvb * ᶜbretherton_factor_uvwT
428
- @. ᶠw = ᶠw₀ + ᶠwb * ᶠbretherton_factor_uvwT
429
- @. ᶜT = ᶜp / (R_d * ᶜρ)
430
-
431
- @. Y. c. ρ = ᶜρ
432
- if ᶜ𝔼_name == :ρθ
433
- @. Y. c. ρθ = ᶜρ * ᶜT * (p_0 / ᶜp)^ (R_d / cp_d)
434
- elseif ᶜ𝔼_name == :ρe
435
- @. Y. c. ρe =
436
- ᶜρ * (
437
- cv_d * (ᶜT - T_tri) +
438
- (ᶜu^ 2 + ᶜv^ 2 + ᶜinterp (ᶠw)^ 2 ) / 2 +
439
- grav * ᶜz
440
- )
441
- elseif ᶜ𝔼_name == :ρe_int
442
- @. Y. c. ρe_int = ᶜρ * cv_d * (ᶜT - T_tri)
443
- end
444
- # NOTE: The following two lines are a temporary workaround b/c Covariant12Vector won't accept a non-zero second component in an XZ-space.
445
- # So we temporarily set it to zero and then reassign its intended non-zero value (since in case of large-scale config ᶜv is non-zero)
446
- @. Y. c. uₕ = Geometry. Covariant12Vector (Geometry. UVVector (ᶜu, FT (0.0 )))
447
- @. Y. c. uₕ. components. data.:2 .= ᶜv
448
- @. Y. f. w = Geometry. Covariant3Vector (Geometry. WVector (ᶠw))
449
- return nothing
450
- end
0 commit comments