Skip to content

Commit 86cce9c

Browse files
committed
remove grid scale thermo state
1 parent c4972d3 commit 86cce9c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+815
-690
lines changed

.buildkite/Manifest-v1.11.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,9 +2918,9 @@ version = "1.0.2"
29182918

29192919
[[deps.Thermodynamics]]
29202920
deps = ["ForwardDiff", "Random", "RootSolvers"]
2921-
git-tree-sha1 = "ed3bda4ef913084e1e028d4fb05e26f1b69356f6"
2921+
git-tree-sha1 = "3958121b3ed912e0858960b682de6e98cb4949dd"
29222922
uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c"
2923-
version = "0.15.4"
2923+
version = "0.15.7"
29242924
weakdeps = ["ClimaParams"]
29252925

29262926
[deps.Thermodynamics.extensions]

.buildkite/pipeline.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -609,10 +609,10 @@ steps:
609609
# --config_file $CONFIG_PATH/baroclinic_wave_equil_amd.yml
610610
# --job_id baroclinic_wave_equil_amd
611611

612-
artifact_paths: "baroclinic_wave_equil_amd/output_active/*"
613-
soft_fail: true
614-
agents:
615-
slurm_constraint: icelake|cascadelake|skylake|epyc
612+
# artifact_paths: "baroclinic_wave_equil_amd/output_active/*"
613+
# soft_fail: true
614+
# agents:
615+
# slurm_constraint: icelake|cascadelake|skylake|epyc
616616

617617
- label: ":computer: held suarez"
618618
key: held_suarez

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ ClimaAtmos.jl Release Notes
33

44
main
55
-------
6+
- [#4231](https://github.com/CliMA/ClimaAtmos.jl/pull/4231) [badge-💥breaking] removes grid-scale
7+
thermo state, including ᶜts in p.precomputed.sfc_conditions.
8+
69
- [#4211](https://github.com/CliMA/ClimaAtmos.jl/pull/4211)
710
add experimental methods to remove negative microphysical condensate values
811

912
v0.34.0
1013
-------
1114
- [#4198](https://github.com/CliMA/ClimaAtmos.jl/pull/4198) [badge-💥breaking] modifies surface conditions
1215
to use SurfaceFluxes v0.15.
16+
1317
- [#4220](https://github.com/CliMA/ClimaAtmos.jl/pull/4220) modifies `SphereGrid` to use spacefillingcurve.
1418

1519
v0.33.2

post_processing/ci_plots.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ AquaplanetPlots = Union{
10511051
Val{:gpu_aquaplanet_dyamond_summer},
10521052
Val{:edonly_edmfx_aquaplanet},
10531053
Val{:mpi_sphere_aquaplanet_rhoe_equil_clearsky},
1054+
Val{:aquaplanet_equil_allsky_gw_raw},
10541055
Val{:aquaplanet_nonequil_allsky_gw_res},
10551056
Val{:aquaplanet_nonequil_allsky_gw_res_2M},
10561057
Val{:rcemipii_sphere_diagnostic_edmfx},

reproducibility_tests/ref_counter.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
303
1+
304
22

33
# **README**
44
#
@@ -21,6 +21,9 @@
2121

2222
#=
2323
24+
304
25+
- Remove grid-scale thermo state from precomputed quantities and uses new thermodynamics functions.
26+
2427
303
2528
- Remove thermo state from initial conditions, which changes the behavior of
2629
prognostic EDMF case, possibly from the change in `enthalpy` function.

src/cache/cloud_fraction.jl

Lines changed: 76 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ end
1313
Diagnose horizontal covariances based on vertical gradients
1414
(i.e. taking turbulence production as the only term)
1515
"""
16-
function compute_covariance(Y, p, thermo_params, ᶜts)
16+
function compute_covariance(Y, p, thermo_params)
1717
coeff = CAP.diagnostic_covariance_coeff(p.params)
1818
turbconv_model = p.atmos.turbconv_model
1919
(; ᶜgradᵥ_q_tot, ᶜgradᵥ_θ_liq_ice) = p.precomputed
@@ -23,10 +23,20 @@ function compute_covariance(Y, p, thermo_params, ᶜts)
2323
if isnothing(turbconv_model)
2424
if p.atmos.call_cloud_diagnostics_per_stage isa
2525
CallCloudDiagnosticsPerStage
26-
@. ᶜgradᵥ_q_tot =
27-
ᶜgradᵥ(ᶠinterp(TD.total_specific_humidity(thermo_params, ᶜts)))
28-
@. ᶜgradᵥ_θ_liq_ice =
29-
ᶜgradᵥ(ᶠinterp(TD.liquid_ice_pottemp(thermo_params, ᶜts)))
26+
(; ᶜT, ᶜq_tot_safe, ᶜq_liq_rai, ᶜq_ice_sno) = p.precomputed
27+
@. ᶜgradᵥ_q_tot = ᶜgradᵥ(ᶠinterp(ᶜq_tot_safe))
28+
@. ᶜgradᵥ_θ_liq_ice = ᶜgradᵥ(
29+
ᶠinterp(
30+
TD.liquid_ice_pottemp(
31+
thermo_params,
32+
ᶜT,
33+
Y.c.ρ,
34+
ᶜq_tot_safe,
35+
ᶜq_liq_rai,
36+
ᶜq_ice_sno,
37+
),
38+
),
39+
)
3040
end
3141
end
3242
# Reminder that gradients need to be precomputed when using compute_gm_mixing_length
@@ -99,14 +109,16 @@ end
99109

100110
"""
101111
function compute_cloud_fraction_quadrature_diagnostics(
102-
thermo_params, SG_quad, ts, q′q′, θ′θ′, θ′q′
112+
thermo_params, SG_quad, p_c, q_mean, θ_mean, q′q′, θ′θ′, θ′q′
103113
)
104114
105115
where:
106116
- thermo params - thermodynamics parameters
107117
- SG_quad is a struct containing information about Gaussian quadrature order,
108118
sampling point values and weights
109-
- ts is the thermodynamic state
119+
- p_c is the air pressure
120+
- q_mean is the total specific humidity
121+
- θ_mean is the liquid-ice potential temperature
110122
- q′q′, θ′θ′, θ′q′ are the covariances of q_tot and liquid ice potential temperature
111123
112124
The function imposes additional limits on the quadrature points
@@ -117,15 +129,13 @@ computed as a sum over quadrature points with weights.
117129
function compute_cloud_fraction_quadrature_diagnostics(
118130
thermo_params,
119131
SG_quad::SGSQuadrature,
120-
ts,
132+
p_c,
133+
q_mean,
134+
θ_mean,
121135
q′q′,
122136
θ′θ′,
123137
θ′q′,
124138
)
125-
# Grab mean pressure, liquid ice potential temperature and total specific humidity
126-
p_c = TD.air_pressure(thermo_params, ts)
127-
q_mean = TD.total_specific_humidity(thermo_params, ts)
128-
θ_mean = TD.liquid_ice_pottemp(thermo_params, ts)
129139

130140
# Return physical values based on quadrature points and limited covarainces
131141
function get_x_hat(χ1, χ2)
@@ -158,7 +168,7 @@ function compute_cloud_fraction_quadrature_diagnostics(
158168

159169
function f(x1_hat, x2_hat)
160170
FT = eltype(thermo_params)
161-
_ts = thermo_state(thermo_params; p = p_c, θ = x1_hat, q_tot = x2_hat)
171+
_ts = TD.PhaseEquil_pθq(thermo_params, p_c, x1_hat, x2_hat)
162172
hc = TD.has_condensate(thermo_params, _ts)
163173

164174
cf = hc ? FT(1) : FT(0) # cloud fraction
@@ -192,23 +202,22 @@ NVTX.@annotate function set_cloud_fraction!(
192202
moist_model::Union{EquilMoistModel, NonEquilMoistModel},
193203
::GridScaleCloud,
194204
)
195-
(; ᶜts) = p.precomputed
196-
thermo_params = CAP.thermodynamics_params(p.params)
205+
(; ᶜq_liq_rai, ᶜq_ice_sno) = p.precomputed
197206
FT = eltype(p.params)
198207

199208
if moist_model isa EquilMoistModel
200209
@. p.precomputed.cloud_diagnostics_tuple =
201210
make_cloud_fraction_named_tuple(
202-
ifelse(TD.has_condensate(thermo_params, ᶜts), FT(1), FT(0)),
203-
TD.PhasePartition(thermo_params, ᶜts).liq,
204-
TD.PhasePartition(thermo_params, ᶜts).ice,
211+
ifelse(TD.has_condensate(ᶜq_liq_rai + ᶜq_ice_sno), FT(1), FT(0)),
212+
ᶜq_liq_rai,
213+
ᶜq_ice_sno,
205214
)
206215
else
207216
q_liq = @. lazy(specific(Y.c.ρq_liq, Y.c.ρ))
208217
q_ice = @. lazy(specific(Y.c.ρq_ice, Y.c.ρ))
209218
@. p.precomputed.cloud_diagnostics_tuple =
210219
make_cloud_fraction_named_tuple(
211-
ifelse(TD.has_condensate(thermo_params, ᶜts), FT(1), FT(0)),
220+
ifelse(TD.has_condensate(ᶜq_liq_rai + ᶜq_ice_sno), FT(1), FT(0)),
212221
q_liq,
213222
q_ice,
214223
)
@@ -222,18 +231,40 @@ NVTX.@annotate function set_cloud_fraction!(
222231
)
223232
thermo_params = CAP.thermodynamics_params(p.params)
224233
turbconv_model = p.atmos.turbconv_model
234+
(; ᶜp, ᶜT, ᶜq_tot_safe, ᶜq_liq_rai, ᶜq_ice_sno) = p.precomputed
225235

226-
ᶜts = turbconv_model isa PrognosticEDMFX ? p.precomputed.ᶜts⁰ : p.precomputed.ᶜts
236+
# For PrognosticEDMFX, use environment state; otherwise use grid-scale
237+
if turbconv_model isa PrognosticEDMFX
238+
ᶜts⁰ = p.precomputed.ᶜts⁰
239+
ᶜp_env = @. lazy(TD.air_pressure(thermo_params, ᶜts⁰))
240+
ᶜq_mean = @. lazy(TD.total_specific_humidity(thermo_params, ᶜts⁰))
241+
ᶜθ_mean = @. lazy(TD.liquid_ice_pottemp(thermo_params, ᶜts⁰))
242+
else
243+
ᶜp_env = ᶜp
244+
ᶜq_mean = ᶜq_tot_safe
245+
ᶜθ_mean = @. lazy(
246+
TD.liquid_ice_pottemp(
247+
thermo_params,
248+
ᶜT,
249+
Y.c.ρ,
250+
ᶜq_tot_safe,
251+
ᶜq_liq_rai,
252+
ᶜq_ice_sno,
253+
),
254+
)
255+
end
227256

228257
# Compute covariance based on the gradients of q_tot and theta_liq_ice
229-
ᶜq′q′, ᶜθ′θ′, ᶜθ′q′ = compute_covariance(Y, p, thermo_params, ᶜts)
258+
ᶜq′q′, ᶜθ′θ′, ᶜθ′q′ = compute_covariance(Y, p, thermo_params)
230259

231260
# Compute SGS cloud fraction diagnostics based on environment quadrature points ...
232261
@. p.precomputed.cloud_diagnostics_tuple =
233262
compute_cloud_fraction_quadrature_diagnostics(
234263
thermo_params,
235264
qc.SG_quad,
236-
ᶜts,
265+
ᶜp_env,
266+
ᶜq_mean,
267+
ᶜθ_mean,
237268
ᶜq′q′,
238269
ᶜθ′θ′,
239270
ᶜθ′q′,
@@ -247,18 +278,21 @@ NVTX.@annotate function set_cloud_fraction!(
247278
qc,
248279
thermo_params,
249280
turbconv_model,
250-
ᶜts,
281+
ᶜp_env,
282+
ᶜq_mean,
283+
ᶜθ_mean,
251284
)
252285
end
253286

254287
# ... weight by environment area fraction if using PrognosticEDMFX (assumed 1 otherwise) ...
255288
if turbconv_model isa PrognosticEDMFX
256289
ᶜρa⁰ = @. lazy(ρa⁰(Y.c.ρ, Y.c.sgsʲs, p.atmos.turbconv_model))
290+
ᶜρ⁰ = @. lazy(TD.air_density(thermo_params, p.precomputed.ᶜts⁰))
257291
@. p.precomputed.cloud_diagnostics_tuple *= NamedTuple{(:cf, :q_liq, :q_ice)}(
258292
tuple(
259-
draft_area(ᶜρa⁰, TD.air_density(thermo_params, ᶜts)),
260-
draft_area(ᶜρa⁰, TD.air_density(thermo_params, ᶜts)),
261-
draft_area(ᶜρa⁰, TD.air_density(thermo_params, ᶜts)),
293+
draft_area(ᶜρa⁰, ᶜρ⁰),
294+
draft_area(ᶜρa⁰, ᶜρ⁰),
295+
draft_area(ᶜρa⁰, ᶜρ⁰),
262296
),
263297
)
264298
end
@@ -294,7 +328,9 @@ function set_ml_cloud_fraction!(
294328
ml_cloud::MLCloud,
295329
thermo_params,
296330
turbconv_model,
297-
ᶜts,
331+
ᶜp_env,
332+
ᶜq_mean,
333+
ᶜθ_mean,
298334
)
299335
FT = eltype(p.params)
300336
ᶜmixing_length_field = p.scratch.ᶜtemp_scalar
@@ -325,8 +361,9 @@ function set_ml_cloud_fraction!(
325361
ᶜmixing_length_field,
326362
ᶜ∇q,
327363
ᶜ∇θ,
328-
specific.(Y.c.ρq_tot, Y.c.ρ),
329-
ᶜts,
364+
ᶜq_mean,
365+
ᶜp_env,
366+
ᶜθ_mean,
330367
thermo_params,
331368
)
332369
end
@@ -337,20 +374,18 @@ function compute_ml_cloud_fraction(
337374
ᶜ∇q,
338375
ᶜ∇θ,
339376
q_tot,
340-
ᶜts,
377+
p_c,
378+
θli,
341379
thermo_params,
342380
)
343381
FT = eltype(thermo_params)
344-
# Saturation state at current thermodynamic state
345-
q_sat = TD.q_vap_saturation(thermo_params, ᶜts)
346-
347-
# Liquid–ice potential temperature at current thermodynamic state
348-
θli = TD.liquid_ice_pottemp(thermo_params, ᶜts)
349-
382+
# Saturation state at current thermodynamic state (via θ, p, q_tot)
383+
ts_current = TD.PhaseEquil_pθq(thermo_params, p_c, θli, q_tot)
384+
q_sat = TD.q_vap_saturation(thermo_params, ts_current)
350385

351386
# distance to saturation in temperature space
352387
Δθli, θli_sat, dqsatdθli =
353-
saturation_distance(q_tot, q_sat, ᶜts, θli, thermo_params, FT(0.1))
388+
saturation_distance(q_tot, q_sat, p_c, θli, thermo_params, FT(0.1))
354389

355390
# form the pi groups
356391
π_1 = (q_sat - q_tot) / q_sat
@@ -359,17 +394,16 @@ function compute_ml_cloud_fraction(
359394
π_4 = (ᶜ∇θ * ᶜmixing_length_field) / θli_sat
360395

361396
return apply_cf_nn(nn_model, π_1, π_2, π_3, π_4)
362-
363397
end
364398

365-
function saturation_distance(q_tot, q_sat, ᶜts, θli, thermo_params, Δθli_fd)
399+
function saturation_distance(q_tot, q_sat, p_c, θli, thermo_params, Δθli_fd)
366400

367401
# Perturbed thermodynamic states for finite-difference
368402
ts_perturbed = TD.PhaseEquil_pθq(
369403
thermo_params,
370-
ᶜts.p,
371-
θli .+ Δθli_fd,
372-
ᶜts.q_tot,
404+
p_c,
405+
θli + Δθli_fd,
406+
q_tot,
373407
)
374408
q_sat_perturbed = TD.q_vap_saturation(thermo_params, ts_perturbed)
375409

0 commit comments

Comments
 (0)