@@ -217,28 +217,31 @@ function get_thresholds_ρ_g(params::CMP.ParametersP3, F_rim, ρ_rim)
217217 return (; D_th, D_gr, D_cr, ρ_g)
218218end
219219
220+ function get_bounded_thresholds (state:: P3State , D_min = 0 , D_max = Inf )
221+ FT = eltype (state)
222+ (; D_th, D_gr, D_cr) = get_thresholds_ρ_g (state)
223+ thresholds = clamp .((FT (D_min), D_th, D_gr, D_cr, FT (D_max)), FT (D_min), FT (D_max))
224+ bounded_thresholds = replace (thresholds, NaN => FT (D_max))
225+ return bounded_thresholds
226+ end
227+
220228"""
221229 get_segments(state::P3State)
222230
223- Return the segments of the size distribution.
231+ Return the segments of the size distribution as a tuple of intervals .
224232
225233# Arguments
226234- `state`: [`P3State`](@ref) object
227235
228236# Returns
229237- `segments`: tuple of tuples, each containing the lower and upper bounds of a segment
230238
231- For example, if the (valid) thresholds are `(D_th, D_gr, D_cr)`, then the segments are:
239+ For example, if the thresholds are `(D_th, D_gr, D_cr)`, then the segments are:
232240- `(0, D_th)`, `(D_th, D_gr)`, `(D_gr, D_cr)`, `(D_cr, Inf)`
233241"""
234- function get_segments (state:: P3State )
235- FT = eltype (state)
236- (; D_th, D_gr, D_cr) = get_thresholds_ρ_g (state)
237- # For certain high rimed values, D_gr < D_th (cf test/p3_tests.jl):
238- # so here we filter away invalid thresholds
239- # (this also works correctly for the unrimed case, where D_gr = D_cr = NaN)
240- valid_D = filter (≥ (D_th), (D_th, D_gr, D_cr))
241- segments = tuple .((FT (0 ), valid_D... ), (valid_D... , FT (Inf )))
242+ function get_segments (state:: P3State , D_min = 0 , D_max = Inf )
243+ thresholds = get_bounded_thresholds (state, D_min, D_max)
244+ segments = tuple .(Base. front (thresholds), Base. tail (thresholds))
242245 return segments
243246end
244247
@@ -300,9 +303,9 @@ Return the mass of a particle based on where it falls in the particle-size-based
300303 - `params, F_rim, ρ_rim`: The [`CMP.ParametersP3`](@ref), rime mass fraction, and rime density,
301304 - `D`: maximum particle dimension [m]
302305"""
303- function ice_mass (args_D ... )
304- D = last (args_D )
305- (a, b) = ice_mass_coeffs (args_D ... )
306+ ice_mass ((; params, F_rim, ρ_rim) :: P3State , D) = ice_mass (params, F_rim, ρ_rim, D )
307+ function ice_mass (params :: CMP.ParametersP3 , F_rim, ρ_rim, D )
308+ (a, b) = ice_mass_coeffs (params, F_rim, ρ_rim, D )
306309 return a * D^ b
307310end
308311
@@ -322,13 +325,14 @@ Return the density of a particle at diameter D
322325 by the volume of a sphere with the same D [MorrisonMilbrandt2015](@cite).
323326 Needed for aspect ratio calculation, so we assume zero liquid fraction.
324327"""
325- function ice_density (args_D ... )
326- D = last (args_D )
327- return ice_mass (args_D ... ) / CO. volume_sphere_D (D)
328+ ice_density ((; params, F_rim, ρ_rim) :: P3State , D) = ice_density (params, F_rim, ρ_rim, D )
329+ function ice_density (params :: CMP.ParametersP3 , F_rim, ρ_rim, D )
330+ return ice_mass (params, F_rim, ρ_rim, D ) / CO. volume_sphere_D (D)
328331end
329332
330- function get_∂mass_∂D_coeffs (args_D... )
331- (a, b) = ice_mass_coeffs (args_D... )
333+ get_∂mass_∂D_coeffs ((; params, F_rim, ρ_rim):: P3State , D) = get_∂mass_∂D_coeffs (params, F_rim, ρ_rim, D)
334+ function get_∂mass_∂D_coeffs (params:: CMP.ParametersP3 , F_rim, ρ_rim, D)
335+ (a, b) = ice_mass_coeffs (params, F_rim, ρ_rim, D)
332336 return a * b, b - 1
333337end
334338
338342
339343Return the derivative of the ice mass with respect to the particle diameter.
340344"""
341- function ∂ice_mass_∂D (args_D ... )
342- D = last (args_D )
343- (a, b) = get_∂mass_∂D_coeffs (args_D ... )
345+ ∂ice_mass_∂D ((; params, F_rim, ρ_rim) :: P3State , D) = ∂ice_mass_∂D (params, F_rim, ρ_rim, D )
346+ function ∂ice_mass_∂D (params :: CMP.ParametersP3 , F_rim, ρ_rim, D )
347+ (a, b) = get_∂mass_∂D_coeffs (params, F_rim, ρ_rim, D )
344348 return a * D^ b
345349end
346350
@@ -391,18 +395,18 @@ Returns the aspect ratio (ϕ) for an ice particle
391395 divided by the volume of a spherical particle with the same D_max [MorrisonMilbrandt2015](@cite).
392396 Assuming zero liquid fraction and oblate shape.
393397"""
394- function ϕᵢ (args_D ... )
395- D = last (args_D )
398+ ϕᵢ ((; params, F_rim, ρ_rim) :: P3State , D) = ϕᵢ (params, F_rim, ρ_rim, D )
399+ function ϕᵢ (params :: CMP.ParametersP3 , F_rim, ρ_rim, D )
396400 FT = eltype (D)
397- mᵢ = ice_mass (args_D ... )
398- aᵢ = ice_area (args_D ... )
399- ρᵢ = ice_density (args_D ... )
401+ mᵢ = ice_mass (params, F_rim, ρ_rim, D )
402+ aᵢ = ice_area (params, F_rim, ρ_rim, D )
403+ ρᵢ = ice_density (params, F_rim, ρ_rim, D )
400404
401405 # TODO - prolate or oblate?
402406 ϕ_ob = min (1 , 3 * sqrt (FT (π)) * mᵢ / (4 * ρᵢ * aᵢ^ FT (1.5 ))) # κ = 1/3
403407 # ϕ_pr = max(1, 16 * ρᵢ^2 * aᵢ^3 / (9 * FT(π) * mᵢ^2)) # κ = -1/6
404408
405- return ifelse (D == 0 , 0 , ϕ_ob)
409+ return ifelse (D == 0 , FT ( 0 ) , ϕ_ob)
406410end
407411
408412# ## ----------------- ###
0 commit comments