Skip to content

Commit deece00

Browse files
Merge pull request #3857 from CliMA/ck/slim_cache4
Make ᶜspecific lazy and remove matching_subfields
2 parents 14f7dfc + 0d80a61 commit deece00

File tree

3 files changed

+140
-177
lines changed

3 files changed

+140
-177
lines changed

src/cache/precomputed_quantities.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function implicit_precomputed_quantities(Y, atmos)
4242
TST = thermo_state_type(moisture_model, FT)
4343
n = n_mass_flux_subdomains(turbconv_model)
4444
gs_quantities = (;
45-
ᶜspecific = specific_gs.(Y.c),
45+
ᶜspecific = Base.materialize(ᶜspecific_gs_tracers(Y)),
4646
ᶜu = similar(Y.c, C123{FT}),
4747
ᶠu³ = similar(Y.f, CT3{FT}),
4848
ᶠu = similar(Y.f, CT123{FT}),
@@ -461,7 +461,7 @@ NVTX.@annotate function set_implicit_precomputed_quantities!(Y, p, t)
461461
thermo_params = CAP.thermodynamics_params(p.params)
462462
thermo_args = (thermo_params, moisture_model, precip_model)
463463

464-
@. ᶜspecific = specific_gs(Y.c)
464+
ᶜspecific .= ᶜspecific_gs_tracers(Y)
465465
@. ᶠuₕ³ = $compute_ᶠuₕ³(Y.c.uₕ, Y.c.ρ)
466466

467467
# TODO: We might want to move this to dss! (and rename dss! to something

src/prognostic_equations/hyperdiffusion.jl

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ import ClimaCore.Geometry as Geometry
66
import ClimaCore.Fields as Fields
77
import ClimaCore.Spaces as Spaces
88

9+
"""
10+
ν₄(hyperdiff, Y)
11+
12+
A `NamedTuple` of the hyperdiffusivity `ν₄_scalar` and the hyperviscosity
13+
`ν₄_vorticity`. These quantities are assumed to scale with `h^3`, where `h` is
14+
the mean nodal distance, following the empirical results of Lauritzen et al.
15+
(2018, https://doi.org/10.1029/2017MS001257). When `h == 1`, these quantities
16+
are equal to `hyperdiff.ν₄_scalar_coeff` and `hyperdiff.ν₄_vorticity_coeff`.
17+
"""
18+
function ν₄(hyperdiff, Y)
19+
h = Spaces.node_horizontal_length_scale(Spaces.horizontal_space(axes(Y.c)))
20+
ν₄_scalar = hyperdiff.ν₄_scalar_coeff * h^3
21+
ν₄_vorticity = hyperdiff.ν₄_vorticity_coeff * h^3
22+
return (; ν₄_scalar, ν₄_vorticity)
23+
end
24+
925
hyperdiffusion_cache(Y, atmos) = hyperdiffusion_cache(
1026
Y,
1127
atmos.hyperdiff,
@@ -34,7 +50,7 @@ function hyperdiffusion_cache(
3450
gs_quantities = (;
3551
ᶜ∇²u = similar(Y.c, C123{FT}),
3652
ᶜ∇²specific_energy = similar(Y.c, FT),
37-
ᶜ∇²specific_tracers = remove_energy_var.(specific_gs.(Y.c)),
53+
ᶜ∇²specific_tracers = Base.materialize(ᶜspecific_gs_tracers(Y)),
3854
)
3955

4056
# Sub-grid scale quantities
@@ -85,7 +101,7 @@ NVTX.@annotate function prep_hyperdiffusion_tendency!(Yₜ, Y, p, t)
85101

86102
n = n_mass_flux_subdomains(turbconv_model)
87103
diffuse_tke = use_prognostic_tke(turbconv_model)
88-
(; ᶜp, ᶜspecific) = p.precomputed
104+
(; ᶜp) = p.precomputed
89105
(; ᶜh_ref) = p.core
90106
(; ᶜ∇²u, ᶜ∇²specific_energy) = p.hyperdiff
91107
if turbconv_model isa PrognosticEDMFX
@@ -125,20 +141,14 @@ NVTX.@annotate function apply_hyperdiffusion_tendency!(Yₜ, Y, p, t)
125141
(; hyperdiff, turbconv_model) = p.atmos
126142
isnothing(hyperdiff) && return nothing
127143

128-
(; ν₄_vorticity_coeff, ν₄_scalar_coeff, divergence_damping_factor) =
129-
hyperdiff
130-
131-
h_space = Spaces.horizontal_space(axes(Y.c))
132-
h_length_scale = Spaces.node_horizontal_length_scale(h_space) # mean nodal distance
133-
134-
ν₄_scalar = ν₄_scalar_coeff * h_length_scale^3
135-
ν₄_vorticity = ν₄_vorticity_coeff * h_length_scale^3
144+
(; divergence_damping_factor) = hyperdiff
145+
(; ν₄_scalar, ν₄_vorticity) = ν₄(hyperdiff, Y)
136146

137147
n = n_mass_flux_subdomains(turbconv_model)
138148
diffuse_tke = use_prognostic_tke(turbconv_model)
139149
ᶜJ = Fields.local_geometry_field(Y.c).J
140150
point_type = eltype(Fields.coordinate_field(Y.c))
141-
(; ᶜp, ᶜspecific) = p.precomputed
151+
(; ᶜp) = p.precomputed
142152
(; ᶜ∇²u, ᶜ∇²specific_energy) = p.hyperdiff
143153
if turbconv_model isa PrognosticEDMFX
144154
(; ᶜρa⁰) = p.precomputed
@@ -241,11 +251,12 @@ NVTX.@annotate function prep_tracer_hyperdiffusion_tendency!(Yₜ, Y, p, t)
241251
(; hyperdiff, turbconv_model) = p.atmos
242252
isnothing(hyperdiff) && return nothing
243253

244-
(; ᶜspecific) = p.precomputed
245254
(; ᶜ∇²specific_tracers) = p.hyperdiff
246255

247-
for χ_name in propertynames(ᶜ∇²specific_tracers)
248-
@. ᶜ∇²specific_tracers.:($$χ_name) = wdivₕ(gradₕ(ᶜspecific.:($$χ_name)))
256+
# TODO: Fix RecursiveApply bug in gradₕ to fuse this operation.
257+
# ᶜ∇²specific_tracers .= wdivₕ.(gradₕ.(ᶜspecific_gs_tracers(Y)))
258+
foreach_gs_tracer(Y, ᶜ∇²specific_tracers) do ᶜρχ, ᶜ∇²χ, _
259+
@. ᶜ∇²χ = wdivₕ(gradₕ(specific(ᶜρχ, Y.c.ρ)))
249260
end
250261

251262
if turbconv_model isa PrognosticEDMFX
@@ -276,31 +287,24 @@ NVTX.@annotate function apply_tracer_hyperdiffusion_tendency!(Yₜ, Y, p, t)
276287
(; hyperdiff, turbconv_model) = p.atmos
277288
isnothing(hyperdiff) && return nothing
278289

279-
α_hyperdiff_tracer = CAP.α_hyperdiff_tracer(p.params)
280-
(; ν₄_scalar_coeff) = hyperdiff
281-
h_space = Spaces.horizontal_space(axes(Y.c))
282-
h_length_scale = Spaces.node_horizontal_length_scale(h_space) # mean nodal distance
283-
ν₄_scalar = ν₄_scalar_coeff * h_length_scale^3
284-
n = n_mass_flux_subdomains(turbconv_model)
290+
# Rescale the hyperdiffusivity for precipitating species.
291+
(; ν₄_scalar) = ν₄(hyperdiff, Y)
292+
ν₄_scalar_for_precip = CAP.α_hyperdiff_tracer(p.params) * ν₄_scalar
285293

294+
n = n_mass_flux_subdomains(turbconv_model)
286295
(; ᶜ∇²specific_tracers) = p.hyperdiff
287296

288297
# TODO: Since we are not applying the limiter to density (or area-weighted
289298
# density), the mass redistributed by hyperdiffusion will not be conserved
290299
# by the limiter. Is this a significant problem?
291-
# TODO: Figure out why caching the duplicated tendencies in ᶜtemp_scalar
292-
# triggers allocations.
293-
for (ᶜρχₜ, ᶜ∇²χ, χ_name) in matching_subfields(Yₜ.c, ᶜ∇²specific_tracers)
294-
ν₄_scalar = ifelse(
295-
χ_name in (:q_rai, :q_sno, :n_rai),
296-
α_hyperdiff_tracer * ν₄_scalar,
297-
ν₄_scalar,
298-
)
299-
@. ᶜρχₜ -= ν₄_scalar * wdivₕ(Y.c.ρ * gradₕ(ᶜ∇²χ))
300-
301-
# Exclude contributions from hyperdiffusion of condensate,
302-
# precipitating species from mass tendency.
303-
if χ_name == :q_tot
300+
foreach_gs_tracer(Yₜ, ᶜ∇²specific_tracers) do ᶜρχₜ, ᶜ∇²χ, ρχ_name
301+
ν₄_scalar_for_χ =
302+
ρχ_name in (@name(ρq_rai), @name(ρq_sno), @name(ρn_rai)) ?
303+
ν₄_scalar_for_precip : ν₄_scalar
304+
@. ᶜρχₜ -= ν₄_scalar_for_χ * wdivₕ(Y.c.ρ * gradₕ(ᶜ∇²χ))
305+
306+
# Take into account the effect of total water diffusion on density.
307+
if ρχ_name == @name(ρq_tot)
304308
@. Yₜ.c.ρ -= ν₄_scalar * wdivₕ(Y.c.ρ * gradₕ(ᶜ∇²χ))
305309
end
306310
end
@@ -323,13 +327,9 @@ NVTX.@annotate function apply_tracer_hyperdiffusion_tendency!(Yₜ, Y, p, t)
323327
@. Yₜ.c.sgsʲs.:($$j).q_ice -=
324328
ν₄_scalar * wdivₕ(gradₕ(ᶜ∇²q_iceʲs.:($$j)))
325329
@. Yₜ.c.sgsʲs.:($$j).q_rai -=
326-
α_hyperdiff_tracer *
327-
ν₄_scalar *
328-
wdivₕ(gradₕ(ᶜ∇²q_raiʲs.:($$j)))
330+
ν₄_scalar_for_precip * wdivₕ(gradₕ(ᶜ∇²q_raiʲs.:($$j)))
329331
@. Yₜ.c.sgsʲs.:($$j).q_sno -=
330-
α_hyperdiff_tracer *
331-
ν₄_scalar *
332-
wdivₕ(gradₕ(ᶜ∇²q_snoʲs.:($$j)))
332+
ν₄_scalar_for_precip * wdivₕ(gradₕ(ᶜ∇²q_snoʲs.:($$j)))
333333
end
334334
end
335335
end

0 commit comments

Comments
 (0)