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.

Mix Plummer positions with King velocities

San Diego State University

Goal. Build an IC whose positions come from a Plummer profile but whose velocities come from a King lowered-Maxwellian DF. progenax’s protocol-based design makes any SpatialProfile composable with any VelocityDF — but mixing unmatched models breaks detailed equilibrium, so this recipe also shows how to restore Q=0.5Q = 0.5.

How composition works

Every spatial profile implements the SpatialProfile protocol (sample_positions) and every velocity DF implements VelocityDF (sample_velocities), so the two axes are independent:

from progenax.protocols import SpatialProfile, VelocityDF
from progenax import PlummerProfile, KingVelocityDF

profile: SpatialProfile = PlummerProfile(r_h=1.0)
df: VelocityDF      = KingVelocityDF(W0=7.0, r_c=1.0)

isinstance(profile, SpatialProfile)   # True
isinstance(df, VelocityDF)            # True

Recipe

import jax, jax.numpy as jnp
from jaxstro.units import STELLAR
from progenax import (
    PlummerProfile, KingVelocityDF, build_spatial_ic,
    compute_kinetic_energy, compute_potential_energy,
)

G = STELLAR.G
key = jax.random.PRNGKey(0)
masses = jnp.ones(3000)

profile = PlummerProfile(r_h=1.0)          # spatial axis
df      = KingVelocityDF(W0=7.0, r_c=1.0)  # velocity axis (independent)

def virial_Q(ic):
    T = compute_kinetic_energy(ic.velocities, ic.masses)
    V = compute_potential_energy(ic.positions, ic.masses, G=G)
    return T / jnp.abs(V)

# Unscaled: see the raw mismatch (Q=None disables the virial rescale).
ic_raw = build_spatial_ic(profile, masses, df, key=key, G=G, Q=None)
print(f"unscaled mix:  Q = {virial_Q(ic_raw):.4f}")   # -> 0.1888 (NOT 0.5)

# Virialized: rescale velocities to the equilibrium balance Q = 0.5.
ic = build_spatial_ic(profile, masses, df, key=key, G=G, Q=0.5)
print(f"Q=0.5 mix:     Q = {virial_Q(ic):.4f}")        # -> 0.5000

Verified output

Measured (PRNGKey(0), N=3000N=3000):

Build

Measured Q=T/VQ = T/|V|

Interpretation

Q=None (unscaled)

0.1888

Sub-virial — King kinematics are too cold for a Plummer potential.

Q=0.5

0.5000

Velocities rescaled to virial equilibrium.

See also