Budget
- WSM6MassConservation
model
atmospheric_dynamics
wsm6
Mass-conservation rescaling of the WSM6 process rates and the state update it feeds, transcribed from the block 'check mass conservation of generation terms and feedback to the large scale' of mp_wsm6_run (phys/physics_mmm/mp_wsm6.F90, WRF 4.8 NCAR/MMM-physics). The process rates of warm_rain.esm, cold_accretion.esm and ice_deposition.esm each carry their OWN limiter (a single process may not drain more than q/dtcld), but nothing stops the SUM of the processes draining one species from overdrawing it within a sub-step; WSM6 therefore walks the five species budgets in the fixed order cloud water, cloud ice, rain, snow, graupel (four in the warm branch: cloud water, rain, snow, graupel) and, whenever the total sink S of a species over one sub-step exceeds the mass v = max(q_floor, q) available, multiplies EVERY rate entering that budget by v/S. The factors are written branch-free as v/max(S, v) (microphysics_templates.esm mass_conservation_factor), which is 1 for a budget that is not overdrawn and for a net source. Because the blocks run in sequence, a rate that appears in several budgets is scaled once per budget, so its final value is the raw rate times the PRODUCT of the factors of the species whose budgets it drains -- praut = praut_raw f_qc f_qr, paacw = paacw_raw f_qc f_qs f_qg, piacr = piacr_raw f_qr f_qs f_qg, and so on -- which is how the cascade is written here, one factor per species instead of one rescaled copy per block. This is a TIME-STEP ARTEFACT of the explicit operator splitting, not physics: every factor depends on dtcld and all of them are 1 in the dtcld -> 0 limit (EqWeFiC FORTRAN_BUGS.md note N3). The same block then applies the rescaled rates to the state ('feedback to the large scale'): the vapor tendency dqv_dt (WSM6 work2), the latent-heating tendency dT_dt (WSM6 -xlwork2/cpm, with the latent heats xl of vaporization, xls of sublimation and xls - xl of fusion), and the updated mixing ratios, each floored at zero. Below 0 C (`cold`) the deposition/ice branch runs and the ice-rain collection products are partitioned between snow and graupel by the switches delta2, delta3 (rain and snow below the threshold par.q_delta = 1e-4 kg/kg send the products to snow); above 0 C only evaporation of melting precipitation, enhanced melting and pgacs act, cloud ice is untouched, and the accreted cloud water goes to rain rather than to the collector. The two branches are blended with the indicator `cold` rather than an ifelse per quantity, so that each updated field is one expression. The latent heats xl and cpm are INPUTS from saturation.esm at the START-of-sub-step state, as WSM6 uses them (EqWeFiC FORTRAN_BUGS.md note N4), while the mixing ratios and temperature are the state at which the rates were evaluated (after the sub-step's sedimentation, melting and freezing). Consumer-supplied inputs: the column fields T, qv, qc, qi, qr, qs, qg, xl, cpm and the 22 raw process rates are REWRITE-TARGET ops `input_<name>` (esm-spec 4.2 open tier) that the consumer lowers -- in the inline tests through a per-test `expression_template_imports` library (tests/<id>_inputs.esm, extracted from kernel dumps of the instrumented WRF fork ctessum-claude/WRF, commit e42a269 (v4.8.0-2-ge42a269e)) because esm-spec 6.6 `parameter_overrides` admit scalars only, and in EqWeFiC couplings/microphysics_column*.esm through the additive `<name>_in` coupling-target parameters. psacw and pgacw are not inputs: only their mixing-ratio-weighted mean paacw enters the budgets and the update. EqWeFiC, cited here for FORTRAN_BUGS.md and couplings/, is https://github.com/EarthSciML/EqWeFiC, where these components were developed and are coupled into a WRF column.