Skip to content

Commit 72a0440

Browse files
committed
add microphysics 2M tests
1 parent 547df4e commit 72a0440

File tree

5 files changed

+159
-8
lines changed

5 files changed

+159
-8
lines changed

.buildkite/pipeline.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ steps:
8686
--config_file $CONFIG_PATH/single_column_precipitation_test.yml
8787
--job_id single_column_precipitation_test
8888
artifact_paths: "single_column_precipitation_test/output_active/*"
89+
90+
- label: ":umbrella: 2-moment precipitation sanity test single column"
91+
command: >
92+
julia --color=yes --project=.buildkite .buildkite/ci_driver.jl
93+
--config_file $CONFIG_PATH/single_column_precipitation_2M_test.yml
94+
--job_id single_column_precipitation_2M_test
95+
artifact_paths: "single_column_precipitation_2M_test/output_active/*"
8996

9097
- group: "Gravity wave"
9198
steps:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
config: "column"
2+
initial_condition: "PrecipitatingColumn"
3+
surface_setup: "DefaultMoninObukhov"
4+
z_elem: 200
5+
z_max: 10000.0
6+
z_stretch: false
7+
dt: "10secs"
8+
t_end: "1500secs"
9+
dt_save_state_to_disk: "500secs"
10+
dt_cloud_fraction: "60secs"
11+
cloud_model: "grid_scale"
12+
moist: "nonequil"
13+
precip_model: "2M"
14+
vert_diff: "DecayWithHeightDiffusion"
15+
implicit_diffusion: true
16+
approximate_linear_solve_iters: 2
17+
reproducibility_test: false
18+
diagnostics:
19+
- short_name: [hus, clw, cli, husra, hussn, clwnm, clinm, nmra, nmsn, ta, wa]
20+
period: 500secs
21+
- short_name: [pr]
22+
period: 10secs

post_processing/ci_plots.jl

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,23 +621,35 @@ function make_plots(
621621
end
622622

623623
function make_plots(
624-
::Val{:single_column_precipitation_test},
624+
sim_type::Union{
625+
Val{:single_column_precipitation_test},
626+
Val{:single_column_precipitation_2M_test},
627+
},
625628
output_paths::Vector{<:AbstractString},
626629
)
627630
simdirs = SimDir.(output_paths)
628631

629632
# TODO: Move this plotting code into the same framework as the other ones
630633
simdir = simdirs[1]
631634

632-
short_names = ["hus", "clw", "cli", "husra", "hussn", "ta"]
635+
if sim_type isa Val{:single_column_precipitation_test}
636+
short_names = ["hus", "clw", "cli", "husra", "hussn", "ta"]
637+
figsize = (1200, 600)
638+
pr_row = 3
639+
else
640+
short_names = ["hus", "clw", "cli", "husra", "hussn", "ta", "clwnm", "clinm", "nmra", "nmsn"]
641+
figsize = (1200, 1000)
642+
pr_row = 5
643+
end
644+
633645
vars = [
634646
slice(get(simdir; short_name), x = 0.0, y = 0.0) for
635647
short_name in short_names
636648
]
637649

638650
# We first prepare the axes with all the nice labels with ClimaAnalysis, then we use
639651
# CairoMakie to add the additional lines.
640-
fig = CairoMakie.Figure(; size = (1200, 600))
652+
fig = CairoMakie.Figure(; size = figsize)
641653

642654
p_loc = [1, 1]
643655

@@ -677,7 +689,7 @@ function make_plots(
677689
viz.line_plot1D!(
678690
fig,
679691
slice(surface_precip, x = 0.0, y = 0.0);
680-
p_loc = [3, 1:3],
692+
p_loc = [pr_row, 1:3],
681693
)
682694

683695
file_path = joinpath(output_paths[1], "summary.pdf")

src/diagnostics/core_diagnostics.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ add_diagnostic_variable!(
889889
short_name = "clwnm",
890890
long_name = "Number Concentration of Cloud Liquid Water",
891891
standard_name = "number_concentration_of_cloud_liquid_water",
892-
units = "1 m^3",
892+
units = "1 m^-3",
893893
comments = """
894894
This is calculated as the number of cloud liquid water droplets in the grid
895895
cell divided by the cell volume.
@@ -920,7 +920,7 @@ add_diagnostic_variable!(
920920
short_name = "clinm",
921921
long_name = "Number Concentration of Cloud Ice",
922922
standard_name = "number_concentration_of_cloud_ice",
923-
units = "1 m^3",
923+
units = "1 m^-3",
924924
comments = """
925925
This is calculated as the number of cloud ice chrystals in the grid
926926
cell divided by the cell volume.
@@ -951,7 +951,7 @@ add_diagnostic_variable!(
951951
short_name = "nmra",
952952
long_name = "Number Concentration of Rain",
953953
standard_name = "number_concentration_of_rain",
954-
units = "1 m^3",
954+
units = "1 m^-3",
955955
comments = """
956956
This is calculated as the number of raindrops in the grid cell divided
957957
by the cell volume.
@@ -982,7 +982,7 @@ add_diagnostic_variable!(
982982
short_name = "nmsn",
983983
long_name = "Number Concentration of Snow",
984984
standard_name = "number_concentration_of_snow",
985-
units = "1 m^3",
985+
units = "1 m^-3",
986986
comments = """
987987
This is calculated as the number of snow flakes in the grid cell divided
988988
by the cell volume.

test/parameterized_tendencies/microphysics/precipitation.jl

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,113 @@ end
168168
@test minimum(p.precomputed.cloud_diagnostics_tuple.cf) >= FT(0)
169169
@test maximum(p.precomputed.cloud_diagnostics_tuple.cf) <= FT(1)
170170
end
171+
172+
@testset "NonEquilibrium Moisture + 2-moment precipitation RHS terms" begin
173+
174+
### Boilerplate default integrator objects
175+
config = CA.AtmosConfig(
176+
Dict(
177+
"initial_condition" => "PrecipitatingColumn",
178+
"moist" => "nonequil",
179+
"precip_model" => "2M",
180+
"config" => "column",
181+
"output_default_diagnostics" => false,
182+
),
183+
job_id = "precipitation_2M",
184+
)
185+
(; Y, p, params) = generate_test_simulation(config)
186+
187+
FT = eltype(Y)
188+
ᶜYₜ = zero(Y)
189+
190+
# Set all model choices
191+
(; turbconv_model, moisture_model, precip_model) = p.atmos
192+
193+
# Test cache to verify expected variables exist in tendency function
194+
CA.set_precipitation_velocities!(Y, p, moisture_model, precip_model)
195+
CA.set_precipitation_cache!(Y, p, precip_model, turbconv_model)
196+
CA.set_precipitation_surface_fluxes!(Y, p, precip_model)
197+
test_varnames = (
198+
:ᶜSqₗᵖ,
199+
:ᶜSqᵢᵖ,
200+
:ᶜSqᵣᵖ,
201+
:ᶜSqₛᵖ,
202+
:ᶜSnₗᵖ,
203+
:ᶜSnᵢᵖ,
204+
:ᶜSnᵣᵖ,
205+
:ᶜSnₛᵖ,
206+
:surface_rain_flux,
207+
:surface_snow_flux,
208+
:ᶜwₗ,
209+
:ᶜwᵢ,
210+
:ᶜwᵣ,
211+
:ᶜwₛ,
212+
:ᶜwnₗ,
213+
:ᶜwnᵢ,
214+
:ᶜwnᵣ,
215+
:ᶜwnₛ,
216+
:ᶜwₜqₜ,
217+
:ᶜwₕhₜ,
218+
)
219+
for var_name in test_varnames
220+
@test var_name propertynames(p.precomputed)
221+
end
222+
223+
# compute source terms based on the last model state
224+
CA.precipitation_tendency!(
225+
ᶜYₜ,
226+
Y,
227+
p,
228+
FT(0),
229+
moisture_model,
230+
precip_model,
231+
turbconv_model,
232+
)
233+
234+
# check for nans
235+
@assert !any(isnan, ᶜYₜ.c.ρ)
236+
@assert !any(isnan, ᶜYₜ.c.ρq_tot)
237+
@assert !any(isnan, ᶜYₜ.c.ρe_tot)
238+
@assert !any(isnan, ᶜYₜ.c.ρq_liq)
239+
@assert !any(isnan, ᶜYₜ.c.ρq_ice)
240+
@assert !any(isnan, ᶜYₜ.c.ρq_rai)
241+
@assert !any(isnan, ᶜYₜ.c.ρq_sno)
242+
@assert !any(isnan, ᶜYₜ.c.ρn_liq)
243+
@assert !any(isnan, ᶜYₜ.c.ρn_ice)
244+
@assert !any(isnan, ᶜYₜ.c.ρn_rai)
245+
@assert !any(isnan, ᶜYₜ.c.ρn_sno)
246+
@assert !any(isnan, p.precomputed.ᶜwₗ)
247+
@assert !any(isnan, p.precomputed.ᶜwᵢ)
248+
@assert !any(isnan, p.precomputed.ᶜwᵣ)
249+
@assert !any(isnan, p.precomputed.ᶜwₛ)
250+
@assert !any(isnan, p.precomputed.ᶜwnₗ)
251+
@assert !any(isnan, p.precomputed.ᶜwnᵢ)
252+
@assert !any(isnan, p.precomputed.ᶜwnᵣ)
253+
@assert !any(isnan, p.precomputed.ᶜwnₛ)
254+
255+
# test water budget
256+
@test ᶜYₜ.c.ρ == ᶜYₜ.c.ρq_tot
257+
@assert iszero(ᶜYₜ.c.ρ)
258+
259+
# test nonequilibrium cloud condensate
260+
CA.cloud_condensate_tendency!(ᶜYₜ, Y, p, moisture_model, precip_model)
261+
@assert !any(isnan, ᶜYₜ.c.ρq_liq)
262+
@assert !any(isnan, ᶜYₜ.c.ρq_ice)
263+
@assert !any(isnan, ᶜYₜ.c.ρn_liq)
264+
@assert !any(isnan, ᶜYₜ.c.ρn_ice)
265+
266+
# test if terminal velocity is positive
267+
@test minimum(p.precomputed.ᶜwₗ) >= FT(0)
268+
@test minimum(p.precomputed.ᶜwᵢ) >= FT(0)
269+
@test minimum(p.precomputed.ᶜwᵣ) >= FT(0)
270+
@test minimum(p.precomputed.ᶜwₛ) >= FT(0)
271+
@test minimum(p.precomputed.ᶜwnₗ) >= FT(0)
272+
@test minimum(p.precomputed.ᶜwnᵢ) >= FT(0)
273+
@test minimum(p.precomputed.ᶜwnᵣ) >= FT(0)
274+
@test minimum(p.precomputed.ᶜwnₛ) >= FT(0)
275+
276+
# test if cloud fraction diagnostics make sense
277+
@assert !any(isnan, p.precomputed.cloud_diagnostics_tuple.cf)
278+
@test minimum(p.precomputed.cloud_diagnostics_tuple.cf) >= FT(0)
279+
@test maximum(p.precomputed.cloud_diagnostics_tuple.cf) <= FT(1)
280+
end

0 commit comments

Comments
 (0)