101101
102102"""
103103 bulk_microphysics_tendencies(
104- ::Microphysics1Moment,
105- mp,
106- tps,
107- ρ,
108- T,
109- q_tot,
110- q_lcl,
111- q_icl,
112- q_rai,
113- q_sno,
104+ ::Microphysics1Moment, mp, tps,
105+ ρ, T, q_tot, q_lcl, q_icl, q_rai, q_sno,
114106 )
115107
116108Compute all 1-moment microphysics tendencies in one fused call.
@@ -157,17 +149,8 @@ This is a pure function of local thermodynamic state, suitable for:
157149 Limiters depend on timestep `dt` and should be applied by the caller after computing tendencies.
158150"""
159151@inline function bulk_microphysics_tendencies (
160- :: Microphysics1Moment ,
161- mp:: CMP.Microphysics1MParams ,
162- tps,
163- ρ,
164- T,
165- q_tot,
166- q_lcl,
167- q_icl,
168- q_rai,
169- q_sno,
170- N_lcl = zero (ρ),
152+ :: Microphysics1Moment , mp:: CMP.Microphysics1MParams , tps,
153+ ρ, T, q_tot, q_lcl, q_icl, q_rai, q_sno, N_lcl = zero (ρ),
171154)
172155 # Clamp negative inputs to zero (robustness against numerical errors)
173156 ρ = UT. clamp_to_nonneg (ρ)
@@ -590,12 +573,8 @@ the second form uses the supersaturation threshold `S_0 * q_vap_sat`.
590573- Does NOT apply limiters (caller applies based on timestep)
591574"""
592575@inline function bulk_microphysics_tendencies (
593- :: Microphysics0Moment ,
594- mp:: CMP.Microphysics0MParams ,
595- tps,
596- T,
597- q_lcl,
598- q_icl,
576+ :: Microphysics0Moment , mp:: CMP.Microphysics0MParams , tps,
577+ T, q_lcl, q_icl,
599578)
600579 q_lcl = UT. clamp_to_nonneg (q_lcl)
601580 q_icl = UT. clamp_to_nonneg (q_icl)
@@ -642,7 +621,13 @@ Used by both warm-only and warm+ice dispatch methods to reduce code duplication.
642621- `dn_lcl_dt`: Cloud number tendency (1/kg/s)
643622- `dn_rai_dt`: Rain number tendency (1/kg/s)
644623"""
645- @inline function warm_rain_tendencies_2m (sb, q_lcl, q_rai, ρ, n_lcl, n_rai)
624+ @inline function warm_rain_tendencies_2m (warm_rain, tps, T, q_tot, q_lcl, q_rai, q_ice, ρ, n_lcl, n_rai)
625+
626+ # Unpack parameters
627+ sb = warm_rain. seifert_beheng
628+ aps = warm_rain. air_properties
629+ condevap = warm_rain. condevap
630+
646631 # Convert to number densities for CM2 functions
647632 N_lcl = ρ * n_lcl
648633 N_rai = ρ * n_rai
@@ -654,6 +639,17 @@ Used by both warm-only and warm+ice dispatch methods to reduce code duplication.
654639 dn_lcl_dt = zero (FT)
655640 dn_rai_dt = zero (FT)
656641
642+ # --- Condensation of vapor / evaporation of cloud liquid water ---
643+ ∂ₜq_lcl_cond = CMNonEq. conv_q_vap_to_q_lcl_icl_MM2015 (condevap, tps, q_tot, q_lcl, q_ice, q_rai, zero (q_ice), ρ, T)
644+ ∂ₜn_lcl_cond = zero (∂ₜq_lcl_cond) # neglect number change from condensation/evaporation
645+ dq_lcl_dt += ∂ₜq_lcl_cond
646+ dn_lcl_dt += ∂ₜn_lcl_cond
647+
648+ # --- Evaporation of rain ---
649+ evap = CM2. rain_evaporation (sb, aps, tps, q_tot, q_lcl, q_ice, q_rai, zero (q_ice), ρ, N_rai, T)
650+ dq_rai_dt += evap.∂ₜq_rai
651+ dn_rai_dt += evap.∂ₜρn_rai / ρ
652+
657653 # --- Autoconversion ---
658654 acnv = CM2. autoconversion (sb. acnv, sb. pdf_c, q_lcl, q_rai, ρ, N_lcl)
659655 dq_lcl_dt += acnv. dq_lcl_dt
@@ -679,6 +675,17 @@ Used by both warm-only and warm+ice dispatch methods to reduce code duplication.
679675 dn_rai_br = CM2. rain_breakup (sb. pdf_r, sb. brek, q_rai, ρ, N_rai, dn_rai_sc)
680676 dn_rai_dt += dn_rai_br / ρ
681677
678+ # --- Number adjustment for mass limits ---
679+ # Cloud liquid
680+ dn_lcl_inc = CM2. number_increase_for_mass_limit (sb. numadj, sb. pdf_c. xc_max, q_lcl, ρ, N_lcl)
681+ dn_lcl_dec = CM2. number_decrease_for_mass_limit (sb. numadj, sb. pdf_c. xc_min, q_lcl, ρ, N_lcl)
682+ dn_lcl_dt += (dn_lcl_inc + dn_lcl_dec) / ρ
683+
684+ # Rain
685+ dn_rai_inc = CM2. number_increase_for_mass_limit (sb. numadj, sb. pdf_r. xr_max, q_rai, ρ, N_rai)
686+ dn_rai_dec = CM2. number_decrease_for_mass_limit (sb. numadj, sb. pdf_r. xr_min, q_rai, ρ, N_rai)
687+ dn_rai_dt += (dn_rai_inc + dn_rai_dec) / ρ
688+
682689 return (; dq_lcl_dt, dq_rai_dt, dn_lcl_dt, dn_rai_dt)
683690end
684691
689696 bulk_microphysics_tendencies(
690697 ::Microphysics2Moment,
691698 mp::Microphysics2MParams{WR, Nothing},
692- ...
699+ ρ, T, q_tot, q_lcl, n_lcl, q_rai, n_rai,
693700 )
694701
695702Compute 2-moment **warm rain only** microphysics tendencies (Seifert-Beheng 2006).
@@ -719,21 +726,9 @@ For warm rain + P3 ice, see the method that accepts `Microphysics2MParams{FT, WR
719726- `db_rim_dt`: Rime volume tendency (always zero for warm-only)
720727"""
721728@inline function bulk_microphysics_tendencies (
722- :: Microphysics2Moment ,
723- mp:: CMP.Microphysics2MParams{WR, Nothing} ,
724- tps,
725- ρ,
726- T,
727- q_tot,
728- q_lcl,
729- n_lcl,
730- q_rai,
731- n_rai,
732- q_ice = zero (ρ),
733- n_ice = zero (ρ),
734- q_rim = zero (ρ),
735- b_rim = zero (ρ),
736- logλ = zero (ρ),
729+ :: Microphysics2Moment , mp:: CMP.Microphysics2MParams{WR, Nothing} , tps,
730+ ρ, T, q_tot, q_lcl, n_lcl, q_rai, n_rai,
731+ q_ice = zero (ρ), n_ice = zero (ρ), q_rim = zero (ρ), b_rim = zero (ρ), logλ = zero (ρ),
737732) where {WR}
738733 # Clamp negative inputs to zero (robustness against numerical errors)
739734 ρ = UT. clamp_to_nonneg (ρ)
@@ -747,50 +742,27 @@ For warm rain + P3 ice, see the method that accepts `Microphysics2MParams{FT, WR
747742 q_rim = UT. clamp_to_nonneg (q_rim)
748743 b_rim = UT. clamp_to_nonneg (b_rim)
749744
750- # Unpack warm rain parameters
751- sb = mp. warm_rain. seifert_beheng
752- aps = mp. warm_rain. air_properties
753-
754745 # Initialize ice-related tendencies (always zero for warm-only)
755746 dq_ice_dt = zero (ρ)
756747 dq_rim_dt = zero (ρ)
757748 db_rim_dt = zero (ρ)
758749
759750 # --- Core Warm Rain Processes (shared helper) ---
760- warm = warm_rain_tendencies_2m (sb, q_lcl, q_rai, ρ, n_lcl, n_rai)
751+ warm = warm_rain_tendencies_2m (mp . warm_rain, tps, T, q_tot, q_lcl, q_rai, q_ice , ρ, n_lcl, n_rai)
761752 dq_lcl_dt = warm. dq_lcl_dt
762753 dn_lcl_dt = warm. dn_lcl_dt
763754 dq_rai_dt = warm. dq_rai_dt
764755 dn_rai_dt = warm. dn_rai_dt
765756
766- # Convert to number densities for remaining functions
767- N_lcl = ρ * n_lcl
768- N_rai = ρ * n_rai
769-
770- # --- Rain evaporation ---
771- evap = CM2. rain_evaporation (sb, aps, tps, zero (ρ), q_lcl, zero (ρ), q_rai, zero (ρ), ρ, N_rai, T)
772- dq_rai_dt += evap. evap_rate_1
773- dn_rai_dt += evap. evap_rate_0 / ρ
774-
775- # --- Number adjustment for mass limits ---
776- # Cloud liquid
777- dn_lcl_inc = CM2. number_increase_for_mass_limit (sb. numadj, sb. pdf_c. xc_max, q_lcl, ρ, N_lcl)
778- dn_lcl_dec = CM2. number_decrease_for_mass_limit (sb. numadj, sb. pdf_c. xc_min, q_lcl, ρ, N_lcl)
779- dn_lcl_dt += (dn_lcl_inc + dn_lcl_dec) / ρ
780-
781- # Rain
782- dn_rai_inc = CM2. number_increase_for_mass_limit (sb. numadj, sb. pdf_r. xr_max, q_rai, ρ, N_rai)
783- dn_rai_dec = CM2. number_decrease_for_mass_limit (sb. numadj, sb. pdf_r. xr_min, q_rai, ρ, N_rai)
784- dn_rai_dt += (dn_rai_inc + dn_rai_dec) / ρ
785-
786757 return (; dq_lcl_dt, dn_lcl_dt, dq_rai_dt, dn_rai_dt, dq_ice_dt, dq_rim_dt, db_rim_dt)
787758end
788759
789760"""
790761 bulk_microphysics_tendencies(
791762 ::Microphysics2Moment,
792763 mp::Microphysics2MParams{FT, WR, <:P3IceParams},
793- ...
764+ ρ, T, q_tot, q_lcl, n_lcl, q_rai, n_rai,
765+ q_ice, n_ice, q_rim, b_rim, logλ,
794766 )
795767
796768Compute 2-moment **warm rain + P3 ice** microphysics tendencies.
@@ -828,21 +800,9 @@ to be non-Nothing, eliminating runtime type checks and dynamic dispatch.
828800- `db_rim_dt`: Rime volume tendency (m³/kg/s)
829801"""
830802@inline function bulk_microphysics_tendencies (
831- :: Microphysics2Moment ,
832- mp:: CMP.Microphysics2MParams{WR, ICE} ,
833- tps,
834- ρ,
835- T,
836- q_tot,
837- q_lcl,
838- n_lcl,
839- q_rai,
840- n_rai,
841- q_ice = zero (ρ),
842- n_ice = zero (ρ),
843- q_rim = zero (ρ),
844- b_rim = zero (ρ),
845- logλ = zero (ρ),
803+ :: Microphysics2Moment , mp:: CMP.Microphysics2MParams{WR, ICE} , tps,
804+ ρ, T, q_tot, q_lcl, n_lcl, q_rai, n_rai,
805+ q_ice = zero (ρ), n_ice = zero (ρ), q_rim = zero (ρ), b_rim = zero (ρ), logλ = zero (ρ),
846806) where {WR, ICE <: CMP.P3IceParams }
847807 # Clamp negative inputs to zero (robustness against numerical errors)
848808 ρ = UT. clamp_to_nonneg (ρ)
@@ -857,7 +817,6 @@ to be non-Nothing, eliminating runtime type checks and dynamic dispatch.
857817 b_rim = UT. clamp_to_nonneg (b_rim)
858818
859819 # Unpack warm rain parameters (always present)
860- sb = mp. warm_rain. seifert_beheng
861820 aps = mp. warm_rain. air_properties
862821
863822 # Initialize ice-related tendencies
@@ -868,7 +827,7 @@ to be non-Nothing, eliminating runtime type checks and dynamic dispatch.
868827 db_rim_dt = zero (ρ)
869828
870829 # --- Core Warm Rain Processes (shared helper) ---
871- warm = warm_rain_tendencies_2m (sb, q_lcl, q_rai, ρ, n_lcl, n_rai)
830+ warm = warm_rain_tendencies_2m (mp . warm_rain, tps, T, q_tot, q_lcl, q_rai, q_ice , ρ, n_lcl, n_rai)
872831 dq_lcl_dt = warm. dq_lcl_dt
873832 dn_lcl_dt = warm. dn_lcl_dt
874833 dq_rai_dt = warm. dq_rai_dt
@@ -878,26 +837,7 @@ to be non-Nothing, eliminating runtime type checks and dynamic dispatch.
878837 N_lcl = ρ * n_lcl
879838 N_rai = ρ * n_rai
880839
881- # --- Rain evaporation ---
882- evap = CM2. rain_evaporation (sb, aps, tps, zero (ρ), q_lcl, zero (ρ), q_rai, zero (ρ), ρ, N_rai, T)
883- dq_rai_dt += evap. evap_rate_1
884- dn_rai_dt += evap. evap_rate_0 / ρ
885-
886- # --- Number adjustment for mass limits ---
887- # Cloud liquid
888- dn_lcl_inc = CM2. number_increase_for_mass_limit (sb. numadj, sb. pdf_c. xc_max, q_lcl, ρ, N_lcl)
889- dn_lcl_dec = CM2. number_decrease_for_mass_limit (sb. numadj, sb. pdf_c. xc_min, q_lcl, ρ, N_lcl)
890- dn_lcl_dt += (dn_lcl_inc + dn_lcl_dec) / ρ
891-
892- # Rain
893- dn_rai_inc = CM2. number_increase_for_mass_limit (sb. numadj, sb. pdf_r. xr_max, q_rai, ρ, N_rai)
894- dn_rai_dec = CM2. number_decrease_for_mass_limit (sb. numadj, sb. pdf_r. xr_min, q_rai, ρ, N_rai)
895- dn_rai_dt += (dn_rai_inc + dn_rai_dec) / ρ
896-
897840 # --- P3 Ice Processes ---
898- # NOTE: P3 uses gamma_inc_inv from SpecialFunctions which is NOT GPU-compatible
899- # (it uses string formatting for errors). We must keep if-branches to skip
900- # P3 code when there is no ice, otherwise GPU compilation fails.
901841 p3 = mp. ice. scheme
902842 vel = mp. ice. terminal_velocity
903843 pdf_c = mp. ice. cloud_pdf
0 commit comments