“Know how to solve every problem that has been solved.” “What I cannot create, I do not understand.” — Richard Feynman

The Radial Distribution Function

Statistical Mechanics

What you need to know first 2 concepts, 2 layers

The requisite-knowledge inventory for this page, bottom-up: the primitives at the base, combined upward until you reach what this page assumes. Skim the layers you already own; start wherever the ground gets unfamiliar.

  1. base
  2. L1
  3. you are here

Stand on any particle in a fluid and count neighbors in a thin shell at distance . Divide by the count an ideal gas at the same density would give you. That ratio is the radial distribution function — the conditional probability of finding a particle at given one at the origin, relative to pure chance. It is the single most information-dense curve in liquid-state physics: scattering experiments measure it, integral-equation theories predict it, and — for hard spheres — the entire equation of state hides inside one of its values.

Histogramming it without fooling yourself

The measurement is a pair-distance histogram; all the physics care goes into the normalization, which is where first implementations reliably go wrong. Work it from the smallest case up. One tagged particle, ideal gas: the expected count in a shell is density times shell volume, . Now count over all distinct pairs instead of around one tagged particle: that is tagged-particle experiments at once, so the ideal count becomes . Divide the measured histogram by that, and the two classic bugs — a factor of 2 from pair counting, and using at the bin edge instead of the bin center — are both dodged:

@njit(cache=True)
def gr_histogram(pos, L, bins, rmax):
    """Accumulate pair-distance histogram (all pairs, counted once)."""
    N = pos.shape[0]
    hist = np.zeros(bins)
    dr = rmax / bins
    for i in range(N - 1):
        for j in range(i + 1, N):
            d = pos[i] - pos[j]
            d -= L * np.round(d / L)          # minimum image
            r = np.sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2])
            if r < rmax:
                hist[int(r / dr)] += 1.0
    return hist

# normalization: divide by the pair count an IDEAL GAS would put in each shell
r_mid = (np.arange(bins) + 0.5) * dr
shell = 4 * np.pi * r_mid**2 * dr             # shell volume
g = (hist / nsamp) / (0.5 * N * rho * shell)  # N/2 ordered pairs x rho x shell

Sanity anchors before trusting any curve: inside the core (hard spheres cannot interpenetrate), at large (far away, the fluid forgets you exist — no normalization fudging allowed), and for an ideal gas the whole curve is 1 everywhere.

Against an analytic answer: Percus-Yevick

Hard spheres are one of the very few systems where an integral-equation theory can be solved in closed form. The Percus-Yevick closure of the Ornstein-Zernike equation was cracked independently by Wertheim and by Thiele in 1963: the direct correlation function is a cubic polynomial inside the core and zero outside. Fourier transform, apply OZ, transform back, and the theoretical emerges — no simulation, just 1960s algebra. Overlaid on the Monte Carlo histograms from the hard-sphere fluid page at three densities:

Monte Carlo g(r) at packing fractions 0.20, 0.35 and 0.45 overlaid on the analytic Percus-Yevick curves: near-perfect agreement at low density, with PY slightly underestimating the contact peak at the highest density.
PY inversion check at eta=0.35: extrapolated g(sigma+) = 2.7288 vs analytic 2.7811 (-1.88%)

LJ g(r) first peak: 3.006 at r = 1.083

At theory and simulation are indistinguishable. By the PY curve visibly underestimates the contact peak — a known, systematic shortcoming: PY's two thermodynamic routes (virial and compressibility) disagree with each other at high density, bracketing the truth, and the Carnahan-Starling equation of state is in essence their weighted average. Watching an approximate theory fail in a characterized, documented way is worth more than watching it succeed.

Pressure from structure alone

For hard spheres the virial theorem reduces to the contact-value theorem,

so extrapolating these histograms to (a quadratic fit over the first few bins) hands you the full equation of state — which is exactly how route 1 on the equation-of-state page reproduced Carnahan-Starling at the percent level. For this system, structure is thermodynamics: one curve, measured by counting neighbors, contains the pressure at every density.

What attraction adds: the Lennard-Jones contrast

g(r) of hard spheres at packing fraction 0.45 compared with a near-triple-point Lennard-Jones liquid: similar oscillating layer structure, but the LJ first peak is taller and sits near the potential minimum rather than hard against contact.

A dense Lennard-Jones liquid near its triple point against hard spheres at comparable packing: the oscillations — first shell, depletion ring, second shell — are nearly the same, because packing geometry, not attraction, dictates liquid structure. That observation is the seed of the van der Waals picture and of perturbation theories of liquids (Weeks-Chandler-Andersen): treat the liquid as hard spheres for structure, add attraction as a correction for energetics. The visible differences are the signatures of the well: the LJ first peak sits near the potential minimum rather than jammed against contact, and it is taller — particles are not merely allowed to touch, they are invited.

What experiments see

X-ray and neutron scattering measure the static structure factor , which is the Fourier transform of : the scattered intensity at wavevector interrogates density correlations at wavelength . Every measured of a simple liquid — argon from neutrons, colloids from confocal microscopy — shows the shell structure above. In the measurement-to-model language used across this site: is what the detector records, is the model-side object, and the Fourier pair is the bridge.

Try First

Each prompt asks a checkable question about the working code or math above — predict an output, derive a sign, state an invariant, find a bug. Commit to an answer before clicking "reveal." That commitment is the whole point: if your answer matched, you understand the piece you were looking at; if it didn't, that's the part worth re-reading.

predict
Without simulating: what is g(r) for an ideal gas? And what value does g(r) approach as in any fluid — and why must your histogram reproduce it with no adjustable constants?
why does this work
As density rises, the contact value g(σ⁺) grows steeply while the first minimum drops toward zero. What is the fluid doing?
what if
Compress past freezing so the system crystallizes into FCC. What happens to g(r)?

Reproduce it

Every curve here comes from the same run as the equation-of-state page: scripts/gen_hard_spheres.py, including the PY inversion (validated against the exact PY contact value before being trusted with anything else — with one instructive wrinkle: evaluating the numerically inverted at the contact discontinuity returns the jump's midpoint, because a truncated Fourier reconstruction of a step converges to the average of the two sides. The check therefore extrapolates from just outside, the same way the MC contact value is extracted, and lands within 2% of the closed form.