Skip to content

Commit eb02af6

Browse files
committed
use cloud fraction in buoyancy gradient
1 parent bdfa8c0 commit eb02af6

File tree

7 files changed

+54
-55
lines changed

7 files changed

+54
-55
lines changed

src/cache/diagnostic_edmf_precomputed_quantities.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,10 +1366,10 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_env_closures!
13661366
thermo_params,
13671367
moisture_model,
13681368
ᶜts,
1369+
p.precomputed.cloud_diagnostics_tuple.cf,
13691370
C3,
1370-
p.precomputed.ᶜgradᵥ_θ_virt, # ∂θv∂z_unsat
1371-
p.precomputed.ᶜgradᵥ_q_tot, # ∂qt∂z_sat
1372-
p.precomputed.ᶜgradᵥ_θ_liq_ice, # ∂θl∂z_sat
1371+
p.precomputed.ᶜgradᵥ_q_tot,
1372+
p.precomputed.ᶜgradᵥ_θ_liq_ice,
13731373
ᶜlg,
13741374
)
13751375

src/cache/precomputed_quantities.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ function precomputed_quantities(Y, atmos)
8585
TST = thermo_state_type(atmos.moisture_model, FT)
8686
SCT = SurfaceConditions.surface_conditions_type(atmos, FT)
8787
cspace = axes(Y.c)
88-
fspace = axes(Y.f)
8988
n = n_mass_flux_subdomains(atmos.turbconv_model)
9089
n_prog = n_prognostic_mass_flux_subdomains(atmos.turbconv_model)
9190
@assert !(atmos.turbconv_model isa PrognosticEDMFX) || n_prog == 1
@@ -98,6 +97,7 @@ function precomputed_quantities(Y, atmos)
9897
)
9998
cloud_diagnostics_tuple =
10099
similar(Y.c, @NamedTuple{cf::FT, q_liq::FT, q_ice::FT})
100+
@. cloud_diagnostics_tuple.cf = FT(0)
101101
surface_precip_fluxes = (;
102102
surface_rain_flux = zeros(axes(Fields.level(Y.f, half))),
103103
surface_snow_flux = zeros(axes(Fields.level(Y.f, half))),

src/cache/prognostic_edmf_precomputed_quantities.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,14 @@ NVTX.@annotate function set_prognostic_edmf_precomputed_quantities_explicit_clos
299299
)
300300
end
301301

302-
(; ᶜgradᵥ_θ_virt, ᶜgradᵥ_q_tot, ᶜgradᵥ_θ_liq_ice) = p.precomputed
302+
(; ᶜgradᵥ_θ_virt, ᶜgradᵥ_q_tot, ᶜgradᵥ_θ_liq_ice, cloud_diagnostics_tuple) = p.precomputed
303303
@. ᶜlinear_buoygrad = buoyancy_gradients( # TODO - do we need to modify buoyancy gradients based on NonEq + 1M tracers?
304304
BuoyGradMean(),
305305
thermo_params,
306306
moisture_model,
307307
ᶜts,
308+
cloud_diagnostics_tuple.cf,
308309
C3,
309-
ᶜgradᵥ_θ_virt,
310310
ᶜgradᵥ_q_tot,
311311
ᶜgradᵥ_θ_liq_ice,
312312
ᶜlg,

src/prognostic_equations/eddy_diffusion_closures.jl

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ import ClimaCore.Fields as Fields
1515
# Arguments for the first method (most commonly called):
1616
ts::TD.ThermodynamicState,
1717
::Type{C3}, # Covariant3 vector type, for projecting gradients
18-
∂θv∂z_unsat::AbstractField, # Vertical gradient of virtual potential temperature in unsaturated part
19-
∂qt∂z_sat::AbstractField, # Vertical gradient of total specific humidity in saturated part
20-
∂θli∂z_sat::AbstractField, # Vertical gradient of liquid-ice potential temperature in saturated part
18+
∂qt∂z::AbstractField, # Vertical gradient of total specific humidity in saturated part
19+
∂θli∂z::AbstractField, # Vertical gradient of liquid-ice potential temperature in saturated part
2120
local_geometry::Fields.LocalGeometry,
2221
# Argument for the second method (internal use with precomputed EnvBuoyGradVars):
2322
# bg_model::EnvBuoyGradVars
@@ -50,9 +49,8 @@ Arguments:
5049
- `moisture_model`: Moisture model (e.g., `EquilMoistModel`, `NonEquilMoistModel`).
5150
- `ts`: Center-level thermodynamic state of the environment.
5251
- `C3`: The `ClimaCore.Geometry.Covariant3Vector` type, used for projecting input vertical gradients.
53-
- `∂θv∂z_unsat`: Field of vertical gradients of virtual potential temperature in the unsaturated part.
54-
- `∂qt∂z_sat`: Field of vertical gradients of total specific humidity in the saturated part.
55-
- `∂θli∂z_sat`: Field of vertical gradients of liquid-ice potential temperature in the saturated part.
52+
- `∂qt∂z`: Field of vertical gradients of total specific humidity in the saturated part.
53+
- `∂θli∂z`: Field of vertical gradients of liquid-ice potential temperature in the saturated part.
5654
- `local_geometry`: Field of local geometry at cell centers, used for gradient projection.
5755
The second method takes a precomputed `EnvBuoyGradVars` object instead of `ts` and gradient fields.
5856
@@ -66,10 +64,10 @@ function buoyancy_gradients(
6664
thermo_params,
6765
moisture_model,
6866
ts,
67+
cf,
6968
::Type{C3},
70-
∂θv∂z_unsat,
71-
∂qt∂z_sat,
72-
∂θli∂z_sat,
69+
∂qt∂z,
70+
∂θli∂z,
7371
ᶜlg,
7472
) where {C3}
7573
return buoyancy_gradients(
@@ -78,11 +76,11 @@ function buoyancy_gradients(
7876
moisture_model,
7977
EnvBuoyGradVars(
8078
ts,
79+
cf,
8180
projected_vector_buoy_grad_vars(
8281
C3,
83-
∂θv∂z_unsat,
84-
∂qt∂z_sat,
85-
∂θli∂z_sat,
82+
∂qt∂z,
83+
∂θli∂z,
8684
ᶜlg,
8785
),
8886
),
@@ -99,36 +97,36 @@ function buoyancy_gradients(
9997

10098
g = TDP.grav(thermo_params)
10199
Rv_over_Rd = TDP.Rv_over_Rd(thermo_params)
102-
R_d = TDP.R_d(thermo_params)
103100
R_v = TDP.R_v(thermo_params)
104101

105102
ts = bg_model.ts
106-
p = TD.air_pressure(thermo_params, ts)
107-
Π = TD.exner_given_pressure(thermo_params, p)
108-
∂b∂θv = g * (R_d * TD.air_density(thermo_params, ts) / p) * Π
103+
g_over_θv = g / TD.virtual_pottemp(thermo_params, ts)
109104

110-
t_sat = TD.air_temperature(thermo_params, ts)
105+
T = TD.air_temperature(thermo_params, ts)
111106
λ = TD.liquid_fraction(thermo_params, ts)
112107
lh =
113-
λ * TD.latent_heat_vapor(thermo_params, t_sat) +
114-
(1 - λ) * TD.latent_heat_sublim(thermo_params, t_sat)
108+
λ * TD.latent_heat_vapor(thermo_params, T) +
109+
(1 - λ) * TD.latent_heat_sublim(thermo_params, T)
115110
cp_m = TD.cp_m(thermo_params, ts)
116-
qv_sat = TD.vapor_specific_humidity(thermo_params, ts)
117-
qt_sat = TD.total_specific_humidity(thermo_params, ts)
111+
q_sat = TD.q_vap_saturation(thermo_params, ts)
112+
q_tot = TD.total_specific_humidity(thermo_params, ts)
113+
θ = TD.dry_pottemp(thermo_params, ts)
114+
∂b∂θli_unsat = g_over_θv * (1 + (Rv_over_Rd - 1) * q_tot)
115+
∂b∂qt_unsat = g_over_θv * (Rv_over_Rd - 1) * θ
118116
∂b∂θli_sat = (
119-
∂b∂θv *
120-
(1 + Rv_over_Rd * (1 + lh / R_v / t_sat) * qv_sat - qt_sat) /
121-
(1 + lh * lh / cp_m / R_v / t_sat / t_sat * qv_sat)
117+
g_over_θv *
118+
(1 + Rv_over_Rd * (1 + lh / R_v / T) * q_sat - q_tot) /
119+
(1 + lh^2 / cp_m / R_v / T^2 * q_sat)
122120
)
123121
∂b∂qt_sat =
124-
(lh / cp_m / t_sat * ∂b∂θli_sat - ∂b∂θv) *
125-
TD.dry_pottemp(thermo_params, ts)
122+
(lh / cp_m / T * ∂b∂θli_sat - g_over_θv) * θ
126123

127124
∂b∂z = buoyancy_gradient_chain_rule(
128125
ebgc,
129126
bg_model,
130127
thermo_params,
131-
∂b∂θv,
128+
∂b∂θli_unsat,
129+
∂b∂qt_unsat,
132130
∂b∂θli_sat,
133131
∂b∂qt_sat,
134132
)
@@ -140,7 +138,6 @@ end
140138
closure::AbstractEnvBuoyGradClosure,
141139
bg_model::EnvBuoyGradVars,
142140
thermo_params,
143-
∂b∂θv::FT,
144141
∂b∂θli_sat::FT,
145142
∂b∂qt_sat::FT,
146143
) where {FT}
@@ -165,7 +162,6 @@ Arguments:
165162
- `closure`: The environmental buoyancy gradient closure type.
166163
- `bg_model`: Precomputed environmental buoyancy gradient variables (`EnvBuoyGradVars`).
167164
- `thermo_params`: Thermodynamic parameters from `CLIMAParameters`.
168-
- `∂b∂θv`: Partial derivative of buoyancy w.r.t. virtual potential temperature (unsaturated part).
169165
- `∂b∂θli_sat`: Partial derivative of buoyancy w.r.t. liquid-ice potential temperature (saturated part).
170166
- `∂b∂qt_sat`: Partial derivative of buoyancy w.r.t. total specific humidity (saturated part).
171167
@@ -176,18 +172,21 @@ function buoyancy_gradient_chain_rule(
176172
::AbstractEnvBuoyGradClosure,
177173
bg_model::EnvBuoyGradVars,
178174
thermo_params,
179-
∂b∂θv,
175+
∂b∂θli_unsat,
176+
∂b∂qt_unsat,
180177
∂b∂θli_sat,
181178
∂b∂qt_sat,
182179
)
183-
en_cld_frac = ifelse(TD.has_condensate(thermo_params, bg_model.ts), 1, 0)
180+
#en_cld_frac = ifelse(TD.has_condensate(thermo_params, bg_model.ts), 1, 0)
184181

185-
∂b∂z_θl_sat = ∂b∂θli_sat * bg_model.∂θli∂z_sat
186-
∂b∂z_qt_sat = ∂b∂qt_sat * bg_model.∂qt∂z_sat
182+
∂b∂z_θli_unsat = ∂b∂θli_unsat * bg_model.∂θli∂z
183+
∂b∂z_qt_unsat = ∂b∂qt_unsat * bg_model.∂qt∂z
184+
∂b∂z_unsat = ∂b∂z_θli_unsat + ∂b∂z_qt_unsat
185+
∂b∂z_θl_sat = ∂b∂θli_sat * bg_model.∂θli∂z
186+
∂b∂z_qt_sat = ∂b∂qt_sat * bg_model.∂qt∂z
187187
∂b∂z_sat = ∂b∂z_θl_sat + ∂b∂z_qt_sat
188-
∂b∂z_unsat = ∂b∂θv * bg_model.∂θv∂z_unsat
189188

190-
∂b∂z = (1 - en_cld_frac) * ∂b∂z_unsat + en_cld_frac * ∂b∂z_sat
189+
∂b∂z = (1 - bg_model.cf) * ∂b∂z_unsat + bg_model.cf * ∂b∂z_sat
191190

192191
return ∂b∂z
193192
end

src/prognostic_equations/gm_sgs_closures.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ NVTX.@annotate function compute_gm_mixing_length(Y, p)
6767

6868
ᶜdz = Fields.Δz_field(axes(Y.c))
6969
ᶜlg = Fields.local_geometry_field(Y.c)
70-
(; ᶜts, ᶠu³, ᶜlinear_buoygrad, ᶜstrain_rate_norm) = p.precomputed
70+
(; ᶜts, ᶠu³, ᶜlinear_buoygrad, ᶜstrain_rate_norm, cloud_diagnostics_tuple) = p.precomputed
7171

7272
@. ᶜlinear_buoygrad = buoyancy_gradients(
7373
BuoyGradMean(),
7474
thermo_params,
7575
p.atmos.moisture_model,
7676
ᶜts,
77+
cloud_diagnostics_tuple.cf,
7778
C3,
78-
p.precomputed.ᶜgradᵥ_θ_virt, # ∂θv∂z_unsat
79-
p.precomputed.ᶜgradᵥ_q_tot, # ∂qt∂z_sat
80-
p.precomputed.ᶜgradᵥ_θ_liq_ice, # ∂θl∂z_sat
79+
p.precomputed.ᶜgradᵥ_q_tot,
80+
p.precomputed.ᶜgradᵥ_θ_liq_ice,
8181
ᶜlg,
8282
)
8383

src/solver/types.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,17 +376,18 @@ Variables used in the environmental buoyancy gradient computation.
376376
"""
377377
Base.@kwdef struct EnvBuoyGradVars{FT, TS}
378378
ts::TS
379-
∂θv∂z_unsat::FT
380-
∂qt∂z_sat::FT
381-
∂θli∂z_sat::FT
379+
cf::FT
380+
∂qt∂z::FT
381+
∂θli∂z::FT
382382
end
383383

384384
function EnvBuoyGradVars(
385385
ts::TD.ThermodynamicState,
386-
∂θv∂z_unsat_∂qt∂z_sat_∂θli∂z_sat,
386+
cf,
387+
∂qt∂z_∂θli∂z,
387388
)
388-
(; ∂θv∂z_unsat, ∂qt∂z_sat, ∂θli∂z_sat) =θv∂z_unsat_∂qt∂z_sat_∂θli∂z_sat
389-
return EnvBuoyGradVars(ts, ∂θv∂z_unsat, ∂qt∂z_sat, ∂θli∂z_sat)
389+
(; ∂qt∂z, ∂θli∂z) = ∂qt∂z_∂θli∂z
390+
return EnvBuoyGradVars(ts, cf, ∂qt∂z, ∂θli∂z)
390391
end
391392

392393
Base.eltype(::EnvBuoyGradVars{FT}) where {FT} = FT

src/utils/utilities.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,11 @@ The type should correspond to a vector with only one component, i.e., a basis ve
279279
projected_vector_data(::Type{V}, vector, local_geometry) where {V} =
280280
V(vector, local_geometry)[1] / unit_basis_vector_data(V, local_geometry)
281281

282-
function projected_vector_buoy_grad_vars(::Type{V}, v1, v2, v3, lg) where {V}
282+
function projected_vector_buoy_grad_vars(::Type{V}, v1, v2, lg) where {V}
283283
ubvd = unit_basis_vector_data(V, lg)
284284
return (;
285-
∂θv∂z_unsat = V(v1, lg)[1] / ubvd,
286-
∂qt∂z_sat = V(v2, lg)[1] / ubvd,
287-
∂θli∂z_sat = V(v3, lg)[1] / ubvd,
285+
∂qt∂z = V(v1, lg)[1] / ubvd,
286+
∂θli∂z = V(v2, lg)[1] / ubvd,
288287
)
289288
end
290289

0 commit comments

Comments
 (0)