Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Multimass equipartition saturation — the derived m_eq

San Diego State University

Multimass equipartition saturation — the derived meqm_{\rm eq}

The model and the δ\delta ansatz

In the Gieles & Zocchi (2015) (GZ15) multimass lowered-isothermal model, every mass component jj shares one self-consistent potential but carries its own velocity scale and anisotropy radius via power-law mass scalings (GZ15 eqs 24–26; Peuten et al. (2017) eqs 3–5):

sj=sμjδ,r^a,j=r^aμjη,μjmjmˉ,mˉ=jmjαj,s_j = s\,\mu_j^{-\delta}, \qquad \hat r_{a,j} = \hat r_a\,\mu_j^{\eta}, \qquad \mu_j \equiv \frac{m_j}{\bar m}, \qquad \bar m = \sum_j m_j\,\alpha_j ,

with mˉ\bar m the central-density-weighted mean mass (GZ15 eq 26; αj=ρ0j/ρ0\alpha_j = \rho_{0j}/\rho_0, jαj=1\sum_j \alpha_j = 1). The component density rides the shared potential at the rescaled depth Wj=μj2δW0W_j = \mu_j^{2\delta} W_0 (GZ15 eq 29). For the traditional δ=12\delta = \tfrac12, mjsj2m_j s_j^2 is constant across bins by construction — but the model is not in energy equipartition, and the way it falls short is the physics of this page.

The honest sub-equipartition physics: why σ(m)\sigma(m) saturates

The observable central 1-D dispersion of component jj is not sjs_j. In closed form (Bianchini et al. 2016 eq A1, with the paper’s missing 1/2^{1/2} restored — typo note):

σ^1d,j0  =  μjδ[Eγ ⁣(g+52;μj2δϕ^0)Eγ ⁣(g+32;μj2δϕ^0)]1/2,ϕ^0=W0.\hat\sigma_{1d,j0} \;=\; \mu_j^{-\delta} \left[\frac{E_\gamma\!\big(g+\tfrac52;\, \mu_j^{2\delta}\hat\phi_0\big)} {E_\gamma\!\big(g+\tfrac32;\, \mu_j^{2\delta}\hat\phi_0\big)}\right]^{1/2}, \qquad \hat\phi_0 = W_0 .

The two limits of (2) are two different physical regimes:

Both limits are verified analytically (autodiff of (2), nothing fitted) in scripts/validate_equipartition_saturation.py: for the 20-bin [0.1,1]M[0.1, 1]\,M_\odot model (δ=12\delta=\tfrac12, g=1.5g=1.5), η(mmin)=0.026\eta(m_{\rm min}) = 0.0260.039 across W0{5,7,9}W_0 \in \{5, 7, 9\} (flat, escape-limited end), η121.1×1016|\eta - \tfrac12| \le 1.1\times10^{-16} at μ=20\mu = 20 (deep well, float64 noise), and η(m)\eta(m) is strictly monotone increasing. The closed form itself is gated against the multimass solver’s independent quadrature oracle: max relative difference 1.51.7×1071.7\times10^{-7} (gate 10-6).

The crossover is DERIVED, not fitted

Bianchini et al. (2016) introduced the exponential fitting function σ(m)=σ0exp(12m/meq)\sigma(m) = \sigma_0 \exp(-\tfrac12 m/m_{\rm eq}) for mmeqm \le m_{\rm eq}, m1/2\propto m^{-1/2} above (their eq 3), with meqm_{\rm eq} — the mass above which the cluster is in full equipartition — as the fitted “degree of equipartition”. Their Appendix A shows the crossover emerges from the GZ15 DF itself: Taylor-expanding (2) for low mass and matching linear terms (A2 ↔ A3) identifies

  meq  =  mˉ(g+52)(g+72)ϕ^0  \boxed{\;m_{\rm eq} \;=\; \bar m\,\frac{\big(g+\tfrac52\big)\big(g+\tfrac72\big)}{\hat\phi_0}\;}

↗ model card

so meqm_{\rm eq} is fixed by the mean mass, the truncation order gg, and the central concentration ϕ^0=W0\hat\phi_0 = W_0not a free input. Note meq/mˉ1/W0m_{\rm eq}/\bar m \propto 1/W_0: more concentrated clusters reach equipartition down to lighter stars, the model-side face of Bianchini’s headline observational result that meqm_{\rm eq} tracks dynamical age (neq=Tage/Trcn_{\rm eq} = T_{\rm age}/T_{\rm rc}; relaxed clusters → smaller meqm_{\rm eq}).

progenax validates (3) fit-free: since we hold the exact curve (2), the headline gate is the exact μ0\mu \to 0 identity — the local saturation mass m/(2η(m))m/(2\eta(m)), with η\eta by autodiff, must approach the derived meqm_{\rm eq}. Measured at μ=103\mu = 10^{-3} (g=1.5g = 1.5, 20 equal-MjM_j log bins on [0.1,1]M[0.1,1]\,M_\odot):

```{list-table} Derived-m_eq identity (scripts/validate_equipartition_saturation.py, 2026-06-11, ALL PASS; gate 0.5%). :header-rows: 1


::::{figure} ../../50-validation/figures/equipartition_saturation.png
:label: fig-equipartition-saturation
:width: 100%

**Fit-free equipartition saturation** across $W_0 \in \{5,7,9\}$: the exact
Engine A $\sigma(m)$ {eq}`sigma-m-closed-form` (points: quadrature oracle;
line: closed form), the derived $m_{\rm eq}$ {eq}`meq-derived` marking the
crossover, the flat escape-limited low-mass end, the deep-well $m^{-1/2}$
branch, and the dashed tangent exponential
$\sigma_0\exp(-m/2m_{\rm eq})$ illustrating the finite-window fit bias
(see the caution below).
::::

## Sharper than exponential — a caution for literature comparisons

The exponential of Bianchini eq 3 matches the DF only to **first** order. The
exact quadratic Taylor coefficient of the DF's $\sigma(m)$ — eq A2's printed
$(6+3a-4a^2)/(8a^2b^2c)\cdot\hat\phi_0^2$ term, $a=g+\tfrac52$,
$b=g+\tfrac72$, $c=g+\tfrac92$ — is **negative** for all cluster-relevant
$g$, *opposite in sign* to the exponential's $+1/(8m_{\rm eq}^2)$: the DF
saturates **sharper than exponentially**. (A3's "first terms of the Taylor
expansion of the exponential" holds for the linear term only.)

:::{admonition} Caution — fitted m_eq values are window-dependent
:class: warning
Because the true curve bends *below* the tangent exponential, an eq-3
exponential fit over a finite mass window recovers an $m_{\rm eq}$ **biased
low**, by an amount that depends on the window. Measured in a one-off
windowed-fit analysis (2026-06-11; recorded in the validation script's
docstring — the gated validation itself is deliberately fit-free): over
$\mu = m/\bar m \in [0.1/\bar m,\, 1/\bar m]$ per model — the 20-bin
$[0.1,1]\,M_\odot$ window, $\approx[0.14, 1.7]$ across the $W_0$ grid since
$\bar m$ varies — such fits recover **~0.5×** the DF-derived
{eq}`meq-derived` (0.50–0.53 across $W_0 \in \{5,7,9\}$). So when
comparing a *fitted* literature $m_{\rm eq}$ with the derived one:
**window-match first** (fit eq 3 to the model over the data's mass window), or
— future work — skip eq 3 entirely and fit the exact differentiable
$\sigma(m;\, g, W_0, \bar m)$ {eq}`sigma-m-closed-form` directly to the
kinematic data.
:::

The convergence to the identity is itself the evidence that the bias is pure
finite-mass curvature — the local saturation mass over the derived
$m_{\rm eq}$ rises monotonically to 1 as $\mu \to 0$ (printed by the script:
e.g. $W_0=7$: 0.54 at $\mu=0.5$, 0.86 at $\mu=0.1$, 0.985 at $\mu=0.01$,
0.9985 at $\mu=10^{-3}$).

## The $\bar m$ conventions, and parity with canonical LIMEPY

Three $\bar m$-related facts the bookkeeping must keep straight
([Peuten et al. 2017](../../99-bibliography/per-paper/peuten-2017.md) §2):

1. **GZ15 eq 26 (= progenax):** $\bar m$ is the **central-density-weighted**
   mean, $\bar m = \sum_j m_j\,\alpha_j$ — what Engine A's `bar_m` computes
   and what every equation on this page uses.
2. **The reference LIMEPY code's default** is the **global** mean mass
   (faster, especially with black-hole bins); it supports the GZ15 convention
   via `meanmassdef='central'`.
3. **The two describe the same physical model**, related exactly by Peuten
   eqs 8–9 (in the corrected direction — heavier reference mass ⇒ colder
   reference scale ⇒ deeper $W_0^*$):
   $W_0^{*} = W_0\,(\bar m^{*}/\bar m)^{2\delta}$,
   $\hat r_a^{*} = \hat r_a\,(\bar m^{*}/\bar m)^{\eta+\delta}$.

The parity harness (`scripts/validate_limepy_reference.py`) runs the canonical
numpy/scipy LIMEPY (repo SHA `ef2a479`, pinned ephemeral env, outputs cached
with provenance) with `meanmassdef='central'`, so both codes share one
$(W_0, \bar m)$ convention and no eq 8–9 translation is needed. Six configs —
single-mass $g=1$ (King) and $g=1.5$; 2-component $\delta=0.5$; the 4-bin
Maschberger IMF ($\delta=0.4$); and the 2-component anisotropic pair
$\hat r_a = 5$, $\eta \in \{0, 0.5\}$ — compared on scale-invariant
quantities only:

```{list-table} Ours-vs-reference-LIMEPY parity (2026-06-11, ALL PASS; worst case across the 6 configs, per quantity).
:header-rows: 1

* - Quantity (scale-invariant)
  - worst measured
  - gate
* - density shape $\max|\Delta[\rho_j(r)/\rho_j(0)]|$
  - $1.3\times10^{-5}$
  - $2$–$5\times10^{-5}$
* - dispersion shape $\max|\Delta[\sigma_j(r)/\sigma_j(0)]|$
  - $8.4\times10^{-5}$
  - $2\times10^{-5}$–$3\times10^{-4}$
* - central density fractions $\max|\Delta\alpha_j|$
  - $4.9\times10^{-5}$
  - $10^{-8}$–$5\times10^{-4}$
* - realized mass fractions $\max|\Delta M_j/M|$
  - $7.1\times10^{-5}$
  - $10^{-8}$–$5\times10^{-4}$
* - concentration $|\Delta\log_{10}(r_t/r_0)|$
  - $1.5\times10^{-4}$
  - $5\times10^{-4}$
* - half-mass radius $|\Delta r_h|/r_h$
  - $6.3\times10^{-6}$
  - $10^{-4}$

All scale-invariant quantities agree to 1.5×104\lesssim 1.5\times10^{-4} — Engine A is a faithful (and differentiable) reimplementation of the published model. Gates were measured first, then frozen with honest headroom (~3–10× the measured deviations); the skip-if-absent regression test is tests/validation/test_limepy_reference_parity.py.

Reference parity for the representative multimass config: per-component
\rho_j(r) and \sigma_j(r), ours (curves) vs canonical LIMEPY (points),
with residual strips.

Figure 1:Reference parity for the representative multimass config: per-component ρj(r)\rho_j(r) and σj(r)\sigma_j(r), ours (curves) vs canonical LIMEPY (points), with residual strips.

What is deliberately NOT here: meq and zeta

The published LIMEPY code carries two extra knobs absent from the GZ15 and Peuten et al. (2017) equations: meq (a low-mass softening μj=(mj+meq)/mˉ\mu_j = (m_j + m_{\rm eq})/\bar m, whose docstring citation of “GZ15 eq 24” is incorrect — eq 24 is the pure power law) and zeta (a high-mass sj2s_j^2 decoupling motivated by the Spitzer instability). Both are deferred in progenax (decision 2026-06-11): they are fitting freedom, not the saturation mechanism — as this page shows, the standard model already saturates, with the crossover (3) set by (mˉ,g,W0)(\bar m, g, W_0). If a future fit needs to decouple the equipartition degree from g/W0g/W_0 (meq) or model a dark-remnant subsystem (zeta), they will be added as default-off kwargs and documented honestly as code heuristics, not published equations.

Reproduce

env -u VIRTUAL_ENV uv run --no-sync python scripts/validate_limepy_reference.py
env -u VIRTUAL_ENV uv run --no-sync python scripts/validate_equipartition_saturation.py

Implementation, validation & references

References
  1. Gieles, M., & Zocchi, A. (2015). A family of lowered isothermal models. Monthly Notices of the Royal Astronomical Society, 454, 576–592. 10.1093/mnras/stv1848
  2. Peuten, M., Zocchi, A., Gieles, M., Gualandris, A., & Hénault-Brunet, V. (2017). Testing lowered isothermal models with direct N-body simulations of globular clusters – II. Multimass models. Monthly Notices of the Royal Astronomical Society, 470, 2736–2761. 10.1093/mnras/stx1311
  3. Bianchini, P., van de Ven, G., Norris, M. A., Schinnerer, E., & Varri, A. L. (2016). A novel look at energy equipartition in globular clusters. Monthly Notices of the Royal Astronomical Society, 458, 3644–3654. 10.1093/mnras/stw552