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