@@ -369,6 +369,95 @@ as `bulk_microphysics_tendencies`.
369369 return (; ∂tendency_∂q_lcl, ∂tendency_∂q_icl, ∂tendency_∂q_rai, ∂tendency_∂q_sno)
370370end
371371
372+ # --- 2-Moment Microphysics derivatives ---
373+
374+ """
375+ bulk_microphysics_derivatives(
376+ ::Microphysics2Moment,
377+ mp,
378+ tps,
379+ ρ,
380+ T,
381+ q_tot,
382+ q_lcl,
383+ q_icl,
384+ q_rai,
385+ q_sno,
386+ n_lcl,
387+ n_rai,
388+ )
389+
390+ Compute 2-moment microphysics tendency derivatives in one fused call.
391+
392+ Returns leading-order derivatives of species tendencies w.r.t. their own
393+ specific content (q) and number (n). Rain uses the 2-moment rain evaporation
394+ derivatives; snow and cloud formation derivatives are zero for now.
395+
396+ # Arguments
397+ - `mp`: Microphysics2MParams (warm rain; ice optional)
398+ - `n_lcl`, `n_rai`: Cloud and rain number per kg air (1/kg); N_rai = ρ * n_rai used for rain evaporation derivative
399+
400+ # Returns
401+ `NamedTuple` with fields: `∂tendency_∂q_lcl`, `∂tendency_∂q_icl`, `∂tendency_∂q_rai`, `∂tendency_∂q_sno`, `∂tendency_∂n_lcl`, `∂tendency_∂n_rai`
402+ """
403+ @inline function bulk_microphysics_derivatives (
404+ :: Microphysics2Moment ,
405+ mp:: CMP.Microphysics2MParams{FT, WR, ICE} ,
406+ tps,
407+ ρ,
408+ T,
409+ q_tot,
410+ q_lcl,
411+ q_icl,
412+ q_rai,
413+ q_sno,
414+ n_lcl,
415+ n_rai,
416+ ) where {FT, WR, ICE}
417+ ρ = UT. clamp_to_nonneg (ρ)
418+ q_tot = UT. clamp_to_nonneg (q_tot)
419+ q_lcl = UT. clamp_to_nonneg (q_lcl)
420+ q_icl = UT. clamp_to_nonneg (q_icl)
421+ q_rai = UT. clamp_to_nonneg (q_rai)
422+ q_sno = UT. clamp_to_nonneg (q_sno)
423+ n_lcl = UT. clamp_to_nonneg (n_lcl)
424+ n_rai = UT. clamp_to_nonneg (n_rai)
425+
426+ sb = mp. warm_rain. seifert_beheng
427+ aps = mp. warm_rain. air_properties
428+ N_rai = ρ * n_rai
429+
430+ # TODO : Cloud formation — 2M bulk_microphysics_tendencies does not call cloud formation yet;
431+ # once it does, set these from MM2015 (same as 1M) via ∂conv_q_vap_to_q_lcl_icl_MM2015_∂q_cld.
432+ ∂tendency_∂q_lcl = zero (ρ)
433+ ∂tendency_∂q_icl = zero (ρ)
434+
435+ # 2-moment rain evaporation derivatives (return order: ∂n_rai, ∂q_rai, matching rain_evaporation)
436+ (; ∂N_rai, ∂q_rai) =
437+ CM2.∂rain_evaporation_∂N_rai_∂q_rai (sb, aps, tps, q_tot, q_lcl, q_icl, q_rai, q_sno, ρ, N_rai, T)
438+ ∂tendency_∂q_rai = ∂q_rai
439+ ∂tendency_∂n_rai = ∂N_rai / ρ
440+
441+ # TODO : 2M scheme also applies number/mass adjustment terms (e.g. number_increase_for_mass_limit,
442+ # number_decrease_for_mass_limit) to keep the assumed size distribution stable; consider adding
443+ # their derivatives here later.
444+
445+ # Snow derivative zero for now
446+ ∂tendency_∂q_sno = zero (ρ)
447+
448+ # Cloud number derivative zero for now
449+ ∂tendency_∂n_lcl = zero (ρ)
450+
451+ return (;
452+ ∂tendency_∂q_lcl,
453+ ∂tendency_∂q_icl,
454+ ∂tendency_∂q_rai,
455+ ∂tendency_∂q_sno,
456+ ∂tendency_∂n_lcl,
457+ ∂tendency_∂n_rai,
458+ )
459+ end
460+
372461# --- 0-Moment Microphysics ---
373462
374463"""
0 commit comments