Skip to content

Commit ec41c97

Browse files
Fixes
1 parent 85c2bef commit ec41c97

File tree

3 files changed

+43
-34
lines changed

3 files changed

+43
-34
lines changed

src/prognostic_equations/hyperdiffusion.jl

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -289,25 +289,18 @@ NVTX.@annotate function apply_tracer_hyperdiffusion_tendency!(Yₜ, Y, p, t)
289289
# by the limiter. Is this a significant problem?
290290
# TODO: Figure out why caching the duplicated tendencies in ᶜtemp_scalar
291291
# triggers allocations.
292-
UU.unrolled_foreach(propertynames(Yₜ.c)) do ρχ_name
293-
if is_tracer_var(ρχ_name)
294-
ᶜρχ = getproperty(Y.c, ρχ_name)
295-
ᶜρχₜ = getproperty(Yₜ.c, ρχ_name)
296-
ᶜχ = @. lazy(specific(ᶜρχ, Y.c.ρ))
297-
298-
ν₄_scalar = ifelse(
299-
ρχ_name in (:ρq_rai, :ρq_sno, :ρn_rai),
300-
α_hyperdiff_tracer * ν₄_scalar,
301-
ν₄_scalar,
302-
)
303-
ᶜ∇²χ = getproperty(ᶜ∇²specific_tracers, specific_name(ρχ_name))
304-
@. ᶜρχₜ -= ν₄_scalar * wdivₕ(Y.c.ρ * gradₕ(ᶜ∇²χ))
305-
306-
# Exclude contributions from hyperdiffusion of condensate,
307-
# precipitating species from mass tendency.
308-
if ρχ_name == :ρq_tot
309-
@. Yₜ.c.ρ -= ν₄_scalar * wdivₕ(Y.c.ρ * gradₕ(ᶜ∇²χ))
310-
end
292+
for (ᶜρχₜ, ᶜ∇²χ, χ_name) in matching_subfields(Yₜ.c, ᶜ∇²specific_tracers)
293+
ν₄_scalar = ifelse(
294+
χ_name in (:q_rai, :q_sno, :n_rai),
295+
α_hyperdiff_tracer * ν₄_scalar,
296+
ν₄_scalar,
297+
)
298+
@. ᶜρχₜ -= ν₄_scalar * wdivₕ(Y.c.ρ * gradₕ(ᶜ∇²χ))
299+
300+
# Exclude contributions from hyperdiffusion of condensate,
301+
# precipitating species from mass tendency.
302+
if χ_name == :q_tot
303+
@. Yₜ.c.ρ -= ν₄_scalar * wdivₕ(Y.c.ρ * gradₕ(ᶜ∇²χ))
311304
end
312305
end
313306
if turbconv_model isa PrognosticEDMFX

src/prognostic_equations/vertical_diffusion_boundary_layer.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ function vertical_diffusion_boundary_layer_tendency!(
115115
@. ᶜρχₜ -= ᶜρχₜ_diffusion
116116
# Only add contribution from total water diffusion to mass tendency
117117
# (exclude contributions from diffusion of condensate, precipitation)
118-
if χ_name == :q_tot
118+
if ρχ_name == :ρq_tot
119119
@. Yₜ.c.ρ -= ᶜρχₜ_diffusion
120120
end
121121
end

src/utils/variable_manipulations.jl

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,6 @@ Arguments:
4242
"""
4343
@inline specific(ρχ, ρ) = ρχ / ρ
4444

45-
#! format: off
46-
@inline specific_name(ρχ_name::Symbol) =
47-
if ρχ_name == :ρe_tot; return :e_tot
48-
elseif ρχ_name == :ρq_tot; return :q_tot
49-
elseif ρχ_name == :ρq_liq; return :q_liq
50-
elseif ρχ_name == :ρq_ice; return :q_ice
51-
elseif ρχ_name == :ρq_rai; return :q_rai
52-
elseif ρχ_name == :ρn_liq; return :n_liq
53-
elseif ρχ_name == :ρn_rai; return :q_rai
54-
elseif ρχ_name == :ρq_sno; return :q_sno
55-
else; error("Uncaught name: $ρχ_name")
56-
end
57-
#! format: on
58-
5945
@inline function specific(ρaχ, ρa, ρχ, ρ, turbconv_model)
6046
# TODO: Replace turbconv_model struct by parameters, and include a_half in
6147
# parameters, not in config
@@ -216,6 +202,36 @@ value is assumed to be equal to the value of `ρaχ` in `sgs`.
216202
return :(NamedTuple{$specific_sgs_names}(($(specific_sgs_values...),)))
217203
end
218204

205+
"""
206+
matching_subfields(tendency_field, specific_field)
207+
208+
Given a field that contains the tendencies of variables of the form `ρχ` or
209+
`ρaχ` and another field that contains the values of specific variables `χ`,
210+
returns all tuples `(tendency_field.<ρχ or ρaχ>, specific_field.<χ>, :<χ>)`.
211+
Variables in `tendency_field` that do not have matching variables in
212+
`specific_field` are omitted, as are variables in `specific_field` that do not
213+
have matching variables in `tendency_field`. This function is needed to avoid
214+
allocations due to failures in type inference, which are triggered when the
215+
`propertynames` of these fields are manipulated during runtime in order to pick
216+
out the matching subfields (as of Julia 1.8).
217+
"""
218+
@generated function matching_subfields(tendency_field, specific_field)
219+
tendency_names = Base._nt_names(eltype(tendency_field))
220+
specific_names = Base._nt_names(eltype(specific_field))
221+
prefix = :ρa in tendency_names ? :ρa :
222+
relevant_specific_names =
223+
filter(name -> Symbol(prefix, name) in tendency_names, specific_names)
224+
subfield_tuples = map(
225+
name -> :((
226+
tendency_field.$(Symbol(prefix, name)),
227+
specific_field.$name,
228+
$(QuoteNode(name)),
229+
)),
230+
relevant_specific_names,
231+
)
232+
return :(($(subfield_tuples...),))
233+
end
234+
219235
"""
220236
ρa⁺(gs)
221237

0 commit comments

Comments
 (0)