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.

Project 2: Science Background

San Diego State University

ASTR 596 Fall 2025
Instructor: Anna Rosen

Course ethos: Glass-box modeling. Every function is physics-motivated and transparent. This document is your end-to-end reference to sample stellar masses from the Kroupa IMF and positions from a Plummer sphere for star-cluster simulations.


Why these models?

Learning goals:

  1. Translate physics → probability distributions → samplers.

  2. Build a correct, testable sampler for a broken power law (IMF).

  3. Build a correct, testable sampler for a spherical density profile (Plummer).


2 Canonical Kroupa IMF

We use the stellar IMF (counts individual stars, not unresolved systems) with lower and upper mass limits mmin,mmaxm_{\min}, m_{\max} and piecewise power-law slopes. For Project 2 you may use the two-segment form (since α2=α3\alpha_2=\alpha_3 for m>0.5Mm>0.5\,M_\odot):

ξ(m)=kξkimαi,m[mmin,mmax],\xi(m) = k_\xi\,k_i\, m^{-\alpha_i},\quad m\in[m_{\min}, m_{\max}],

with

α1=1.3(0.08m/M<0.5),α2=2.3(0.5m/Mmmax).\alpha_1 = 1.3\quad (0.08\le m/M_\odot < 0.5),\qquad \alpha_2 = 2.3\quad (0.5\le m/M_\odot \le m_{\max}).

Recommended limits:

2.1 Continuity and Normalization

We choose continuity at the break mb=0.5Mm_b=0.5\,M_\odot:

ξ1(m)=A1mα1,m[mmin,mb),ξ2(m)=A2mα2,m[mb,mmax],\xi_1(m) = A_1\, m^{-\alpha_1},\quad m\in[m_{\min}, m_b),\qquad \xi_2(m) = A_2\, m^{-\alpha_2},\quad m\in[m_b, m_{\max}],

with A2=A1mbα2α1A_2 = A_1\, m_b^{\alpha_2-\alpha_1} so that ξ1(mb)=ξ2(mb)\xi_1(m_b)=\xi_2(m_b).

Let NN be the expected number of stars. Then

N=mminmbA1mα1dm+mbmmaxA2mα2dm.N = \int_{m_{\min}}^{m_b} A_1 m^{-\alpha_1}\,dm + \int_{m_b}^{m_{\max}} A_2 m^{-\alpha_2}\,dm.

Solve for A1A_1 given NN (or set kξk_\xi such that ξdm=1\int \xi\,dm = 1 and then scale to NN). For α1\alpha\neq 1,

abmαdm=b1αa1α1α.\int_a^b m^{-\alpha}dm = \frac{b^{1-\alpha}-a^{1-\alpha}}{1-\alpha}.

Computing Normalization Constants Analytically

To generate exactly NN stars, compute the normalization constants without numerical integration:

Step 1 - Calculate segment integrals:

For segment 1 (m[mmin,mb]m \in [m_{\min}, m_b] with slope α1\alpha_1):

I1=mb1α1mmin1α11α1I_1 = \frac{m_b^{1-\alpha_1} - m_{\min}^{1-\alpha_1}}{1-\alpha_1}

For segment 2 (m[mb,mmax]m \in [m_b, m_{\max}] with slope α2\alpha_2):

I2=mmax1α2mb1α21α2I_2 = \frac{m_{\max}^{1-\alpha_2} - m_b^{1-\alpha_2}}{1-\alpha_2}

Step 2 - Apply continuity constraint:

With A2=A1mbα2α1A_2 = A_1 \cdot m_b^{\alpha_2-\alpha_1} ensuring continuity at mbm_b:

A1=NI1+mbα2α1I2A_1 = \frac{N}{I_1 + m_b^{\alpha_2-\alpha_1} \cdot I_2}
A2=A1mbα2α1A_2 = A_1 \cdot m_b^{\alpha_2-\alpha_1}

Step 3 - Compute segment probabilities:

The probability of drawing from each segment:

P1=A1I1N,P2=A2I2NP_1 = \frac{A_1 \cdot I_1}{N}, \quad P_2 = \frac{A_2 \cdot I_2}{N}

These probabilities sum to 1 and determine which segment to sample from.

2.2 Inverse-transform sampling within one segment

To draw mm from p(m)mαp(m)\propto m^{-\alpha} on [a,b][a,b] with α1\alpha\neq 1:

  1. Precompute the normalization constant:

    C=b1αa1α1αC = \dfrac{b^{1-\alpha}-a^{1-\alpha}}{1-\alpha}
  2. Draw uu from a uniform distribution:

    uU(0,1)u\sim\mathcal U(0,1)
  3. Invert the CDF:

m=[a1α+u(b1αa1α)] ⁣1/(1α).m = \big[\,a^{1-\alpha} + u\,(b^{1-\alpha}-a^{1-\alpha})\,\big]^{\!1/(1-\alpha)}.

2.3 Piecewise Sampling Algorithm (Two-Segment IMF)

  1. Compute segment weights (probabilities) P1P_1 and P2P_2 from the normalized integrals of ξ1\xi_1 and ξ2\xi_2.

  2. Draw sU(0,1)s\sim\mathcal U(0,1). If s<P1s<P_1 sample from segment 1 using α1,a=mmin,b=mb\alpha_1, a=m_{\min}, b=m_b; else sample from segment 2 using α2,a=mb,b=mmax\alpha_2, a=m_b, b=m_{\max} with the inverse formula above.

Numerical guardrails: work in double precision, precompute powers a1αa^{1-\alpha}, b1αb^{1-\alpha}, and clamp u[1012,1)u\in[10^{-12}, 1) to avoid boundary issues.


3 Plummer Sphere for Spatial Positions

3.1 Density and cumulative mass

The Plummer density with total mass MM and scale radius aa is

ρ(r)=3M4πa3(1+r2a2)5/2.\rho(r) = \frac{3M}{4\pi a^3}\left(1+\frac{r^2}{a^2}\right)^{-5/2}.

The enclosed mass is

M(<r)=Mr3(r2+a2)3/2.M(<r) = M\,\frac{r^3}{\big(r^2+a^2\big)^{3/2}}.

Define the CDF for radius: F(r)M(<r)/M[0,1)F(r)\equiv M(<r)/M\in[0,1).

3.2 Inverse-transform for the Radius

Set F(r)=uF(r)=u with uU(0,1)u\sim\mathcal U(0,1). Solve for rr:

r=a(u2/31)1/2.r = a\,\Big(u^{-2/3}-1\Big)^{-1/2}.

Draw u[1012,11012)u\in[10^{-12},1-10^{-12}) to avoid infinities.

3.3 Sample angles uniformly on a sphere

Draw ϕ=2πv\phi=2\pi v with vU(0,1)v\sim\mathcal U(0,1) and cosθ=12w\cos\theta=1-2w with wU(0,1)w\sim\mathcal U(0,1). Then

x=rsinθcosϕ,y=rsinθsinϕ,z=rcosθ.x=r\sin\theta\cos\phi,\quad y=r\sin\theta\sin\phi,\quad z=r\cos\theta.

3.4 Scale by half-mass radius (user-friendly)

If you want a specific half-mass radius r1/2r_{1/2}: r1/2=a22/31        a=r1/222/310.766r1/2. r_{1/2} = \frac{a}{\sqrt{2^{2/3}-1}}\;\;\Rightarrow\;\; a = r_{1/2}\,\sqrt{2^{2/3}-1} \approx 0.766\, r_{1/2}.

3.4.1 Typical scales for real star clusters

Plummer Scale Parameters for Different Cluster Types

Cluster Type

Scale Radius (a)

Half-mass Radius

Examples

Ultra-compact clusters

0.1-0.3 pc

0.08-0.23 pc

Super star clusters, nuclear clusters

Young massive clusters

0.3-1 pc

0.23-0.8 pc

Arches, Westerlund 1

Open clusters

0.5-3 pc

0.4-2.3 pc

Pleiades, Hyades

Globular clusters

1-5 pc

0.8-4 pc

Milky Way globulars

OB associations (sparse)

5-20 pc

4-15 pc

Extended stellar associations

For computational simulations with N ≤ 200 particles: Use much smaller scales to represent a cluster core:

3.5 Re-centering

After sampling NN stars with positions {ri}\{\boldsymbol r_i\} and masses {mi}\{m_i\}, subtract the mass-weighted center of mass so that

imiri=0\sum_i m_i\boldsymbol r_i=\boldsymbol 0

3.6 Virial Equilibrium Velocities

For a Plummer sphere in virial equilibrium, assign velocities by drawing each component independently from a Gaussian distribution with radius-dependent (1D) velocity dispersion:

σ1D2(r)=GM6a(1+r2a2)1/2\sigma_{1D}^2(r) = \frac{GM}{6a} \cdot \left(1 + \frac{r^2}{a^2}\right)^{-1/2}

where MM is the total mass and aa is the Plummer scale radius.

Implementation:

For each particle at radius rr:

  1. Calculate σ1D(r)\sigma_{1D}(r) using the formula above

  2. Draw vxN(0,σ1D)v_x \sim \mathcal{N}(0, \sigma_{1D})

  3. Draw vyN(0,σ1D)v_y \sim \mathcal{N}(0, \sigma_{1D})

  4. Draw vzN(0,σ1D)v_z \sim \mathcal{N}(0, \sigma_{1D})

Validation check: The 3D velocity dispersion should satisfy: σ3D=v2=3σ1D\sigma_{3D} = \sqrt{\langle v^2 \rangle} = \sqrt{3} \cdot \sigma_{1D}

After assigning velocities, subtract the mass-weighted center-of-mass velocity to ensure imivi=0\sum_i m_i \vec{v}_i = 0.

This initialization produces a system with virial ratio Q0Q \approx 0 (equilibrium). If your initial Q>0.01Q > 0.01, check your velocity assignment.


4 Putting It All Together - Initial Conditions Sampler Blueprint

Inputs: NN, r1/2r_{1/2} (or aa), mmin,mmaxm_{\min}, m_{\max}.

Outputs: arrays of stellar masses mim_i, positions (xi,yi,zi)(x_i,y_i,z_i), and initial velocities (vx,i,vy,i,vz,i)(v_{x,i}, v_{y,i}, v_{z,i}).

4.1 If NN is given

  1. Precompute segment probabilities P1,P2P_1, P_2.

  2. For each star: choose segment → draw mim_i via inverse-CDF.

  3. Draw u,v,wu,v,w → compute ri,θi,ϕir_i,\theta_i,\phi_i(xi,yi,zi)(x_i,y_i,z_i).

  4. Recentre to the mass-weighted COM.

  5. Draw velocities from Gaussian with σ1D(ri)\sigma_{1D}(r_i)(vx,i,vy,i,vz,i)(v_{x,i}, v_{y,i}, v_{z,i}).

Avoid rescaling all masses post-hoc (it distorts the IMF).


5) Validation & Diagnostics (Required)

5.1 IMF checks

5.2 Plummer checks


6) Common pitfalls (and fixes)

  1. Forgetting normalization of piecewise segments. Fix: compute normalized integrals for segment weights.

  2. Uniform in logm\log m instead of a power law in mm. Fix: use inverse-CDF for mαm^{-\alpha}, not uniform in logm\log m unless α=1\alpha=1.

  3. Segment weighting error. Fix: compute normalized segment probabilities from integrals, not from slopes or widths.

  4. Angular sampling bias. Fix: sample cosθU(1,1)\cos\theta\sim\mathcal U(-1,1), ϕU(0,2π)\phi\sim\mathcal U(0,2\pi).

  5. Radius divergence at u1u\to 1. Fix: clamp uu away from 0 and 1.

  6. Rescaling masses to hit MclM_{\rm cl}. Fix: prefer stop-at-or-above or reject-last; document choice.

  7. Forgetting Center-of-Mass (COM) recentering. Fix: subtract mass-weighted COM from positions.


7) Energy and Virial Diagnostics for N-body Systems

7.1 Energy Components

For an N-body gravitational system, monitor these quantities throughout your simulation:

Kinetic Energy (sum over all particles):

EK=12i=1Nmivi2E_K = \frac{1}{2} \sum_{i=1}^{N} m_i v_i^2

where vi2=vx,i2+vy,i2+vz,i2v_i^2 = v_{x,i}^2 + v_{y,i}^2 + v_{z,i}^2 for star ii.

Gravitational Potential Energy (sum over unique pairs):

W=i<jGmimjrijW = -\sum_{i<j} \frac{Gm_im_j}{r_{ij}}

Critical: Count each pair only once using i<ji<j, not iji \neq j which would double-count.

Total Energy:

Etot=EK+WE_{\rm tot} = E_K + W

7.2 The Virial Theorem

For a self-gravitating system in equilibrium, the time-averaged kinetic and potential energies satisfy:

2EK+W=0\langle 2E_K + W \rangle = 0

Define the Virial Ratio:

Q=2EK+WWQ = \frac{|2E_K + W|}{|W|}

Physical Interpretation:

7.3 Using Energy Conservation for Debugging

Monitor all three components (EKE_K, WW, EtotE_{\rm tot}) separately:

Expected Conservation by Method:

The virial ratio should remain < 0.01 for a properly initialized cluster.


8) Optional Project Extension Ideas


9) Quick-reference formulas

IMF inverse within [a,b], α1\alpha\ne 1:

m(u)=[a1α+u(b1αa1α)]1/(1α),uU(0,1).m(u)=\Big[a^{1-\alpha}+u\,(b^{1-\alpha}-a^{1-\alpha})\Big]^{1/(1-\alpha)}\,,\quad u\sim\mathcal U(0,1).

Plummer radius inverse:

r(u)=a(u2/31)1/2,uU(0,1).r(u)= a\,\big(u^{-2/3}-1\big)^{-1/2},\quad u\sim\mathcal U(0,1).

Half-mass scaling: a=r1/222/310.766r1/2a = r_{1/2}\,\sqrt{2^{2/3}-1}\approx 0.766\,r_{1/2}. Continuity constant: A2=A1mbα2α1A_2=A_1\,m_b^{\alpha_2-\alpha_1}.


Code Verification Checklist

Before you perform production runs.

End of guide.