@@ -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
@@ -158,6 +144,35 @@ function divide_by_ρa(ρaχ, ρa, ρχ, ρ, turbconv_model)
158144 return ρa == 0 ? ρχ / ρ : weight * ρaχ / ρa + (1 - weight) * ρχ / ρ
159145end
160146
147+ """
148+ matching_subfields(tendency_field, specific_field)
149+ Given a field that contains the tendencies of variables of the form `ρχ` or
150+ `ρaχ` and another field that contains the values of specific variables `χ`,
151+ returns all tuples `(tendency_field.<ρχ or ρaχ>, specific_field.<χ>, :<χ>)`.
152+ Variables in `tendency_field` that do not have matching variables in
153+ `specific_field` are omitted, as are variables in `specific_field` that do not
154+ have matching variables in `tendency_field`. This function is needed to avoid
155+ allocations due to failures in type inference, which are triggered when the
156+ `propertynames` of these fields are manipulated during runtime in order to pick
157+ out the matching subfields (as of Julia 1.8).
158+ """
159+ @generated function matching_subfields (tendency_field, specific_field)
160+ tendency_names = Base. _nt_names (eltype (tendency_field))
161+ specific_names = Base. _nt_names (eltype (specific_field))
162+ prefix = :ρa in tendency_names ? :ρa : :ρ
163+ relevant_specific_names =
164+ filter (name -> Symbol (prefix, name) in tendency_names, specific_names)
165+ subfield_tuples = map (
166+ name -> :((
167+ tendency_field.$ (Symbol (prefix, name)),
168+ specific_field.$ name,
169+ $ (QuoteNode (name)),
170+ )),
171+ relevant_specific_names,
172+ )
173+ return :(($ (subfield_tuples... ),))
174+ end
175+
161176# Helper functions for manipulating symbols in the generated functions:
162177has_prefix (symbol, prefix_symbol) =
163178 startswith (string (symbol), string (prefix_symbol))
0 commit comments