Skip to content

Commit 1313221

Browse files
authored
Merge pull request #3820 from CliMA/j/cape
Add CAPE diagnostic
2 parents 6bfc537 + 4014bca commit 1313221

File tree

5 files changed

+67
-2
lines changed

5 files changed

+67
-2
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ ClimaAtmos.jl Release Notes
44
main
55
-------
66

7+
### Add diagnostic for CAPE
8+
PR [#3820](https://github.com/CliMA/ClimaAtmos.jl/pull/3820) adds support for computing convective available potential energy (CAPE), or the vertical integral of the buoyancy differential between a parcel lifted from the surface and the environment. Exemplified in the TRMM deep convection case.
9+
710
v0.30.2
811
-------
912

config/model_configs/prognostic_edmfx_trmm_column_0M.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@ z_stretch: false
3030
dz_bottom: 30
3131
dt: 150secs
3232
t_end: 6hours
33-
dt_save_state_to_disk: 10mins
3433
toml: [toml/prognostic_edmfx_implicit_scm_calibrated_5_cases_shallow_deep_v1.toml]
3534
netcdf_interpolation_num_points: [8, 8, 82]
3635
diagnostics:
37-
- short_name: [ts, ta, thetaa, ha, pfull, rhoa, ua, va, wa, hur, hus, cl, clw, cli, hussfc, evspsbl, pr]
36+
- short_name: [ts, ta, thetaa, ha, pfull, rhoa, ua, va, wa, hur, hus, cl, clw, cli, hussfc, evspsbl, pr, cape]
3837
period: 10mins
3938
- short_name: [arup, waup, taup, thetaaup, haup, husup, hurup, clwup, cliup, waen, taen, thetaaen, haen, husen, huren, clwen, clien, tke]
4039
period: 10mins

src/diagnostics/Diagnostics.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import ClimaCore:
1111
import ClimaCore.Utilities: half
1212
import Thermodynamics as TD
1313

14+
# compute lazily to reduce allocations
15+
import ..lazy
16+
1417
import ..AtmosModel
1518
import ..AtmosCallback
1619
import ..EveryNSteps

src/diagnostics/core_diagnostics.jl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,3 +1349,62 @@ add_diagnostic_variable!(
13491349
end
13501350
end,
13511351
)
1352+
1353+
###
1354+
# Convective Available Potential Energy (2d)
1355+
###
1356+
function compute_cape!(out, state, cache, time)
1357+
thermo_params = lazy.(CAP.thermodynamics_params(cache.params))
1358+
g = lazy.(TD.Parameters.grav(thermo_params))
1359+
1360+
# Get surface parcel properties
1361+
surface_thermal_state = lazy.(cache.precomputed.sfc_conditions.ts)
1362+
surface_q =
1363+
lazy.(TD.total_specific_humidity.(thermo_params, surface_thermal_state))
1364+
surface_θ_liq_ice =
1365+
lazy.(TD.liquid_ice_pottemp.(thermo_params, surface_thermal_state))
1366+
1367+
# Create parcel thermodynamic states at each level based on energy & moisture at surface
1368+
parcel_ts_moist =
1369+
lazy.(
1370+
TD.PhaseEquil_pθq.(
1371+
thermo_params,
1372+
cache.precomputed.ᶜp,
1373+
surface_θ_liq_ice,
1374+
surface_q,
1375+
)
1376+
)
1377+
1378+
# Calculate virtual temperatures for parcel & environment
1379+
parcel_Tv = lazy.(TD.virtual_temperature.(thermo_params, parcel_ts_moist))
1380+
env_Tv =
1381+
lazy.(TD.virtual_temperature.(thermo_params, cache.precomputed.ᶜts))
1382+
1383+
# Calculate buoyancy from the difference in virtual temperatures
1384+
ᶜbuoyancy = cache.scratch.ᶜtemp_scalar
1385+
ᶜbuoyancy .= g .* (parcel_Tv .- env_Tv) ./ env_Tv
1386+
1387+
# restrict to tropospheric buoyancy (generously below 20km) TODO: integrate from LFC to LNB
1388+
FT = Spaces.undertype(axes(ᶜbuoyancy))
1389+
ᶜbuoyancy .=
1390+
ᶜbuoyancy .*
1391+
ifelse.(
1392+
Fields.coordinate_field(state.c.ρ).z .< FT(20000.0),
1393+
FT(1.0),
1394+
FT(0.0),
1395+
)
1396+
1397+
# Integrate positive buoyancy to get CAPE
1398+
out′ = isnothing(out) ? zeros(axes(Fields.level(state.f, half))) : out
1399+
Operators.column_integral_definite!(out′, lazy.(max.(ᶜbuoyancy, 0)))
1400+
return out′
1401+
end
1402+
1403+
add_diagnostic_variable!(
1404+
short_name = "cape",
1405+
long_name = "Convective Available Potential Energy",
1406+
standard_name = "convective_available_potential_energy",
1407+
units = "J kg^-1",
1408+
comments = "Energy available to a parcel lifted moist adiabatically from the surface. We assume fully reversible phase changes and no precipitation.",
1409+
compute! = compute_cape!,
1410+
)

src/diagnostics/default_diagnostics.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ function default_diagnostics(
209209
"lwp",
210210
"clwvi",
211211
"clivi",
212+
"cape",
212213
]
213214
average_func = frequency_averages(duration)
214215
return [average_func(moist_diagnostics...; output_writer, start_date)...]

0 commit comments

Comments
 (0)