Skip to content

Ram-pressure ISM stripping + precipitation regulation (now default-on)#20

Merged
MBradley1985 merged 13 commits into
devfrom
feature/ram-pressure-stripping
Jul 5, 2026
Merged

Ram-pressure ISM stripping + precipitation regulation (now default-on)#20
MBradley1985 merged 13 commits into
devfrom
feature/ram-pressure-stripping

Conversation

@MBradley1985

Copy link
Copy Markdown
Owner

Summary

Adds two physics channels, validated against microUchuu this branch, and turns them on by default:

  • Ram-pressure ISM stripping (RamPressureStrippingOn, default 1). Gunn & Gott (1972): satellite ColdGas at disk radius r is stripped where eps * rho_host(R_orb) * v_sat^2 > 2*pi*G*Sigma_disk(r)*Sigma_gas(r). Analytic stripped fraction (1 + r_strip/rs)*exp(-r_strip/rs), applied once per snapshot with the 1-exp(-dT/t_strip) cadence. Independent of PhysicalStrippingOn (hot/CGM starvation); covers Type 1 satellites and Type 2 orphans (frozen-orbit approximation, dormant in the default config). New src/model_ram_pressure.c.
  • Self-regulating precipitation (PrecipRegulationOn, default 1). The CGM precipitation flow condenses only the gas above the tcool/tff = threshold Voit equilibrium, so it relaxes to equilibrium instead of draining the reservoir at the free-fall rate.

Also includes a latent bugfix surfaced during the profile experiments: do_AGN_heating_cgm could let the caller overdraw the CGM by the Bondi-accreted mass (aborts under CGMDensityProfile=1).

Validation (microUchuu, on vs off)

  • Satellite HI-deficiency vs host mass reproduces the observed ladder (median HI retention 0.77 in 1e13 groups to 0.52 in >1e14.5 clusters).
  • Quenched Type-1 satellite fraction lifts toward Wetzel+12 at cluster scales.
  • Fixed-M* gas fractions move toward xGASS; global HIMF calibration-safe.
  • Precipitation regulation is the physically-correct Voit behaviour (macroscopically small at z=0, since little CGM sits in the marginal window).

Defaults & baselines

This intentionally changes the default output. Regression baselines (millennium, millennium_all) and the MPI benchmark reference were regenerated to bless the new physics as canonical; all verify passes. Classic-SAGE output remains reproducible via the vanilla configs (pinned off). RamPressureEpsilon (1.0) and both toggles are exposed in the parameter file.

Tests

  • 20/20 unit suites pass, including tests/test_ram_pressure.c and new precipitation-regulation cases in tests/test_cooling_heating.c.
  • millennium + millennium_all regression verify: pass (5444 datasets each).
  • MPI benchmark verify: pass (64 files).

Not included

Black-hole seeding was prototyped to probe the high-mass HIMF tail (it bracketed the problem: the tail is a BH-demographics issue, not a wind/cooling one) and then reverted -- that work belongs to the dedicated BH effort.

New model_ram_pressure.c implements the Gunn & Gott (1972) criterion for
stripping satellite ColdGas: gas at disk radius r is removed where
P_ram = eps * rho_host(R_orb) * v_sat^2 exceeds the restoring force
2*pi*G*Sigma_disk(r)*Sigma_gas(r). With exponential gas and stellar disks
sharing DiskScaleRadius the stripping radius is analytic and the stripped
fraction is (1 + r_strip/rs)*exp(-r_strip/rs).

The driver runs once per snapshot from evolve_galaxies(), outside the
substep loop, with the same 1-exp(-dT/t_strip) cadence and t_strip as the
PhysicalStrippingOn == 2 hot-gas scheme; the two channels are otherwise
independent (halo starvation vs ISM removal). Ambient density comes from
the same profiles the cooling recipes assume: cgm_density_at_radius()
(now external) for CGM-regime hosts, isothermal M_hot/(4 pi Rvir r^2)
for hot-regime hosts. Stripped gas and metals route to the central via
the regime-aware add_gas_to_hot_reservoir().

New optional parameters (registered and range-checked at startup):
RamPressureStrippingOn (0/1, default 0) and RamPressureEpsilon
(default 1.0, order-unity infall-geometry prefactor).

With the default RamPressureStrippingOn = 0 the millennium and
microuchuu baselines verify bit-identical.
Covers ram_pressure_stripped_fraction (bounds over 12 decades of P_ram,
guard values, monotonicity, f_strip = 1 at/above the central restoring
force, ~0 in the deep-potential limit, exact (1+x)exp(-x) at x = 2) and
ram_pressure_strip_satellite (mass and metal conservation between the
satellite and the host reservoir, metallicity of the stripped gas,
regime-aware routing to CGMgas, the 1-exp(-dt/t_strip) cadence factor,
no-ambient-medium / gas-free / zero-disk-radius guards, the Vvir
fallback for degenerate velocities, and weaker stripping at larger
orbital radius in the isothermal host profile).
Adds a ram_pressure_strip_satellite() section to docs/physics/infall.md
(criterion, ambient profiles, analytic stripped fraction, once-per-
snapshot cadence, the fixed-rs surface-density caveat, and the
calibration-check warning for toggled-on runs) and registers
RamPressureStrippingOn / RamPressureEpsilon in the parameter tables.
RamPressureStrippingOn = 0 and RamPressureEpsilon = 1.0, the built-in
defaults, so the millennium_all baseline stays bit-identical (verified:
5444 datasets).
plotting/rps_validation.py compares matched microUchuu runs (toggle
off / epsilon sweep) against the validation-plan observables:
quenched Type-1 satellite fraction vs host mass (Wetzel+12 SDSS band),
median satellite HI-to-stellar ratio vs host mass (Brown+17 trend),
the global HI mass function against the ALFALFA Schechter fit
(Jones+18) as the calibration-safety check, and median HI retention
vs time since infall split by host mass -- the cumulative-exposure
signature of the mechanism. Missing sweep runs are skipped so the
script works on any subset.
Orphans dominate cluster cores but were skipped, capping the HI
deficiency the channel can produce exactly where observations show the
strongest signal. Include them with a frozen-orbit approximation: the
position stays frozen at the snapshot the subhalo was lost (the true
orbit only decays further in, so rho_host and hence the stripping are
underestimated -- the conservative side), while the stale stored
velocity is replaced by the host Vvir, since its offset from the
CURRENT central velocity is not a meaningful orbital speed.

Adds a unit test pinning the orphan path to the equivalent Type 1
satellite at v = Vvir. Default-off output unchanged (millennium verify
bit-identical).
Type 2 orphans merge or disrupt within a snapshot of subhalo loss in
the default configuration (zero survive to any output), so the
frozen-orbit path only matters for configurations with long-lived
orphans.
do_AGN_heating_cgm clamps coolingGas against the pre-accretion CGMgas,
then subtracts the Bondi AGNaccreted from the reservoir -- so the
returned coolingGas can exceed the remaining CGM by up to AGNaccreted
and the caller overdraws it. Latent with the default uniform profile
(the overlap of a reservoir-limited cooling clamp and nonzero accretion
stays below the 1e-12 assert tolerance); CGMDensityProfile = 1 (NFW)
trips the XASSERT abort immediately at startup.

Millennium regression remains bit-identical; full unit suite passes.
The precipitation branch drains the CGM at dM/dt = f_precip * M_CGM /
t_ff once tcool/tff < PRECIP_THRESHOLD, so the only stable end state is
an empty reservoir: 99% of CGM-regime centrals at logMvir 11.3-12 sit
below the threshold (median tcool/tff ~ 0.2) and dump their whole CGM
into the disk, where H2-thermostated SF cannot consume it. This is the
dominant source of the factor 2-90 HIMF excess over ALFALFA and the
+0.2-0.45 dex offset from the xGASS gas fractions (the excess is 80%
centrals). The CGM density profile does not matter: NFW and beta runs
move the census by ~1% because the sigmoid saturates regardless.

PrecipRegulationOn = 1 condenses only the gas above the Voit
equilibrium: t_cool scales as 1/M_CGM at fixed profile and temperature,
so M_eq = M_CGM * (tcool/tff)/threshold and

    dM/dt = f_precip * (M_CGM - M_eq) / t_ff

relaxes toward tcool/tff = threshold and shuts off, converting the
free-fall dump of the stored reservoir into a pass-through limited by
the rate at which infall and reheated gas push the CGM back over M_eq.

Default 0 is byte-identical (millennium verify passes). Unit tests
cover the exact throttle factor and the self-quenching relaxation.
BHs currently bootstrap only through mergers and disk instabilities, so
merger-poor field halos arrive at the Mshock crossing with undermassive
BHs (median logM_BH 6.7 vs 7.4 for normal 1e12 centrals) and no
radio-mode maintenance -- they keep cooling at 14-38 Msun/yr and build
the logMHI > 10.5 tail of the HI mass function (x50-90 over ALFALFA,
unmoved by every wind/cooling/reincorporation lever tested).

BlackHoleSeedOn = 1 gives every new galaxy a BlackHoleSeedMass seed
(default 1e-5 = 10^5 Msun/h) so the Bondi radio-mode loop can engage in
quiet halos. EXPERIMENTAL placeholder for the dedicated BH-seeding work;
default 0 leaves output bit-identical (millennium verify passes).
…efault

Flip RamPressureStrippingOn and PrecipRegulationOn to on by default after
the microUchuu validation this branch built:
- RamPressureStrippingOn = 1: Gunn & Gott (1972) ISM stripping of
  satellites reproduces the satellite HI-deficiency-vs-host-mass trend
  and lifts the cluster-scale quenched fraction toward Wetzel+12.
- PrecipRegulationOn = 1: precipitation relaxes toward the tcool/tff
  equilibrium instead of draining the CGM at the free-fall rate; the
  physically correct Voit behaviour (macroscopically small at z=0 since
  little CGM sits in the marginal window, but correct).

millennium_all.par updated to pin both on explicitly; the gitignored
vanilla configs are pinned off locally to preserve classic-SAGE runs.
This intentionally changes the default output -- baselines regenerated
in the following commit.
Intentional baseline update to bless the on-by-default ram-pressure
stripping + precipitation regulation as the canonical output. Recaptured
with the serial build (make USE-MPI=):
- tests/baseline/millennium (5444 datasets), verify passes
- tests/baseline/millennium_all (5444 datasets), verify passes
- tests/benchmark/reference.sha256 (64 binary files), verify passes
The local microuchuu baseline (gitignored) was recaptured too.

These replace the pre-toggle byte-identical references; classic-SAGE
output remains reproducible via the vanilla configs.
@MBradley1985 MBradley1985 merged commit e368459 into dev Jul 5, 2026
2 checks passed
MBradley1985 added a commit that referenced this pull request Jul 5, 2026
Bring README, CHANGELOG, and the RTD physics docs up to date with the
now-default-on channels merged in #20/#21:

- CHANGELOG.md: new top entry covering ram-pressure ISM stripping, the
  self-regulating precipitation law, the AGN/CGM overdraw bugfix, and the
  intentional default flip with regenerated baselines.
- README.md: RamPressureStrippingOn + PrecipRegulationOn added to the
  'what is new' table, a satellite ram-pressure stripping subsection, and
  the precipitation-regulation row in the CGM table.
- docs/physics/cooling_and_heating.md: precipitation self-regulation
  (M_eq / free-fall shut-off), the PrecipRegulationOn switch, and the
  post-accretion coolingGas re-cap.

parameters.md and infall.md were already updated in #20/#21. RTD build
verified locally (doxygen + sphinx, all pages render clean).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant