Skip to content

Commit fe5bf0d

Browse files
authored
Merge pull request #3843 from CliMA/aj/edmf_1M_sedimentation
Add sedimentation of rhoa, q_tot and moisture tracers to edmf
2 parents a52524b + 0349181 commit fe5bf0d

File tree

9 files changed

+257
-70
lines changed

9 files changed

+257
-70
lines changed

.buildkite/pipeline.yml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ steps:
8888
--config_file $CONFIG_PATH/single_column_precipitation_test.yml
8989
--job_id single_column_precipitation_test
9090
artifact_paths: "single_column_precipitation_test/output_active/*"
91-
91+
9292
- label: ":umbrella: 2-moment precipitation sanity test single column"
9393
command: >
9494
julia --color=yes --project=.buildkite .buildkite/ci_driver.jl
@@ -916,6 +916,15 @@ steps:
916916
agents:
917917
slurm_mem: 20GB
918918

919+
- label: ":genie: Prognostic EDMFX Dycoms RF02 in a column"
920+
command: >
921+
julia --color=yes --project=.buildkite .buildkite/ci_driver.jl
922+
--config_file $CONFIG_PATH/prognostic_edmfx_dycoms_rf02_column.yml
923+
--job_id prognostic_edmfx_dycoms_rf02_column
924+
artifact_paths: "prognostic_edmfx_dycoms_rf02_column/output_active/*"
925+
agents:
926+
slurm_mem: 20GB
927+
919928
- label: ":umbrella: Prognostic EDMFX Rico in a column"
920929
command: >
921930
julia --color=yes --project=.buildkite .buildkite/ci_driver.jl
@@ -1127,9 +1136,9 @@ steps:
11271136
agents:
11281137
slurm_gpus: 1
11291138
slurm_mem: 16GB
1130-
1139+
11311140
- label: ":earth_americas: GPU: Diagnostic EDMFX ERA5 Weather Model Initial Condition"
1132-
command: >
1141+
command: >
11331142
julia --color=yes --project=.buildkite .buildkite/ci_driver.jl
11341143
--config_file $COMMON_CONFIG_PATH/numerics_sphere_he6ze31.yml
11351144
--config_file $CONFIG_PATH/diagnostic_edmfx_era5_initial_condition.yml
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
initial_condition: DYCOMS_RF02
2+
subsidence: DYCOMS
3+
scm_coriolis: DYCOMS_RF02
4+
rad: DYCOMS
5+
surface_setup: DYCOMS_RF02
6+
turbconv: "prognostic_edmfx"
7+
implicit_diffusion: false
8+
approximate_linear_solve_iters: 2
9+
edmfx_upwinding: first_order
10+
edmfx_entr_model: "Generalized"
11+
edmfx_detr_model: "Generalized"
12+
edmfx_sgs_mass_flux: true
13+
edmfx_sgs_diffusive_flux: true
14+
edmfx_nh_pressure: true
15+
edmfx_filter: true
16+
prognostic_tke: true
17+
moist: "nonequil"
18+
cloud_model: "quadrature_sgs"
19+
precip_model: "1M"
20+
call_cloud_diagnostics_per_stage: true
21+
config: "column"
22+
x_elem: 2
23+
y_elem: 2
24+
z_elem: 30
25+
z_max: 1500
26+
z_stretch: false
27+
perturb_initstate: false
28+
dt: 10secs
29+
t_end: 5hours
30+
dt_save_state_to_disk: 10mins
31+
toml: [toml/prognostic_edmfx_1M.toml]
32+
netcdf_interpolation_num_points: [8, 8, 30]
33+
diagnostics:
34+
- short_name: [ts, ta, thetaa, ha, pfull, rhoa, ua, va, wa, hur, hus, cl, clw, cli, hussfc, evspsbl, pr]
35+
period: 10mins
36+
- short_name: [arup, waup, taup, thetaaup, haup, husup, hurup, clwup, cliup, husraup, hussnup]
37+
period: 10mins
38+
- short_name: [waen, taen, thetaaen, haen, husen, huren, clwen, clien, husraen, hussnen, tke]
39+
period: 10mins
40+
- short_name: [entr, detr, lmix, bgrad, strain, edt, evu]
41+
period: 10mins
42+
- short_name: [husra, hussn]
43+
period: 10mins

config/model_configs/prognostic_edmfx_rico_column.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ subsidence: "Rico"
33
ls_adv: "Rico"
44
surface_setup: "Rico"
55
turbconv: "prognostic_edmfx"
6-
implicit_diffusion: false
6+
implicit_diffusion: true
77
implicit_sgs_advection: false
88
approximate_linear_solve_iters: 2
99
edmfx_upwinding: first_order
@@ -25,9 +25,9 @@ y_elem: 2
2525
z_elem: 100
2626
z_stretch: false
2727
perturb_initstate: false
28-
dt: "10secs"
29-
t_end: "6hours"
30-
dt_save_state_to_disk: "10mins"
28+
dt: "5secs"
29+
t_end: "180mins"
30+
dt_save_state_to_disk: "60mins"
3131
toml: [toml/prognostic_edmfx_1M.toml]
3232
netcdf_interpolation_num_points: [8, 8, 100]
3333
diagnostics:

post_processing/ci_plots.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,7 @@ EDMFBoxPlots = Union{
13971397
EDMFBoxPlotsWithPrecip = Union{
13981398
Val{:prognostic_edmfx_rico_column},
13991399
Val{:prognostic_edmfx_trmm_column},
1400+
Val{:prognostic_edmfx_dycoms_rf02_column},
14001401
}
14011402

14021403
DiagEDMFBoxPlotsWithPrecip = Union{

src/cache/precomputed_quantities.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ function precomputed_quantities(Y, atmos)
138138
ᶜSqᵢᵖʲs = similar(Y.c, NTuple{n, FT}),
139139
ᶜSqᵣᵖʲs = similar(Y.c, NTuple{n, FT}),
140140
ᶜSqₛᵖʲs = similar(Y.c, NTuple{n, FT}),
141+
ᶜwₗʲs = similar(Y.c, NTuple{n, FT}),
142+
ᶜwᵢʲs = similar(Y.c, NTuple{n, FT}),
143+
ᶜwᵣʲs = similar(Y.c, NTuple{n, FT}),
144+
ᶜwₛʲs = similar(Y.c, NTuple{n, FT}),
145+
ᶜwₜʲs = similar(Y.c, NTuple{n, FT}),
146+
ᶜwₕʲs = similar(Y.c, NTuple{n, FT}),
141147
ᶜSqₗᵖ⁰ = similar(Y.c, FT),
142148
ᶜSqᵢᵖ⁰ = similar(Y.c, FT),
143149
ᶜSqᵣᵖ⁰ = similar(Y.c, FT),

src/cache/prognostic_edmf_precomputed_quantities.jl

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,13 +538,73 @@ NVTX.@annotate function set_prognostic_edmf_precomputed_quantities_precipitation
538538
(; ᶜSqₗᵖʲs, ᶜSqᵢᵖʲs, ᶜSqᵣᵖʲs, ᶜSqₛᵖʲs, ᶜρʲs, ᶜtsʲs) = p.precomputed
539539
(; ᶜSqₗᵖ⁰, ᶜSqᵢᵖ⁰, ᶜSqᵣᵖ⁰, ᶜSqₛᵖ⁰, ᶜts⁰) = p.precomputed
540540

541+
(; ᶜwₗʲs, ᶜwᵢʲs, ᶜwᵣʲs, ᶜwₛʲs, ᶜwₜʲs, ᶜwₕʲs) = p.precomputed
542+
541543
# TODO - can I re-use them between js and env?
542544
ᶜSᵖ = p.scratch.ᶜtemp_scalar
543545
ᶜSᵖ_snow = p.scratch.ᶜtemp_scalar_2
544546

545547
n = n_mass_flux_subdomains(p.atmos.turbconv_model)
548+
FT = eltype(params)
546549

547550
for j in 1:n
551+
552+
# compute terminal velocity for precipitation
553+
@. ᶜwᵣʲs.:($$j) = CM1.terminal_velocity(
554+
cmp.pr,
555+
cmp.tv.rain,
556+
ᶜρʲs.:($$j),
557+
max(zero(Y.c.ρ), Y.c.sgsʲs.:($$j).q_rai),
558+
)
559+
@. ᶜwₛʲs.:($$j) = CM1.terminal_velocity(
560+
cmp.ps,
561+
cmp.tv.snow,
562+
ᶜρʲs.:($$j),
563+
max(zero(Y.c.ρ), Y.c.sgsʲs.:($$j).q_sno),
564+
)
565+
# compute sedimentation velocity for cloud condensate [m/s]
566+
@. ᶜwₗʲs.:($$j) = CMNe.terminal_velocity(
567+
cmc.liquid,
568+
cmc.Ch2022.rain,
569+
ᶜρʲs.:($$j),
570+
max(zero(Y.c.ρ), Y.c.sgsʲs.:($$j).q_liq),
571+
)
572+
@. ᶜwᵢʲs.:($$j) = CMNe.terminal_velocity(
573+
cmc.ice,
574+
cmc.Ch2022.small_ice,
575+
ᶜρʲs.:($$j),
576+
max(zero(Y.c.ρ), Y.c.sgsʲs.:($$j).q_ice),
577+
)
578+
# compute their contirbutions to energy and total water advection
579+
@. ᶜwₜʲs.:($$j) = ifelse(
580+
Y.c.sgsʲs.:($$j).ρa * Y.c.sgsʲs.:($$j).q_tot > FT(0),
581+
(
582+
ᶜwₗʲs.:($$j) * Y.c.sgsʲs.:($$j).q_liq +
583+
ᶜwᵢʲs.:($$j) * Y.c.sgsʲs.:($$j).q_ice +
584+
ᶜwᵣʲs.:($$j) * Y.c.sgsʲs.:($$j).q_rai +
585+
ᶜwₛʲs.:($$j) * Y.c.sgsʲs.:($$j).q_sno
586+
) / Y.c.sgsʲs.:($$j).q_tot,
587+
FT(0),
588+
)
589+
@. ᶜwₕʲs.:($$j) = ifelse(
590+
Y.c.sgsʲs.:($$j).ρa * abs(Y.c.sgsʲs.:($$j).mse) > FT(0),
591+
(
592+
ᶜwₗʲs.:($$j) *
593+
Y.c.sgsʲs.:($$j).q_liq *
594+
(Iₗ(thp, ᶜtsʲs.:($$j)) + ᶜΦ) +
595+
ᶜwᵢʲs.:($$j) *
596+
Y.c.sgsʲs.:($$j).q_ice *
597+
(Iᵢ(thp, ᶜtsʲs.:($$j)) + ᶜΦ) +
598+
ᶜwᵣʲs.:($$j) *
599+
Y.c.sgsʲs.:($$j).q_rai *
600+
(Iₗ(thp, ᶜtsʲs.:($$j)) + ᶜΦ) +
601+
ᶜwₛʲs.:($$j) *
602+
Y.c.sgsʲs.:($$j).q_sno *
603+
(Iᵢ(thp, ᶜtsʲs.:($$j)) + ᶜΦ)
604+
) / abs(Y.c.sgsʲs.:($$j).mse),
605+
FT(0),
606+
)
607+
548608
# Precipitation sources and sinks from the updrafts
549609
compute_precipitation_sources!(
550610
ᶜSᵖ,

src/prognostic_equations/advection.jl

Lines changed: 116 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import ClimaCore.Geometry as Geometry
1010
horizontal_dynamics_tendency!(Yₜ, Y, p, t)
1111
1212
Computes tendencies due to horizontal advection for prognostic variables of the
13-
grid mean and EDMFX subdomains, and also applies horizontal pressure gradient and
13+
grid mean and EDMFX subdomains, and also applies horizontal pressure gradient and
1414
gravitational acceleration terms for horizontal momentum.
1515
1616
Specifically, this function calculates:
@@ -344,7 +344,6 @@ function edmfx_sgs_vertical_advection_tendency!(
344344
turbconv_params = CAP.turbconv_params(params)
345345
α_b = CAP.pressure_normalmode_buoy_coeff1(turbconv_params)
346346
ᶠz = Fields.coordinate_field(Y.f).z
347-
ᶜa_scalar = p.scratch.ᶜtemp_scalar
348347
ᶜu₃ʲ = p.scratch.ᶜtemp_C3
349348
ᶜKᵥʲ = p.scratch.ᶜtemp_scalar_2
350349
for j in 1:n
@@ -370,58 +369,127 @@ function edmfx_sgs_vertical_advection_tendency!(
370369
end
371370

372371
for j in 1:n
373-
@. ᶜa_scalar = draft_area(Y.c.sgsʲs.:($$j).ρa, ᶜρʲs.:($$j))
374-
vtt = vertical_transport(
375-
ᶜρʲs.:($j),
376-
ᶠu³ʲs.:($j),
377-
ᶜa_scalar,
378-
dt,
379-
edmfx_upwinding,
380-
)
372+
ᶜa = (@. lazy(draft_area(Y.c.sgsʲs.:($$j).ρa, ᶜρʲs.:($$j))))
373+
edmf_upwnd = edmfx_upwinding
374+
375+
# Flux form vertical advection of area farction with the grid mean velocity
376+
vtt = vertical_transport(ᶜρʲs.:($j), ᶠu³ʲs.:($j), ᶜa, dt, edmf_upwnd)
381377
@. Yₜ.c.sgsʲs.:($$j).ρa += vtt
382378

383-
va = vertical_advection(
384-
ᶠu³ʲs.:($j),
385-
Y.c.sgsʲs.:($j).mse,
386-
edmfx_upwinding,
387-
)
388-
@. Yₜ.c.sgsʲs.:($$j).mse += va
379+
# Advective form advection of mse and q_tot with the grid mean velocity
380+
# TODO - make it work for multiple updrafts
381+
if j > 1
382+
error("Below code doesn't work for multiple updrafts")
383+
end
384+
sgs_q_tot_mse = (@name(c.sgsʲs.:(1).mse), @name(c.sgsʲs.:(1).q_tot))
385+
MatrixFields.unrolled_foreach(sgs_q_tot_mse) do χʲ_name
386+
MatrixFields.has_field(Y, χʲ_name) || return
387+
ᶜχʲ = MatrixFields.get_field(Y, χʲ_name)
388+
ᶜχʲₜ = MatrixFields.get_field(Yₜ, χʲ_name)
389+
390+
va = vertical_advection(ᶠu³ʲs.:($j), ᶜχʲ, edmf_upwnd)
391+
@. ᶜχʲₜ += va
392+
end
389393

390-
va = vertical_advection(
391-
ᶠu³ʲs.:($j),
392-
Y.c.sgsʲs.:($j).q_tot,
393-
edmfx_upwinding,
394-
)
395-
@. Yₜ.c.sgsʲs.:($$j).q_tot += va
396394
if p.atmos.moisture_model isa NonEquilMoistModel &&
397395
p.atmos.microphysics_model isa Microphysics1Moment
398-
# TODO - add precipitation terminal velocity
399-
# TODO - add cloud sedimentation velocity
400-
# TODO - add their contributions to mean energy and mass
401-
va = vertical_advection(
402-
ᶠu³ʲs.:($j),
403-
Y.c.sgsʲs.:($j).q_liq,
404-
edmfx_upwinding,
405-
)
406-
@. Yₜ.c.sgsʲs.:($$j).q_liq += va
407-
va = vertical_advection(
408-
ᶠu³ʲs.:($j),
409-
Y.c.sgsʲs.:($j).q_ice,
410-
edmfx_upwinding,
411-
)
412-
@. Yₜ.c.sgsʲs.:($$j).q_ice += va
413-
va = vertical_advection(
414-
ᶠu³ʲs.:($j),
415-
Y.c.sgsʲs.:($j).q_rai,
416-
edmfx_upwinding,
396+
# TODO - add contibutions to sgs mass flux from tracer sedimentation
397+
# TODO - add precipitation and cloud sedimentation in implicit solver/tendency with if/else
398+
399+
FT = eltype(params)
400+
thp = CAP.thermodynamics_params(params)
401+
(; ᶜΦ) = p.core
402+
(; ᶜtsʲs) = p.precomputed
403+
404+
# Sedimentation velocities for microphysics tracers
405+
# TODO - lazify ᶜwₗʲs computation. No need to cache it.
406+
sgs_microphysics_tracers = (
407+
(@name(c.sgsʲs.:(1).q_liq), @name(q_liq), @name(ᶜwₗʲs.:(1))),
408+
(@name(c.sgsʲs.:(1).q_ice), @name(q_ice), @name(ᶜwᵢʲs.:(1))),
409+
(@name(c.sgsʲs.:(1).q_rai), @name(q_rai), @name(ᶜwᵣʲs.:(1))),
410+
(@name(c.sgsʲs.:(1).q_sno), @name(q_sno), @name(ᶜwₛʲs.:(1))),
417411
)
418-
@. Yₜ.c.sgsʲs.:($$j).q_rai += va
419-
va = vertical_advection(
420-
ᶠu³ʲs.:($j),
421-
Y.c.sgsʲs.:($j).q_sno,
422-
edmfx_upwinding,
423-
)
424-
@. Yₜ.c.sgsʲs.:($$j).q_sno += va
412+
413+
MatrixFields.unrolled_foreach(
414+
sgs_microphysics_tracers,
415+
) do (qʲ_name, name, wʲ_name)
416+
MatrixFields.has_field(Y, qʲ_name) || return
417+
418+
ᶜqʲ = MatrixFields.get_field(Y, qʲ_name)
419+
ᶜqʲₜ = MatrixFields.get_field(Yₜ, qʲ_name)
420+
ᶜwʲ = MatrixFields.get_field(p.precomputed, wʲ_name)
421+
ᶠw³ʲ = (@. lazy(CT3(ᶠinterp(Geometry.WVector(-1 * ᶜwʲ)))))
422+
ᶜw³ʲ = (@. lazy(CT3(Geometry.WVector(-1 * ᶜwʲ))))
423+
ᶜaqʲ = (@. lazy(ᶜa * ᶜqʲ))
424+
425+
# Flux form vertical advection of rho * area with sedimentation velocities
426+
# Eq (4) term (3) in the writeup
427+
vtt = vertical_transport(ᶜρʲs.:($j), ᶠw³ʲ, ᶜaqʲ, dt, edmf_upwnd)
428+
@. Yₜ.c.sgsʲs.:($$j).ρa += vtt
429+
430+
# Advective form advection of moisture tracers with the grid mean velocity
431+
# Eq (2) term (1) in the writeup
432+
va = vertical_advection(ᶠu³ʲs.:($j), ᶜqʲ, edmf_upwnd)
433+
@. ᶜqʲₜ += va
434+
435+
# Advective form advection of q_tot and moisture tracers with sedimentation velocities
436+
# Eq (1-2) term (2)
437+
va = vertical_advection(ᶠw³ʲ, ᶜqʲ, edmf_upwnd)
438+
@. Yₜ.c.sgsʲs.:($$j).q_tot += (1 - Y.c.sgsʲs.:($$j).q_tot) * va
439+
@. ᶜqʲₜ += va
440+
# Advective form advection of mse with sedimentation velocity
441+
# Eq (3) term (2)
442+
if name in (@name(q_liq), @name(q_rai))
443+
ᶜmse_li = (@. lazy(
444+
TD.internal_energy_liquid(thp, ᶜtsʲs.:($$j)) + ᶜΦ,
445+
))
446+
elseif name in (@name(q_ice), @name(q_sno))
447+
ᶜmse_li = (@. lazy(
448+
TD.internal_energy_ice(thp, ᶜtsʲs.:($$j)) + ᶜΦ,
449+
))
450+
else
451+
error("Unsupported moisture tracer variable")
452+
end
453+
va = vertical_advection(ᶠw³ʲ, ᶜqʲ .* ᶜmse_li, edmf_upwnd)
454+
@. Yₜ.c.sgsʲs.:($$j).mse += va
455+
va = vertical_advection(ᶠw³ʲ, ᶜqʲ, edmf_upwnd)
456+
@. Yₜ.c.sgsʲs.:($$j).mse -= Y.c.sgsʲs.:($$j).mse * va
457+
458+
# mse, q_tot and moisture tracers terms proportional to 1/ρ̂ ∂zρ̂
459+
# Eq (1-3) term (3)
460+
ᶜinv_ρ̂ = (@. lazy(
461+
specific(
462+
FT(1),
463+
Y.c.sgsʲs.:($$j).ρa,
464+
FT(0),
465+
Y.c.ρ,
466+
turbconv_model,
467+
),
468+
))
469+
ᶜ∂ρ̂∂z = (@. lazy(
470+
upwind_biased_grad(
471+
-1 * Geometry.WVector(ᶜwʲ),
472+
Y.c.sgsʲs.:($$j).ρa,
473+
),
474+
))
475+
@. Yₜ.c.sgsʲs.:($$j).mse -=
476+
dot(ᶜinv_ρ̂ * ᶜ∂ρ̂∂z, ᶜw³ʲ) *
477+
ᶜqʲ *
478+
(ᶜmse_li - Y.c.sgsʲs.:($$j).mse)
479+
@. Yₜ.c.sgsʲs.:($$j).q_tot -=
480+
dot(ᶜinv_ρ̂ * ᶜ∂ρ̂∂z, ᶜw³ʲ) *
481+
ᶜqʲ *
482+
(1 - Y.c.sgsʲs.:($$j).q_tot)
483+
@. ᶜqʲₜ -= dot(ᶜinv_ρ̂ * ᶜ∂ρ̂∂z, ᶜw³ʲ) * ᶜqʲ
484+
485+
# mse, q_tot and moisture tracer terms proportional to velocity gradients
486+
# Eq (1-3) term (4)
487+
@. Yₜ.c.sgsʲs.:($$j).mse -=
488+
ᶜdivᵥ(ᶠw³ʲ) * ᶜqʲ * (ᶜmse_li - Y.c.sgsʲs.:($$j).mse)
489+
@. Yₜ.c.sgsʲs.:($$j).q_tot -=
490+
ᶜdivᵥ(ᶠw³ʲ) * ᶜqʲ * (1 - Y.c.sgsʲs.:($$j).q_tot)
491+
@. ᶜqʲₜ -= ᶜdivᵥ(ᶠw³ʲ) * ᶜqʲ
492+
end
425493
end
426494
end
427495
end

0 commit comments

Comments
 (0)