diff --git a/Project.toml b/Project.toml index 6fb243ed4..ac88928d8 100644 --- a/Project.toml +++ b/Project.toml @@ -1,12 +1,13 @@ name = "CloudMicrophysics" uuid = "6a9e3e04-43cd-43ba-94b9-e8782df3c71b" -authors = ["Climate Modeling Alliance"] version = "0.32" +authors = ["Climate Modeling Alliance"] [deps] ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3" LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" RootSolvers = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" @@ -27,6 +28,7 @@ ClimaParams = "1" DataFrames = "1.6" DocStringExtensions = "0.8, 0.9" ForwardDiff = "0.10, 1" +InteractiveUtils = "1" LazyArtifacts = "1" LogExpFunctions = "0.3.29" MLJ = "0.20" diff --git a/docs/src/API.md b/docs/src/API.md index 40a8bf287..3463a0474 100644 --- a/docs/src/API.md +++ b/docs/src/API.md @@ -128,9 +128,7 @@ P3Scheme ## Construct parameterization set ```@docs -CMP.ParametersP3{Float64} -CMP.ParametersP3(::Float64) -CMP.ParametersP3(::Parameters.CP.ParamDict) +CMP.ParametersP3 ``` ### Sub-parameterizations @@ -432,3 +430,10 @@ Parameters.Microphysics2MParams PrecipitationSusceptibility.precipitation_susceptibility_autoconversion PrecipitationSusceptibility.precipitation_susceptibility_accretion ``` + + +# Developer docs + +```@autodocs +Modules = [ShowMethods] +``` diff --git a/docs/src/plots/CloudDiagnostics.jl b/docs/src/plots/CloudDiagnostics.jl index fecb59e89..f0853d039 100644 --- a/docs/src/plots/CloudDiagnostics.jl +++ b/docs/src/plots/CloudDiagnostics.jl @@ -24,7 +24,7 @@ override_file = joinpath( ) toml_dict = CP.create_toml_dict(FT; override_file) SB = CMP.SB2006(toml_dict) -SB_no_limiters = CMP.SB2006(toml_dict, false) +SB_no_limiters = CMP.SB2006(toml_dict; is_limited = false) ρ_air = FT(1) diff --git a/docs/src/plots/TerminalVelocity.jl b/docs/src/plots/TerminalVelocity.jl index 8b5d5ef80..88f60cee3 100644 --- a/docs/src/plots/TerminalVelocity.jl +++ b/docs/src/plots/TerminalVelocity.jl @@ -17,7 +17,7 @@ const ice = CMP.CloudIce(FT) const snow = CMP.Snow(FT) const SB2006 = CMP.SB2006(FT) -const SB2006_no_lim = CMP.SB2006(FT, false) +const SB2006_no_lim = CMP.SB2006(FT; is_limited = false) const Chen2022 = CMP.Chen2022VelType(FT) const STVel = CMP.StokesRegimeVelType(FT) diff --git a/docs/src/plots/TerminalVelocity2M.jl b/docs/src/plots/TerminalVelocity2M.jl index c2cc6b602..f644342ee 100644 --- a/docs/src/plots/TerminalVelocity2M.jl +++ b/docs/src/plots/TerminalVelocity2M.jl @@ -9,7 +9,7 @@ FT = Float64 const rain = CMP.Rain(FT) const SB2006 = CMP.SB2006(FT) -const SB2006_no_lim = CMP.SB2006(FT, false) +const SB2006_no_lim = CMP.SB2006(FT; is_limited = false) const SB2006Vel = CMP.SB2006VelType(FT) ρ_air = 1.2 diff --git a/parcel/ParcelDistributions.jl b/parcel/ParcelDistributions.jl index e435fd8e4..b5b24c7d8 100644 --- a/parcel/ParcelDistributions.jl +++ b/parcel/ParcelDistributions.jl @@ -1,10 +1,10 @@ import CloudMicrophysics.Parameters as CMP -struct Monodisperse{FT} <: CMP.ParametersType{FT} end +struct Monodisperse <: CMP.ParametersType end -struct MonodisperseMix{FT} <: CMP.ParametersType{FT} end +struct MonodisperseMix <: CMP.ParametersType end -struct Gamma{FT} <: CMP.ParametersType{FT} end +struct Gamma <: CMP.ParametersType end #! format: off # Size distributiom moments diff --git a/parcel/ParcelModel.jl b/parcel/ParcelModel.jl index 8777b3737..04ead541f 100644 --- a/parcel/ParcelModel.jl +++ b/parcel/ParcelModel.jl @@ -8,7 +8,7 @@ include(joinpath(pkgdir(CM), "parcel", "ParcelParameters.jl")) """ Parcel simulation parameters """ -Base.@kwdef struct parcel_params{FT} <: CMP.ParametersType{FT} +Base.@kwdef struct parcel_params{FT} <: CMP.ParametersType prescribed_thermodynamics = false t_profile = [] T_profile = [] @@ -21,7 +21,7 @@ Base.@kwdef struct parcel_params{FT} <: CMP.ParametersType{FT} deposition_growth = "None" liq_size_distribution = "Monodisperse" ice_size_distribution = "Monodisperse" - aerosol = Empty{FT}() + aerosol = Empty() aero_σ_g = FT(0) wps = CMP.WaterProperties(FT) aps = CMP.AirProperties(FT) @@ -102,7 +102,7 @@ function parcel_model(dY, Y, p, t) qₗ_mode1 = Y[11] Nₗ_mode1 = Y[12] _tmp_state = merge(state, (; qₗ = qₗ_mode1, Nₗ = Nₗ_mode1)) - PSD_liq_mode1 = distribution_moments(Monodisperse{FT}(), qₗ_mode1, Nₗ_mode1, ρₗ, ρ_air) + PSD_liq_mode1 = distribution_moments(Monodisperse(), qₗ_mode1, Nₗ_mode1, ρₗ, ρ_air) dqₗ_mode1_dt = condensation(ce_params, PSD_liq_mode1, _tmp_state, ρ_air) dNₗ_mode1_dt = dqₗ_mode1_dt < FT(0) && qₗ_mode1 > FT(0) && qₗ_mode1 < FT(1e-6) ? Nₗ_mode1 * dqₗ_mode1_dt / qₗ_mode1 : FT(0) @@ -231,20 +231,20 @@ function run_parcel(IC, t_0, t_end, pp) info = "\nSize distribution (liq): $(pp.liq_size_distribution)\n" if pp.liq_size_distribution == "Monodisperse" - liq_distr = Monodisperse{FT}() + liq_distr = Monodisperse() elseif pp.liq_size_distribution == "Gamma" - liq_distr = Gamma{FT}() + liq_distr = Gamma() elseif pp.liq_size_distribution == "MonodisperseMix" - liq_distr = MonodisperseMix{FT}() + liq_distr = MonodisperseMix() else throw("Unrecognized size distribution") end info *= "Size distribution (ice): $(pp.ice_size_distribution)\n" if pp.ice_size_distribution == "Monodisperse" - ice_distr = Monodisperse{FT}() + ice_distr = Monodisperse() elseif pp.ice_size_distribution == "Gamma" - ice_distr = Gamma{FT}() + ice_distr = Gamma() else throw("Unrecognized size distribution") end @@ -253,7 +253,7 @@ function run_parcel(IC, t_0, t_end, pp) info *= "Aerosol Activation: $(pp.aerosol_act)\n" if pp.aerosol_act == "None" - aero_act_params = Empty{FT}() + aero_act_params = Empty() elseif pp.aerosol_act == "AeroAct" aero_act_params = AeroAct{FT}(pp.aap, pp.aerosol, pp.aero_σ_g, pp.r_nuc, pp.const_dt, pp.Nₐ) @@ -263,7 +263,7 @@ function run_parcel(IC, t_0, t_end, pp) info *= "Deposition: $(pp.deposition)\n" if pp.deposition == "None" - dep_params = Empty{FT}() + dep_params = Empty() elseif pp.deposition == "MohlerAF" dep_params = MohlerAF{FT}(pp.ips, pp.aerosol, pp.tps, pp.const_dt) elseif pp.deposition == "MohlerRate" @@ -278,7 +278,7 @@ function run_parcel(IC, t_0, t_end, pp) info *= "Heterogeneous: $(pp.heterogeneous)\n" if pp.heterogeneous == "None" - imm_params = Empty{FT}() + imm_params = Empty() elseif pp.heterogeneous == "ABIFM" imm_params = ABIFM{FT}(pp.tps, pp.aerosol, pp.A_aer, pp.const_dt) elseif pp.heterogeneous == "P3_het" @@ -296,7 +296,7 @@ function run_parcel(IC, t_0, t_end, pp) info *= "Homogeneous: $(pp.homogeneous)\n" if pp.homogeneous == "None" - hom_params = Empty{FT}() + hom_params = Empty() elseif pp.homogeneous == "ABHOM" hom_params = ABHOM{FT}(pp.tps, pp.ips, pp.const_dt) elseif pp.homogeneous == "P3_hom" @@ -307,7 +307,7 @@ function run_parcel(IC, t_0, t_end, pp) info *= "Condensation growth: $(pp.condensation_growth)\n" if pp.condensation_growth == "None" - ce_params = Empty{FT}() + ce_params = Empty() elseif pp.condensation_growth == "Condensation" ce_params = CondParams{FT}(pp.aps, pp.tps, pp.const_dt) elseif pp.condensation_growth == "NonEq_Condensation_simple" @@ -320,7 +320,7 @@ function run_parcel(IC, t_0, t_end, pp) info *= "Deposition growth: $(pp.deposition_growth)\n" if pp.deposition_growth == "None" - ds_params = Empty{FT}() + ds_params = Empty() elseif pp.deposition_growth == "Deposition" ds_params = DepParams{FT}(pp.aps, pp.tps, pp.const_dt) elseif pp.deposition_growth == "NonEq_Deposition_simple" diff --git a/parcel/ParcelParameters.jl b/parcel/ParcelParameters.jl index 9c6a11513..fb647affd 100644 --- a/parcel/ParcelParameters.jl +++ b/parcel/ParcelParameters.jl @@ -1,111 +1,111 @@ import CloudMicrophysics.Parameters as CMP import CloudMicrophysics.ThermodynamicsInterface.TD.Parameters as TDP -struct Empty{FT} <: CMP.ParametersType{FT} end +struct Empty <: CMP.ParametersType end -struct AeroAct{FT} <: CMP.ParametersType{FT} - aap::CMP.ParametersType{FT} - aerosol::CMP.AerosolType{FT} +struct AeroAct{FT} <: CMP.ParametersType + aap::CMP.ParametersType + aerosol::CMP.AerosolType aero_σ_g::FT r_nuc::FT const_dt::FT Nₐ::FT end -struct MohlerAF{FT} <: CMP.ParametersType{FT} - ips::CMP.ParametersType{FT} - aerosol::CMP.AerosolType{FT} +struct MohlerAF{FT} <: CMP.ParametersType + ips::CMP.ParametersType + aerosol::CMP.AerosolType tps::TDP.ThermodynamicsParameters{FT} const_dt::FT end -struct MohlerRate{FT} <: CMP.ParametersType{FT} - ips::CMP.ParametersType{FT} - aerosol::CMP.AerosolType{FT} +struct MohlerRate{FT} <: CMP.ParametersType + ips::CMP.ParametersType + aerosol::CMP.AerosolType tps::TDP.ThermodynamicsParameters{FT} const_dt::FT end -struct ABDINM{FT} <: CMP.ParametersType{FT} +struct ABDINM{FT} <: CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} - aerosol::CMP.AerosolType{FT} + aerosol::CMP.AerosolType r_nuc::FT const_dt::FT end -struct P3_dep{FT} <: CMP.ParametersType{FT} - ips::CMP.ParametersType{FT} +struct P3_dep{FT} <: CMP.ParametersType + ips::CMP.ParametersType const_dt::FT end -struct ABIFM{FT} <: CMP.ParametersType{FT} +struct ABIFM{FT} <: CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} - aerosol::CMP.AerosolType{FT} + aerosol::CMP.AerosolType A_aer::FT const_dt::FT end -struct P3_het{FT} <: CMP.ParametersType{FT} - ips::CMP.ParametersType{FT} +struct P3_het{FT} <: CMP.ParametersType + ips::CMP.ParametersType const_dt::FT end -struct Frostenberg_random{FT} <: CMP.ParametersType{FT} - ip::CMP.ParametersType{FT} +struct Frostenberg_random{FT} <: CMP.ParametersType + ip::CMP.ParametersType sampling_interval::FT const_dt::FT end -struct Frostenberg_stochastic{FT} <: CMP.ParametersType{FT} - ip::CMP.ParametersType{FT} +struct Frostenberg_stochastic{FT} <: CMP.ParametersType + ip::CMP.ParametersType γ::FT const_dt::FT end -struct Frostenberg_mean{FT} <: CMP.ParametersType{FT} - ip::CMP.ParametersType{FT} +struct Frostenberg_mean{FT} <: CMP.ParametersType + ip::CMP.ParametersType const_dt::FT end -struct ABHOM{FT} <: CMP.ParametersType{FT} +struct ABHOM{FT} <: CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} - ips::CMP.ParametersType{FT} + ips::CMP.ParametersType const_dt::FT end -struct P3_hom{FT} <: CMP.ParametersType{FT} +struct P3_hom{FT} <: CMP.ParametersType const_dt::FT end -struct CondParams{FT} <: CMP.ParametersType{FT} - aps::CMP.ParametersType{FT} +struct CondParams{FT} <: CMP.ParametersType + aps::CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} const_dt::FT end -struct NonEqCondParams_simple{FT} <: CMP.ParametersType{FT} +struct NonEqCondParams_simple{FT} <: CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} liquid::CMP.CloudLiquid{FT} end -struct NonEqCondParams{FT} <: CMP.ParametersType{FT} +struct NonEqCondParams{FT} <: CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} liquid::CMP.CloudLiquid{FT} dt::FT end -struct DepParams{FT} <: CMP.ParametersType{FT} - aps::CMP.ParametersType{FT} +struct DepParams{FT} <: CMP.ParametersType + aps::CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} const_dt::FT end -struct NonEqDepParams_simple{FT} <: CMP.ParametersType{FT} +struct NonEqDepParams_simple{FT} <: CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} ice::CMP.CloudIce{FT} end -struct NonEqDepParams{FT} <: CMP.ParametersType{FT} +struct NonEqDepParams{FT} <: CMP.ParametersType tps::TDP.ThermodynamicsParameters{FT} ice::CMP.CloudIce{FT} dt::FT diff --git a/src/BulkMicrophysicsTendencies.jl b/src/BulkMicrophysicsTendencies.jl index 6f632c765..1645c4f34 100644 --- a/src/BulkMicrophysicsTendencies.jl +++ b/src/BulkMicrophysicsTendencies.jl @@ -510,7 +510,7 @@ derivatives; snow and cloud formation derivatives are zero for now. """ @inline function bulk_microphysics_derivatives( ::Microphysics2Moment, - mp::CMP.Microphysics2MParams{FT, WR, ICE}, + mp::CMP.Microphysics2MParams{WR, ICE}, tps, ρ, T, @@ -521,7 +521,7 @@ derivatives; snow and cloud formation derivatives are zero for now. q_sno, n_lcl, n_rai, -) where {FT, WR, ICE} +) where {WR, ICE} ρ = UT.clamp_to_nonneg(ρ) q_tot = UT.clamp_to_nonneg(q_tot) q_lcl = UT.clamp_to_nonneg(q_lcl) @@ -688,7 +688,7 @@ end """ bulk_microphysics_tendencies( ::Microphysics2Moment, - mp::Microphysics2MParams{FT, WR, Nothing}, + mp::Microphysics2MParams{WR, Nothing}, ... ) @@ -720,7 +720,7 @@ For warm rain + P3 ice, see the method that accepts `Microphysics2MParams{FT, WR """ @inline function bulk_microphysics_tendencies( ::Microphysics2Moment, - mp::CMP.Microphysics2MParams{FT, WR, Nothing}, + mp::CMP.Microphysics2MParams{WR, Nothing}, tps, ρ, T, @@ -734,7 +734,7 @@ For warm rain + P3 ice, see the method that accepts `Microphysics2MParams{FT, WR q_rim = zero(ρ), b_rim = zero(ρ), logλ = zero(ρ), -) where {FT, WR} +) where {WR} # Clamp negative inputs to zero (robustness against numerical errors) ρ = UT.clamp_to_nonneg(ρ) q_tot = UT.clamp_to_nonneg(q_tot) @@ -829,7 +829,7 @@ to be non-Nothing, eliminating runtime type checks and dynamic dispatch. """ @inline function bulk_microphysics_tendencies( ::Microphysics2Moment, - mp::CMP.Microphysics2MParams{FT, WR, ICE}, + mp::CMP.Microphysics2MParams{WR, ICE}, tps, ρ, T, @@ -843,7 +843,7 @@ to be non-Nothing, eliminating runtime type checks and dynamic dispatch. q_rim = zero(ρ), b_rim = zero(ρ), logλ = zero(ρ), -) where {FT, WR, ICE <: CMP.P3IceParams} +) where {WR, ICE <: CMP.P3IceParams} # Clamp negative inputs to zero (robustness against numerical errors) ρ = UT.clamp_to_nonneg(ρ) q_tot = UT.clamp_to_nonneg(q_tot) diff --git a/src/CloudDiagnostics.jl b/src/CloudDiagnostics.jl index 06d454f61..57ccfa80d 100644 --- a/src/CloudDiagnostics.jl +++ b/src/CloudDiagnostics.jl @@ -60,10 +60,8 @@ based on the assumed cloud and rain particle size distribuions. Normalized by the reflectivty of 1 millimiter drop in a volume of 1m3. The values are clipped at -150 dBZ. """ -function radar_reflectivity_2M( - (; pdf_c, pdf_r)::CMP.SB2006{FT}, - q_lcl, q_rai, N_lcl, N_rai, ρ_air, -) where {FT} +function radar_reflectivity_2M((; pdf_c, pdf_r)::CMP.SB2006, q_lcl, q_rai, N_lcl, N_rai, ρ_air) + FT = eltype(q_lcl) # free parameters (; νc, μc) = pdf_c (; νr, μr, ρw) = pdf_r @@ -98,10 +96,8 @@ end Returns effective radius for the 2-moment microphysics scheme. Computed based on the assumed cloud and rain particle size distributions. """ -function effective_radius_2M( - (; pdf_c, pdf_r)::CMP.SB2006{FT}, - q_lcl, q_rai, N_lcl, N_rai, ρ_air, -) where {FT} +function effective_radius_2M((; pdf_c, pdf_r)::CMP.SB2006, q_lcl, q_rai, N_lcl, N_rai, ρ_air) + FT = eltype(q_lcl) # free parameters (; νc, μc) = pdf_c (; νr, μr, ρw) = pdf_r diff --git a/src/CloudMicrophysics.jl b/src/CloudMicrophysics.jl index 0c8e8ada1..3c4e79aef 100644 --- a/src/CloudMicrophysics.jl +++ b/src/CloudMicrophysics.jl @@ -1,5 +1,7 @@ module CloudMicrophysics +include("show.jl") + include("parameters/Parameters.jl") import .Parameters const CMP = Parameters diff --git a/src/Microphysics1M.jl b/src/Microphysics1M.jl index 26c929a46..8a15af274 100644 --- a/src/Microphysics1M.jl +++ b/src/Microphysics1M.jl @@ -431,8 +431,8 @@ with cloud water (liquid or ice). - `ρ`: air density """ @inline function accretion( - cloud::CMP.CloudCondensateType{FT}, - precip::CMP.PrecipitationType{FT}, + cloud::CMP.CloudCondensateType, + precip::CMP.PrecipitationType, vel::Union{CMP.Blk1MVelTypeRain{FT}, CMP.Blk1MVelTypeSnow{FT}}, ce::CMP.CollisionEff, q_clo::FT, @@ -529,8 +529,8 @@ deviations are proportional to the mean fall velocities, with coefficient - `ρ`: air density [kg/m³] """ @inline function accretion_snow_rain( - type_i::CMP.PrecipitationType{FT}, - type_j::CMP.PrecipitationType{FT}, + type_i::CMP.PrecipitationType, + type_j::CMP.PrecipitationType, blk1mveltype_ti::Union{CMP.Blk1MVelTypeRain{FT}, CMP.Blk1MVelTypeSnow{FT}}, blk1mveltype_tj::Union{CMP.Blk1MVelTypeRain{FT}, CMP.Blk1MVelTypeSnow{FT}}, ce::CMP.CollisionEff, diff --git a/src/Microphysics2M.jl b/src/Microphysics2M.jl index cf4ad8006..3dc75ef2b 100644 --- a/src/Microphysics2M.jl +++ b/src/Microphysics2M.jl @@ -207,7 +207,7 @@ where - `(logN₀c, λc, νcD, μcD)`: Parameters of the generalized gamma distribution in terms of diameter """ function pdf_cloud_parameters(pdf_c, q, ρₐ, N) - FT = eltype(pdf_c) + FT = eltype(q) logAc, logBc = log_pdf_cloud_parameters_mass(pdf_c, q, ρₐ, N) (; νc, μc, ρw) = pdf_c k_m = ρw * π / 6 @@ -308,9 +308,9 @@ the size distribution is within (1 - p) to (p) probability of the true size dist The bounds are calculated through quantile functions of the size distribution. """ function get_size_distribution_bounds( - pdf::CMP.RainParticlePDF_SB2006{FT}, - q, ρₐ, N, p = eps(FT), -) where {FT} + pdf::CMP.RainParticlePDF_SB2006, q, ρₐ, N, p = eps(eltype(q)), +) + FT = eltype(q) (; Dr_mean) = pdf_rain_parameters(pdf, q, ρₐ, N) iszero(Dr_mean) && return (FT(0), FT(0)) D_min = DT.exponential_quantile(Dr_mean, p) @@ -318,9 +318,8 @@ function get_size_distribution_bounds( return D_min, D_max end function get_size_distribution_bounds( - pdf::CMP.CloudParticlePDF_SB2006{FT}, - q, ρₐ, N, p = eps(FT), -) where {FT} + pdf::CMP.CloudParticlePDF_SB2006, q, ρₐ, N, p = eps(eltype(q)), +) (; λc, νcD, μcD) = pdf_cloud_parameters(pdf, q, ρₐ, N) D_min = DT.generalized_gamma_quantile(νcD, μcD, λc, p) @@ -337,7 +336,7 @@ end A structure containing the rates of change of the specific contents and number densities of cloud liquid water and rain water. """ -Base.@kwdef struct LclRaiRates{FT} +@kwdef struct LclRaiRates{FT} "Rate of change of the cloud liquid water specific content" dq_lcl_dt::FT = FT(0) "Rate of change of the cloud liquid water number density" @@ -366,10 +365,9 @@ Compute autoconversion rates collisions between cloud droplets (autoconversion) """ function autoconversion( - acnv::CMP.AcnvSB2006{FT}, pdf_c::CMP.CloudParticlePDF_SB2006{FT}, - q_lcl, q_rai, ρ, N_lcl, -) where {FT} - + acnv::CMP.AcnvSB2006, pdf_c::CMP.CloudParticlePDF_SB2006, q_lcl, q_rai, ρ, N_lcl, +) + FT = eltype(q_lcl) if q_lcl < UT.ϵ_numerics_2M_M(FT) || N_lcl < UT.ϵ_numerics_2M_N(FT) return LclRaiRates{FT}() end @@ -379,7 +377,7 @@ function autoconversion( L_lcl = ρ * q_lcl x_lcl = min(x_star, L_lcl / N_lcl) - q_rai = max(FT(0), q_rai) + q_rai = max(0, q_rai) τ = 1 - q_lcl / (q_lcl + q_rai) # Eq. (5) from SB2006 ϕ_au = A * τ^a * (1 - τ^a)^b @@ -414,8 +412,9 @@ Compute accretion rate - [`LclRaiRates`](@ref) with `q_lcl`, `N_lcl`, `q_rai`, `N_rai` tendencies due to collisions between raindrops and cloud droplets (accretion) """ -function accretion((; accr)::CMP.SB2006{FT}, q_lcl, q_rai, ρ, N_lcl) where {FT} +function accretion((; accr)::CMP.SB2006, q_lcl, q_rai, ρ, N_lcl) + FT = eltype(q_lcl) if q_lcl < UT.ϵ_numerics_2M_M(FT) || q_rai < UT.ϵ_numerics_2M_M(FT) || N_lcl < UT.ϵ_numerics_2M_N(FT) return LclRaiRates{FT}() end @@ -457,10 +456,9 @@ Compute cloud liquid self-collection rate that produce larger cloud droplets (self-collection) """ function cloud_liquid_self_collection( - acnv::CMP.AcnvSB2006{FT}, pdf_c::CMP.CloudParticlePDF_SB2006{FT}, - q_lcl, ρ, dN_lcl_dt_au, -) where {FT} - + acnv::CMP.AcnvSB2006, pdf_c::CMP.CloudParticlePDF_SB2006, q_lcl, ρ, dN_lcl_dt_au, +) + FT = eltype(q_lcl) if q_lcl < UT.ϵ_numerics_2M_M(FT) return FT(0) end @@ -492,9 +490,8 @@ Compute autoconversion and cloud liquid self-collection rates cloud liquid self-collection rate. """ function autoconversion_and_cloud_liquid_self_collection( - (; acnv, pdf_c)::CMP.SB2006{FT}, - q_lcl, q_rai, ρ, N_lcl, -) where {FT} + (; acnv, pdf_c)::CMP.SB2006, q_lcl, q_rai, ρ, N_lcl, +) au = autoconversion(acnv, pdf_c, q_lcl, q_rai, ρ, N_lcl) sc = cloud_liquid_self_collection(acnv, pdf_c, q_lcl, ρ, au.dN_lcl_dt) @@ -519,9 +516,9 @@ Compute the rain self-collection rate produce larger raindrops (self-collection). """ function rain_self_collection( - pdf::CMP.RainParticlePDF_SB2006{FT}, self::CMP.SelfColSB2006{FT}, - q_rai, ρ, N_rai, -) where {FT} + pdf::CMP.RainParticlePDF_SB2006, self::CMP.SelfColSB2006, q_rai, ρ, N_rai, +) + FT = eltype(q_rai) if q_rai < UT.ϵ_numerics_2M_M(FT) || N_rai < UT.ϵ_numerics_2M_N(FT) return FT(0) @@ -555,9 +552,9 @@ Compute the raindrops number density tendency due to breakup of raindrops smaller raindrops """ function rain_breakup( - pdf::CMP.RainParticlePDF_SB2006{FT}, brek::CMP.BreakupSB2006{FT}, - q_rai, ρ, N_rai, dN_rai_dt_sc, -) where {FT} + pdf::CMP.RainParticlePDF_SB2006, brek::CMP.BreakupSB2006, q_rai, ρ, N_rai, dN_rai_dt_sc, +) + FT = eltype(q_rai) if q_rai < UT.ϵ_numerics_2M_M(FT) || N_rai < UT.ϵ_numerics_2M_N(FT) return FT(0) @@ -624,10 +621,11 @@ Individual droplet terminal velocities follow v_{term}(D) = (1/18) (ρw - ρₐ) μ_air = ρₐ * ν_air and assuming constant ν_air. """ function cloud_terminal_velocity( - pdf_c::CMP.CloudParticlePDF_SB2006{FT}, - (; ρw, grav, ν_air)::CMP.StokesRegimeVelType{FT}, + pdf_c::CMP.CloudParticlePDF_SB2006, + (; ρw, grav, ν_air)::CMP.StokesRegimeVelType, q_liq, ρₐ, N_liq, -) where {FT} +) + FT = eltype(q_liq) if N_liq < UT.ϵ_numerics_2M_N(FT) || q_liq < UT.ϵ_numerics_2M_M(FT) return (FT(0), FT(0)) @@ -668,9 +666,9 @@ Fall velocity of individual rain drops is parameterized: - following Chen et. al 2022, DOI: 10.1016/j.atmosres.2022.106171 for `velo_scheme == Chen2022Type` """ function rain_terminal_velocity( - (; pdf_r)::CMP.SB2006{FT}, (; ρ0, aR, bR, cR)::CMP.SB2006VelType{FT}, - q_rai, ρ, N_rai, -) where {FT} + (; pdf_r)::CMP.SB2006, (; ρ0, aR, bR, cR)::CMP.SB2006VelType, q_rai, ρ, N_rai, +) + FT = eltype(q_rai) # TODO: Input argument list needs to be redesigned (; Dr_mean) = pdf_rain_parameters(pdf_r, q_rai, ρ, N_rai) @@ -679,16 +677,16 @@ function rain_terminal_velocity( vt0 = N_rai < UT.ϵ_numerics_2M_N(FT) ? FT(0) : - max(FT(0), sqrt(ρ0 / ρ) * (aR * _pa0 - bR * _pb0 / (1 + cR * Dr_mean))) + max(0, sqrt(ρ0 / ρ) * (aR * _pa0 - bR * _pb0 / (1 + cR * Dr_mean))) vt1 = q_rai < UT.ϵ_numerics_2M_M(FT) ? FT(0) : - max(FT(0), sqrt(ρ0 / ρ) * (aR * _pa1 - bR * _pb1 / (1 + cR * Dr_mean)^4)) + max(0, sqrt(ρ0 / ρ) * (aR * _pa1 - bR * _pb1 / (1 + cR * Dr_mean)^4)) return (vt0, vt1) end function rain_terminal_velocity( - (; pdf_r)::CMP.SB2006{FT}, vel::CMP.Chen2022VelTypeRain{FT}, - q_rai, ρ, N_rai, -) where {FT} + (; pdf_r)::CMP.SB2006, vel::CMP.Chen2022VelTypeRain, q_rai, ρ, N_rai, +) + FT = eltype(q_rai) # coefficients from Table B1 from Chen et. al. 2022 aiu, bi, ciu = CO.Chen2022_vel_coeffs(vel, ρ) # size distribution parameter @@ -698,28 +696,29 @@ function rain_terminal_velocity( vt0 = sum(CO.Chen2022_exponential_pdf.(aiu, bi, ciu, Dr_mean, 0)) vt3 = sum(CO.Chen2022_exponential_pdf.(aiu, bi, ciu, Dr_mean, 3)) - vt0 = N_rai < UT.ϵ_numerics_2M_N(FT) ? FT(0) : max(FT(0), vt0) - vt3 = q_rai < UT.ϵ_numerics_2M_M(FT) ? FT(0) : max(FT(0), vt3) + vt0 = N_rai < UT.ϵ_numerics_2M_N(FT) ? FT(0) : max(0, vt0) + vt3 = q_rai < UT.ϵ_numerics_2M_M(FT) ? FT(0) : max(0, vt3) # It should be (ϕ^κ * vt0, ϕ^κ * vt3), but for rain drops ϕ = 1 and κ = 0 return (vt0, vt3) end function _sb_rain_terminal_velocity_helper( - pdf_r::CMP.RainParticlePDF_SB2006_limited{FT}, λr, aR, bR, cR, -) where {FT} + ::CMP.RainParticlePDF_SB2006_limited, λr, aR, bR, cR, +) + FT = eltype(λr) return (FT(1), FT(1), FT(1), FT(1)) end function _sb_rain_terminal_velocity_helper( - pdf_r::CMP.RainParticlePDF_SB2006_notlimited{FT}, λr, aR, bR, cR, -) where {FT} + ::CMP.RainParticlePDF_SB2006_notlimited, λr, aR, bR, cR, +) # Integrate velocity of particles over a range of r with # positive terminal velocity (v = aR - bR exp(-lambda D)) _rc = -1 / (2 * cR) * log(aR / bR) _Γ_1(t) = exp(-t) _Γ_4(t) = (t^3 + 3 * t^2 + 6 * t + 6) * exp(-t) - _pa0::FT = _Γ_1(2 * _rc * λr) - _pb0::FT = _Γ_1(2 * _rc * (λr + cR)) - _pa1::FT = _Γ_4(2 * _rc * λr) / 6 - _pb1::FT = _Γ_4(2 * _rc * (λr + cR)) / 6 + _pa0 = _Γ_1(2 * _rc * λr) + _pb0 = _Γ_1(2 * _rc * (λr + cR)) + _pa1 = _Γ_4(2 * _rc * λr) / 6 + _pb1 = _Γ_4(2 * _rc * (λr + cR)) / 6 return (_pa0, _pb0, _pa1, _pb1) end @@ -753,11 +752,11 @@ specific content due to rain rain_evaporation, assuming a power law velocity rel fall velocity of individual drops and an exponential size distribution, for `scheme == SB2006Type` """ function rain_evaporation( - (; pdf_r, evap)::CMP.SB2006{FT}, aps::CMP.AirProperties, - tps::TDI.PS, + (; pdf_r, evap)::CMP.SB2006, aps::CMP.AirProperties, tps::TDI.PS, q_tot, q_lcl, q_icl, q_rai, q_sno, ρ, N_rai, T, -) where {FT} +) + FT = eltype(q_tot) evap_rate_0 = FT(0) evap_rate_1 = FT(0) S = TDI.supersaturation_over_liquid(tps, q_tot, q_lcl + q_rai, q_icl + q_sno, ρ, T) @@ -812,18 +811,10 @@ Uses the same approximation pattern as `NamedTuple` with fields `(; ∂tendency_∂N_rai, ∂tendnecy_∂q_rai)`. """ @inline function ∂rain_evaporation_∂N_rai_∂q_rai( - sb::CMP.SB2006{FT}, - aps::CMP.AirProperties, - tps::TDI.PS, - q_tot, - q_lcl, - q_icl, - q_rai, - q_sno, - ρ, - N_rai, - T, -) where {FT} + sb::CMP.SB2006, aps::CMP.AirProperties, tps::TDI.PS, + q_tot, q_lcl, q_icl, q_rai, q_sno, ρ, N_rai, T, +) + FT = eltype(q_tot) result = rain_evaporation(sb, aps, tps, q_tot, q_lcl, q_icl, q_rai, q_sno, ρ, N_rai, T) ∂N_rai = N_rai > UT.ϵ_numerics_2M_N(FT) ? result.evap_rate_0 / N_rai : zero(result.evap_rate_0) ∂q_rai = q_rai > UT.ϵ_numerics_2M_M(FT) ? result.evap_rate_1 / q_rai : zero(result.evap_rate_1) @@ -848,11 +839,8 @@ The method is based on Horn (2012, DOI: [10.5194/gmd-5-345-2012](https://doi.org # Returns - The rate of change of number concentration [1/(m³·s)] needed to bring the mean mass within the upper bound. """ -function number_increase_for_mass_limit( - (; τ)::CMP.NumberAdjustmentHorn2012{FT}, x_max, q, ρ, N, -) where {FT} - return max(FT(0), ρ * q / x_max - N) / τ -end +number_increase_for_mass_limit((; τ)::CMP.NumberAdjustmentHorn2012, x_max, q, ρ, N) = + max(0, ρ * q / x_max - N) / τ """ number_decrease_for_mass_limit(numadj, x_min, q, ρ, N) @@ -872,14 +860,10 @@ The method is based on Horn (2012, DOI: [10.5194/gmd-5-345-2012](https://doi.org # Returns - The rate of change of number concentration [1/(m³·s)] needed to bring the mean mass within the lower bound. """ -function number_decrease_for_mass_limit( - (; τ)::CMP.NumberAdjustmentHorn2012{FT}, x_min, q, ρ, N, -) where {FT} - - # Avoid NaN when both q and x_min are 0; use typed Inf to avoid type promotion - N_max = iszero(x_min) ? FT(Inf) : ρ * q / x_min - - return min(FT(0), N_max - N) / τ +function number_decrease_for_mass_limit((; τ)::CMP.NumberAdjustmentHorn2012, x_min, q, ρ, N) + # Avoid NaN when both q and x_min are 0 + N_max = iszero(x_min) ? oftype(q, Inf) : ρ * q / x_min + return min(0, N_max - N) / τ end # Additional double moment autoconversion and accretion parametrizations: @@ -909,66 +893,48 @@ additionally accept `smooth_transition` flag that smoothes their thershold behaviour if set to `true`. The default value is `false`. """ -function conv_q_lcl_to_q_rai((; acnv)::CMP.KK2000{FT}, q_lcl, ρ, N_d) where {FT} +function conv_q_lcl_to_q_rai((; acnv)::CMP.KK2000, q_lcl, ρ, N_d) q_lcl = max(0, q_lcl) (; A, a, b, c) = acnv return A * q_lcl^a * N_d^b * ρ^c end -function conv_q_lcl_to_q_rai( - (; acnv)::CMP.B1994{FT}, - q_lcl, - ρ, - N_d, - smooth_transition = false, -) where {FT} +function conv_q_lcl_to_q_rai((; acnv)::CMP.B1994, q_lcl, ρ, N_d, smooth_transition = false) q_lcl = max(0, q_lcl) (; C, a, b, c, N_0, k, d_low, d_high) = acnv - d = FT(0) + d = zero(q_lcl) if smooth_transition d_low_acnv_fraction = CO.logistic_function(N_d, N_0, k) - d_high_acnv_fraction = FT(1) - d_low_acnv_fraction + d_high_acnv_fraction = 1 - d_low_acnv_fraction d = d_low_acnv_fraction * d_low + d_high_acnv_fraction * d_high else d = N_d >= N_0 ? d_low : d_high end return C * d^a * (q_lcl * ρ)^b * N_d^c / ρ end -function conv_q_lcl_to_q_rai( - (; acnv)::CMP.TC1980{FT}, - q_lcl, - ρ, - N_d, - smooth_transition = false, -) where {FT} +function conv_q_lcl_to_q_rai((; acnv)::CMP.TC1980, q_lcl, ρ, N_d, smooth_transition = false) #TODO - The original paper is actually formulated for mixing ratios, not specific contents q_lcl = max(0, q_lcl) (; m0_liq_coeff, me_liq, D, a, b, r_0, k) = acnv - q_liq_threshold::FT = m0_liq_coeff * N_d / ρ * r_0^me_liq + q_liq_threshold = m0_liq_coeff * N_d / ρ * r_0^me_liq output = smooth_transition ? CO.logistic_function(q_lcl, q_liq_threshold, k) : CO.heaviside(q_lcl - q_liq_threshold) return D * q_lcl^a * N_d^b * output end function conv_q_lcl_to_q_rai( - (; ρ_w, R_6C_0, E_0, k)::CMP.LD2004{FT}, - q_lcl, - ρ, - N_d, - smooth_transition = false, -) where {FT} - if q_lcl <= UT.ϵ_numerics_2M_M(FT) - return FT(0) + (; ρ_w, R_6C_0, E_0, k)::CMP.LD2004, q_lcl, ρ, N_d, smooth_transition = false, +) + if q_lcl <= UT.ϵ_numerics_2M_M(eltype(q_lcl)) + return zero(q_lcl) else # Mean volume radius in microns (assuming spherical cloud droplets) - r_vol = - (FT(3) * (q_lcl * ρ) / FT(4) / FT(π) / ρ_w / N_d)^FT(1 / 3) * - FT(1e6) + r_vol = cbrt(3 * q_lcl * ρ / 4 / π / ρ_w / N_d) * 1_000_000 # Assumed size distribution: modified gamma distribution - β_6 = ((r_vol + FT(3)) / r_vol)^FT(1 / 3) + β_6 = cbrt((r_vol + 3) / r_vol) E = E_0 * β_6^6 R_6 = β_6 * r_vol - R_6C = R_6C_0 / (q_lcl * ρ)^FT(1 / 6) / R_6^FT(1 / 2) + R_6C = R_6C_0 / cbrt(sqrt(q_lcl * ρ)) / sqrt(R_6) # cbrt(sqrt(x)) = x^(1/6) output = smooth_transition ? CO.logistic_function(R_6, R_6C, k) : @@ -976,14 +942,8 @@ function conv_q_lcl_to_q_rai( return E * (q_lcl * ρ)^3 / N_d / ρ * output end end -function conv_q_lcl_to_q_rai( - (; τ, α)::CMP.VarTimescaleAcnv{FT}, - q_lcl::FT, - ρ::FT, - N_d::FT, -) where {FT} - return max(0, q_lcl) / (τ * (N_d / 1e8)^α) -end +conv_q_lcl_to_q_rai((; τ, α)::CMP.VarTimescaleAcnv, q_lcl, ρ, N_d) = + max(0, q_lcl) / (τ * (N_d / 100_000_000)^α) """ accretion(accretion_scheme, q_lcl, q_rai, ρ) @@ -998,21 +958,21 @@ end - Beheng (1994) for `scheme == B1994Type` - Tripoli and Cotton (1980) for `scheme == TC1980Type` """ -function accretion((; accr)::CMP.KK2000{FT}, q_lcl, q_rai, ρ) where {FT} +function accretion((; accr)::CMP.KK2000, q_lcl, q_rai, ρ) q_lcl = max(0, q_lcl) q_rai = max(0, q_rai) (; A, a, b) = accr return A * (q_lcl * q_rai)^a * ρ^b end -function accretion((; accr)::CMP.B1994{FT}, q_lcl, q_rai, ρ) where {FT} +function accretion((; accr)::CMP.B1994, q_lcl, q_rai, ρ) q_lcl = max(0, q_lcl) q_rai = max(0, q_rai) (; A) = accr return A * q_lcl * ρ * q_rai end -function accretion((; accr)::CMP.TC1980{FT}, q_lcl, q_rai) where {FT} +function accretion((; accr)::CMP.TC1980, q_lcl, q_rai) #TODO - The original paper is actually formulated for mixing ratios, not specific contents q_lcl = max(0, q_lcl) q_rai = max(0, q_rai) diff --git a/src/P3.jl b/src/P3.jl index 77f84068f..1e1c76555 100644 --- a/src/P3.jl +++ b/src/P3.jl @@ -20,6 +20,7 @@ import CloudMicrophysics.Common as CO import CloudMicrophysics.DistributionTools as DT import CloudMicrophysics.HetIceNucleation as CM_HetIce import CloudMicrophysics.Microphysics2M as CM2 +import CloudMicrophysics: ShowMethods include("P3_particle_properties.jl") include("P3_size_distribution.jl") diff --git a/src/P3_particle_properties.jl b/src/P3_particle_properties.jl index 6f13f9a4e..dccb1abd3 100644 --- a/src/P3_particle_properties.jl +++ b/src/P3_particle_properties.jl @@ -25,6 +25,9 @@ $(FIELDS) "Rime density" ρ_rim::FT end +Base.show(io::IO, mime::MIME"text/plain", x::P3State) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) +ShowMethods.field_units(::P3State) = (; L_ice = "kg/m³", N_ice = "1/m³", ρ_rim = "kg/m³") """ get_state(params; L_ice, N_ice, F_rim, ρ_rim) @@ -51,10 +54,21 @@ Create a [`P3State`](@ref) from [`CMP.ParametersP3`](@ref) and rime state parame julia> params = CMP.ParametersP3(FT); julia> state = P3.get_state(params; F_rim = FT(0.5), ρ_rim = FT(916.7)) - P3State{Float32} - ├── params = {MassPowerLaw, AreaPowerLaw, SlopePowerLaw, VentilationFactor} - ├── F_rim = 0.5 [-] - └── ρ_rim = 916.7 [kg/m^3] + P3State + ├─ params: ParametersP3 + │ ├─ mass: MassPowerLaw(α_va = 0.018537706f0 [kg m^(-β_va)], β_va = 1.9f0 [-]) + │ ├─ area: AreaPowerLaw(γ = 0.2285f0 [μm^(2-σ)], σ = 1.88f0 [-]) + │ ├─ slope: SlopePowerLaw(a = 0.00191f0 [m^b], b = 0.8f0 [-], c = 2.0f0 [-], μ_max = 6.0f0 [-]) + │ ├─ vent: VentilationFactor(aᵥ = 0.78f0 [-], bᵥ = 0.308f0 [-]) + │ ├─ ρ_rim_local: LocalRimeDensity(a = 51.0f0 [-], b = 114.0f0 [-], c = -5.5f0 [-], ρ_ice = 916.7f0 [kg m⁻³]) + │ ├─ τ_wet = 100.0 [s] + │ ├─ ρ_i = 916.7 [kg m⁻³] + │ ├─ ρ_l = 1000.0 [kg m⁻³] + │ └─ T_freeze = 273.15 [K] + ├─ L_ice = 0.3 + ├─ N_ice = 1.0e6 + ├─ F_rim = 0.5 + └─ ρ_rim = 916.7 ``` """ function get_state(params::CMP.ParametersP3; L_ice, N_ice, F_rim, ρ_rim) @@ -408,19 +422,3 @@ function ϕᵢ(params::CMP.ParametersP3, F_rim, ρ_rim, D) return ifelse(D == 0, FT(0), ϕ_ob) end - -### ----------------- ### -### ----- UTILS ----- ### -### ----------------- ### - -function Base.show(io::IO, state::P3State) - FT = eltype(state) - _name(state, field) = typeof(getfield(state.params, field)).name.name - param_types = join(_name.(state, (:mass, :area, :slope, :vent)), ", ") - println(io, "P3State{$FT}") - println(io, "├── params = {$param_types}") - println(io, "├── L_ice = $(state.L_ice) [kg/m³]") - println(io, "├── N_ice = $(state.N_ice) [1/m³]") - println(io, "├── F_rim = $(state.F_rim) [-]") - println(io, "└── ρ_rim = $(state.ρ_rim) [kg/m³]") -end diff --git a/src/PrecipitationSusceptibility.jl b/src/PrecipitationSusceptibility.jl index 18f85eb28..4464ccf92 100644 --- a/src/PrecipitationSusceptibility.jl +++ b/src/PrecipitationSusceptibility.jl @@ -13,7 +13,7 @@ A structure containing the logarithmic derivatives of the production of precipitation with respect to the specific contents and number densities of cloud liquid water and rain water. """ -Base.@kwdef struct precip_susceptibility_rates{FT} +@kwdef struct precip_susceptibility_rates{FT} d_ln_pp_d_ln_q_lcl::FT = FT(0) d_ln_pp_d_ln_q_rai::FT = FT(0) d_ln_pp_d_ln_N_lcl::FT = FT(0) @@ -34,12 +34,8 @@ object, using automatic differentiation. Works for any 2-moment scheme, as long as autoconversion is defined for it. """ function precipitation_susceptibility_autoconversion( - scheme::CMP.SB2006{FT}, - q_lcl::FT, - q_rai::FT, - ρ::FT, - N_lcl::FT, -) where {FT} + scheme::CMP.SB2006, q_lcl, q_rai, ρ, N_lcl, +) grad = ForwardDiff.gradient( x -> log( CM2.autoconversion(scheme.acnv, scheme.pdf_c, exp.(x)...).dq_rai_dt, @@ -50,7 +46,7 @@ function precipitation_susceptibility_autoconversion( d_ln_pp_d_ln_q_lcl = grad[1], d_ln_pp_d_ln_q_rai = grad[2], d_ln_pp_d_ln_N_lcl = grad[4], - d_ln_pp_d_ln_N_rai = FT(0), + d_ln_pp_d_ln_N_rai = zero(q_lcl), ) end @@ -68,13 +64,8 @@ object, using automatic differentiation. Works for any 2-moment scheme, as long as accretion is defined for it. """ function precipitation_susceptibility_accretion( - scheme::CMP.SB2006{FT}, - q_lcl::FT, - q_rai::FT, - ρ::FT, - N_lcl::FT, -) where {FT} - + scheme::CMP.SB2006, q_lcl, q_rai, ρ, N_lcl, +) grad = ForwardDiff.gradient( x -> log(CM2.accretion(scheme, exp.(x)...).dq_rai_dt), log.(abs.([q_lcl, q_rai, ρ, N_lcl])), @@ -83,7 +74,7 @@ function precipitation_susceptibility_accretion( d_ln_pp_d_ln_q_lcl = grad[1], d_ln_pp_d_ln_q_rai = grad[2], d_ln_pp_d_ln_N_lcl = grad[4], - d_ln_pp_d_ln_N_rai = FT(0), + d_ln_pp_d_ln_N_rai = zero(q_lcl), ) end diff --git a/src/parameters/AbstractTypes.jl b/src/parameters/AbstractTypes.jl index fea0e9c41..f1ec840ed 100644 --- a/src/parameters/AbstractTypes.jl +++ b/src/parameters/AbstractTypes.jl @@ -1,18 +1,25 @@ """ - ParametersType{FT} + ParametersType The top-level super-type for all cloud microphysics parameters """ -abstract type ParametersType{FT} end -Base.eltype(::ParametersType{FT}) where {FT} = FT +abstract type ParametersType end + + +# Temporary fallback until we stop checking eltype from the parameters +Base.eltype(p::ParametersType) = fieldcount(typeof(p)) > 0 ? eltype(getfield(p, 1)) : Any Base.broadcastable(x::ParametersType) = tuple(x) +Base.show(io::IO, x::ParametersType) = + ShowMethods.parseable_show_with_fields_no_type_header(io, x; with_module_prefix = false) +Base.show(io::IO, mime::MIME"text/plain", x::ParametersType) = + ShowMethods.show_type_and_fields(io, mime, x) """ - AerosolType{FT} + AerosolType The top-level super-type for all aerosol properties """ -abstract type AerosolType{FT} <: ParametersType{FT} end +abstract type AerosolType <: ParametersType end """ AerosolDistributionType @@ -22,29 +29,29 @@ The top-level super-type for all aerosol distribution types abstract type AerosolDistributionType end """ - CloudCondensateType{FT} + CloudCondensateType The top-level super-type for cloud condensate types (liquid and ice) """ -abstract type CloudCondensateType{FT} <: ParametersType{FT} end +abstract type CloudCondensateType <: ParametersType end """ - PrecipitationType{FT} + PrecipitationType The top-level super-type for precipitation types (rain and snow) """ -abstract type PrecipitationType{FT} <: ParametersType{FT} end +abstract type PrecipitationType <: ParametersType end """ - TerminalVelocityType{FT} + TerminalVelocityType The top-level super-type for terminal velocity parameterizations """ -abstract type TerminalVelocityType{FT} <: ParametersType{FT} end +abstract type TerminalVelocityType <: ParametersType end """ Precipitation2MType The top-level super-type for 2-moment precipitation parameterizations """ -abstract type Precipitation2MType{FT} <: ParametersType{FT} end +abstract type Precipitation2MType <: ParametersType end diff --git a/src/parameters/AerosolATD.jl b/src/parameters/AerosolATD.jl index d0c1e59c6..ac1e243cb 100644 --- a/src/parameters/AerosolATD.jl +++ b/src/parameters/AerosolATD.jl @@ -9,7 +9,7 @@ Mohler et al, 2006. DOI: 10.5194/acp-6-3007-2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct ArizonaTestDust{FT} <: AerosolType{FT} +@kwdef struct ArizonaTestDust{FT} <: AerosolType "S₀ for T > T_thr [-]" S₀_warm::FT "S₀ for T < T_thr [-]" @@ -28,9 +28,6 @@ Base.@kwdef struct ArizonaTestDust{FT} <: AerosolType{FT} ABIFM_c::FT end -ArizonaTestDust(::Type{FT}) where {FT <: AbstractFloat} = - ArizonaTestDust(CP.create_toml_dict(FT)) - function ArizonaTestDust(td::CP.ParamDict) name_map = (; :Mohler2006_S0_warm_ArizonaTestDust => :S₀_warm, @@ -43,6 +40,5 @@ function ArizonaTestDust(td::CP.ParamDict) :J_ABIFM_c_ArizonaTestDust => :ABIFM_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return ArizonaTestDust{FT}(; parameters...) + return ArizonaTestDust(; parameters...) end diff --git a/src/parameters/AerosolActivation.jl b/src/parameters/AerosolActivation.jl index f044425a2..c43184038 100644 --- a/src/parameters/AerosolActivation.jl +++ b/src/parameters/AerosolActivation.jl @@ -9,7 +9,7 @@ DOI: 10.1029/1999JD901161 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AerosolActivationParameters{FT} <: ParametersType{FT} +@kwdef struct AerosolActivationParameters{FT} <: ParametersType "molar mass of water [kg/mol]" M_w::FT "gas constant [J/mol/K]" @@ -36,9 +36,6 @@ Base.@kwdef struct AerosolActivationParameters{FT} <: ParametersType{FT} p2::FT end -AerosolActivationParameters(::Type{FT}) where {FT <: AbstractFloat} = - AerosolActivationParameters(CP.create_toml_dict(FT)) - function AerosolActivationParameters(td::CP.ParamDict) name_map = (; :molar_mass_water => :M_w, @@ -55,6 +52,5 @@ function AerosolActivationParameters(td::CP.ParamDict) :ARG2000_pow_2 => :p2, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AerosolActivationParameters{FT}(; parameters...) + return AerosolActivationParameters(; parameters...) end diff --git a/src/parameters/AerosolAsianDust.jl b/src/parameters/AerosolAsianDust.jl index a16880969..f91a5a0cb 100644 --- a/src/parameters/AerosolAsianDust.jl +++ b/src/parameters/AerosolAsianDust.jl @@ -8,7 +8,7 @@ Parameters for Asian Dust # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AsianDust{FT} <: AerosolType{FT} +@kwdef struct AsianDust{FT} <: AerosolType "m coefficient for deposition nucleation J [-]" deposition_m::FT "c coefficient for deposition nucleation J [-]" @@ -19,9 +19,6 @@ Base.@kwdef struct AsianDust{FT} <: AerosolType{FT} ABIFM_c::FT end -AsianDust(::Type{FT}) where {FT <: AbstractFloat} = - AsianDust(CP.create_toml_dict(FT)) - function AsianDust(td::CP.ParamDict) name_map = (; :J_ABDINM_m_AsianDust => :deposition_m, @@ -30,6 +27,5 @@ function AsianDust(td::CP.ParamDict) :J_ABIFM_c_AsianDust => :ABIFM_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AsianDust{FT}(; parameters...) + return AsianDust(; parameters...) end diff --git a/src/parameters/AerosolDesertDust.jl b/src/parameters/AerosolDesertDust.jl index ef84dbc93..e49ca8184 100644 --- a/src/parameters/AerosolDesertDust.jl +++ b/src/parameters/AerosolDesertDust.jl @@ -10,7 +10,7 @@ and from Mohler et al, 2006 DOI: 10.5194/acp-6-3007-2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct DesertDust{FT} <: AerosolType{FT} +@kwdef struct DesertDust{FT} <: AerosolType "S₀ for T > T_thr [-]" S₀_warm::FT "S₀ for T < T_thr [-]" @@ -25,9 +25,6 @@ Base.@kwdef struct DesertDust{FT} <: AerosolType{FT} ABIFM_c::FT end -DesertDust(::Type{FT}) where {FT <: AbstractFloat} = - DesertDust(CP.create_toml_dict(FT)) - function DesertDust(td::CP.ParamDict) name_map = (; :Mohler2006_S0_warm_DesertDust => :S₀_warm, @@ -38,6 +35,5 @@ function DesertDust(td::CP.ParamDict) :AlpertKnopf2016_J_ABIFM_c_DesertDust => :ABIFM_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return DesertDust{FT}(; parameters...) + return DesertDust(; parameters...) end diff --git a/src/parameters/AerosolDust.jl b/src/parameters/AerosolDust.jl index fd82973e7..800afc543 100644 --- a/src/parameters/AerosolDust.jl +++ b/src/parameters/AerosolDust.jl @@ -8,7 +8,7 @@ Parameters for generic dust. # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Dust{FT} <: AerosolType{FT} +@kwdef struct Dust{FT} <: AerosolType "m coefficient for deposition nucleation J [-]" deposition_m::FT "c coefficient for deposition nucleation J [-]" @@ -19,8 +19,6 @@ Base.@kwdef struct Dust{FT} <: AerosolType{FT} ABIFM_c::FT end -Dust(::Type{FT}) where {FT <: AbstractFloat} = Dust(CP.create_toml_dict(FT)) - function Dust(td::CP.ParamDict) name_map = (; :J_ABDINM_m_Dust => :deposition_m, @@ -29,6 +27,5 @@ function Dust(td::CP.ParamDict) :J_ABIFM_c_Dust => :ABIFM_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Dust{FT}(; parameters...) + return Dust(; parameters...) end diff --git a/src/parameters/AerosolFeldspar.jl b/src/parameters/AerosolFeldspar.jl index 2ba7fa3e2..3e2ac85b2 100644 --- a/src/parameters/AerosolFeldspar.jl +++ b/src/parameters/AerosolFeldspar.jl @@ -9,22 +9,18 @@ DOI: 10.1039/D1EA00077B # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Feldspar{FT} <: AerosolType{FT} +@kwdef struct Feldspar{FT} <: AerosolType "m coefficient for deposition nucleation J [-]" deposition_m::FT "c coefficient for deposition nucleation J [-]" deposition_c::FT end -Feldspar(::Type{FT}) where {FT <: AbstractFloat} = - Feldspar(CP.create_toml_dict(FT)) - function Feldspar(td::CP.ParamDict) name_map = (; :Alpert2022_J_deposition_m_Feldspar => :deposition_m, :Alpert2022_J_deposition_c_Feldspar => :deposition_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Feldspar{FT}(; parameters...) + return Feldspar(; parameters...) end diff --git a/src/parameters/AerosolFerrihydrite.jl b/src/parameters/AerosolFerrihydrite.jl index aa6c05a58..740d28470 100644 --- a/src/parameters/AerosolFerrihydrite.jl +++ b/src/parameters/AerosolFerrihydrite.jl @@ -9,22 +9,18 @@ DOI: 10.1039/D1EA00077B # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Ferrihydrite{FT} <: AerosolType{FT} +@kwdef struct Ferrihydrite{FT} <: AerosolType "m coefficient for deposition nucleation J [-]" deposition_m::FT "c coefficient for deposition nucleation J [-]" deposition_c::FT end -Ferrihydrite(::Type{FT}) where {FT <: AbstractFloat} = - Ferrihydrite(CP.create_toml_dict(FT)) - function Ferrihydrite(td::CP.ParamDict) name_map = (; :Alpert2022_J_deposition_m_Ferrihydrite => :deposition_m, :Alpert2022_J_deposition_c_Ferrihydrite => :deposition_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Ferrihydrite{FT}(; parameters...) + return Ferrihydrite(; parameters...) end diff --git a/src/parameters/AerosolIllite.jl b/src/parameters/AerosolIllite.jl index cfdfd7747..e3861decb 100644 --- a/src/parameters/AerosolIllite.jl +++ b/src/parameters/AerosolIllite.jl @@ -9,7 +9,7 @@ DOI: 10.1039/C3FD00035D # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Illite{FT} <: AerosolType{FT} +@kwdef struct Illite{FT} <: AerosolType "m coefficient for deposition nucleation J [-]" deposition_m::FT "c coefficient for deposition nucleation J [-]" @@ -20,8 +20,6 @@ Base.@kwdef struct Illite{FT} <: AerosolType{FT} ABIFM_c::FT end -Illite(::Type{FT}) where {FT <: AbstractFloat} = Illite(CP.create_toml_dict(FT)) - function Illite(td::CP.ParamDict) name_map = (; :J_ABDINM_m_Illite => :deposition_m, @@ -30,6 +28,5 @@ function Illite(td::CP.ParamDict) :KnopfAlpert2013_J_ABIFM_c_Illite => :ABIFM_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Illite{FT}(; parameters...) + return Illite(; parameters...) end diff --git a/src/parameters/AerosolKaolinite.jl b/src/parameters/AerosolKaolinite.jl index 144d6f159..708ee35e2 100644 --- a/src/parameters/AerosolKaolinite.jl +++ b/src/parameters/AerosolKaolinite.jl @@ -10,7 +10,7 @@ DOI: 10.1002/2016JD025817 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Kaolinite{FT} <: AerosolType{FT} +@kwdef struct Kaolinite{FT} <: AerosolType "m coefficient for deposition nucleation J [-]" deposition_m::FT "c coefficient for deposition nucleation J [-]" @@ -21,9 +21,6 @@ Base.@kwdef struct Kaolinite{FT} <: AerosolType{FT} ABIFM_c::FT end -Kaolinite(::Type{FT}) where {FT <: AbstractFloat} = - Kaolinite(CP.create_toml_dict(FT)) - function Kaolinite(td::CP.ParamDict) name_map = (; :China2017_J_deposition_m_Kaolinite => :deposition_m, @@ -32,6 +29,5 @@ function Kaolinite(td::CP.ParamDict) :KnopfAlpert2013_J_ABIFM_c_Kaolinite => :ABIFM_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Kaolinite{FT}(; parameters...) + return Kaolinite(; parameters...) end diff --git a/src/parameters/AerosolMiddleEasternDust.jl b/src/parameters/AerosolMiddleEasternDust.jl index 75d9514e5..1af84d228 100644 --- a/src/parameters/AerosolMiddleEasternDust.jl +++ b/src/parameters/AerosolMiddleEasternDust.jl @@ -8,22 +8,18 @@ Parameters for Middle Eastern Dust # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct MiddleEasternDust{FT} <: AerosolType{FT} +@kwdef struct MiddleEasternDust{FT} <: AerosolType "m coefficient for immersion freezing J [-]" ABIFM_m::FT "c coefficient for immersion freezing J [-]" ABIFM_c::FT end -MiddleEasternDust(::Type{FT}) where {FT <: AbstractFloat} = - MiddleEasternDust(CP.create_toml_dict(FT)) - function MiddleEasternDust(td::CP.ParamDict) name_map = (; :J_ABIFM_m_MiddleEasternDust => :ABIFM_m, :J_ABIFM_c_MiddleEasternDust => :ABIFM_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return MiddleEasternDust{FT}(; parameters...) + return MiddleEasternDust(; parameters...) end diff --git a/src/parameters/AerosolModalNucleation.jl b/src/parameters/AerosolModalNucleation.jl index 8a2c803e9..e33e8642d 100644 --- a/src/parameters/AerosolModalNucleation.jl +++ b/src/parameters/AerosolModalNucleation.jl @@ -10,7 +10,7 @@ DOI:10.1126/science.aaf2649 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct H2S04NucleationParameters{FT} <: ParametersType{FT} +@kwdef struct H2S04NucleationParameters{FT} <: ParametersType p_b_n::FT p_b_i::FT u_b_n::FT @@ -33,9 +33,6 @@ Base.@kwdef struct H2S04NucleationParameters{FT} <: ParametersType{FT} a_i::FT end -H2S04NucleationParameters(::Type{FT}) where {FT <: AbstractFloat} = - H2S04NucleationParameters(CP.create_toml_dict(FT)) - function H2S04NucleationParameters(td::CP.ParamDict) name_map = (; :mam3_nucleation_p_b_n_neutral => :p_b_n, @@ -60,8 +57,7 @@ function H2S04NucleationParameters(td::CP.ParamDict) :mam3_nucleation_a_i_ion_induced => :a_i, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return H2S04NucleationParameters{FT}(; parameters...) + return H2S04NucleationParameters(; parameters...) end @@ -74,7 +70,7 @@ DOI: 10.1038/nature17953 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct OrganicNucleationParameters{FT} <: ParametersType{FT} +@kwdef struct OrganicNucleationParameters{FT} <: ParametersType a_1::FT a_2::FT a_3::FT @@ -88,9 +84,6 @@ Base.@kwdef struct OrganicNucleationParameters{FT} <: ParametersType{FT} exp_MTOH::FT end -OrganicNucleationParameters(::Type{FT}) where {FT <: AbstractFloat} = - OrganicNucleationParameters(CP.create_toml_dict(FT)) - function OrganicNucleationParameters(td::CP.ParamDict) name_map = (; :mam3_nucleation_a_1_neutral => :a_1, @@ -106,8 +99,7 @@ function OrganicNucleationParameters(td::CP.ParamDict) :mam3_nucleation_exp_MTOH_organic_factor => :exp_MTOH, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return OrganicNucleationParameters{FT}(; parameters...) + return OrganicNucleationParameters(; parameters...) end """ @@ -119,15 +111,12 @@ DOI:10.1126/science.1243527 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct MixedNucleationParameters{FT} <: ParametersType{FT} +@kwdef struct MixedNucleationParameters{FT} <: ParametersType k_H2SO4org::FT k_MTOH::FT exp_MTOH::FT end -MixedNucleationParameters(::Type{FT}) where {FT <: AbstractFloat} = - MixedNucleationParameters(CP.create_toml_dict(FT)) - function MixedNucleationParameters(td::CP.ParamDict) name_map = (; :mam3_nucleation_k_H2SO4_mixed_organic_sulfuric_acid_factor => @@ -136,6 +125,5 @@ function MixedNucleationParameters(td::CP.ParamDict) :mam3_nucleation_exp_MTOH_organic_factor => :exp_MTOH, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return MixedNucleationParameters{FT}(; parameters...) + return MixedNucleationParameters(; parameters...) end diff --git a/src/parameters/AerosolSaharanDust.jl b/src/parameters/AerosolSaharanDust.jl index 1549abdc4..188de2509 100644 --- a/src/parameters/AerosolSaharanDust.jl +++ b/src/parameters/AerosolSaharanDust.jl @@ -8,22 +8,18 @@ Parameters for Saharan Dust # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct SaharanDust{FT} <: AerosolType{FT} +@kwdef struct SaharanDust{FT} <: AerosolType "m coefficient for deposition nucleation J [-]" deposition_m::FT "c coefficient for deposition nucleation J [-]" deposition_c::FT end -SaharanDust(::Type{FT}) where {FT <: AbstractFloat} = - SaharanDust(CP.create_toml_dict(FT)) - function SaharanDust(td::CP.ParamDict) name_map = (; :J_ABDINM_m_SaharanDust => :deposition_m, :J_ABDINM_c_SaharanDust => :deposition_c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return SaharanDust{FT}(; parameters...) + return SaharanDust(; parameters...) end diff --git a/src/parameters/AerosolSeasalt.jl b/src/parameters/AerosolSeasalt.jl index 5d1b39a1d..d4029d50e 100644 --- a/src/parameters/AerosolSeasalt.jl +++ b/src/parameters/AerosolSeasalt.jl @@ -8,7 +8,7 @@ Parameters for seasalt # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Seasalt{FT} <: AerosolType{FT} +@kwdef struct Seasalt{FT} <: AerosolType "molar mass [kg/mol]" M::FT "density [kg/m3]" @@ -22,10 +22,6 @@ Base.@kwdef struct Seasalt{FT} <: AerosolType{FT} "hygroscopicity parameter [-]" κ::FT end - -Seasalt(::Type{FT}) where {FT <: AbstractFloat} = - Seasalt(CP.create_toml_dict(FT)) - function Seasalt(td::CP.ParamDict) name_map = (; :seasalt_aerosol_molar_mass => :M, @@ -36,6 +32,5 @@ function Seasalt(td::CP.ParamDict) :seasalt_aerosol_kappa => :κ, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Seasalt{FT}(; parameters...) + return Seasalt(; parameters...) end diff --git a/src/parameters/AerosolSulfate.jl b/src/parameters/AerosolSulfate.jl index 72a20ab08..72aaf7e71 100644 --- a/src/parameters/AerosolSulfate.jl +++ b/src/parameters/AerosolSulfate.jl @@ -8,7 +8,7 @@ Parameters for sulfate aerosol # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Sulfate{FT} <: AerosolType{FT} +@kwdef struct Sulfate{FT} <: AerosolType "molar mass [kg/mol]" M::FT "density [kg/m3]" @@ -23,9 +23,6 @@ Base.@kwdef struct Sulfate{FT} <: AerosolType{FT} κ::FT end -Sulfate(::Type{FT}) where {FT <: AbstractFloat} = - Sulfate(CP.create_toml_dict(FT)) - function Sulfate(td::CP.ParamDict) name_map = (; :sulfate_aerosol_molar_mass => :M, @@ -36,6 +33,5 @@ function Sulfate(td::CP.ParamDict) :sulfate_aerosol_kappa => :κ, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Sulfate{FT}(; parameters...) + return Sulfate(; parameters...) end diff --git a/src/parameters/Aerosol_H2SO4_Solution.jl b/src/parameters/Aerosol_H2SO4_Solution.jl index 019235d8e..911f086ca 100644 --- a/src/parameters/Aerosol_H2SO4_Solution.jl +++ b/src/parameters/Aerosol_H2SO4_Solution.jl @@ -9,7 +9,7 @@ from Luo et al 1995. DOI: 10.1029/94GL02988 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct H2SO4SolutionParameters{FT} <: ParametersType{FT} +@kwdef struct H2SO4SolutionParameters{FT} <: ParametersType "max temperature for which the parameterization is valid [K]" T_max::FT "min temperature for which the parameterization is valid [K]" @@ -32,9 +32,6 @@ Base.@kwdef struct H2SO4SolutionParameters{FT} <: ParametersType{FT} c7::FT end -H2SO4SolutionParameters(::Type{FT}) where {FT <: AbstractFloat} = - H2SO4SolutionParameters(CP.create_toml_dict(FT)) - function H2SO4SolutionParameters(td::CP.ParamDict) name_map = (; :p_over_sulphuric_acid_solution_T_max => :T_max, @@ -49,6 +46,5 @@ function H2SO4SolutionParameters(td::CP.ParamDict) :p_over_sulphuric_acid_solution_c7 => :c7, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return H2SO4SolutionParameters{FT}(; parameters...) + return H2SO4SolutionParameters(; parameters...) end diff --git a/src/parameters/AirProperties.jl b/src/parameters/AirProperties.jl index 3449817fa..961f32655 100644 --- a/src/parameters/AirProperties.jl +++ b/src/parameters/AirProperties.jl @@ -8,17 +8,17 @@ Parameters with air properties. # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AirProperties{FT} <: ParametersType{FT} +@kwdef struct AirProperties{FT} <: ParametersType "thermal conductivity of air [w/m/K]" K_therm::FT - "diffusivity of water vapor [m2/s]" + "diffusivity of water vapor [m²/s]" D_vapor::FT - "kinematic viscosity of air [m2/s]" + "kinematic viscosity of air [m²/s]" ν_air::FT end -AirProperties(::Type{FT}) where {FT <: AbstractFloat} = - AirProperties(CP.create_toml_dict(FT)) +ShowMethods.field_units(::AirProperties) = + (; K_therm = "W/m/K", D_vapor = "m²/s", ν_air = "m²/s") function AirProperties(td::CP.ParamDict) name_map = (; @@ -27,6 +27,5 @@ function AirProperties(td::CP.ParamDict) :kinematic_viscosity_of_air => :ν_air, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AirProperties{FT}(; parameters...) + return AirProperties(; parameters...) end diff --git a/src/parameters/IceNucleation.jl b/src/parameters/IceNucleation.jl index 08db0e117..2b22af636 100644 --- a/src/parameters/IceNucleation.jl +++ b/src/parameters/IceNucleation.jl @@ -10,7 +10,7 @@ DOI: 10.5194/acp-6-3007-2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Mohler2006{FT} <: ParametersType{FT} +@kwdef struct Mohler2006{FT} <: ParametersType "max allowed supersaturation [-]" Sᵢ_max::FT "threshold temperature [K]" @@ -23,8 +23,7 @@ function Mohler2006(td::CP.ParamDict) :Mohler2006_threshold_T => :T_thr, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Mohler2006{FT}(; parameters...) + return Mohler2006(; parameters...) end """ @@ -36,7 +35,7 @@ DOI: 10.1038/35020537 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Koop2000{FT} <: ParametersType{FT} +@kwdef struct Koop2000{FT} <: ParametersType "min Δaw [-]" Δa_w_min::FT "max Δaw [-]" @@ -67,8 +66,7 @@ function Koop2000(td::CP.ParamDict) :Linear_J_hom_coeff2 => :linear_c₂, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Koop2000{FT}(; parameters...) + return Koop2000(; parameters...) end """ @@ -80,7 +78,7 @@ DOI: 10.1175/JAS-D-14-0065.1 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct MorrisonMilbrandt2014{FT} <: ParametersType{FT} +@kwdef struct MorrisonMilbrandt2014{FT} <: ParametersType "Cutoff temperature for deposition nucleation [K]" T_dep_thres::FT "coefficient [-]" @@ -105,8 +103,7 @@ function MorrisonMilbrandt2014(td::CP.ParamDict) :BarklieGokhale1959_B_parameter => :het_B, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return MorrisonMilbrandt2014{FT}(; parameters...) + return MorrisonMilbrandt2014(; parameters...) end """ @@ -117,29 +114,18 @@ Parameters for ice nucleation # Fields $(DocStringExtensions.FIELDS) """ -struct IceNucleationParameters{FT, DEP, HOM, P3_type} <: ParametersType{FT} +@kwdef struct IceNucleationParameters{DEP, HOM, P3_type} <: ParametersType deposition::DEP homogeneous::HOM p3::P3_type end -IceNucleationParameters(::Type{FT}) where {FT <: AbstractFloat} = - IceNucleationParameters(CP.create_toml_dict(FT)) - -function IceNucleationParameters(toml_dict::CP.ParamDict) - deposition = Mohler2006(toml_dict) - homogeneous = Koop2000(toml_dict) - p3 = MorrisonMilbrandt2014(toml_dict) - DEP = typeof(deposition) - HOM = typeof(homogeneous) - P3_type = typeof(p3) - FT = CP.float_type(toml_dict) - return IceNucleationParameters{FT, DEP, HOM, P3_type}( - deposition, - homogeneous, - p3, +IceNucleationParameters(toml_dict::CP.ParamDict) = + IceNucleationParameters(; + deposition = Mohler2006(toml_dict), + homogeneous = Koop2000(toml_dict), + p3 = MorrisonMilbrandt2014(toml_dict), ) -end """ @@ -151,7 +137,7 @@ DOI: 10.5194/acp-23-10883-2023 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Frostenberg2023{FT} <: ParametersType{FT} +@kwdef struct Frostenberg2023{FT} <: ParametersType "standard deviation" σ::FT "coefficient" @@ -162,9 +148,6 @@ Base.@kwdef struct Frostenberg2023{FT} <: ParametersType{FT} T_freeze::FT end -Frostenberg2023(::Type{FT}) where {FT <: AbstractFloat} = - Frostenberg2023(CP.create_toml_dict(FT)) - function Frostenberg2023(td::CP.ParamDict) name_map = (; :Frostenberg2023_standard_deviation => :σ, @@ -173,6 +156,5 @@ function Frostenberg2023(td::CP.ParamDict) :temperature_water_freeze => :T_freeze, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Frostenberg2023{FT}(; parameters...) + return Frostenberg2023(; parameters...) end diff --git a/src/parameters/Microphysics0M.jl b/src/parameters/Microphysics0M.jl index 3f0795998..90c9882da 100644 --- a/src/parameters/Microphysics0M.jl +++ b/src/parameters/Microphysics0M.jl @@ -8,7 +8,7 @@ Parameters for zero-moment bulk microphysics scheme # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Parameters0M{FT} <: ParametersType{FT} +@kwdef struct Parameters0M{FT} <: ParametersType "precipitation timescale [s]" τ_precip::FT "condensate specific content precipitation threshold [-]" @@ -17,9 +17,6 @@ Base.@kwdef struct Parameters0M{FT} <: ParametersType{FT} S_0::FT end -Parameters0M(::Type{FT}) where {FT <: AbstractFloat} = - Parameters0M(CP.create_toml_dict(FT)) - function Parameters0M(td::CP.ParamDict) name_map = (; :precipitation_timescale => :τ_precip, @@ -27,6 +24,5 @@ function Parameters0M(td::CP.ParamDict) :supersaturation_precipitation_threshold => :S_0, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return Parameters0M{FT}(; parameters...) + return Parameters0M(; parameters...) end diff --git a/src/parameters/Microphysics0MParams.jl b/src/parameters/Microphysics0MParams.jl index 4c5a979bd..cff826315 100644 --- a/src/parameters/Microphysics0MParams.jl +++ b/src/parameters/Microphysics0MParams.jl @@ -1,32 +1,25 @@ export Microphysics0MParams """ - Microphysics0MParams{FT, P} + Microphysics0MParams{P} Unified parameter container for 0-moment microphysics. # Fields -- `precip::P`: Parameters0M — precipitation removal parameters -""" -struct Microphysics0MParams{FT, P} <: ParametersType{FT} - precip::P -end - -""" - Microphysics0MParams(::Type{FT}) where {FT <: AbstractFloat} +$(DocStringExtensions.FIELDS) -Create a `Microphysics0MParams` object from a floating point type. -""" -Microphysics0MParams(::Type{FT}) where {FT <: AbstractFloat} = - Microphysics0MParams(CP.create_toml_dict(FT)) +# Constructors -""" - Microphysics0MParams(toml_dict::CP.ParamDict) + Microphysics0MParams(FT) + Microphysics0MParams(toml_dict::ClimaParams.ParamDict) -Create a `Microphysics0MParams` object from a ClimaParams TOML dictionary. +where +- `FT::Type`: A floating point type, e.g. `Float32` +- `toml_dict::ParamDict`: A ClimaParams parameter TOML dictionary (`ParamDict`) """ -function Microphysics0MParams(toml_dict::CP.ParamDict) - precip = Parameters0M(toml_dict) - FT = CP.float_type(toml_dict) - return Microphysics0MParams{FT, typeof(precip)}(precip) +@kwdef struct Microphysics0MParams{P} <: ParametersType + "Precipitation removal parameters" + precip::P end +Microphysics0MParams(toml_dict::CP.ParamDict) = + Microphysics0MParams(; precip = Parameters0M(toml_dict)) diff --git a/src/parameters/Microphysics1M.jl b/src/parameters/Microphysics1M.jl index ca4da3dda..8ffbf6d47 100644 --- a/src/parameters/Microphysics1M.jl +++ b/src/parameters/Microphysics1M.jl @@ -8,7 +8,7 @@ A struct with snow size distribution parameters # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct ParticlePDFSnow{FT} <: ParametersType{FT} +@kwdef struct ParticlePDFSnow{FT} <: ParametersType "snow size distribution coefficient [1/m4]" μ::FT "snow size distribution coefficient [-]" @@ -23,7 +23,7 @@ A struct with snow size distribution parameters # Fields $(DocStringExtensions.FIELDS) """ -struct ParticlePDFIceRain{FT} <: ParametersType{FT} +struct ParticlePDFIceRain{FT} <: ParametersType "Size distribution coefficient [1/m4]" n0::FT end @@ -38,7 +38,7 @@ m(r) = m0 χm (r/r0)^(me + Δm) # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct ParticleMass{FT} <: ParametersType{FT} +@kwdef struct ParticleMass{FT} <: ParametersType "particle length scale [m]" r0::FT "mass size relation coefficient [kg]" @@ -52,6 +52,7 @@ Base.@kwdef struct ParticleMass{FT} <: ParametersType{FT} "pre-computed gamma(me + Δm + 1) for performance [-]" gamma_coeff::FT end +ShowMethods.field_units(::ParticleMass) = (; r0 = "m", m0 = "kg") """ ParticleArea{FT} @@ -64,8 +65,8 @@ a(r) = a0 χa (r/r0)^(ae + Δa) # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct ParticleArea{FT} <: ParametersType{FT} - "cross section size relation coefficient [m2]" +@kwdef struct ParticleArea{FT} <: ParametersType + "cross section size relation coefficient [m²]" a0::FT "cross section size relation coefficient [-]" ae::FT @@ -74,6 +75,7 @@ Base.@kwdef struct ParticleArea{FT} <: ParametersType{FT} "cross section size relation coefficient [-]" χa::FT end +ShowMethods.field_units(::ParticleArea) = (; a0 = "m²") """ Ventilation{FT} @@ -83,7 +85,7 @@ A struct with ventilation coefficients # Fields $(DocStringExtensions.FIELDS) """ -struct Ventilation{FT} <: ParametersType{FT} +struct Ventilation{FT} <: ParametersType "ventilation coefficient `a` [-]" a::FT "ventilation coefficient `b` [-]" @@ -98,7 +100,7 @@ A struct with aspect ratio coefficients # Fields $(DocStringExtensions.FIELDS) """ -struct SnowAspectRatio{FT} <: ParametersType{FT} +struct SnowAspectRatio{FT} <: ParametersType "aspect ratio [-]" ϕ::FT "power law coefficient in terminal velocity parameterization from Chen et al 2022 [-]" @@ -113,7 +115,7 @@ A struct with autoconversion parameters # Fields $(DocStringExtensions.FIELDS) """ -struct Acnv1M{FT} <: ParametersType{FT} +struct Acnv1M{FT} <: ParametersType "autoconversion timescale [s]" τ::FT "condensate specific content autoconversion threshold [-]" @@ -130,19 +132,18 @@ The parameters and type for cloud liquid water condensate # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct CloudLiquid{FT} <: CloudCondensateType{FT} +@kwdef struct CloudLiquid{FT} <: CloudCondensateType "condensation evaporation non_equil microphysics relaxation timescale [s]" τ_relax::FT - "water density [kg/m3]" + "water density [kg/m³]" ρw::FT "effective radius [m]" r_eff::FT - "assumed number concentration for cloud sedimentation [1/m3]" + "assumed number concentration for cloud sedimentation [1/m³]" N_0::FT end - -CloudLiquid(::Type{FT}) where {FT <: AbstractFloat} = - CloudLiquid(CP.create_toml_dict(FT)) +ShowMethods.field_units(::CloudLiquid) = + (; τ_relax = "s", ρw = "kg/m³", r_eff = "m", N_0 = "1/m³") function CloudLiquid(toml_dict::CP.ParamDict) name_map = (; @@ -151,10 +152,8 @@ function CloudLiquid(toml_dict::CP.ParamDict) :liquid_cloud_effective_radius => :r_eff, :cloud_liquid_sedimentation_number_concentration => :N_0, ) - parameters = - CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - FT = CP.float_type(toml_dict) - return CloudLiquid{FT}(; parameters...) + parameters = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") + return CloudLiquid(; parameters...) end """ @@ -165,7 +164,7 @@ The parameters and type for cloud ice condensate # Fields $(DocStringExtensions.FIELDS) """ -struct CloudIce{FT, PD, MS} <: CloudCondensateType{FT} +@kwdef struct CloudIce{FT, PD, MS} <: CloudCondensateType "a struct with size distribution parameters" pdf::PD "a struct with mass size relation parameters" @@ -176,18 +175,17 @@ struct CloudIce{FT, PD, MS} <: CloudCondensateType{FT} r_ice_snow::FT "deposition sublimation non_equil microphysics relaxation timescale [s]" τ_relax::FT - "cloud ice apparent density [kg/m3]" + "cloud ice apparent density [kg/m³]" ρᵢ::FT "effective radius [m]" r_eff::FT - "assumed number concentration for cloud sedimentation [1/m3]" + "assumed number concentration for cloud sedimentation [1/m³]" N_0::FT end +ShowMethods.field_units(::CloudIce) = + (; r0 = "m", r_ice_snow = "m", τ_relax = "s", ρᵢ = "kg/m³", r_eff = "m", N_0 = "1/m³") -CloudIce(::Type{FT}) where {FT <: AbstractFloat} = - CloudIce(CP.create_toml_dict(FT)) - -function CloudIce(toml_dict::CP.ParamDict = CP.create_toml_dict(FT)) +function CloudIce(toml_dict::CP.ParamDict) name_map = (; :cloud_ice_apparent_density => :ρᵢ, :cloud_ice_crystals_length_scale => :r0, @@ -201,19 +199,7 @@ function CloudIce(toml_dict::CP.ParamDict = CP.create_toml_dict(FT)) p = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") mass = ParticleMass(CloudIce, toml_dict) pdf = ParticlePDFIceRain(p.n0) - FT = CP.float_type(toml_dict) - P = typeof(pdf) - M = typeof(mass) - return CloudIce{FT, P, M}( - pdf, - mass, - p.r0, - p.r_ice_snow, - p.τ_relax, - p.ρᵢ, - p.r_eff, - p.N_0, - ) + return CloudIce(; pdf, mass, p.r0, p.r_ice_snow, p.τ_relax, p.ρᵢ, p.r_eff, p.N_0) end function ParticleMass(::Type{CloudIce}, td::CP.ParamDict) @@ -225,10 +211,9 @@ function ParticleMass(::Type{CloudIce}, td::CP.ParamDict) :cloud_ice_mass_size_relation_coefficient_chim => :χm, ) p = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - m0 = 4 / 3 * π * p.ρᵢ * p.r0^p.me - FT = CP.float_type(td) - gamma_coeff = FT(SF.gamma(p.me + p.Δm + 1)) - return ParticleMass{FT}(; p.r0, m0, p.me, p.Δm, p.χm, gamma_coeff) + m0 = p.ρᵢ * p.r0^p.me * π * 4 / 3 + gamma_coeff = SF.gamma(p.me + p.Δm + 1) + return ParticleMass(; p.r0, m0, p.me, p.Δm, p.χm, gamma_coeff) end """ @@ -239,7 +224,7 @@ The parameters and type for rain # Fields $(DocStringExtensions.FIELDS) """ -struct Rain{FT, PD, MS, AR, VT, AC} <: PrecipitationType{FT} +@kwdef struct Rain{FT, PD, MS, AR, VT, AC} <: PrecipitationType "a struct with size distribution parameters" pdf::PD "a struct with mass size relation parameters" @@ -253,8 +238,7 @@ struct Rain{FT, PD, MS, AR, VT, AC} <: PrecipitationType{FT} "particle length scale [m]" r0::FT end - -Rain(::Type{FT}) where {FT <: AbstractFloat} = Rain(CP.create_toml_dict(FT)) +ShowMethods.field_units(::Rain) = (; r0 = "m") function Rain(toml_dict::CP.ParamDict) name_map = (; @@ -264,27 +248,20 @@ function Rain(toml_dict::CP.ParamDict) :rain_mass_size_relation_coefficient_me => :me, :rain_cross_section_size_relation_coefficient_ae => :ae, :rain_autoconversion_timescale => :τ, - :cloud_liquid_water_specific_humidity_autoconversion_threshold => - :q_threshold, + :cloud_liquid_water_specific_humidity_autoconversion_threshold => :q_threshold, :threshold_smooth_transition_steepness => :k, :rain_ventilation_coefficient_a => :a, :rain_ventilation_coefficient_b => :b, ) p = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - - mass = ParticleMass(Rain, toml_dict) - area = ParticleArea(Rain, toml_dict) - pdf = ParticlePDFIceRain(p.n0) - vent = Ventilation(p.a, p.b) - acnv1M = Acnv1M(p.τ, p.q_threshold, p.k) - - FT = CP.float_type(toml_dict) - P = typeof(pdf) - M = typeof(mass) - A = typeof(area) - V = typeof(vent) - AC = typeof(acnv1M) - return Rain{FT, P, M, A, V, AC}(pdf, mass, area, vent, acnv1M, p.r0) + return Rain(; + mass = ParticleMass(Rain, toml_dict), + area = ParticleArea(Rain, toml_dict), + pdf = ParticlePDFIceRain(p.n0), + vent = Ventilation(p.a, p.b), + acnv1M = Acnv1M(p.τ, p.q_threshold, p.k), + p.r0, + ) end function ParticleMass(::Type{Rain}, td::CP.ParamDict) @@ -296,10 +273,9 @@ function ParticleMass(::Type{Rain}, td::CP.ParamDict) :rain_mass_size_relation_coefficient_chim => :χm, ) p = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - m0 = 4 / 3 * π * p.ρ * p.r0^p.me - FT = CP.float_type(td) - gamma_coeff = FT(SF.gamma(p.me + p.Δm + 1)) - return ParticleMass{FT}(; p.r0, m0, p.me, p.Δm, p.χm, gamma_coeff) + m0 = p.ρ * p.r0^p.me * π * 4 / 3 + gamma_coeff = SF.gamma(p.me + p.Δm + 1) + return ParticleMass(; p.r0, m0, p.me, p.Δm, p.χm, gamma_coeff) end function ParticleArea(::Type{Rain}, td::CP.ParamDict) @@ -311,8 +287,7 @@ function ParticleArea(::Type{Rain}, td::CP.ParamDict) ) p = CP.get_parameter_values(td, name_map, "CloudMicrophysics") a0 = π * p.r0^p.ae - FT = CP.float_type(td) - return ParticleArea{FT}(; a0, p.ae, p.Δa, p.χa) + return ParticleArea(; a0, p.ae, p.Δa, p.χa) end """ @@ -323,7 +298,7 @@ The parameters and type for snow # Fields $(DocStringExtensions.FIELDS) """ -struct Snow{FT, PD, MS, AR, VT, AP, AC} <: PrecipitationType{FT} +@kwdef struct Snow{FT, PD, MS, AR, VT, AP, AC} <: PrecipitationType "a struct with size distribution parameters" pdf::PD "a struct with mass size relation parameters" @@ -348,15 +323,12 @@ struct Snow{FT, PD, MS, AR, VT, AP, AC} <: PrecipitationType{FT} gamma_aspect_prolate::FT end -Snow(::Type{FT}) where {FT <: AbstractFloat} = Snow(CP.create_toml_dict(FT)) - function Snow(toml_dict::CP.ParamDict) name_map = (; :cloud_ice_crystals_length_scale => :r0, :snow_apparent_density => :ρᵢ, :snow_autoconversion_timescale => :τ, - :cloud_ice_specific_humidity_autoconversion_threshold => - :q_threshold, + :cloud_ice_specific_humidity_autoconversion_threshold => :q_threshold, :threshold_smooth_transition_steepness => :k, :temperature_water_freeze => :T_freeze, :snow_flake_size_distribution_coefficient_mu => :μ, @@ -370,40 +342,24 @@ function Snow(toml_dict::CP.ParamDict) mass = ParticleMass(Snow, toml_dict) area = ParticleArea(Snow, toml_dict) - pdf = ParticlePDFSnow(p.μ, p.ν) - vent = Ventilation(p.a, p.b) - aspr = SnowAspectRatio(p.ϕ, p.κ) - acnv1M = Acnv1M(p.τ, p.q_threshold, p.k) FT = CP.float_type(toml_dict) # Pre-compute gamma aspect ratio for oblate and prolate shapes # Oblate: α = me + Δm - 3/2 * (ae + Δa) # Prolate: α = 3 * (ae + Δa) - 2 * (me + Δm) - α_oblate = mass.me + mass.Δm - FT(3 / 2) * (area.ae + area.Δa) + α_oblate = mass.me + mass.Δm - (3 // 2) * (area.ae + area.Δa) α_prolate = 3 * (area.ae + area.Δa) - 2 * (mass.me + mass.Δm) - gamma_aspect_oblate = FT(SF.gamma(α_oblate + 4) / SF.gamma(FT(4))) - gamma_aspect_prolate = FT(SF.gamma(α_prolate + 4) / SF.gamma(FT(4))) - - return Snow{ - FT, - typeof(pdf), - typeof(mass), - typeof(area), - typeof(vent), - typeof(aspr), - typeof(acnv1M), - }( - pdf, + + return Snow(; + pdf = ParticlePDFSnow(p.μ, p.ν), mass, area, - vent, - aspr, - acnv1M, - p.r0, - p.T_freeze, - p.ρᵢ, - gamma_aspect_oblate, - gamma_aspect_prolate, + vent = Ventilation(p.a, p.b), + aspr = SnowAspectRatio(p.ϕ, p.κ), + acnv1M = Acnv1M(p.τ, p.q_threshold, p.k), + p.r0, p.T_freeze, p.ρᵢ, + gamma_aspect_oblate = SF.gamma(α_oblate + 4) / SF.gamma(FT(4)), + gamma_aspect_prolate = SF.gamma(α_prolate + 4) / SF.gamma(FT(4)), ) end @@ -415,10 +371,9 @@ function ParticleMass(::Type{Snow}, td::CP.ParamDict) :snow_mass_size_relation_coefficient_chim => :χm, ) p = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - m0 = 1e-1 * p.r0^p.me - FT = CP.float_type(td) - gamma_coeff = FT(SF.gamma(p.me + p.Δm + 1)) - return ParticleMass{FT}(; p.r0, m0, p.me, p.Δm, p.χm, gamma_coeff) + m0 = p.r0^p.me / 10 + gamma_coeff = SF.gamma(p.me + p.Δm + 1) + return ParticleMass(; p.r0, m0, p.me, p.Δm, p.χm, gamma_coeff) end function ParticleArea(::Type{Snow}, toml_dict::CP.ParamDict) @@ -429,9 +384,9 @@ function ParticleArea(::Type{Snow}, toml_dict::CP.ParamDict) :snow_cross_section_size_relation_coefficient_chia => :χa, ) p = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - a0 = 0.3 * π * p.r0^p.ae FT = CP.float_type(toml_dict) - return ParticleArea{FT}(; a0, p.ae, p.Δa, p.χa) + a0 = FT(0.3 * π * p.r0^p.ae) + return ParticleArea(; a0, p.ae, p.Δa, p.χa) end """ @@ -442,7 +397,7 @@ Collision efficiency parameters for the 1-moment scheme # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct CollisionEff{FT} <: ParametersType{FT} +@kwdef struct CollisionEff{FT} <: ParametersType "cloud liquid-rain collision efficiency [-]" e_lcl_rai::FT "cloud liquid-snow collision efficiency [-]" @@ -457,9 +412,6 @@ Base.@kwdef struct CollisionEff{FT} <: ParametersType{FT} coeff_disp::FT end -CollisionEff(::Type{FT}) where {FT <: AbstractFloat} = - CollisionEff(CP.create_toml_dict(FT)) - function CollisionEff(td::CP.ParamDict) name_map = (; :cloud_liquid_rain_collision_efficiency => :e_lcl_rai, @@ -470,6 +422,5 @@ function CollisionEff(td::CP.ParamDict) :rain_snow_velocity_dispersion_coefficient => :coeff_disp, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return CollisionEff{FT}(; parameters...) + return CollisionEff(; parameters...) end diff --git a/src/parameters/Microphysics1MParams.jl b/src/parameters/Microphysics1MParams.jl index 897bebf2c..4cf6fb6d4 100644 --- a/src/parameters/Microphysics1MParams.jl +++ b/src/parameters/Microphysics1MParams.jl @@ -9,11 +9,14 @@ Parameters for cloud-phase (non-precipitating) hydrometeors in 1-moment scheme. - `liquid::LCL`: CloudLiquid — cloud liquid water parameters - `ice::ICL`: CloudIce — cloud ice parameters """ -struct CloudPhaseParams1M{FT, LCL, ICL} <: ParametersType{FT} +@kwdef struct CloudPhaseParams1M{LCL, ICL} <: ParametersType liquid::LCL ice::ICL end +Base.show(io::IO, mime::MIME"text/plain", x::CloudPhaseParams1M) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) + """ PrecipPhaseParams1M{FT, RAI, SNO} @@ -23,11 +26,14 @@ Parameters for precipitating hydrometeors in 1-moment scheme. - `rain::RAI`: Rain — rain parameters (includes autoconversion) - `snow::SNO`: Snow — snow parameters (includes autoconversion) """ -struct PrecipPhaseParams1M{FT, RAI, SNO} <: ParametersType{FT} +@kwdef struct PrecipPhaseParams1M{RAI, SNO} <: ParametersType rain::RAI snow::SNO end +Base.show(io::IO, mime::MIME"text/plain", x::PrecipPhaseParams1M) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) + """ Microphysics1MParams{FT, CP, PP, CE, AP, VL, VA} @@ -53,7 +59,7 @@ mp = CMP.Microphysics1MParams(Float64) mp_with_2M = CMP.Microphysics1MParams(Float64; with_2M_autoconv = true) ``` """ -struct Microphysics1MParams{FT, CP, PP, CE, AP, VL, VA} <: ParametersType{FT} +@kwdef struct Microphysics1MParams{FT, CP, PP, CE, AP, VL, VA} <: ParametersType cloud::CP precip::PP collision::CE @@ -62,18 +68,8 @@ struct Microphysics1MParams{FT, CP, PP, CE, AP, VL, VA} <: ParametersType{FT} autoconv_2M::VA prescribed_Nc::FT end - -""" - Microphysics1MParams(::Type{FT}; with_2M_autoconv = false) where {FT <: AbstractFloat} - -Create a `Microphysics1MParams` object from a floating point type. - -# Arguments -- `FT`: Floating point type (e.g., Float64, Float32) -- `with_2M_autoconv`: Include 2-moment autoconversion parameters (default: false) -""" -Microphysics1MParams(::Type{FT}; with_2M_autoconv = false) where {FT <: AbstractFloat} = - Microphysics1MParams(CP.create_toml_dict(FT); with_2M_autoconv) +Base.show(io::IO, mime::MIME"text/plain", x::Microphysics1MParams) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) """ Microphysics1MParams(toml_dict::CP.ParamDict; with_2M_autoconv = false) @@ -85,50 +81,27 @@ Create a `Microphysics1MParams` object from a ClimaParams TOML dictionary. - `with_2M_autoconv`: Include 2-moment autoconversion parameters (default: false) """ function Microphysics1MParams(toml_dict::CP.ParamDict; with_2M_autoconv = false) - FT = CP.float_type(toml_dict) - - # Cloud phase parameters - liquid = CloudLiquid(toml_dict) - ice = CloudIce(toml_dict) - cloud = CloudPhaseParams1M{FT, typeof(liquid), typeof(ice)}(liquid, ice) - - # Precipitation phase parameters - rain = Rain(toml_dict) - snow = Snow(toml_dict) - precip = PrecipPhaseParams1M{FT, typeof(rain), typeof(snow)}(rain, snow) - - # Shared physics parameters - collision = CollisionEff(toml_dict) - air_properties = AirProperties(toml_dict) - terminal_velocity = Blk1MVelType(toml_dict) - - # Optional 2M autoconversion - autoconv_2M = with_2M_autoconv ? VarTimescaleAcnv(toml_dict) : nothing - - - # Prescribed cloud droplet number concentration - (; prescribed_cloud_droplet_number_concentration) = - CP.get_parameter_values( - toml_dict, - "prescribed_cloud_droplet_number_concentration", - "CloudMicrophysics", - ) - prescribed_Nc = FT(prescribed_cloud_droplet_number_concentration) - return Microphysics1MParams{ - FT, - typeof(cloud), - typeof(precip), - typeof(collision), - typeof(air_properties), - typeof(terminal_velocity), - typeof(autoconv_2M), - }( - cloud, - precip, - collision, - air_properties, - terminal_velocity, - autoconv_2M, - prescribed_Nc, + (; prescribed_cloud_droplet_number_concentration) = CP.get_parameter_values( + toml_dict, "prescribed_cloud_droplet_number_concentration", "CloudMicrophysics", + ) + return Microphysics1MParams(; + # Cloud phase parameters + cloud = CloudPhaseParams1M(; + liquid = CloudLiquid(toml_dict), + ice = CloudIce(toml_dict), + ), + # Precipitation phase parameters + precip = PrecipPhaseParams1M(; + rain = Rain(toml_dict), + snow = Snow(toml_dict), + ), + # Shared physics parameters + collision = CollisionEff(toml_dict), + air_properties = AirProperties(toml_dict), + terminal_velocity = Blk1MVelType(toml_dict), + # Optional 2M autoconversion + autoconv_2M = with_2M_autoconv ? VarTimescaleAcnv(toml_dict) : nothing, + # Prescribed cloud droplet number concentration + prescribed_Nc = prescribed_cloud_droplet_number_concentration, ) end diff --git a/src/parameters/Microphysics2M.jl b/src/parameters/Microphysics2M.jl index f6645b68b..623aa2ae1 100644 --- a/src/parameters/Microphysics2M.jl +++ b/src/parameters/Microphysics2M.jl @@ -8,7 +8,7 @@ Khairoutdinov and Kogan (2000) autoconversion parameters # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AcnvKK2000{FT} <: ParametersType{FT} +@kwdef struct AcnvKK2000{FT} <: ParametersType "Autoconversion coefficient A" A::FT "Autoconversion coefficient a" @@ -27,8 +27,7 @@ function AcnvKK2000(td::CP.ParamDict) :KK2000_autoconversion_coeff_c => :c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AcnvKK2000{FT}(; parameters...) + return AcnvKK2000(; parameters...) end """ @@ -39,7 +38,7 @@ Khairoutdinov and Kogan (2000) accretion parameters # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AccrKK2000{FT} <: ParametersType{FT} +@kwdef struct AccrKK2000{FT} <: ParametersType "Accretion coefficient A" A::FT "Accretion coefficient a" @@ -55,8 +54,7 @@ function AccrKK2000(td::CP.ParamDict) :KK2000_accretion_coeff_b => :b, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AccrKK2000{FT}(; parameters...) + return AccrKK2000(; parameters...) end """ @@ -70,22 +68,15 @@ DOI:10.1175/1520-0493(2000)128<0229:ANCPPI>2.0.CO;2 # Fields $(DocStringExtensions.FIELDS) """ -struct KK2000{FT, AV, AR} <: Precipitation2MType{FT} +@kwdef struct KK2000{AV, AR} <: Precipitation2MType "Autoconversion parameters" acnv::AV "Accretion parameters" accr::AR end -KK2000(::Type{FT}) where {FT <: AbstractFloat} = KK2000(CP.create_toml_dict(FT)) - - -function KK2000(toml_dict::CP.ParamDict) - acnv = AcnvKK2000(toml_dict) - accr = AccrKK2000(toml_dict) - FT = CP.float_type(toml_dict) - return KK2000{FT, typeof(acnv), typeof(accr)}(acnv, accr) -end +KK2000(toml_dict::CP.ParamDict) = + KK2000(; acnv = AcnvKK2000(toml_dict), accr = AccrKK2000(toml_dict)) """ AcnvB1994 @@ -95,7 +86,7 @@ Beheng (1994) autoconversion parameters # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AcnvB1994{FT} <: ParametersType{FT} +@kwdef struct AcnvB1994{FT} <: ParametersType "Autoconversion coeff C" C::FT "Autoconversion coeff a" @@ -126,8 +117,7 @@ function AcnvB1994(td::CP.ParamDict) :threshold_smooth_transition_steepness => :k, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AcnvB1994{FT}(; parameters...) + return AcnvB1994(; parameters...) end """ @@ -138,7 +128,7 @@ Beheng (1994) accretion parameters # Fields $(DocStringExtensions.FIELDS) """ -struct AccrB1994{FT} <: ParametersType{FT} +@kwdef struct AccrB1994{FT} <: ParametersType "Accretion coefficient A" A::FT end @@ -149,8 +139,7 @@ function AccrB1994(toml_dict::CP.ParamDict) "B1994_accretion_coeff_A", "CloudMicrophysics", ) - FT = CP.float_type(toml_dict) - return AccrB1994{FT}(B1994_accretion_coeff_A) + return AccrB1994(B1994_accretion_coeff_A) end """ @@ -162,21 +151,15 @@ DOI: 10.1016/0169-8095(94)90020-5 # Fields $(DocStringExtensions.FIELDS) """ -struct B1994{FT, AV, AR} <: Precipitation2MType{FT} +@kwdef struct B1994{AV, AR} <: Precipitation2MType "Autoconversion coeff C" acnv::AV "Autoconversion coeff a" accr::AR end -B1994(::Type{FT}) where {FT <: AbstractFloat} = B1994(CP.create_toml_dict(FT)) - -function B1994(toml_dict::CP.ParamDict) - acnv = AcnvB1994(toml_dict) - accr = AccrB1994(toml_dict) - FT = CP.float_type(toml_dict) - return B1994{FT, typeof(acnv), typeof(accr)}(acnv, accr) -end +B1994(toml_dict::CP.ParamDict) = + B1994(; acnv = AcnvB1994(toml_dict), accr = AccrB1994(toml_dict)) """ AcnvTC1980 @@ -186,7 +169,7 @@ Tripoli and Cotton (1980) autoconversion parameters # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AcnvTC1980{FT} <: ParametersType{FT} +@kwdef struct AcnvTC1980{FT} <: ParametersType "Autoconversion coefficient a" a::FT "Autoconversion coefficient b" @@ -214,10 +197,8 @@ function AcnvTC1980(td::CP.ParamDict) :density_liquid_water => :m0_liq_coeff, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - m0_liq_coeff = 4 / 3 * π * parameters.m0_liq_coeff - - FT = CP.float_type(td) - return AcnvTC1980{FT}(; parameters..., m0_liq_coeff) + m0_liq_coeff = parameters.m0_liq_coeff * 4 / 3 * π + return AcnvTC1980(; parameters..., m0_liq_coeff) end """ @@ -228,7 +209,7 @@ Tripoli and Cotton (1980) accretion parameters # Fields $(DocStringExtensions.FIELDS) """ -struct AccrTC1980{FT} <: ParametersType{FT} +struct AccrTC1980{FT} <: ParametersType "Accretion coefficient A" A::FT end @@ -239,8 +220,7 @@ function AccrTC1980(toml_dict::CP.ParamDict) "TC1980_accretion_coeff_A", "CloudMicrophysics", ) - FT = CP.float_type(toml_dict) - return AccrTC1980{FT}(TC1980_accretion_coeff_A) + return AccrTC1980(TC1980_accretion_coeff_A) end """ @@ -254,21 +234,15 @@ DOI: 10.1175/1520-0450(1980)019<1037:ANIOSF>2.0.CO;2 # Fields $(DocStringExtensions.FIELDS) """ -struct TC1980{FT, AV, AR} <: Precipitation2MType{FT} +@kwdef struct TC1980{AV, AR} <: Precipitation2MType "Autoconversion parameters" acnv::AV "Accretion parameters" accr::AR end -TC1980(::Type{FT}) where {FT <: AbstractFloat} = TC1980(CP.create_toml_dict(FT)) - -function TC1980(toml_dict::CP.ParamDict) - acnv = AcnvTC1980(toml_dict) - accr = AccrTC1980(toml_dict) - FT = CP.float_type(toml_dict) - return TC1980{FT, typeof(acnv), typeof(accr)}(acnv, accr) -end +TC1980(toml_dict::CP.ParamDict) = + TC1980(; acnv = AcnvTC1980(toml_dict), accr = AccrTC1980(toml_dict)) """ LD2004 @@ -281,7 +255,7 @@ DOI: 10.1175/1520-0469(2004)061<1539:POTAPI>2.0.CO;2 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct LD2004{FT} <: Precipitation2MType{FT} +@kwdef struct LD2004{FT} <: Precipitation2MType "Autoconversion coefficient R_6C_0" R_6C_0::FT "Autoconversion coefficient E_0" @@ -292,8 +266,6 @@ Base.@kwdef struct LD2004{FT} <: Precipitation2MType{FT} k::FT end -LD2004(::Type{FT}) where {FT <: AbstractFloat} = LD2004(CP.create_toml_dict(FT)) - function LD2004(td::CP.ParamDict) name_map = (; :LD2004_R_6C_coeff => :R_6C_0, @@ -302,8 +274,7 @@ function LD2004(td::CP.ParamDict) :threshold_smooth_transition_steepness => :k, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return LD2004{FT}(; parameters...) + return LD2004(; parameters...) end """ @@ -315,24 +286,20 @@ The type for 2-moment precipitation formation based on the # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct VarTimescaleAcnv{FT} <: Precipitation2MType{FT} +@kwdef struct VarTimescaleAcnv{FT} <: Precipitation2MType "Timescale [s]" τ::FT "Powerlaw coefficient [-]" α::FT end -VarTimescaleAcnv(::Type{FT}) where {FT <: AbstractFloat} = - VarTimescaleAcnv(CP.create_toml_dict(FT)) - function VarTimescaleAcnv(td::CP.ParamDict) name_map = (; :rain_autoconversion_timescale => :τ, :Variable_time_scale_autoconversion_coeff_alpha => :α, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return VarTimescaleAcnv{FT}(; parameters...) + return VarTimescaleAcnv(; parameters...) end """ @@ -341,9 +308,24 @@ end Abstract type for the size distribution parameters of rain particles See [`RainParticlePDF_SB2006_limited`](@ref) and [`RainParticlePDF_SB2006_notlimited`](@ref) -for the concrete types. +for the concrete types. These can be constructed with: +```julia +RainParticlePDF_SB2006(toml_dict; is_limited = true) # -> RainParticlePDF_SB2006_limited + +RainParticlePDF_SB2006(toml_dict; is_limited = false) # -> RainParticlePDF_SB2006_notlimited +``` +where `toml_dict` is a `CP.ParamDict` containing the parameters for the size +distribution, and `is_limited` is a boolean indicating whether to use the +limited or not limited version of the size distribution. """ -abstract type RainParticlePDF_SB2006{FT} <: ParametersType{FT} end +abstract type RainParticlePDF_SB2006 <: ParametersType end +RainParticlePDF_SB2006(toml_dict::CP.ParamDict; is_limited = true) = + is_limited ? + RainParticlePDF_SB2006_limited(toml_dict) : + RainParticlePDF_SB2006_notlimited(toml_dict) + +Base.show(io::IO, mime::MIME"text/plain", x::RainParticlePDF_SB2006) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) """ RainParticlePDF_SB2006_limited @@ -354,7 +336,7 @@ on drop maximum mass and the size distribution coefficinets N0 and lambda # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct RainParticlePDF_SB2006_limited{FT} <: RainParticlePDF_SB2006{FT} +@kwdef struct RainParticlePDF_SB2006_limited{FT} <: RainParticlePDF_SB2006 "Raindrop size distribution coefficient νr" νr::FT "Raindrop size distribution coefficient μr" @@ -391,8 +373,7 @@ function RainParticlePDF_SB2006_limited(td::CP.ParamDict) :SB2006_reference_air_density => :ρ0, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return RainParticlePDF_SB2006_limited{FT}(; parameters...) + return RainParticlePDF_SB2006_limited(; parameters...) end """ @@ -403,7 +384,7 @@ Rain size distribution parameters from SB2006 but without the limiters # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct RainParticlePDF_SB2006_notlimited{FT} <: RainParticlePDF_SB2006{FT} +@kwdef struct RainParticlePDF_SB2006_notlimited{FT} <: RainParticlePDF_SB2006 "Raindrop size distribution coefficient νr" νr::FT "Raindrop size distribution coefficient μr" @@ -428,12 +409,11 @@ function RainParticlePDF_SB2006_notlimited(td::CP.ParamDict) :SB2006_reference_air_density => :ρ0, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return RainParticlePDF_SB2006_notlimited{FT}(; parameters...) + return RainParticlePDF_SB2006_notlimited(; parameters...) end -islimited(pdf::RainParticlePDF_SB2006_limited) = true -islimited(pdf::RainParticlePDF_SB2006_notlimited) = false +islimited(::RainParticlePDF_SB2006_limited) = true +islimited(::RainParticlePDF_SB2006_notlimited) = false """ CloudParticlePDF_SB2006 @@ -443,7 +423,7 @@ Cloud droplets size distribution parameters from SB2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct CloudParticlePDF_SB2006{FT} <: ParametersType{FT} +@kwdef struct CloudParticlePDF_SB2006{FT} <: ParametersType "Cloud droplet size distribution coefficient νc" νc::FT "Cloud droplet size distribution coefficient μc" @@ -465,8 +445,7 @@ function CloudParticlePDF_SB2006(td::CP.ParamDict) :density_liquid_water => :ρw, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return CloudParticlePDF_SB2006{FT}(; parameters...) + return CloudParticlePDF_SB2006(; parameters...) end """ @@ -477,7 +456,7 @@ Autoconversion parameters from SB2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AcnvSB2006{FT} <: ParametersType{FT} +@kwdef struct AcnvSB2006{FT} <: ParametersType "Collection kernel coefficient" kcc::FT "Minimum mass of rain droplets" @@ -502,8 +481,7 @@ function AcnvSB2006(td::CP.ParamDict) :SB2006_autoconversion_correcting_function_coeff_b => :b, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AcnvSB2006{FT}(; parameters...) + return AcnvSB2006(; parameters...) end @@ -515,7 +493,7 @@ Accretion parameters from SB2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct AccrSB2006{FT} <: ParametersType{FT} +@kwdef struct AccrSB2006{FT} <: ParametersType "Collection kernel coefficient Kcr" kcr::FT "Accretion correcting function coefficient τ_0" @@ -534,8 +512,7 @@ function AccrSB2006(td::CP.ParamDict) :SB2006_accretion_correcting_function_coeff_c => :c, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return AccrSB2006{FT}(; parameters...) + return AccrSB2006(; parameters...) end """ @@ -546,7 +523,7 @@ Rain selfcollection parameters from SB2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct SelfColSB2006{FT} <: ParametersType{FT} +@kwdef struct SelfColSB2006{FT} <: ParametersType "Collection kernel coefficient krr" krr::FT "Collection kernel coefficient kappa rr" @@ -562,8 +539,7 @@ function SelfColSB2006(td::CP.ParamDict) Symbol("SB2006_raindrops_self-collection_coeff_d") => :d, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return SelfColSB2006{FT}(; parameters...) + return SelfColSB2006(; parameters...) end """ @@ -574,7 +550,7 @@ Rain breakup parameters from SB2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct BreakupSB2006{FT} <: ParametersType{FT} +@kwdef struct BreakupSB2006{FT} <: ParametersType "Raindrop equilibrium mean diamater" Deq::FT "Raindrop breakup mean diamater threshold" @@ -593,8 +569,7 @@ function BreakupSB2006(td::CP.ParamDict) :SB2006_raindrops_breakup_coeff_kappabr => :κbr, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return BreakupSB2006{FT}(; parameters...) + return BreakupSB2006(; parameters...) end """ @@ -605,14 +580,14 @@ Rain evaporation parameters from SB2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct EvaporationSB2006{FT} <: ParametersType{FT} - "Ventillation coefficient a" +@kwdef struct EvaporationSB2006{FT} <: ParametersType + "Ventilation coefficient a" av::FT - "Ventillation coefficient b" + "Ventilation coefficient b" bv::FT - "Rain evapoartion coefficient α" + "Rain evaporation coefficient α" α::FT - "Rain evapoartion coefficient β" + "Rain evaporation coefficient β" β::FT "Reference air density [kg/m3]" ρ0::FT @@ -627,8 +602,7 @@ function EvaporationSB2006(td::CP.ParamDict) :SB2006_reference_air_density => :ρ0, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return EvaporationSB2006{FT}(; parameters...) + return EvaporationSB2006(; parameters...) end """ @@ -639,7 +613,7 @@ Number concentration adjustment parameter from Horn (2012, DOI: 10.5194/gmd-5-34 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct NumberAdjustmentHorn2012{FT} <: ParametersType{FT} +@kwdef struct NumberAdjustmentHorn2012{FT} <: ParametersType "Number concentration adjustment timescale [s]" τ::FT end @@ -649,8 +623,7 @@ function NumberAdjustmentHorn2012(td::CP.ParamDict) :Horn2012_number_concentration_adjustment_timescale => :τ, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return NumberAdjustmentHorn2012{FT}(; parameters...) + return NumberAdjustmentHorn2012(; parameters...) end """ @@ -665,7 +638,7 @@ DOI: 10.1007/s00703-005-0112-4 # Fields $(DocStringExtensions.FIELDS) """ -struct SB2006{FT, PDc, PDr, AV, AR, SC, BR, EV, NA} <: Precipitation2MType{FT} +@kwdef struct SB2006{PDc, PDr, AV, AR, SC, BR, EV, NA} <: Precipitation2MType "Cloud particle size distribution parameters" pdf_c::PDc "Rain particle size distribution parameters" @@ -684,37 +657,15 @@ struct SB2006{FT, PDc, PDr, AV, AR, SC, BR, EV, NA} <: Precipitation2MType{FT} numadj::NA end -SB2006(::Type{FT}, is_limited = true) where {FT <: AbstractFloat} = - SB2006(CP.create_toml_dict(FT), is_limited) - -function SB2006(toml_dict::CP.ParamDict, is_limited = true) - pdf_c = CloudParticlePDF_SB2006(toml_dict) - pdf_r = - is_limited ? RainParticlePDF_SB2006_limited(toml_dict) : - RainParticlePDF_SB2006_notlimited(toml_dict) - acnv = AcnvSB2006(toml_dict) - accr = AccrSB2006(toml_dict) - self = SelfColSB2006(toml_dict) - brek = BreakupSB2006(toml_dict) - evap = EvaporationSB2006(toml_dict) - numadj = NumberAdjustmentHorn2012(toml_dict) - FT = CP.float_type(toml_dict) - PDc = typeof(pdf_c) - PDr = typeof(pdf_r) - AN = typeof(acnv) - AR = typeof(accr) - SE = typeof(self) - BR = typeof(brek) - EV = typeof(evap) - NA = typeof(numadj) - return SB2006{FT, PDc, PDr, AN, AR, SE, BR, EV, NA}( - pdf_c, - pdf_r, - acnv, - accr, - self, - brek, - evap, - numadj, +# Construct SB2006 from a ClimaParams TOML dict +SB2006(toml_dict::CP.ParamDict; is_limited = true) = + SB2006(; + pdf_c = CloudParticlePDF_SB2006(toml_dict), + pdf_r = RainParticlePDF_SB2006(toml_dict; is_limited), + acnv = AcnvSB2006(toml_dict), + accr = AccrSB2006(toml_dict), + self = SelfColSB2006(toml_dict), + brek = BreakupSB2006(toml_dict), + evap = EvaporationSB2006(toml_dict), + numadj = NumberAdjustmentHorn2012(toml_dict), ) -end diff --git a/src/parameters/Microphysics2MParams.jl b/src/parameters/Microphysics2MParams.jl index 0a302c7fc..f661ad26a 100644 --- a/src/parameters/Microphysics2MParams.jl +++ b/src/parameters/Microphysics2MParams.jl @@ -1,7 +1,7 @@ export Microphysics2MParams, WarmRainParams2M, P3IceParams """ - WarmRainParams2M{FT, SB, AP} + WarmRainParams2M Parameters for 2-moment warm rain processes (Seifert-Beheng 2006). @@ -9,13 +9,22 @@ Parameters for 2-moment warm rain processes (Seifert-Beheng 2006). - `seifert_beheng::SB`: SB2006 — all warm rain parameters (autoconversion, accretion, etc.) - `air_properties::AP`: AirProperties — air properties for evaporation """ -struct WarmRainParams2M{FT, SB, AP} <: ParametersType{FT} +@kwdef struct WarmRainParams2M{SB, AP} <: ParametersType seifert_beheng::SB air_properties::AP end +# Construct WarmRainParams2M from a ClimaParams TOML dictionary +WarmRainParams2M(toml_dict::CP.ParamDict; is_limited = true) = + WarmRainParams2M(; + seifert_beheng = SB2006(toml_dict; is_limited), + air_properties = AirProperties(toml_dict), + ) + +Base.show(io::IO, mime::MIME"text/plain", x::WarmRainParams2M) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) """ - P3IceParams{FT, P3, VL, PDc, PDr} + P3IceParams Parameters for P3 ice-phase processes (optional). @@ -25,15 +34,24 @@ Parameters for P3 ice-phase processes (optional). - `cloud_pdf::PDc`: CloudParticlePDF_SB2006 — cloud droplet size distribution - `rain_pdf::PDr`: RainParticlePDF_SB2006 — rain drop size distribution """ -struct P3IceParams{FT, P3, VL, PDc, PDr} <: ParametersType{FT} +@kwdef struct P3IceParams{P3, VL, PDc, PDr} <: ParametersType scheme::P3 terminal_velocity::VL cloud_pdf::PDc rain_pdf::PDr end +Base.show(io::IO, mime::MIME"text/plain", x::P3IceParams) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) + +P3IceParams(toml_dict::CP.ParamDict; is_limited = true) = + P3IceParams(; + scheme = ParametersP3(toml_dict), + terminal_velocity = Chen2022VelType(toml_dict), + cloud_pdf = CloudParticlePDF_SB2006(toml_dict), + rain_pdf = RainParticlePDF_SB2006(toml_dict; is_limited), + ) """ - Microphysics2MParams{FT, WR, ICE} Unified parameter container for 2-moment microphysics. @@ -56,23 +74,12 @@ mp_warm = CMP.Microphysics2MParams(Float64; with_ice = false) mp_p3 = CMP.Microphysics2MParams(Float64; with_ice = true) ``` """ -struct Microphysics2MParams{FT, WR, ICE} <: ParametersType{FT} +@kwdef struct Microphysics2MParams{WR, ICE} <: ParametersType warm_rain::WR ice::ICE end - -""" - Microphysics2MParams(::Type{FT}; with_ice = false, is_limited = true) where {FT <: AbstractFloat} - -Create a `Microphysics2MParams` object from a floating point type. - -# Arguments -- `FT`: Floating point type (e.g., Float64, Float32) -- `with_ice`: Include P3 ice-phase parameters (default: false) -- `is_limited`: Use limited rain size distribution parameters (default: true) -""" -Microphysics2MParams(::Type{FT}; with_ice = false, is_limited = true) where {FT <: AbstractFloat} = - Microphysics2MParams(CP.create_toml_dict(FT); with_ice, is_limited) +Base.show(io::IO, mime::MIME"text/plain", x::Microphysics2MParams) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) """ Microphysics2MParams(toml_dict::CP.ParamDict; with_ice = false, is_limited = true) @@ -84,34 +91,10 @@ Create a `Microphysics2MParams` object from a ClimaParams TOML dictionary. - `with_ice`: Include P3 ice-phase parameters (default: false) - `is_limited`: Use limited rain size distribution parameters (default: true) """ -function Microphysics2MParams(toml_dict::CP.ParamDict; with_ice = false, is_limited = true) - FT = CP.float_type(toml_dict) - - # Warm rain parameters (always present) - seifert_beheng = SB2006(toml_dict, is_limited) - air_properties = AirProperties(toml_dict) - warm_rain = WarmRainParams2M{FT, typeof(seifert_beheng), typeof(air_properties)}( - seifert_beheng, - air_properties, +Microphysics2MParams(toml_dict::CP.ParamDict; with_ice = false, is_limited = true) = + Microphysics2MParams(; + # Warm rain parameters (always present) + warm_rain = WarmRainParams2M(toml_dict; is_limited), + # Optional ice phase parameters + ice = with_ice ? P3IceParams(toml_dict; is_limited) : nothing, ) - - # Optional ice phase parameters - ice = if with_ice - scheme = ParametersP3(toml_dict) - terminal_velocity = Chen2022VelType(toml_dict) - cloud_pdf = CloudParticlePDF_SB2006(toml_dict) - rain_pdf = - is_limited ? RainParticlePDF_SB2006_limited(toml_dict) : - RainParticlePDF_SB2006_notlimited(toml_dict) - P3IceParams{FT, typeof(scheme), typeof(terminal_velocity), typeof(cloud_pdf), typeof(rain_pdf)}( - scheme, - terminal_velocity, - cloud_pdf, - rain_pdf, - ) - else - nothing - end - - return Microphysics2MParams{FT, typeof(warm_rain), typeof(ice)}(warm_rain, ice) -end diff --git a/src/parameters/MicrophysicsP3.jl b/src/parameters/MicrophysicsP3.jl index c740f5b1f..1899f2048 100644 --- a/src/parameters/MicrophysicsP3.jl +++ b/src/parameters/MicrophysicsP3.jl @@ -23,7 +23,7 @@ A part of the [`ParametersP3`](@ref) parameter set. # Fields $(DocStringExtensions.FIELDS) """ -@kwdef struct MassPowerLaw{FT} <: ParametersType{FT} +@kwdef struct MassPowerLaw{FT} <: ParametersType "Coefficient in mass(size) relation [`kg m^(-β_va)`]" α_va::FT "Coefficient in mass(size) relation [`-`]" @@ -57,7 +57,7 @@ A part of the [`ParametersP3`](@ref) parameter set. # Fields $(DocStringExtensions.FIELDS) """ -@kwdef struct AreaPowerLaw{FT} <: ParametersType{FT} +@kwdef struct AreaPowerLaw{FT} <: ParametersType "Scale [`μm^(2-σ)`]" γ::FT "Power [`-`]" @@ -71,13 +71,13 @@ function AreaPowerLaw(toml_dict::CP.ParamDict) end """ - SlopeLaw{FT} + SlopeLaw The top-level super-type for slope parameterizations. See [`SlopePowerLaw`](@ref) and [`SlopeConstant`](@ref) for concrete implementations. """ -abstract type SlopeLaw{FT} <: ParametersType{FT} end +abstract type SlopeLaw <: ParametersType end """ SlopePowerLaw{FT} @@ -101,7 +101,7 @@ A part of the [`ParametersP3`](@ref) parameter set. # Fields $(DocStringExtensions.FIELDS) """ -@kwdef struct SlopePowerLaw{FT} <: SlopeLaw{FT} +@kwdef struct SlopePowerLaw{FT} <: SlopeLaw "Scale [`m^b`]" a::FT "Power [`-`]" @@ -119,8 +119,7 @@ function SlopePowerLaw(toml_dict::CP.ParamDict) :Heymsfield_mu_cutoff => :μ_max, ) params = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - FT = CP.float_type(toml_dict) - return SlopePowerLaw{FT}(; params...) + return SlopePowerLaw(; params...) end """ @@ -137,15 +136,14 @@ A part of the [`ParametersP3`](@ref) parameter set. # Fields $(DocStringExtensions.FIELDS) """ -@kwdef struct SlopeConstant{FT} <: SlopeLaw{FT} +@kwdef struct SlopeConstant{FT} <: SlopeLaw "Slope parameter μ [`-`]" μ::FT end function SlopeConstant(toml_dict::CP.ParamDict) name_map = (; :P3_constant_slope_parameterization_value => :μ) params = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - FT = CP.float_type(toml_dict) - return SlopeConstant{FT}(; params...) + return SlopeConstant(; params...) end """ @@ -166,7 +164,7 @@ A part of the [`ParametersP3`](@ref) parameter set. # Fields $(DocStringExtensions.FIELDS) """ -@kwdef struct VentilationFactor{FT} <: ParametersType{FT} +@kwdef struct VentilationFactor{FT} <: ParametersType "Constant coefficient in ventilation factor [`-`]" aᵥ::FT "Linear coefficient in ventilation factor [`-`]" @@ -178,8 +176,7 @@ function VentilationFactor(toml_dict::CP.ParamDict) :SB2006_ventilation_factor_coeff_bv => :bᵥ, ) params = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - FT = CP.float_type(toml_dict) - return VentilationFactor{FT}(; params...) + return VentilationFactor(; params...) end """ @@ -202,7 +199,7 @@ The range is extended to `R_i ≤ 12`, by linearly interpolating between For calculating Rᵢ, see [`compute_local_rime_density`](@ref CloudMicrophysics.P3Scheme.compute_local_rime_density). """ -@kwdef struct LocalRimeDensity{FT} <: ParametersType{FT} +@kwdef struct LocalRimeDensity{FT} <: ParametersType "Constant coefficient" a::FT "Linear coefficient" @@ -220,8 +217,7 @@ function LocalRimeDensity(toml_dict::CP.ParamDict) :density_ice_water => :ρ_ice, ) params = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - FT = CP.float_type(toml_dict) - return LocalRimeDensity{FT}(; params...) + return LocalRimeDensity(; params...) end function ((; a, b, c, ρ_ice)::LocalRimeDensity)(Rᵢ) Rᵢ = clamp(Rᵢ, 1, 12) # P3 fortran code, microphy_p3.f90, Line 3315 clamps to 1 ≤ Rᵢ ≤ 12 @@ -247,7 +243,7 @@ end ### ----------------------------- ### """ - ParametersP3{FT} + ParametersP3 Parameters for P3 bulk microphysics scheme. @@ -256,7 +252,7 @@ From Morrison and Milbrandt (2015) [MorrisonMilbrandt2015](@cite) # Fields $(DocStringExtensions.FIELDS) """ -@kwdef struct ParametersP3{FT, SLOPELAW <: SlopeLaw{FT}} <: ParametersType{FT} +@kwdef struct ParametersP3{FT, SLOPELAW <: SlopeLaw} <: ParametersType "Mass-size relation, e.g. [`MassPowerLaw`](@ref)" mass::MassPowerLaw{FT} "Area-size relation, e.g. [`AreaPowerLaw`](@ref)" @@ -277,45 +273,6 @@ $(DocStringExtensions.FIELDS) T_freeze::FT end -""" - ParametersP3(FT) - -Create a `ParametersP3` object from a floating point type `FT`. - -# Examples - -```jldoctest -julia> import CloudMicrophysics.Parameters as CMP - -julia> CMP.ParametersP3(Float64) -ParametersP3{Float64} -├── mass: MassPowerLaw -│ ├── α_va = 0.018537721864540644 [kg μm^(-β_va)] -│ └── β_va = 1.9 [-] -├── area: AreaPowerLaw -│ ├── γ = 0.2285 [μm^(2-σ)] -│ └── σ = 1.88 [-] -├── slope: SlopePowerLaw -│ ├── a = 0.00191 [m^b] -│ ├── b = 0.8 [-] -│ ├── c = 2.0 [-] -│ └── μ_max = 6.0 [-] -├── vent: VentilationFactor -│ ├── aᵥ = 0.78 [-] -│ └── bᵥ = 0.308 [-] -├── ρ_rim_local: LocalRimeDensity -│ ├── a = 51.0 [m^b] -│ ├── b = 114.0 [-] -│ ├── c = -5.5 [-] -│ └── ρ_ice = 916.7 [-] -├── τ_wet = 100.0 [s] -├── ρ_i = 916.7 [kg m⁻³] -├── ρ_l = 1000.0 [kg m⁻³] -└── T_freeze = 273.15 [K] -``` -""" -ParametersP3(::Type{FT}; kw...) where {FT} = ParametersP3(CP.create_toml_dict(FT); kw...) - """ ParametersP3(toml_dict::CP.ParamDict; [slope_law = :powerlaw]) @@ -328,91 +285,31 @@ Create a `ParametersP3` object from a `ClimaParams` TOML dictionary. """ function ParametersP3(toml_dict::CP.ParamDict; slope_law = :powerlaw) @assert slope_law in (:constant, :powerlaw) - mass = MassPowerLaw(toml_dict) - area = AreaPowerLaw(toml_dict) - slope = if slope_law == :powerlaw - SlopePowerLaw(toml_dict) - else - SlopeConstant(toml_dict) - end - vent = VentilationFactor(toml_dict) - ρ_rim_local = LocalRimeDensity(toml_dict) - name_map = (; - :density_ice_water => :ρ_i, - :density_liquid_water => :ρ_l, - :temperature_water_freeze => :T_freeze, - :P3_wet_growth_timescale => :τ_wet, + params = CP.get_parameter_values(toml_dict, + (; + :density_ice_water => :ρ_i, + :density_liquid_water => :ρ_l, + :temperature_water_freeze => :T_freeze, + :P3_wet_growth_timescale => :τ_wet, + ), "CloudMicrophysics") + return ParametersP3(; + mass = MassPowerLaw(toml_dict), + area = AreaPowerLaw(toml_dict), + slope = slope_law == :powerlaw ? SlopePowerLaw(toml_dict) : SlopeConstant(toml_dict), + vent = VentilationFactor(toml_dict), + ρ_rim_local = LocalRimeDensity(toml_dict), + params..., ) - params = CP.get_parameter_values(toml_dict, name_map, "CloudMicrophysics") - FT = CP.float_type(toml_dict) - return ParametersP3{FT, typeof(slope)}(; mass, area, slope, vent, ρ_rim_local, params...) end ### ----------------- ### ### ----- UTILS ----- ### ### ----------------- ### -function Base.show( - io::IO, - p::Union{ - ParametersP3, - MassPowerLaw, - AreaPowerLaw, - SlopePowerLaw, - SlopeConstant, - VentilationFactor, - LocalRimeDensity, - }, -) - indent = get(io, :indent, "") - prefix = get(io, :prefix, "") - - # Get type information - T = typeof(p) - FT = eltype(p) - type = (FT != get(io, :typeinfo, Any)) ? "{$FT}" : "" - - # Print type name, handling nested types - type_name = T.name.name - println(io, "$(prefix)$(type_name)$type") - - # Print each field - fields = fieldnames(T) - for (i, field) in enumerate(fields) - value = getfield(p, field) - is_last = i == length(fields) - prefix_char = is_last ? "└" : "├" - - if typeof(value) <: Number - # Simple value - print directly with unit - unit = _get_parameter_unit(field) - println( - io, - "$(indent)$(prefix_char)── $(field) = $(value) [$(unit)]", - ) - else - # Nested struct - recursively show with proper context - nested_io = IOContext( - io, - :prefix => "$(prefix_char)── $(field): ", - :indent => "$(indent)│ ", - :typeinfo => FT, - ) - show(nested_io, value) - end - end -end - -function _get_parameter_unit(field::Symbol) - units = Dict( - :α_va => "kg μm^(-β_va)", - :γ => "μm^(2-σ)", - :a => "m^b", - :τ_wet => "s", - :ρ_i => "kg m⁻³", - :ρ_l => "kg m⁻³", - :T_freeze => "K", - ) - # unitless parameters: β_va, σ, b, c, μ_max, μ, aᵥ, bᵥ - return get(units, field, "-") -end +# Unit annotations for verbose show (used by ShowMethods.verbose_show_type_and_fields) +ShowMethods.field_units(::MassPowerLaw) = (; α_va = "kg m^(-β_va)") +ShowMethods.field_units(::AreaPowerLaw) = (; γ = "μm^(2-σ)") +ShowMethods.field_units(::SlopePowerLaw) = (; a = "m^b") +ShowMethods.field_units(::LocalRimeDensity) = (; ρ_ice = "kg m⁻³") +ShowMethods.field_units(::ParametersP3) = + (; τ_wet = "s", ρ_i = "kg m⁻³", ρ_l = "kg m⁻³", T_freeze = "K") diff --git a/src/parameters/Parameters.jl b/src/parameters/Parameters.jl index 16b8aadb6..dc7391757 100644 --- a/src/parameters/Parameters.jl +++ b/src/parameters/Parameters.jl @@ -9,6 +9,7 @@ using DocStringExtensions import ClimaParams as CP import SpecialFunctions as SF +import CloudMicrophysics: ShowMethods # Super-types (dispatch, broadcasting, etc...) include("AbstractTypes.jl") @@ -51,4 +52,22 @@ include("Microphysics1MParams.jl") include("Microphysics2MParams.jl") +### Create methods that enables the creation of parameter types with a given float type +### for all subtypes of `ParametersType` +### e.g. `Microphysics1MParams(Float32)` +import InteractiveUtils +function get_concrete_subtypes(type) + sub_types = InteractiveUtils.subtypes(type) + isempty(sub_types) && return [type] + + concrete_types = [] + for t in sub_types + append!(concrete_types, get_concrete_subtypes(t)) + end + return concrete_types +end +for T in get_concrete_subtypes(ParametersType) + @eval (::Type{$T})(::Type{FT}; kw...) where {FT} = $T(CP.create_toml_dict(FT); kw...) +end + end # module diff --git a/src/parameters/TerminalVelocity.jl b/src/parameters/TerminalVelocity.jl index a9259aa7c..eaa30153a 100644 --- a/src/parameters/TerminalVelocity.jl +++ b/src/parameters/TerminalVelocity.jl @@ -9,7 +9,7 @@ for rain # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Blk1MVelTypeRain{FT} <: ParametersType{FT} +@kwdef struct Blk1MVelTypeRain{FT} <: ParametersType "particle length scale [m]" r0::FT "rain terminal velocity size relation coefficient [-]" @@ -53,11 +53,10 @@ function Blk1MVelTypeRain(td::CP.ParamDict) parameters = CP.get_parameter_values(td, vel_map, "CloudMicrophysics") mass_p = CP.get_parameter_values(td, mass_map, "CloudMicrophysics") area_p = CP.get_parameter_values(td, area_map, "CloudMicrophysics") - FT = CP.float_type(td) - gamma_vent = FT(SF.gamma((parameters.ve + parameters.Δv + 5) / 2)) - gamma_term = FT(SF.gamma(mass_p.me + parameters.ve + mass_p.Δm + parameters.Δv + 1)) - gamma_accr = FT(SF.gamma(area_p.ae + parameters.ve + area_p.Δa + parameters.Δv + 1)) - return Blk1MVelTypeRain{FT}(; parameters..., gamma_vent, gamma_term, gamma_accr) + gamma_vent = SF.gamma((parameters.ve + parameters.Δv + 5) / 2) + gamma_term = SF.gamma(mass_p.me + parameters.ve + mass_p.Δm + parameters.Δv + 1) + gamma_accr = SF.gamma(area_p.ae + parameters.ve + area_p.Δa + parameters.Δv + 1) + return Blk1MVelTypeRain(; parameters..., gamma_vent, gamma_term, gamma_accr) end """ @@ -69,7 +68,7 @@ for snow # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Blk1MVelTypeSnow{FT} <: ParametersType{FT} +@kwdef struct Blk1MVelTypeSnow{FT} <: ParametersType "particle length scale [m]" r0::FT "snow terminal velocity size relation coefficient [-]" @@ -107,12 +106,12 @@ function Blk1MVelTypeSnow(td::CP.ParamDict) mass_p = CP.get_parameter_values(td, mass_map, "CloudMicrophysics") area_p = CP.get_parameter_values(td, area_map, "CloudMicrophysics") - v0 = 2^(9 / 4) * parameters.r0^parameters.ve FT = CP.float_type(td) - gamma_vent = FT(SF.gamma((parameters.ve + parameters.Δv + 5) / 2)) - gamma_term = FT(SF.gamma(mass_p.me + parameters.ve + mass_p.Δm + parameters.Δv + 1)) - gamma_accr = FT(SF.gamma(area_p.ae + parameters.ve + area_p.Δa + parameters.Δv + 1)) - return Blk1MVelTypeSnow{FT}(; parameters..., v0, gamma_vent, gamma_term, gamma_accr) + v0 = FT(2^(9 / 4) * parameters.r0^parameters.ve) + gamma_vent = SF.gamma((parameters.ve + parameters.Δv + 5) / 2) + gamma_term = SF.gamma(mass_p.me + parameters.ve + mass_p.Δm + parameters.Δv + 1) + gamma_accr = SF.gamma(area_p.ae + parameters.ve + area_p.Δa + parameters.Δv + 1) + return Blk1MVelTypeSnow(; parameters..., v0, gamma_vent, gamma_term, gamma_accr) end """ @@ -124,20 +123,18 @@ The type for precipitation terminal velocity from the simple 1-moment scheme # Fields $(DocStringExtensions.FIELDS) """ -struct Blk1MVelType{FT, R, S} <: TerminalVelocityType{FT} +@kwdef struct Blk1MVelType{R, S} <: TerminalVelocityType rain::R snow::S end +Base.show(io::IO, mime::MIME"text/plain", x::Blk1MVelType) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) -Blk1MVelType(::Type{FT}) where {FT <: AbstractFloat} = - Blk1MVelType(CP.create_toml_dict(FT)) - -function Blk1MVelType(toml_dict::CP.ParamDict) - rain = Blk1MVelTypeRain(toml_dict) - snow = Blk1MVelTypeSnow(toml_dict) - FT = CP.float_type(toml_dict) - return Blk1MVelType{FT, typeof(rain), typeof(snow)}(rain, snow) -end +Blk1MVelType(toml_dict::CP.ParamDict) = + Blk1MVelType(; + rain = Blk1MVelTypeRain(toml_dict), + snow = Blk1MVelTypeSnow(toml_dict), + ) """ StokesRegimeVelType @@ -147,15 +144,12 @@ The type for precipitation terminal velocity in the Stokes regime (Re < 1) # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct StokesRegimeVelType{FT} <: TerminalVelocityType{FT} +@kwdef struct StokesRegimeVelType{FT} <: TerminalVelocityType ρw::FT ν_air::FT grav::FT end -StokesRegimeVelType(::Type{FT}) where {FT <: AbstractFloat} = - StokesRegimeVelType(CP.create_toml_dict(FT)) - function StokesRegimeVelType(td::CP.ParamDict) name_map = (; :density_liquid_water => :ρw, @@ -163,8 +157,7 @@ function StokesRegimeVelType(td::CP.ParamDict) :gravitational_acceleration => :grav, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return StokesRegimeVelType{FT}(; parameters...) + return StokesRegimeVelType(; parameters...) end """ @@ -175,7 +168,7 @@ The type for precipitation terminal velocity from Seifert and Beheng 2006 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct SB2006VelType{FT} <: TerminalVelocityType{FT} +@kwdef struct SB2006VelType{FT} <: TerminalVelocityType ρ0::FT aR::FT bR::FT @@ -185,9 +178,6 @@ Base.@kwdef struct SB2006VelType{FT} <: TerminalVelocityType{FT} grav::FT end -SB2006VelType(::Type{FT}) where {FT <: AbstractFloat} = - SB2006VelType(CP.create_toml_dict(FT)) - function SB2006VelType(td::CP.ParamDict) name_map = (; :SB2006_reference_air_density => :ρ0, @@ -199,8 +189,7 @@ function SB2006VelType(td::CP.ParamDict) :gravitational_acceleration => :grav, ) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return SB2006VelType{FT}(; parameters...) + return SB2006VelType(; parameters...) end """ @@ -212,7 +201,7 @@ See Table B3 for parameter definitions. DOI: 10.1016/j.atmosres.2022.106171 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Chen2022VelTypeSmallIce{FT, N, M} <: TerminalVelocityType{FT} +@kwdef struct Chen2022VelTypeSmallIce{FT, N, M} <: TerminalVelocityType A::NTuple{N, FT} B::NTuple{N, FT} C::NTuple{M, FT} @@ -222,6 +211,8 @@ Base.@kwdef struct Chen2022VelTypeSmallIce{FT, N, M} <: TerminalVelocityType{FT} "cutoff for small vs large ice particle dimension [m]" cutoff::FT end +Base.show(io::IO, mime::MIME"text/plain", x::Chen2022VelTypeSmallIce) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) function Chen2022VelTypeSmallIce(td::CP.ParamDict) # TODO: These should be array parameters. @@ -250,7 +241,7 @@ See Table B4 for parameter definitions. DOI: 10.1016/j.atmosres.2022.106171 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Chen2022VelTypeLargeIce{FT, N} <: TerminalVelocityType{FT} +@kwdef struct Chen2022VelTypeLargeIce{FT, N} <: TerminalVelocityType A::NTuple{N, FT} B::NTuple{N, FT} C::NTuple{N, FT} @@ -291,7 +282,7 @@ DOI: 10.1016/j.atmosres.2022.106171 # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct Chen2022VelTypeRain{FT, N} <: TerminalVelocityType{FT} +@kwdef struct Chen2022VelTypeRain{FT, N} <: TerminalVelocityType ρ0::FT a::NTuple{N, FT} a3_pow::FT @@ -299,9 +290,8 @@ Base.@kwdef struct Chen2022VelTypeRain{FT, N} <: TerminalVelocityType{FT} b_ρ::FT c::NTuple{N, FT} end - -Chen2022VelTypeRain(::Type{FT}) where {FT <: AbstractFloat} = - Chen2022VelTypeRain(CP.create_toml_dict(FT)) +Base.show(io::IO, mime::MIME"text/plain", x::Chen2022VelTypeRain) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) function Chen2022VelTypeRain(td::CP.ParamDict) name_map = (; @@ -329,34 +319,23 @@ DOI: 10.1016/j.atmosres.2022.106171 # Fields $(DocStringExtensions.FIELDS) """ -struct Chen2022VelType{FT, R, SI, LI} <: TerminalVelocityType{FT} +@kwdef struct Chen2022VelType{R, SI, LI} <: TerminalVelocityType rain::R small_ice::SI large_ice::LI end - -Chen2022VelType(::Type{FT}) where {FT <: AbstractFloat} = - Chen2022VelType(CP.create_toml_dict(FT)) - -function Chen2022VelType(toml_dict::CP.ParamDict) - rain = Chen2022VelTypeRain(toml_dict) - small_ice = Chen2022VelTypeSmallIce(toml_dict) - large_ice = Chen2022VelTypeLargeIce(toml_dict) - FT = CP.float_type(toml_dict) - return Chen2022VelType{ - FT, - typeof(rain), - typeof(small_ice), - typeof(large_ice), - }( - rain, - small_ice, - large_ice, +Chen2022VelType(toml_dict::CP.ParamDict) = + Chen2022VelType(; + rain = Chen2022VelTypeRain(toml_dict), + small_ice = Chen2022VelTypeSmallIce(toml_dict), + large_ice = Chen2022VelTypeLargeIce(toml_dict), ) -end + +Base.show(io::IO, mime::MIME"text/plain", x::Chen2022VelType) = + ShowMethods.verbose_show_type_and_fields(io, mime, x) """ - TerminalVelocityParams{FT, STOKES, CHEN, BLK1M} + TerminalVelocityParams Unified container for all terminal velocity parameterizations used in CloudMicrophysics. @@ -409,23 +388,12 @@ v_snow = CM1.terminal_velocity(snow, tv.blk1m.snow, ρ, q_sno) - [`Chen2022VelType`](@ref): Chen et al. (2022) terminal velocity - [`Blk1MVelType`](@ref): 1-moment bulk terminal velocity """ -struct TerminalVelocityParams{FT, STOKES, CHEN, BLK1M} <: ParametersType{FT} +@kwdef struct TerminalVelocityParams{STOKES, CHEN, BLK1M} <: ParametersType stokes::STOKES chen2022::CHEN blk1m::BLK1M end -""" - TerminalVelocityParams(::Type{FT}) where {FT <: AbstractFloat} - -Create a `TerminalVelocityParams` object from a floating point type. - -# Arguments -- `FT`: Floating point type (e.g., Float64, Float32) -""" -TerminalVelocityParams(::Type{FT}) where {FT <: AbstractFloat} = - TerminalVelocityParams(CP.create_toml_dict(FT)) - """ TerminalVelocityParams(toml_dict::CP.ParamDict) @@ -434,16 +402,9 @@ Create a `TerminalVelocityParams` object from a ClimaParams TOML dictionary. # Arguments - `toml_dict`: ClimaParams parameter dictionary """ -function TerminalVelocityParams(toml_dict::CP.ParamDict) - FT = CP.float_type(toml_dict) - - stokes = StokesRegimeVelType(toml_dict) - chen2022 = Chen2022VelType(toml_dict) - blk1m = Blk1MVelType(toml_dict) - - return TerminalVelocityParams{FT, typeof(stokes), typeof(chen2022), typeof(blk1m)}( - stokes, - chen2022, - blk1m, +TerminalVelocityParams(toml_dict::CP.ParamDict) = + TerminalVelocityParams(; + stokes = StokesRegimeVelType(toml_dict), + chen2022 = Chen2022VelType(toml_dict), + blk1m = Blk1MVelType(toml_dict), ) -end diff --git a/src/parameters/WaterProperties.jl b/src/parameters/WaterProperties.jl index aaa9153be..95c5da47f 100644 --- a/src/parameters/WaterProperties.jl +++ b/src/parameters/WaterProperties.jl @@ -8,19 +8,15 @@ Parameters with water properties. # Fields $(DocStringExtensions.FIELDS) """ -Base.@kwdef struct WaterProperties{FT} <: ParametersType{FT} +@kwdef struct WaterProperties{FT} <: ParametersType "density of liquid water [kg/m3]" ρw::FT "density of ice [kg/m3]" ρi::FT end -WaterProperties(::Type{FT}) where {FT <: AbstractFloat} = - WaterProperties(CP.create_toml_dict(FT)) - function WaterProperties(td::CP.ParamDict) name_map = (; :density_liquid_water => :ρw, :density_ice_water => :ρi) parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics") - FT = CP.float_type(td) - return WaterProperties{FT}(; parameters...) + return WaterProperties(; parameters...) end diff --git a/src/show.jl b/src/show.jl new file mode 100644 index 000000000..b80f1aec9 --- /dev/null +++ b/src/show.jl @@ -0,0 +1,304 @@ +""" +This module contains methods for showing parameter structs in a human-friendly way. + +# Main show methods + +- [`verbose_show_type_and_fields(io::IO, ::MIME"text/plain", x; kw...)`](@ref) +- [`compact_show_type_and_fields(io::IO, ::MIME"text/plain", x; kw...)`](@ref) +- [`parseable_show_with_fields_no_type_header(io::IO, x; kw...)`](@ref) + +The verbose and compact methods display multiline and singleline representations +of the contents of the structs in a human-friendly way. The parseable method +displays a singleline representation of the struct such that it can be copied +and pasted back into the REPL to recreate the struct. See their respective +signatures for additional keyword arguments, which modify how the output is +displayed. + +# Use with parameter structs + +For convenience all subtypes of [`ParametersType`](@ref CloudMicrophysics.Parameters.ParametersType) +are defined to use: + +```julia +Base.show(io::IO, x::ParametersType) = + ShowMethods.parseable_show_with_fields_no_type_header(io, x; with_module_prefix = false) +Base.show(io::IO, mime::MIME"text/plain", x::ParametersType) = + ShowMethods.show_type_and_fields(io, mime, x) +``` + +The second method, [`show_type_and_fields`](@ref), automatically selects between +[`verbose_show_type_and_fields`](@ref) and [`compact_show_type_and_fields`](@ref) +based on the number of fields in the struct (current cutoff is 7 fields). +This minimizes the need to define custom show methods for new parameter structs. + +For wrapper-structs (structs that contain other structs, +e.g. [`Microphysics2MParams`](@ref CloudMicrophysics.Parameters.Microphysics2MParams)), +it may be desireable to define +```julia +Base.show(io::IO, mime::MIME"text/plain", x::WrapperStruct) = + ShowMethods.verbose_show_type_and_fields(io, mime, x; with_module_prefix = false) +``` +even if the number of fields is small, as the contents of the containing fields +may be large. + +# Units + +The verbose and compact show methods also display units, if defined. +If the contents of a struct are numbers, it may be useful to define +[`field_units`](@ref) for the struct: +```julia +@kwdef struct MyStruct{FT} + velocity::FT + mass::FT + constant_value::FT +end + +Base.show(io::IO, mime::MIME"text/plain", x::MyStruct) = + ShowMethods.compact_show_type_and_fields(io, mime, x) + +ShowMethods.field_units(x::MyStruct) = (; velocity = "m/s", mass = "kg") +``` +If a field is not present in the returned `NamedTuple`, it is assumed to be +dimensionless. In the example above, `constant_value` is dimensionless. When +this struct is displayed in REPL, it will be shown as: +```julia-repl +julia> MyStruct(; velocity = 1.0, mass = 2.0, constant_value = 3.0) +MyStruct(velocity = 1.0 [m/s], mass = 2.0 [kg], constant_value = 3.0 [-]) +``` +As a reminder, as long as the parameter struct is a subtype of +[`ParametersType`](@ref CloudMicrophysics.Parameters.ParametersType), +you should not need to define `Base.show` for it. + + +Further reading: [julia discourse](https://discourse.julialang.org/t/print-vs-two-argument-show-repr-vs-three-argument-show-repr-with-mime-text-plain/117790) +""" +module ShowMethods + +# TODO: Add these once JuliaFormatter supports `public` +# see e.g. https://github.com/julia-vscode/julia-vscode/issues/3860 +# public verbose_show_type_and_fields +# public compact_show_type_and_fields +# public parseable_show_with_fields_no_type_header +# public show_type_and_fields + + +### ----------------------- ### +### Helper methods for show ### +### ----------------------- ### + +""" + verbose_show_type_and_fields(io::IO, ::MIME"text/plain", x; with_module_prefix = false) + +Print a verbose representation of the type and fields of `x` to `io`. + +# Keyword arguments +- `with_module_prefix = false`: Use module-qualified type name. + + When true, display e.g. `CloudMicrophysics.Parameters.AirProperties` + + When false, display e.g. `AirProperties` +""" +function verbose_show_type_and_fields(io::IO, mime::MIME"text/plain", x; with_module_prefix = false) + compact = get(io, :compact, false)::Bool + indent = get(io, :indent, "")::String + typename = _type_name(x; with_module_prefix) + keys = fieldnames(typeof(x)) + vals = [getfield(x, k) for k in keys] + units = field_units(x) + print(io, "$(typename)") + if compact + print(io, "(") + for (k, v) in zip(keys, vals) + print(io, "$k = ", v, ",") + k == keys[end] || print(io, " ") + end + print(io, ")") + else + for (i, (k, v)) in enumerate(zip(keys, vals)) + is_last = i == length(keys) + connector = is_last ? "└─ " : "├─ " + continuation = is_last ? " " : "│ " + if _is_nested_struct(v) + print(io, "\n$(indent)$(connector)$(k): ") + nested_io = IOContext(io, :indent => indent * continuation) + show(nested_io, mime, v) + elseif v isa NamedTuple && length(v) > 5 + # Large NamedTuples: print on new lines with tree formatting + print(io, "\n$(indent)$(connector)$(k):") + nt_keys = Base.keys(v) + for (j, nk) in enumerate(nt_keys) + nt_last = j == length(nt_keys) + nt_connector = nt_last ? "└─ " : "├─ " + print(io, "\n$(indent)$(continuation)$(nt_connector)$(nk) = ", v[nk]) + end + else + print(io, "\n$(indent)$(connector)$(k) = ", v) + _print_unit(io, units, k) + end + end + end +end + +""" + compact_show_type_and_fields(io::IO, ::MIME"text/plain", x; kw...) + +Print a compact one-line representation of `x`: `TypeName(field = value, ...)`. + +# Keyword arguments +- `with_units = true`: Append unit annotations from [`field_units`](@ref). + + When true, display e.g. `1.0 [m/s]` (if [`field_units`](@ref) is defined for the struct) + + When false, display only the value, e.g. `1.0` +- `with_kwargs = true`: Print fields as keyword arguments (`field = value`). + + It is recommended that this is `true` only when the struct has + a `@kwdef` prefix to its definition, which provides a keyword constructor. +- `with_module_prefix = false`: Use module-qualified type name. + + When true, display e.g. `CloudMicrophysics.Parameters.AirProperties` + + When false, display e.g. `AirProperties` +- `skip_fields_by_value = ()`: Skip fields whose values are in this tuple. + + This is useful for skipping default values when displaying the struct + in the REPL, for example. + +# Example output + +```julia-repl +julia> import CloudMicrophysics.Parameters as CMP + +julia> ap = CMP.AirProperties(Float32) +AirProperties(K_therm = 0.024 [W/m/K], D_vapor = 2.26e-5 [m²/s], ν_air = 1.6e-5 [m²/s]) +``` +""" +function compact_show_type_and_fields(io::IO, ::MIME"text/plain", x; + with_units = true, with_kwargs = true, + with_module_prefix = false, skip_fields_by_value = (), +) + typename = _type_name(x; with_module_prefix) + keys = fieldnames(typeof(x)) + vals = [getfield(x, k) for k in keys] + units = with_units ? field_units(x) : nothing + print(io, typename, "(") + printed_first = false + for (k, v) in zip(keys, vals) + v ∈ skip_fields_by_value && continue + printed_first && print(io, ", ") + with_kwargs && print(io, k, " = ") + show(io, v) + _print_unit(io, units, k) + printed_first = true + end + print(io, ")") +end + +""" + parseable_show_with_fields_no_type_header(io::IO, x; kw...) + +Print a parseable (copy-pasteable) one-line representation of `x`. +Thin wrapper around [`compact_show_type_and_fields`](@ref) with +`with_units = false` and `with_module_prefix = true` by default. + +Note: This assumes that the type has a `@kwdef` prefix to its definition, +which provides a keyword constructor. + +# Examples +```julia-repl +julia> show(stdout, CM.Parameters.NumberAdjustmentHorn2012(τ = 3.0f0)) +CloudMicrophysics.Parameters.NumberAdjustmentHorn2012(τ = 3.0f0) +``` +""" +parseable_show_with_fields_no_type_header(io::IO, x; with_module_prefix = true, kw...) = + compact_show_type_and_fields(io, MIME("text/plain"), x; + with_units = false, with_module_prefix, kw..., + ) + + +""" + show_type_and_fields(io::IO, mime::MIME"text/plain", x; threshold = 7, kw...) + +Auto-select verbose or compact display based on field count. + +Types with more than `threshold` fields are displayed with +[`verbose_show_type_and_fields`](@ref) (multi-line tree). +Types with `threshold` or fewer fields use +[`compact_show_type_and_fields`](@ref) (one-liner with units). +""" +show_type_and_fields(io::IO, mime::MIME"text/plain", x; threshold = 7, kw...) = + if fieldcount(typeof(x)) > threshold + verbose_show_type_and_fields(io, mime, x; kw...) + else + compact_show_type_and_fields(io, mime, x; kw...) + end + + +### +### Internal helper methods +### + +""" + field_units(x) + +Return a `NamedTuple` mapping field names to unit strings for type `x`, +or `nothing` if no units are defined. + +# Example + +To include unit annotations in the verbose or compact `show` output for a type, +define a method that associates field names with units, such as + +```julia +@kwdef struct MyStruct{FT} + velocity::FT + mass::FT + constant_value::FT +end + +Base.show(io::IO, mime::MIME"text/plain", x::MyStruct) = + ShowMethods.compact_show_type_and_fields(io, mime, x) + +ShowMethods.field_units(x::MyStruct) = (; velocity = "m/s", mass = "kg") +``` + +If a field is not present in the returned `NamedTuple`, it is assumed to be +dimensionless. In the example above, `constant_value` is dimensionless. When +this struct is displayed in REPL, it will be shown as: + +```julia-repl +julia> MyStruct(; velocity = 1.0, mass = 2.0, constant_value = 3.0) +MyStruct(velocity = 1.0 [m/s], mass = 2.0 [kg], constant_value = 3.0 [-]) +``` + +As a reminder, as long as the parameter struct is a subtype of +[`ParametersType`](@ref CloudMicrophysics.Parameters.ParametersType), +you should not need to define `Base.show` for it. +""" +field_units(_) = nothing + +"Print unit annotation for field `k` based on the units spec." +_print_unit(::IO, _, _) = nothing +function _print_unit(io::IO, units::NamedTuple, k::Symbol) + unit = haskey(units, k) ? units[k] : "-" + print(io, " [", unit, "]") +end + +function _type_name(x; with_module_prefix = false) + c = Base.text_colors[:cyan] + n = Base.text_colors[:normal] + name = if with_module_prefix + # name with module prefix, e.g. CloudMicrophysics.Parameters.SB2006 + typeof(x).name.wrapper + else + # name without module prefix, e.g. SB2006 + typeof(x).name.name + end + return string(c, name, n) +end + +""" + _is_nested_struct(v) + +Return `true` if `v` is a composite struct that should be recursively +pretty-printed (i.e. a non-trivial struct with fields, but not a +`Number`, `AbstractString`, `Symbol`, or `Nothing`). +""" +_is_nested_struct(v) = + isstructtype(typeof(v)) && + fieldcount(typeof(v)) > 0 && + !(v isa Union{Number, AbstractString, Symbol, Nothing}) + +end # module ShowMethods diff --git a/test/cloud_diagnostics.jl b/test/cloud_diagnostics.jl index 0cab05969..61ac9989b 100644 --- a/test/cloud_diagnostics.jl +++ b/test/cloud_diagnostics.jl @@ -18,7 +18,7 @@ function test_cloud_diagnostics(FT) ) toml_dict = CP.create_toml_dict(FT; override_file) SB2006 = CMP.SB2006(toml_dict) - SB2006_no_limiters = CMP.SB2006(toml_dict, false) + SB2006_no_limiters = CMP.SB2006(toml_dict; is_limited = false) # Water parameters wtr = CMP.WaterProperties(FT) diff --git a/test/common_types_tests.jl b/test/common_types_tests.jl index bc381c0eb..fde432fc3 100644 --- a/test/common_types_tests.jl +++ b/test/common_types_tests.jl @@ -3,13 +3,13 @@ import CloudMicrophysics.Parameters as CMP function test_common_types_broadcasts(FT) for some_type in ( - CMP.ParametersType{FT}, - CMP.AerosolType{FT}, + CMP.ParametersType, + CMP.AerosolType, CMP.AerosolDistributionType, - CMP.CloudCondensateType{FT}, - CMP.PrecipitationType{FT}, - CMP.TerminalVelocityType{FT}, - CMP.Precipitation2MType{FT}, + CMP.CloudCondensateType, + CMP.PrecipitationType, + CMP.TerminalVelocityType, + CMP.Precipitation2MType, CMP.ArizonaTestDust{FT}, CMP.DesertDust{FT}, CMP.Kaolinite{FT}, @@ -48,7 +48,7 @@ function test_common_types_broadcasts(FT) CMP.AccrTC1980{FT}, CMP.LD2004{FT}, CMP.VarTimescaleAcnv{FT}, - CMP.RainParticlePDF_SB2006{FT}, + CMP.RainParticlePDF_SB2006, CMP.CloudParticlePDF_SB2006{FT}, CMP.AcnvSB2006{FT}, CMP.AccrSB2006{FT}, diff --git a/test/gpu_tests.jl b/test/gpu_tests.jl index ba70805b7..94335f839 100644 --- a/test/gpu_tests.jl +++ b/test/gpu_tests.jl @@ -457,7 +457,7 @@ function test_gpu(FT) # 2-moment microphysics SB2006 = CMP.SB2006(FT) - SB2006_no_limiters = CMP.SB2006(FT, false) + SB2006_no_limiters = CMP.SB2006(FT; is_limited = false) KK2000 = CMP.KK2000(FT) B1994 = CMP.B1994(FT) TC1980 = CMP.TC1980(FT) diff --git a/test/microphysics2M_tests.jl b/test/microphysics2M_tests.jl index e029d8fc9..a8e1f0c56 100644 --- a/test/microphysics2M_tests.jl +++ b/test/microphysics2M_tests.jl @@ -28,7 +28,7 @@ function test_microphysics2M(FT) ) toml_dict = CP.create_toml_dict(FT; override_file) SB2006 = CMP.SB2006(toml_dict) - SB2006_no_limiters = CMP.SB2006(toml_dict, false) + SB2006_no_limiters = CMP.SB2006(toml_dict; is_limited = false) # Thermodynamics and air properties parameters aps = CMP.AirProperties(FT) diff --git a/test/performance_tests.jl b/test/performance_tests.jl index be00b89f4..5c1181624 100644 --- a/test/performance_tests.jl +++ b/test/performance_tests.jl @@ -90,7 +90,7 @@ function benchmark_test(FT) override_file = joinpath(pkgdir(CM), "src", "parameters", "toml", "SB2006_limiters.toml") toml_dict = CP.create_toml_dict(FT; override_file) sb2006 = CMP.SB2006(toml_dict) - sb2006_no_limiters = CMP.SB2006(toml_dict, false) + sb2006_no_limiters = CMP.SB2006(toml_dict; is_limited = false) # P3 parameters params_P3 = CMP.ParametersP3(FT)