@@ -42,20 +42,6 @@ Arguments:
42
42
"""
43
43
@inline specific (ρχ, ρ) = ρχ / ρ
44
44
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
-
59
45
@inline function specific (ρaχ, ρa, ρχ, ρ, turbconv_model)
60
46
# TODO : Replace turbconv_model struct by parameters, and include a_half in
61
47
# parameters, not in config
@@ -158,6 +144,35 @@ function divide_by_ρa(ρaχ, ρa, ρχ, ρ, turbconv_model)
158
144
return ρa == 0 ? ρχ / ρ : weight * ρaχ / ρa + (1 - weight) * ρχ / ρ
159
145
end
160
146
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
+
161
176
# Helper functions for manipulating symbols in the generated functions:
162
177
has_prefix (symbol, prefix_symbol) =
163
178
startswith (string (symbol), string (prefix_symbol))
0 commit comments