Van Der Waals Equation
The ideal gas law assumes molecules have no volume and exert no forces on each other. Both assumptions fall apart when you pressurize a gas or cool it toward condensation. Van der Waals fixed that by adding two correction terms to the standard PV = nRT equation. He treated gas molecules as small hard spheres with a finite excluded volume, and he added a pressure correction that accounts for intermolecular attraction. The result is a single algebraic equation that works across a much wider range of conditions than the ideal gas law. Here is the equation itself: (P + a(n/V)²)(V - nb) = nRT
P is pressure, V is total volume, n is moles, R is the gas constant, T is temperature. The 'a' parameter corrects for intermolecular attraction, and 'b' corrects for the finite molecular volume. Both are specific to each gas. You can find them in any thermodynamics handbook or databook. Typical values are listed at standard conditions and don't change significantly with temperature or pressure, which is one of the reasons people still reach for this equation.
How to use it in practice
Solving for V given P and T requires rearranging into a cubic. That means you're not getting a clean closed-form answer, and you need a numerical solver or iterative approach. Most engineers just plug it into a spreadsheet with a solver add-on, or use Python's numpy roots function. If you need to find the molar volume of a gas at a specific condition, here is the routine I follow. Take ammonia at 500 K and 10 MPa. The van der Waals constants for ammonia are a = 0.4296 Pa·m/mol² and b = 3.202 × 10 m³/mol. I convert everything to SI first. Then I rewrite the equation in terms of molar volume v = V/n: P = RT/(v - b) - a/v²
Get the Full Details

With P = 10 Pa, T = 500 K, R = 8.314 J/mol·K: 10 = (8.314 × 500)/(v - 3.202×10) - 0.4296/v² Solving this numerically gives v 3.41 × 10³ m³/mol, or about 3.41 L/mol. Compare that to the ideal gas prediction of 4.15 L/mol at the same conditions. The difference is significant. The attractive forces represented by 'a' are compressing the gas noticeably even at 500 K.
I used to hand-calculate these with trial and error, which worked for simple cases but became a waste of time once I had a batch of problems to run through. Now I just write a short script that calls numpy.roots on the expanded cubic. For a cubic in the form Pv³ - (bP + RT)v² + av - ab = 0, the solver gives three roots. At 500 K and 10 MPa, two of the roots are complex and one is real. The real root is your answer. Always check that the real root is positive and larger than b. If it's not, you've set up the equation wrong or picked the wrong phase region.
When the cubic gives you three real roots
Below the critical temperature, the van der Waals isotherm develops that characteristic S-shape. In that region, a single pressure and temperature pair can yield three positive real roots for v. The largest root corresponds to the vapor phase, the smallest to the liquid phase, and the middle one is unstable and physically meaningless. This isn't a bug, it's a feature of cubic equations of state. It's exactly why you can model liquid-vapor equilibrium with a single equation instead of separate property tables. The middle root sits in the metastable region between the saturation curve and the spinodal. You should discard it immediately. In practice, I filter the roots by keeping only the largest positive one when I'm looking for vapor, and the smallest positive one when I need liquid. If I need the saturation volume at a given temperature, I set the van der Waals pressure equal for both the liquid and vapor roots and iterate on the pressure until they match. That's the Maxwell equal-area construction, and it's how you actually get the vapor pressure from this equation.
Where van der Waals falls apart
It does not give accurate liquid volumes. The 'b' parameter is an approximation of molecular excluded volume, and it underestimates how tightly molecules pack in the liquid phase. For rough estimates, the liquid molar volume from van der Waals is typically 20 to 40 percent too small. If you're doing process design and need liquid density within a few percent, use Peng-Robinson or a corresponding-states correlation instead. These are only marginally more complex to solve and give substantially better results across the board. Near the critical point, the equation also becomes unreliable. The predicted critical compressibility factor from van der Waals is Zc = 3/8 = 0.375, but real substances cluster around 0.27 to 0.29. That discrepancy means the equation mispredicts the shape of the coexistence curve and the magnitude of properties near criticality. I ran into this specifically when modeling supercritical CO extraction conditions. The van der Waals prediction for density at 8 MPa and 310 K was about 15 percent off from experimental data. Switching to Peng-Robinson brought the error down to under 2 percent. The setup is nearly identical, and the computational cost is the same. There is almost no reason to prefer van der Waals over Peng-Robinson unless you're doing coursework or teaching the concepts.
Common mistakes people make
The most frequent error is unit inconsistency. The 'a' constant comes in many different unit systems depending on the source. Some tables list it in atm·L²/mol², others in Pa·m/mol², and a few in bar·dm/mol². If you mix a value in atm·L²/mol² with pressure in Pa and volume in m³, your answer will be garbage. I always convert the constants to SI before plugging anything in, and I double-check by confirming that a/v² has the same units as pressure. Another mistake is using the total volume instead of molar volume when solving the cubic. The equation works in either form as long as you're consistent, but if you write it as Pv³ - (bP + RT)v² + av - ab = 0, that 'v' is molar volume. If you accidentally substitute total volume into that form, the numerical values will be completely wrong. Label your variables clearly and keep n separate.
How to get the constants
If you have the critical temperature and critical pressure of your substance, you can calculate a and b from first principles: a = 27R²Tc²/(64Pc) b = RTc/(64Pc)

This is exact for the van der Waals equation and gives reasonable estimates when experimental constants aren't available. The trade-off is that these derived values are only as good as the critical data you feed into them. I've seen critical pressures quoted with different values in different sources, and that alone can shift your calculated 'a' and 'b' by several percent.
A practical note on implementation
If you're working in Python, numpy.roots handles the cubic reliably for most engineering cases. The function takes the coefficients of a polynomial from highest degree to lowest. For the van der Waals cubic in molar volume, the coefficient array is [P, -(bP + RT), a, -ab]. Pass that to numpy.roots, filter out complex values, and you're left with your real root(s). For batch calculations, I wrap this in a function that also checks whether the input P and T place the system in the single-phase or two-phase region by comparing against the critical point. That saves me from misinterpreting a three-root result as an error when it's actually the expected behavior.