@@ -99,3 +99,131 @@ function ice_melt(
99
99
dLdt = min (dLdt, L_ice / dt)
100
100
return (; dNdt, dLdt)
101
101
end
102
+
103
+ """
104
+ compute_max_freeze_rate(state, aps, tps, velocity_params, ρₐ, Tₐ)
105
+
106
+ Returns a function `max_freeze_rate(Dᵢ)` that returns the maximum possible freezing rate [kg/s]
107
+ for an ice particle of diameter `Dᵢ` [m]. Evaluates to 0 if T ≥ T_freeze.
108
+
109
+ # Arguments
110
+ - `state`: [`P3State`](@ref)
111
+ - `aps`: [`CMP.AirProperties`](@ref)
112
+ - `tps`: `TDP.ThermodynamicsParameters`
113
+ - `velocity_params`: The velocity parameterization, e.g. [`CMP.Chen2022VelType`](@ref)
114
+ - `ρₐ`: air density [kg/m³]
115
+ - `Tₐ`: air temperature [K]
116
+
117
+ This rate represents the thermodynamic upper limit to collisional freezing,
118
+ which occurs when the heat transfer from the ice particle to the environment is
119
+ balanced by the latent heat of fusion.
120
+
121
+ From Eq (A7) in Musil (1970), [Musil1970](@cite).
122
+ """
123
+ function compute_max_freeze_rate (state, aps, tps, velocity_params, ρₐ, Tₐ)
124
+ (; D_vapor, K_therm) = aps
125
+ cp_l = TDP. cp_l (tps)
126
+ T_frz = TDP. T_freeze (tps)
127
+ Lᵥ = TD. latent_heat_vapor (tps, Tₐ)
128
+ L_f = TD. latent_heat_fusion (tps, Tₐ)
129
+ Tₛ = T_frz # the surface of the ice particle is assumed to be at the freezing temperature
130
+ ΔT = Tₛ - Tₐ # temperature difference between the surface of the ice particle and the air
131
+ Δρᵥ_sat =
132
+ ρₐ * ( # saturation vapor density difference between the surface of the ice particle and the air
133
+ TD. q_vap_saturation (tps, Tₛ, ρₐ, TD. PhaseNonEquil) -
134
+ TD. q_vap_saturation (tps, Tₐ, ρₐ, TD. PhaseNonEquil)
135
+ )
136
+ v_term = ice_particle_terminal_velocity (state, velocity_params, ρₐ)
137
+ F_v = CO. ventilation_factor (state. params. vent, aps, v_term)
138
+ function max_freeze_rate (Dᵢ)
139
+ Tₐ ≥ T_frz && return zero (Dᵢ) # No collisional freezing above the freezing temperature
140
+ return 2 * (π * Dᵢ) * F_v (Dᵢ) * (K_therm * ΔT + Lᵥ * D_vapor * Δρᵥ_sat) / (L_f - cp_l * ΔT)
141
+ end
142
+ return max_freeze_rate
143
+ end
144
+
145
+ """
146
+ compute_local_rime_density(state, velocity_params, ρₐ, T)
147
+
148
+ Provides a function `ρ′ᵣ(Dᵢ, Dₗ)` that computes the local rime density [kg/m³]
149
+ for a given ice particle diameter `Dᵢ` [m] and liquid particle diameter `Dₗ` [m].
150
+
151
+ From Cober and List (1993).
152
+
153
+ # Arguments
154
+ - `state`: a [`P3State`](@ref) object
155
+ - `velocity_params`: The velocity parameterization, e.g. [`CMP.Chen2022VelType`](@ref)
156
+ - `ρₐ`: air density [kg/m³]
157
+ - `T`: temperature [K]
158
+
159
+ # Returns
160
+ A function that computes the local rime density [kg/m³] using the equation:
161
+
162
+ ```math
163
+ ρ′_r = 51 + 114 R_i - 5.5 R_i^2
164
+ ```
165
+ where
166
+ ```math
167
+ R_i = ( D_{liq} ⋅ |v_{liq} - v_{ice}| ) / ( 2 T_{sfc} )
168
+ ```
169
+ and ``T_{sfc}`` is the surface temperature [°C], ``D_{liq}`` is the liquid particle
170
+ diameter [m], ``v_{liq/ice}`` is the particle terminal velocity [m/s].
171
+ So the units of ``R_i`` are [m² s⁻¹ °C⁻¹]. The units of ``ρ′_r`` are [kg/m³].
172
+
173
+ They assume for simplicity that `T_sfc` equals `T`, the ambient air temperature.
174
+ For real graupel, `T_sfc` is slightly higher than `T` due to latent heat release
175
+ of freezing liquid particles onto the ice particle. MM13 found little sensitivity
176
+ to "realistic" increases in `T_sfc`.
177
+
178
+ Implementation follows Cober and List (1993), Eq. 16 and 17.
179
+ See also the P3 fortran code, microphy_p3.f90, Line 3315-3323,
180
+ which extends the range of the calculation to Rᵢ ≤ 12, the upper limit of which
181
+ then equals the solid bulk ice density, ``ρ^⭒ = 900 kg/m^3``.
182
+
183
+ Note that MM15 only uses this parameterization for collisions with cloud droplets.
184
+ For rain drops, they use the solid bulk ice density, ``ρ^* = 900 kg/m^3``.
185
+ We do not consider this distinction, and use this parameterization for all liquid particles.
186
+ """
187
+ function compute_local_rime_density (state, velocity_params, ρₐ, T)
188
+ (; T_freeze) = state. params
189
+ T°C = T - T_freeze # Convert to °C
190
+
191
+ v_ice = ice_particle_terminal_velocity (state, velocity_params, ρₐ)
192
+ v_liq = CO. particle_terminal_velocity (velocity_params. rain, ρₐ)
193
+ function ρ′ᵣ (Dᵢ, Dₗ)
194
+ v_term = abs (v_ice (Dᵢ) - v_liq (Dₗ))
195
+ Rᵢ = (Dₗ * v_term) / (2 * T°C) # Eq. 16 in Cober and List (1993). Note: no `-` due to absolute value in v_term
196
+ return ρ′ᵣ_P3 (Rᵢ)
197
+ end
198
+ return ρ′ᵣ
199
+ end
200
+
201
+ """
202
+ ρ′ᵣ_P3(Rᵢ)
203
+
204
+ Returns the local rime density [kg/m³] for a given Rᵢ [m² s⁻¹ °C⁻¹].
205
+
206
+ Based on Cober and List (1993), Eq. 16 and 17 (valid for 1 ≤ Rᵢ ≤ 8).
207
+ For 8 < Rᵢ ≤ 12, linearly interpolate between ρ′ᵣ(8) ≡ 611 kg/m³ and ρ⭒ = 900 kg/m³.
208
+ See also the P3 fortran code
209
+ """
210
+ function ρ′ᵣ_P3 (Rᵢ)
211
+ # TODO : Externalize these parameters
212
+ a, b, c = 51 , 114 , - 11 // 2 # coeffs for Eq. 17 in Cober and List (1993), converted to [kg / m³]
213
+ ρ⭒ = 900 # ρ^⭒: density of solid bulk ice
214
+
215
+ Rᵢ = clamp (Rᵢ, 1 , 12 ) # P3 fortran code, microphy_p3.f90, Line 3315 clamps to 1 ≤ Rᵢ ≤ 12
216
+
217
+ ρ′ᵣ_CL93 (Rᵢ) = a + b * Rᵢ + c * Rᵢ^ 2 # Eq. 17 in Cober and List (1993), in [kg / m³], valid for 1 ≤ Rᵢ ≤ 8
218
+ ρ′ᵣ = if Rᵢ ≤ 8
219
+ ρ′ᵣ_CL93 (Rᵢ)
220
+ else
221
+ # following P3 fortran code, microphy_p3.f90, Line 3323
222
+ # https://github.com/P3-microphysics/P3-microphysics/blob/main/src/microphy_p3.f90#L3323
223
+ # for 8 < Rᵢ ≤ 12, linearly interpolate between ρ′ᵣ(8) ≡ 611 kg/m³ and ρ⭒ = 900 kg/m³
224
+ ρ′ᵣ8 = ρ′ᵣ_CL93 (8 )
225
+ f_ρ⭒ = (Rᵢ - 8 ) / (12 - 8 )
226
+ (1 - f_ρ⭒) * ρ′ᵣ8 + f_ρ⭒ * ρ⭒ # Linear interpolation beyond 8.
227
+ end
228
+ return float (ρ′ᵣ)
229
+ end
0 commit comments