progenax.cluster¶
Auto-generated by scripts/build_api_reference.py from progenax source. Re-run after public-API changes; the script is idempotent.
Module path: progenax/cluster/
Public symbols: 15
Contents¶
cluster.MultiComponentCluster¶
class
📇 model card · ∇ gradient-verified — 9 audit cases
MultiComponentCluster(alpha_j=None, w_j=None, m_j=None, W0=None, g=None, r_c=None, xi_grid=None, psi_grid=None, ra_hat_j=None, residual=0.0, n_grid: int = 1000, rho_on_xi=None, dens_fn=None, psi_raw=None, *, _fields=None)Multi-component cluster in shared-potential equilibrium (two engines).
Engine A (DF-defined, lowered-isothermal/LIMEPY family): construct with
from_components (direct per-component velocity-scale ratios w_j -- the
general case), from_mass_segregation (the equipartition law
w_j = mu_j^(-delta)), or from_imf (bin an IMF, eigenvalue-solve for
alpha_j).
Engine B (density-defined, Eddington inversion): construct with
from_density_profiles (Plummer/EFF/King density components in ONE
shared self-consistent potential, per-component DFs via Eddington
inversion, optional per-component Osipkov-Merritt r_a_j).
Either way, sample_cluster returns an
:class:~progenax.builders.ICResult whose component_id labels each
star’s generating component.
Differentiable in every per-component parameter (Engine A: alpha_j, w_j, ra_hat_j, W0, g; Engine B: profile scales, mass fractions, r_a_j) through construction AND sampling.
Attributes
| Parameter | Description |
|---|---|
r_t | tidal/truncation radius (shared by both engines). |
m_j | representative stellar mass per component [M_sun] (labels only). |
N_frac_j | number fraction of stars per component. |
engine | “A” or “B” (static; resolves dispatch at trace time). |
engine_a | grouped Engine A state (_EngineAState; None on B models). |
engine_b | grouped Engine B state (_EngineBState; None on A models). Engine-A-only quantities (W0, g, r_c, mu_tot, alpha_j, w_j, ra_hat_j, xi_grid, psi_grid, residual) are exposed as delegating properties reading through engine_a: W0, g, r_c: structural parameters / scales. |
alpha_j | central density fractions (sum to 1). |
w_j | per-component velocity-scale ratios s_j/s (rescale_j = w_j^-2). |
ra_hat_j | per-component anisotropy radii r_{a,j}/r_c (inf = isotropic). |
mu_tot | total dimensionless mass integral (sets the velocity scale). |
residual | eigenvalue-solve residual (0 for direct constructors). xi_grid, psi_grid: shared coupled-Poisson solution W(xi). On an Engine B model each raises an informative AttributeError naming the engine (this replaced the NaN-sentinel tripwires). |
Source: src/progenax/cluster/multicomponent.py#L143
cluster.energy_sorted_segregation¶
function
energy_sorted_segregation(key: PRNGKeyArray, masses: Float[Array, 'N'], positions_pool: Float[Array, 'N_pool 3'], velocities_pool: Float[Array, 'N_pool 3'], potential_fn: Callable[[Float[Array, 'N_pool 3']], Float[Array, 'N_pool']]) -> Tuple[Float[Array, 'N'], Float[Array, 'N 3'], Float[Array, 'N 3']]Assign positions/velocities to masses using Baumgardt energy-ordered method.
This implements full energy-ordered segregation (S=1 at the bin level) — a PRIMORDIAL generator. For partial/continuous segregation use the equilibrium family (MultiComponentCluster.from_mass_segregation), not a blend of this function’s output.
.. warning::
Reassigning masses by energy rank changes the mass-weighted density, so it
no longer matches the parent profile the orbit pool was drawn from — the
self-consistent potential of the segregated system DIFFERS, and the output is
not exactly in equilibrium (audit S6). Callers should finalize with a global
virial rescale (virial_scale), as the validation suite does.
Algorithm (Baumgardt+2008 Appendix, McLuster implementation): 1. Sort masses descending → m_sorted[i] for mass rank i 2. Cumulative-mass coordinate M_cum_norm[i] = sum(m_sorted[0:i+1]) / M_total, and the bin-centre target energy-rank t[i] = floor(N_pool * M_cum_mid[i]), M_cum_mid[i] = (M_cum_norm[i-1] + M_cum_norm[i]) / 2 3. Sort orbit pool by specific energy (most bound first) 4. Assign each mass rank a DISTINCT orbit by isotonic-rounding the targets to a strictly increasing integer sequence in [0, N_pool-1]: idx[i] = max(idx[i-1] + 1, min(t[i], N_pool - N + i)) (the per-rank upper clamp prevents overflow; the running max guarantees no reuse). Most massive rank 0 -> smallest index -> most bound orbit. 5. Map back to original mass ordering
This deterministic monotonic assignment replaced an earlier per-bin random sampler whose cumulative-mass bins collapsed below one orbit for steep IMFs, forcing many low-mass ranks onto the same orbit (coincident stars, V = -inf). See docs/website/50-validation/mass-segregation.md.
Args
| Parameter | Description |
|---|---|
key | JAX random key (retained for API stability; the assignment is now deterministic — realisation variety comes from the random orbit pool). |
masses | Stellar masses with shape (N,). Will be sorted internally; output preserves original ordering. |
positions_pool | Orbit pool positions with shape (N_pool, 3) from equilibrium distribution function. |
velocities_pool | Orbit pool velocities with shape (N_pool, 3) from equilibrium distribution function. Must use consistent units with potential_fn so that E = 0.5 * v² + Φ is meaningful. |
potential_fn | Callable computing specific potential Φ(r) (per unit mass) at positions. Must return shape (N_pool,) with same energy units as 0.5 * v². Should be the analytic profile potential (Plummer/King/EFF), NOT a direct N-body sum, ensuring consistency between the DF used to draw orbits and the energy ordering used for segregation. |
Returns: Tuple of (masses_out, positions, velocities): - masses_out: Masses in original order (N,) - unchanged from input - positions: Assigned positions (N, 3) - velocities: Assigned velocities (N, 3) Shape Expectations: - masses: (N,) - positions_pool: (N_pool, 3) - velocities_pool: (N_pool, 3) - potential_fn(positions_pool) must return: (N_pool,) Pool Size Recommendations: Set N_pool = pool_factor * N with pool_factor >= 4 so the assigned orbits are a well-spread mass-weighted subsample of the pool and the segregation signal is smooth. Any N_pool >= N yields a valid no-reuse assignment; small N_pool just leaves fewer distinct orbits between mass ranks. No-Orbit-Reuse Guarantee: The isotonic-rounding assignment (Step 4) produces a strictly increasing integer sequence in [0, N_pool-1], so every mass rank receives a DISTINCT orbit and no two stars are coincident — for ANY mass spectrum, including steep IMFs. (The previous per-bin sampler did NOT guarantee this: sub-orbit bins collapsed and reused orbits.) Verified for uniform/bimodal/Kroupa/extreme-steep spectra in tests/unit/cluster/test_mass_segregation.py. Non-Differentiability: This function is NOT differentiable (argsort, floor) and is not meant to be: it is a discrete primordial-assignment generator. For gradient-based inference over segregation strength, use the first-principles equilibrium knob instead — MultiComponentCluster.from_mass_segregation(delta), which is differentiable in delta and a true shared-potential equilibrium at every value. (The historical lambda_seg catalog blend was retired: its intermediate states drift from per-mass-group virial balance — see per_group_virial_ratio and the mass-segregation validation page.) Segregation Strength: Implements full Baumgardt-style energy ordering (S=1): the most massive stars occupy the most bound orbits. The assignment is deterministic given the pool; realisation variety comes from re-drawing the random orbit pool.
Source: src/progenax/cluster/mass_segregation.py#L45
cluster.G_KMS¶
value
Convert a string or number to a floating-point number, if possible.
cluster.C_S_DEFAULT¶
value
Convert a string or number to a floating-point number, if possible.
cluster.B_DEFAULT¶
value
Convert a string or number to a floating-point number, if possible.
cluster.BETA_KOLMOGOROV¶
value
Convert a string or number to a floating-point number, if possible.
cluster.BETA_BURGERS¶
value
Convert a string or number to a floating-point number, if possible.
cluster.SIGMA_V0_DEFAULT¶
value
Convert a string or number to a floating-point number, if possible.
cluster.ALPHA_LARSON¶
value
Convert a string or number to a floating-point number, if possible.
cluster.sigma_ln_rho_from_mach¶
function
sigma_ln_rho_from_mach(mach: "Float[Array, '...']", b: 'float' = 0.4) -> "Float[Array, '...']"Density contrast from Mach number (Federrath+2010 Eq. 19).
The variance of the log-density field in supersonic turbulence: σ²_ln_ρ = ln(1 + b²M²)
This is FK10 Eq. 19 (the log form of the linear relation Eq. 18, σ_ρ/⟨ρ⟩ = b·M); the mean is fixed by mass conservation to ⟨s⟩ = -σ²_ln_ρ/2 (FK10 Eq. 11). See the per-paper note federrath-2010 for the equation-number history.
Parameters¶
mach : array Turbulent Mach number M = σ_v / c_s. b : float, optional Turbulence driving parameter (default 0.4). - b ≈ 1/3: Solenoidal (incompressible) driving - b ≈ 1.0: Compressive driving - b ≈ 0.4: Natural mixture
Returns¶
sigma_ln_rho : array Standard deviation of log-density field.
Notes¶
Physical ranges: - Small OC (M ~ 5): σ_ln_ρ ~ 0.9 - Large OC (M ~ 10): σ_ln_ρ ~ 1.4 - YMC (M ~ 25): σ_ln_ρ ~ 1.9 - GC (M ~ 50): σ_ln_ρ ~ 2.4
References¶
.. [1] Federrath et al. (2010) A&A 512, A81, Eq. 19
Source: src/progenax/cluster/turbulence.py#L43
cluster.spectral_slope_from_mach¶
function
spectral_slope_from_mach(mach: "Float[Array, '...']") -> "Float[Array, '...']"DENSITY power-spectrum slope β from Mach number (Kim & Ryu 2005).
Returns the slope of the 3D density power spectrum P_3D(k) ∝ k^{-β}. In supersonic turbulence the density spectrum FLATTENS as the Mach number rises (mass is swept into sheets and filaments), so β decreases with M — the opposite of the velocity (Kolmogorov→Burgers) cascade.
Calibration: Kim & Ryu (2005, ApJ 630, L45) measure 3D density spectra E_ρ(k)∝k^{-s} with s = 1.73 (M=1.2, ≈Kolmogorov 5/3), 1.08 (3.4), 0.75 (7.3), 0.52 (12). Converting to the 3D power-spectral-density convention β = s + 2 and least-squares fitting in log10(M): β(M) = 3.788 - 1.203·log10(M), clipped to [2.0, 11/3]. The Kolmogorov ceiling (11/3) is the transonic limit; the floor (2.0) is the 1D strong-shock density limit P_ρ ∝ k^0.
Parameters¶
mach : array Turbulent Mach number M = σ_v / c_s.
Returns¶
beta : array Density power spectrum slope P_3D(k) ∝ k^{-β} (decreasing in M).
Notes¶
This is a log-linear fit to Kim & Ryu’s four measured 3D Mach points (1.2–12); treat it as a calibrated interpolation, not a first-principles law. It is a density slope — distinct from the velocity Kolmogorov/Burgers slopes. Magnetic fields and self-gravity (not modelled by Kim & Ryu) modify it further.
References¶
.. [1] Kim & Ryu (2005) ApJ 630, L45 - density power spectrum vs Mach .. [2] Kolmogorov (1941) - transonic ceiling (E_ρ slope ≈ -5/3)
Source: src/progenax/cluster/turbulence.py#L86
cluster.cloud_radius_from_density¶
function
cloud_radius_from_density(M_ecl: "Float[Array, '...']", sfe: "Float[Array, '...']", rho_cl: "Float[Array, '...']") -> "Float[Array, '...']"Parent cloud radius [pc] from cluster mass, SFE, and cloud density.
R_cloud = (3 M_gas / (4π ρ_cl))^(1/3)
where M_gas = M_ecl / SFE is the gas mass.
Parameters¶
M_ecl : array Stellar mass of embedded cluster [M☉]. sfe : array Star formation efficiency ε = M_ecl / M_gas. rho_cl : array Cloud density [M☉ pc⁻³].
Returns¶
R_cloud : array Parent cloud radius [pc].
Notes¶
The cloud radius is used for Larson velocity-size relation. This is NOT the stellar half-mass radius r_h.
References¶
.. [1] Larson (1981) MNRAS 194, 809
Source: src/progenax/cluster/turbulence.py#L133
cluster.larson_sigma_v¶
function
larson_sigma_v(R_cloud: "Float[Array, '...']", sigma_v0: 'float' = 1.0, alpha: 'float' = 0.5) -> "Float[Array, '...']"Velocity dispersion [km/s] from Larson velocity-size relation.
σ_v(R) = σ_v0 × (R / 1 pc)^α
Parameters¶
R_cloud : array Cloud radius [pc]. sigma_v0 : float, optional Normalization velocity [km/s] at 1 pc. Default 1.0. alpha : float, optional Power-law exponent. Default 0.5.
Returns¶
sigma_v : array Turbulent velocity dispersion [km/s].
Notes¶
Typical literature values: - Larson (1981): σ_v0 ≈ 1.1, α ≈ 0.38 - Solomon+1987: σ_v0 ≈ 0.72, α ≈ 0.5
References¶
.. [1] Larson (1981) MNRAS 194, 809 .. [2] Solomon et al. (1987) ApJ 319, 730
Source: src/progenax/cluster/turbulence.py#L172
cluster.turbulent_mach_from_cloud¶
function
turbulent_mach_from_cloud(R_cloud: "Float[Array, '...']", c_s: 'float' = 0.2, sigma_v0: 'float' = 1.0, alpha: 'float' = 0.5) -> "Float[Array, '...']"Gas turbulent Mach number from Larson velocity-size relation.
M = σ_v(R_cloud) / c_s
This is the RECOMMENDED method for deriving Mach numbers.
Parameters¶
R_cloud : array Parent cloud radius [pc]. c_s : float, optional Sound speed [km/s]. Default 0.2. sigma_v0 : float, optional Larson normalization [km/s]. Default 1.0. alpha : float, optional Larson exponent. Default 0.5.
Returns¶
mach : array Turbulent Mach number M = σ_v / c_s.
Notes¶
Expected ranges: | R_cloud | Mach | |---------|------| | 2 pc | ~7 | | 3 pc | ~9 | | 5 pc | ~11 | | 10 pc | ~16 |
References¶
.. [1] Larson (1981) MNRAS 194, 809 .. [2] Federrath et al. (2010) A&A 512, A81
Source: src/progenax/cluster/turbulence.py#L209
cluster.b_from_environment¶
function
b_from_environment(log_rho_cl: "Float[Array, '...']", log_rho_transition: 'float' = 4.0, b_low: 'float' = 0.33, b_high: 'float' = 0.7, width: 'float' = 1.0) -> "Float[Array, '...']"Turbulence driving parameter b from cloud density.
Interpolates: - Low-density: solenoidal driving (b ≈ 0.33) - High-density: compressive driving (b ≈ 0.7)
Parameters¶
log_rho_cl : array Log₁₀ of cloud density [M☉/pc³]. log_rho_transition : float, optional Transition density (default 10⁴ M☉/pc³). b_low : float, optional Low-density b value (default 0.33). b_high : float, optional High-density b value (default 0.7). width : float, optional Transition width in dex (default 1.0).
Returns¶
b : array Turbulence driving parameter.
Notes¶
This mapping is TENTATIVE. The relationship between density and driving mode is not firmly established.
References¶
.. [1] Federrath et al. (2010) A&A 512, A81 .. [2] Federrath (2013) MNRAS 436, 1245