Skip to content
2 changes: 2 additions & 0 deletions src/ClimaAtmos.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import LazyBroadcast
import LazyBroadcast: lazy
import Thermodynamics as TD
import Thermodynamics
import ClimaCore.MatrixFields: @name


include("compat.jl")
include(joinpath("parameters", "Parameters.jl"))
Expand Down
22 changes: 9 additions & 13 deletions src/cache/cloud_fraction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,10 @@ NVTX.@annotate function set_cloud_fraction!(
TD.PhasePartition(thermo_params, ᶜts).ice,
)
else
@. cloud_diagnostics_tuple = make_named_tuple(
ifelse(
specific(Y.c.ρq_liq, Y.c.ρ) + specific(Y.c.ρq_ice, Y.c.ρ) > 0,
1,
0,
),
specific(Y.c.ρq_liq, Y.c.ρ),
specific(Y.c.ρq_ice, Y.c.ρ),
)
q_liq = @. lazy(specific(Y.c.ρq_liq, Y.c.ρ))
q_ice = @. lazy(specific(Y.c.ρq_ice, Y.c.ρ))
@. cloud_diagnostics_tuple =
make_named_tuple(ifelse(q_liq + q_ice > 0, 1, 0), q_liq, q_ice)
end
end

Expand Down Expand Up @@ -194,8 +189,9 @@ NVTX.@annotate function set_cloud_fraction!(
FT = eltype(params)
thermo_params = CAP.thermodynamics_params(params)
(; ᶜts⁰, cloud_diagnostics_tuple) = p.precomputed
(; ᶜρʲs, ᶜtsʲs, ᶜρa⁰, ᶜρ⁰) = p.precomputed
(; ᶜρʲs, ᶜtsʲs) = p.precomputed
(; turbconv_model) = p.atmos
ᶜρa⁰ = @. lazy(ρa⁰(Y.c.ρ, Y.c.sgsʲs, turbconv_model))

# TODO - we should make this default when using diagnostic edmf
# environment
Expand All @@ -217,9 +213,9 @@ NVTX.@annotate function set_cloud_fraction!(
# weight cloud diagnostics by environmental area
@. cloud_diagnostics_tuple *= NamedTuple{(:cf, :q_liq, :q_ice)}(
tuple(
draft_area(ᶜρa⁰, ᶜρ⁰),
draft_area(ᶜρa⁰, ᶜρ⁰),
draft_area(ᶜρa⁰, ᶜρ⁰),
draft_area(ᶜρa⁰, TD.air_density(thermo_params, ᶜts⁰)),
draft_area(ᶜρa⁰, TD.air_density(thermo_params, ᶜts⁰)),
draft_area(ᶜρa⁰, TD.air_density(thermo_params, ᶜts⁰)),
),
)
# updrafts
Expand Down
47 changes: 31 additions & 16 deletions src/cache/diagnostic_edmf_precomputed_quantities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ NVTX.@annotate function set_diagnostic_edmfx_env_quantities_level!(
local_geometry_halflevel,
turbconv_model,
)
@. u³⁰_halflevel = divide_by_ρa(
@. u³⁰_halflevel = specific(
ρ_level * u³_halflevel -
unrolled_dotproduct(ρaʲs_level, u³ʲs_halflevel),
ρ_level,
Expand Down Expand Up @@ -93,23 +93,28 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_bottom_bc!(
FT = eltype(Y)
n = n_mass_flux_subdomains(turbconv_model)
(; ᶜΦ) = p.core
(; ᶜp, ᶠu³, ᶜh_tot, ᶜK) = p.precomputed
(; q_tot) = p.precomputed.ᶜspecific
(; ᶜp, ᶠu³, ᶜK) = p.precomputed
(; ustar, obukhov_length, buoyancy_flux, ρ_flux_h_tot, ρ_flux_q_tot) =
p.precomputed.sfc_conditions
(; ᶜρaʲs, ᶠu³ʲs, ᶜKʲs, ᶜmseʲs, ᶜq_totʲs, ᶜtsʲs, ᶜρʲs) = p.precomputed
(; ᶠu³⁰, ᶜK⁰) = p.precomputed

(; params) = p

thermo_params = CAP.thermodynamics_params(params)
turbconv_params = CAP.turbconv_params(params)
ᶜts = p.precomputed.ᶜts #TODO replace

ᶜq_tot = @. lazy(specific(Y.c.ρq_tot, Y.c.ρ))
ᶜe_tot = @. lazy(specific(Y.c.ρe_tot, Y.c.ρ))
ᶜh_tot = @. lazy(TD.total_specific_enthalpy(thermo_params, ᶜts, ᶜe_tot))

ρ_int_level = Fields.field_values(Fields.level(Y.c.ρ, 1))
uₕ_int_level = Fields.field_values(Fields.level(Y.c.uₕ, 1))
u³_int_halflevel = Fields.field_values(Fields.level(ᶠu³, half))
h_tot_int_level = Fields.field_values(Fields.level(ᶜh_tot, 1))
K_int_level = Fields.field_values(Fields.level(ᶜK, 1))
q_tot_int_level = Fields.field_values(Fields.level(q_tot, 1))
q_tot_int_level = Fields.field_values(Fields.level(ᶜq_tot, 1))

p_int_level = Fields.field_values(Fields.level(ᶜp, 1))
Φ_int_level = Fields.field_values(Fields.level(ᶜΦ, 1))
Expand Down Expand Up @@ -305,8 +310,7 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_do_integral!(
(; dt) = p
dt = float(dt)
(; ᶜΦ, ᶜgradᵥ_ᶠΦ) = p.core
(; ᶜp, ᶠu³, ᶜts, ᶜh_tot, ᶜK) = p.precomputed
(; q_tot) = p.precomputed.ᶜspecific
(; ᶜp, ᶠu³, ᶜts, ᶜK) = p.precomputed
(;
ᶜρaʲs,
ᶠu³ʲs,
Expand All @@ -321,13 +325,13 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_do_integral!(
ᶠnh_pressure³_buoyʲs,
ᶠnh_pressure³_dragʲs,
) = p.precomputed
(; ᶠu³⁰, ᶜK⁰, ᶜtke⁰) = p.precomputed
(; ᶠu³⁰, ᶜK⁰) = p.precomputed



if microphysics_model isa Microphysics1Moment
ᶜq_liqʲs = p.precomputed.ᶜq_liqʲs
ᶜq_iceʲs = p.precomputed.ᶜq_iceʲs
q_rai = p.precomputed.ᶜqᵣ
q_sno = p.precomputed.ᶜqₛ
q_rai = @. lazy(specific(Y.c.ρq_rai, Y.c.ρ))
q_sno = @. lazy(specific(Y.c.ρq_sno, Y.c.ρ))
end

thermo_params = CAP.thermodynamics_params(params)
Expand All @@ -347,13 +351,24 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_do_integral!(
Fields.field_values(Fields.level(Fields.coordinate_field(Y.f).z, half))

# integral
ᶜq_tot = @. lazy(specific(Y.c.ρq_tot, Y.c.ρ))
ᶜh_tot = @. lazy(
TD.total_specific_enthalpy(
thermo_params,
ᶜts,
specific(Y.c.ρe_tot, Y.c.ρ),
),
)

ᶜtke⁰ = @. lazy(specific_tke(Y.c.ρ, Y.c.sgs⁰.ρatke, Y.c.ρ, turbconv_model))

for i in 2:Spaces.nlevels(axes(Y.c))
ρ_level = Fields.field_values(Fields.level(Y.c.ρ, i))
uₕ_level = Fields.field_values(Fields.level(Y.c.uₕ, i))
u³_halflevel = Fields.field_values(Fields.level(ᶠu³, i - half))
K_level = Fields.field_values(Fields.level(ᶜK, i))
h_tot_level = Fields.field_values(Fields.level(ᶜh_tot, i))
q_tot_level = Fields.field_values(Fields.level(q_tot, i))
q_tot_level = Fields.field_values(Fields.level(ᶜq_tot, i))
p_level = Fields.field_values(Fields.level(ᶜp, i))
Φ_level = Fields.field_values(Fields.level(ᶜΦ, i))
local_geometry_level = Fields.field_values(
Expand All @@ -378,7 +393,7 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_do_integral!(
u³⁰_data_prev_halflevel = u³⁰_prev_halflevel.components.data.:1
K_prev_level = Fields.field_values(Fields.level(ᶜK, i - 1))
h_tot_prev_level = Fields.field_values(Fields.level(ᶜh_tot, i - 1))
q_tot_prev_level = Fields.field_values(Fields.level(q_tot, i - 1))
q_tot_prev_level = Fields.field_values(Fields.level(ᶜq_tot, i - 1))
ts_prev_level = Fields.field_values(Fields.level(ᶜts, i - 1))
p_prev_level = Fields.field_values(Fields.level(ᶜp, i - 1))
z_prev_level = Fields.field_values(Fields.level(ᶜz, i - 1))
Expand Down Expand Up @@ -965,15 +980,14 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_env_closures!
(; dt) = p
(; ᶜp, ᶜu, ᶜts) = p.precomputed
(; ustar, obukhov_length) = p.precomputed.sfc_conditions
(; ᶜtke⁰) = p.precomputed
(; ᶜlinear_buoygrad, ᶜstrain_rate_norm) = p.precomputed
(; ρatke_flux) = p.precomputed
turbconv_params = CAP.turbconv_params(params)
thermo_params = CAP.thermodynamics_params(params)
ᶜlg = Fields.local_geometry_field(Y.c)

if p.atmos.turbconv_model isa DiagnosticEDMFX
(; ᶜρaʲs, ᶠu³ʲs, ᶜdetrʲs, ᶠu³⁰, ᶜu⁰) = p.precomputed
(; ᶠu³⁰, ᶜu⁰) = p.precomputed
elseif p.atmos.turbconv_model isa EDOnlyEDMFX
ᶠu³⁰ = p.precomputed.ᶠu³
ᶜu⁰ = ᶜu
Expand Down Expand Up @@ -1042,11 +1056,12 @@ NVTX.@annotate function set_diagnostic_edmf_precomputed_quantities_env_precipita
(; ᶜts, ᶜSqₜᵖ⁰) = p.precomputed

# Environment precipitation sources (to be applied to grid mean)
ᶜq_tot = @. lazy(specific(Y.c.ρq_tot, Y.c.ρ))
@. ᶜSqₜᵖ⁰ = q_tot_0M_precipitation_sources(
thermo_params,
microphys_0m_params,
dt,
specific(Y.c.ρq_tot, Y.c.ρ),
ᶜq_tot,
ᶜts,
)
return nothing
Expand Down
58 changes: 38 additions & 20 deletions src/cache/precipitation_precomputed_quantities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,11 @@ function set_precipitation_cache!(
::PrognosticEDMFX,
)
(; ᶜΦ) = p.core
(; ᶜSqₜᵖ⁰, ᶜSqₜᵖʲs, ᶜρa⁰) = p.precomputed
(; ᶜSqₜᵖ⁰, ᶜSqₜᵖʲs) = p.precomputed
(; ᶜS_ρq_tot, ᶜS_ρe_tot) = p.precomputed
(; ᶜts⁰, ᶜtsʲs) = p.precomputed
thermo_params = CAP.thermodynamics_params(p.params)
ᶜρa⁰ = @. lazy(ρa⁰(Y.c.ρ, Y.c.sgsʲs, p.atmos.turbconv_model))

n = n_mass_flux_subdomains(p.atmos.turbconv_model)

Expand All @@ -283,7 +284,11 @@ function set_precipitation_cache!(Y, p, ::Microphysics1Moment, _)
(; ᶜts, ᶜwᵣ, ᶜwₛ, ᶜu) = p.precomputed
(; ᶜSqₗᵖ, ᶜSqᵢᵖ, ᶜSqᵣᵖ, ᶜSqₛᵖ) = p.precomputed

(; q_tot, q_liq, q_ice, q_rai, q_sno) = p.precomputed.ᶜspecific
ᶜq_tot = @. lazy(specific(Y.c.ρq_tot, Y.c.ρ))
ᶜq_rai = @. lazy(specific(Y.c.ρq_rai, Y.c.ρ))
ᶜq_sno = @. lazy(specific(Y.c.ρq_sno, Y.c.ρ))
ᶜq_liq = @. lazy(specific(Y.c.ρq_liq, Y.c.ρ))
ᶜq_ice = @. lazy(specific(Y.c.ρq_ice, Y.c.ρ))

ᶜSᵖ = p.scratch.ᶜtemp_scalar
ᶜSᵖ_snow = p.scratch.ᶜtemp_scalar_2
Expand All @@ -303,11 +308,11 @@ function set_precipitation_cache!(Y, p, ::Microphysics1Moment, _)
ᶜSqᵣᵖ,
ᶜSqₛᵖ,
Y.c.ρ,
q_tot,
q_liq,
q_ice,
q_rai,
q_sno,
ᶜq_tot,
ᶜq_liq,
ᶜq_ice,
ᶜq_rai,
ᶜq_sno,
ᶜts,
dt,
cmp,
Expand All @@ -320,11 +325,11 @@ function set_precipitation_cache!(Y, p, ::Microphysics1Moment, _)
ᶜSqᵣᵖ,
ᶜSqₛᵖ,
Y.c.ρ,
q_tot,
q_liq,
q_ice,
q_rai,
q_sno,
ᶜq_tot,
ᶜq_liq,
ᶜq_ice,
ᶜq_rai,
ᶜq_sno,
ᶜts,
dt,
cmp,
Expand Down Expand Up @@ -469,14 +474,27 @@ function set_precipitation_surface_fluxes!(
sfc_ρ = @. lazy(int_ρ * int_J / sfc_J)

# Constant extrapolation to surface, consistent with simple downwinding
sfc_wᵣ = sfc_lev(ᶜwᵣ)
sfc_wₛ = sfc_lev(ᶜwₛ)
sfc_wₗ = sfc_lev(ᶜwₗ)
sfc_wᵢ = sfc_lev(ᶜwᵢ)
sfc_qᵣ = lazy.(specific.(sfc_lev(Y.c.ρq_rai), sfc_ρ))
sfc_qₛ = lazy.(specific.(sfc_lev(Y.c.ρq_sno), sfc_ρ))
sfc_qₗ = lazy.(specific.(sfc_lev(Y.c.ρq_liq), sfc_ρ))
sfc_qᵢ = lazy.(specific.(sfc_lev(Y.c.ρq_ice), sfc_ρ))
# Temporary scratch variables are used here until CC.field_values supports <lazy> fields
ᶜq_rai = p.scratch.ᶜtemp_scalar
ᶜq_sno = p.scratch.ᶜtemp_scalar_2
ᶜq_liq = p.scratch.ᶜtemp_scalar_3
ᶜq_ice = p.scratch.ᶜtemp_scalar_4
@. ᶜq_rai = specific(Y.c.ρq_rai, Y.c.ρ)
@. ᶜq_sno = specific(Y.c.ρq_sno, Y.c.ρ)
@. ᶜq_liq = specific(Y.c.ρq_liq, Y.c.ρ)
@. ᶜq_ice = specific(Y.c.ρq_ice, Y.c.ρ)
sfc_qᵣ =
Fields.Field(Fields.field_values(Fields.level(ᶜq_rai, 1)), sfc_space)
sfc_qₛ =
Fields.Field(Fields.field_values(Fields.level(ᶜq_sno, 1)), sfc_space)
sfc_qₗ =
Fields.Field(Fields.field_values(Fields.level(ᶜq_liq, 1)), sfc_space)
sfc_qᵢ =
Fields.Field(Fields.field_values(Fields.level(ᶜq_ice, 1)), sfc_space)
sfc_wᵣ = Fields.Field(Fields.field_values(Fields.level(ᶜwᵣ, 1)), sfc_space)
sfc_wₛ = Fields.Field(Fields.field_values(Fields.level(ᶜwₛ, 1)), sfc_space)
sfc_wₗ = Fields.Field(Fields.field_values(Fields.level(ᶜwₗ, 1)), sfc_space)
sfc_wᵢ = Fields.Field(Fields.field_values(Fields.level(ᶜwᵢ, 1)), sfc_space)

@. surface_rain_flux = sfc_ρ * (sfc_qᵣ * (-sfc_wᵣ) + sfc_qₗ * (-sfc_wₗ))
@. surface_snow_flux = sfc_ρ * (sfc_qₛ * (-sfc_wₛ) + sfc_qᵢ * (-sfc_wᵢ))
Expand Down
Loading
Loading