Skip to content
cfd-lab:~/en/posts/2026-06-30-van-der-waals…online
NOTE #090DAY TUE 유체역학DATE 2026.06.30READ 6 min readWORDS 1,101#Fluid-Mechanics#Equation-of-State#Van-der-Waals#Compressibility#Supercritical

Where the Ideal Gas Starts to Lie — Compressibility Factor Z and the van der Waals Equation

Real gases through the compressibility factor, corresponding states, and the van der Waals loop

Take nitrogen at 100 bar and 200 K, compute its density with the ideal gas law, and you miss the real value by more than a quarter. Same pressure, same temperature — yet the molecules pull on each other and take up room of their own. This post is about catching that mismatch with a single number (the compressibility factor ZZ), about how van der Waals mimicked a real gas with just two constants, and about the S-shaped curve below the critical point that splits liquid from vapor. At the end we see why all of this reaches straight into rocket-injector flow and the cells of a CFD grid.

Nitrogen at 100 bar is heavier than an ideal gas#

The ideal gas law Pv=RTPv = RT treats molecules as points and ignores the forces between them. It works for dilute gases, where molecules sit far apart.

Raise the pressure and that breaks. Molecules crowd together. A weak attraction (the van der Waals force) pulls them in and shrinks the volume. At the same time, the molecules' own volume stops being negligible.

The two effects pull opposite ways. Attraction shrinks the volume; finite size inflates it. Which one wins is set by temperature and pressure. So "a real gas is heavier — or lighter — than an ideal gas" flips depending on the conditions.

The compressibility factor Z — one number for the mismatch#

That mismatch gets bundled into a single number.

Z=PvRT=vactualvidealZ = \frac{Pv}{RT} = \frac{v_\text{actual}}{v_\text{ideal}}

PP is pressure, vv molar volume, RR the gas constant, TT temperature. If Z=1Z=1, the gas is ideal. The farther ZZ strays from 1, the larger the deviation.

Z<1Z<1 means attraction dominates: molecules draw together and the real volume is smaller than ideal. Z>1Z>1 means finite size dominates: molecules push apart and the volume grows. For the nitrogen above, Z0.79Z \approx 0.79, so the real density was 1/0.791.271/0.79 \approx 1.27 times the ideal value.

The principle of corresponding states: where every gas looks alike#

Every gas has its own ZZ curve. Yet divide pressure and temperature by each gas's own critical values, and the curves nearly collapse onto one.

PR=PPc,TR=TTcP_R = \frac{P}{P_c}, \qquad T_R = \frac{T}{T_c}

PcP_c and TcT_c are the critical pressure and temperature. The principle of corresponding states says this: at the same reduced pressure PRP_R and reduced temperature TRT_R, nearly all gases share nearly the same ZZ.

Nitrogen, methane, carbon dioxide — at TR=1.5T_R=1.5, PR=2P_R=2 they have similar ZZ. It is not the species but the position relative to the critical point that sets behavior. That universality lets a single generalized chart cover countless gases.

van der Waals: mimicking molecules with two constants#

In 1873 van der Waals added two corrections to the ideal gas law.

(P+av2)(vb)=RT\left(P + \frac{a}{v^2}\right)(v - b) = RT

a/v2a/v^2 is the pressure drop from intermolecular attraction; the denser the gas (the smaller vv), the stronger it gets. bb is the volume the molecules themselves occupy, so the free space shrinks to vbv-b.

The two constants are fixed at the critical point. There the PPvv isotherm passes through an inflection where slope and curvature both vanish.

(Pv)Tc=0,(2Pv2)Tc=0\left(\frac{\partial P}{\partial v}\right)_{T_c} = 0, \qquad \left(\frac{\partial^2 P}{\partial v^2}\right)_{T_c} = 0

Solving both conditions gives the constants and the critical compressibility.

a=27R2Tc264Pc,b=RTc8Pc,Zc=PcvcRTc=38a = \frac{27 R^2 T_c^2}{64 P_c}, \qquad b = \frac{R T_c}{8 P_c}, \qquad Z_c = \frac{P_c v_c}{R T_c} = \frac{3}{8}

Here Zc=3/8=0.375Z_c = 3/8 = 0.375 is a constant independent of which gas. Real gases have ZcZ_c around 0.27–0.29, so van der Waals overshoots quantitatively — but the qualitative picture is exactly right.

Rewrite in reduced variables and the constants aa, bb disappear.

PR=8TR3vR13vR2P_R = \frac{8 T_R}{3 v_R - 1} - \frac{3}{v_R^2}

That single line is the equation form of corresponding states. The critical point is pinned at (vR,PR,TR)=(1,1,1)(v_R, P_R, T_R) = (1, 1, 1).

The S-curve below the critical point and the Maxwell construction#

For TR>1T_R > 1 the isotherm decreases monotonically. Raise the pressure and the volume shrinks — the intuitive curve.

For TR<1T_R < 1 it wobbles. An S-shaped loop appears. Its middle branch has (P/v)T>0(\partial P/\partial v)_T > 0: raise the pressure and the volume grows, which is mechanically unstable. Real matter simply skips this branch.

Instead a single horizontal line bridges liquid and vapor. Its height is the saturation pressure. The position comes from the Maxwell equal-area construction: pick the height at which the line cuts off two equal areas, above and below, from the loop. That condition is equivalent to the liquid and vapor sharing the same Gibbs free energy. It is the one pressure at which the two phases can coexist.

Play with the simulation below. Drag the reduced-temperature slider under 1 and the loop grows, while the Maxwell construction shades two equal-area regions (pink and cyan) and draws the saturation pressure.

saturation pressure P_r,sat = 0.647
Z(sat. vapor) = 0.633  ·   Z(sat. liquid) = 0.163

Drop TRT_R to 0.85 and the gap in ZZ between saturated vapor and saturated liquid widens sharply. The liquid-side ZZ falls below 0.1, because the molecules nearly touch and attraction overwhelms. Push TRT_R toward 1 and the two values merge into one point — the moment at the critical point where liquid and vapor stop being distinct.

Solving for Z in Python#

Rearrange the van der Waals equation for ZZ and you get a cubic. With nothing but the real gas's critical constants you can solve for ZZ at any PP, TT.

import numpy as np
 
R = 8.314  # J/(mol·K)
 
def vdw_constants(Tc, Pc):
    """van der Waals a, b from the critical constants."""
    a = 27.0 * R**2 * Tc**2 / (64.0 * Pc)
    b = R * Tc / (8.0 * Pc)
    return a, b
 
def vdw_compressibility(P, T, Tc, Pc):
    """Physical root of Z^3 - (1+B)Z^2 + A Z - A B = 0."""
    a, b = vdw_constants(Tc, Pc)
    A = a * P / (R * T)**2          # dimensionless size of the attraction term
    B = b * P / (R * T)            # dimensionless size of the finite-volume term
    coeffs = [1.0, -(1.0 + B), A, -A * B]
    roots = np.roots(coeffs)
    real = roots[np.abs(roots.imag) < 1e-8].real
    real = real[real > B]          # only v > b  ⇒  Z > B is physical
    return real.max(), real.min(), real.size
 
# Nitrogen: Tc = 126.2 K, Pc = 3.39 MPa, M = 28 g/mol
Tc, Pc, M = 126.2, 3.39e6, 0.028
P, T = 1.0e7, 200.0                # 100 bar, 200 K
Z_gas, Z_liq, n = vdw_compressibility(P, T, Tc, Pc)
 
rho_ideal = P * M / (R * T)        # ideal-gas density
rho_real = rho_ideal / Z_gas       # real density
print(f"roots = {n},  Z = {Z_gas:.4f}")
print(f"ideal density = {rho_ideal:6.1f} kg/m^3")
print(f"real  density = {rho_real:6.1f} kg/m^3  ({100*(rho_real/rho_ideal-1):+.0f}%)")

The output is:

roots = 1,  Z = 0.7905
ideal density =  168.4 kg/m^3
real  density =  213.0 kg/m^3  (+27%)

Since TR=200/126.21.59T_R = 200/126.2 \approx 1.59, we are above critical. There is a single real root, so no liquid/vapor split. Even so, the ideal-gas density is 27% below the real one — exactly the "more than a quarter" error from the opening line.

Supercritical injection and CFD — why the equation of state shakes the grid#

This is not chalkboard-only. A liquid rocket engine's combustion chamber usually runs above the propellant's critical pressure. When LOX (liquid oxygen) or a cryogenic nitrogen jet sprays into such a chamber, no familiar droplets form.

Surface tension disappears. Cross the critical point and the boundary between liquid and gas dissolves. The jet does not break into drops; its density gradient unfurls like a comb and mixes with the surroundings. This is supercritical (or transcritical) injection, a central flow phenomenon in next-generation engine design.

Here the equation of state shakes the grid, because density is bound nonlinearly to pressure and temperature. If a CFD solver assumes an ideal gas, it gets the jet density wrong by tens of percent, and with it the momentum flux ρu2\rho u^2 and the mixing length go off entirely. So real codes use real-gas models — a cubic EOS (Peng–Robinson, SRK) or NASG (Noble–Abel Stiffened Gas). The compressibility factor ZZ is exactly what those models solve in every grid cell.

Things to remember#

  • The compressibility factor Z=Pv/RTZ = Pv/RT captures, in one number, how far a real gas departs from ideal. Z<1Z<1 means attraction dominates; Z>1Z>1 means finite volume dominates.
  • The van der Waals equation reproduces the critical point, the loop, and the phase transition qualitatively with just two constants — attraction a/v2a/v^2 and molecular volume bb. In reduced variables it universalizes to Zc=3/8Z_c = 3/8.
  • Beyond the critical point, supercritical flows mix without surface tension, and solving them in CFD requires a real equation of state — not the ideal gas — in every grid cell.

Share if you found it helpful.