Lab 3.7 · 35 min

Lab: thermostats by hand

A thermostat must do two jobs: bring the system to the target temperature, and then let the temperature fluctuate exactly as it would in a real system touching a heat bath. We take the 9-atom box of Lab 2, start it too hot, and apply every common thermostat by hand. The numbers show which ones do both jobs, which ones only do the first, and what each one costs.

The setup

We reuse the 9 atoms of Lab 2 on the 3×3 lattice in the periodic box L = 3.6, with the same Gaussian velocities (drift removed). This time the velocities are scaled so that the system starts too hot, at T = 2.0, and the thermostat has to bring it down to T₀ = 0.72.

atoms N = 9, 2D, periodic, L = 3.6 start lattice, T = 2.0 (too hot) target T₀ = 0.72 time step dt = 0.005 coupling time τ = 0.1 (20 time steps) degrees of N_f = 2N − 2 = 16 freedom (momentum is conserved, Lab 2) temperature T = Σ v² / N_f (mass 1, k_B = 1)

One idea runs through the whole lab. Temperature is an average property; the kinetic energy of a finite system at a fixed temperature is not constant, it fluctuates. A thermostat that removes these fluctuations gives the right average with the wrong physics.

Step 1

How much should the temperature fluctuate?

Why: Before we can judge a thermostat, we need the right answer. A system in contact with a heat bath (the canonical, NVT ensemble) exchanges energy with it all the time, so its kinetic energy goes up and down. How much it goes up and down is fixed by statistics, and we can compute it by hand.

hot start: Σ v² = 32.000, T = 32 / 16 = 2.000 each velocity component is Gaussian; for a Gaussian ⟨v⁴⟩ = 3 ⟨v²⟩² (check from 10⁶ samples: 3.002) so one component has variance of v² = ⟨v⁴⟩ − ⟨v²⟩² = 2 ⟨v²⟩² K is a sum of N_f independent v²/2 terms: mean of K = N_f ⟨v²⟩/2 std. dev. of K = √N_f × √2 ⟨v²⟩/2 relative fluctuation = std / mean = √(2 / N_f) 9 atoms, 2D √(2/16) = 0.354 (35 %) 1000 atoms, 3D √(2/2997) = 0.026 (2.6 %)

What the numbers say: For our 9 atoms at T₀ = 0.72, the instantaneous temperature should wander by about ±0.25 (35 %) around 0.72. That is not noise to be removed: it is the correct physics. In a large system it is smaller (2.6 % for 1000 atoms) but still there, and quantities like the heat capacity are computed from it. This number, 0.354, is the test every thermostat below must pass.

Step 2

Simple velocity rescaling: right temperature, no fluctuations

Why: The most obvious idea: if T is 2.0 and we want 0.72, multiply every velocity by the same factor λ so that T becomes exactly 0.72. Since T is proportional to v², we need λ² = T₀/T.

λ = √(T₀ / T) = √(0.72 / 2.000) = 0.6000 new Σ v² = 0.6² × 32.000 = 11.52 new T = 11.52 / 16 = 0.720 exactly repeat every step -> T = 0.720 at every step KE fluctuation (long run) = 0.000 correct value = 0.354

What the numbers say: Merit: it reaches the target in one step, which is useful to remove a huge excess of heat at the very start. Limitation: applied every step, the temperature never fluctuates (0.000 instead of 0.354), so the system is not in the canonical ensemble. The sudden velocity jumps also distort the dynamics. Use it only for a first rough cooling, never for collecting data.

Step 3

Berendsen: a gentle version of rescaling

Why: Instead of jumping to T₀ in one step, Berendsen moves T only a small fraction dt/τ of the way each step. τ is a coupling time chosen by the user. This removes the violent jumps, but we must check whether the fluctuations come back.

rule T_new = T + (dt/τ)(T₀ − T), dt/τ = 0.05 factor λ = √(1 + (dt/τ)(T₀/T − 1)) step 1 λ = √(1 + 0.05(0.72/2.0000 − 1)) = 0.98387 T: 2.0000 -> 1.9360 step 2 λ = √(1 + 0.05(0.72/1.9360 − 1)) = 0.98417 T: 1.9360 -> 1.8752 step 3 λ = 0.98448 T: 1.8752 -> 1.8174 step 4 λ = 0.98479 T: 1.8174 -> 1.7626 T − T₀: 1.2800, 1.2160, 1.1552, 1.0974, 1.0426 each step × (1 − dt/τ) = × 0.95 after τ/dt = 20 steps: 0.95²⁰ = 0.358 ≈ 1/e

(These hand steps show only the thermostat part of each step. In a real run the forces also move energy between kinetic and potential energy between thermostat steps; the long runs below include everything.) Now let it run, and watch two numbers in windows of 100 time units (20 000 steps): the kinetic-energy fluctuation, and the share of the kinetic energy in the sliding modes.

sliding modes: whole rows moving together in x, whole columns moving together in y -> 6 modes, 2 of them fixed by zero total momentum -> 4 free fair share of KE = 4 / 16 = 0.25
time windowBerendsen τ = 0.1Berendsen τ = 1.0Bussi τ = 0.1 (step 5)
correct0.25 / 0.3540.25 / 0.3540.25 / 0.354
0–1000.253 / 0.1500.256 / 0.1940.251 / 0.342
100–2000.257 / 0.1480.251 / 0.1710.261 / 0.351
200–3000.426 / 0.1190.252 / 0.1700.242 / 0.341
300–4000.921 / 0.0220.245 / 0.1660.244 / 0.354
400–5000.972 / 0.0070.260 / 0.1720.256 / 0.358
900–10000.993 / 0.0020.247 / 0.1750.271 / 0.350

Each cell is sliding share / KE fluctuation.

What the numbers say: Merit: smooth, predictable cooling: the deviation from T₀ falls to 1/e in a time τ. That makes Berendsen excellent for equilibration. Limitation 1: even while things look healthy, the fluctuation is 0.15 (τ = 0.1) or 0.17 (τ = 1.0) instead of 0.354, so the ensemble is wrong, only less wrong for weak coupling. Limitation 2, much worse: with τ = 0.1, after about 250 time units the kinetic energy drains into the 4 sliding modes, until 99 % of it is there (fair share 25 %) and the fluctuation has collapsed to 0.002. The atoms inside the rows have stopped vibrating, they are frozen, while whole rows glide past each other: the thermometer still reads 0.72. Why: rescaling all velocities by a common factor every step breaks the balance of energy flow between motions of different speed (Harvey, Tan and Cheatham, 1998). The slow collective motions exchange energy with the rest very slowly, so each small bias adds up there, step after step. In big simulations this is the famous flying ice cube: the whole system moves as a block while it freezes inside. Weak coupling (τ = 1.0) did not show it within 1000 time units, but it still has the wrong fluctuation. This is why Berendsen must not be used for production runs.

Step 4

Nosé–Hoover: a friction that has its own equation

Why: We want the right average and the right fluctuations, and we do not want to force T at every step. Nosé–Hoover adds one extra variable, a friction ξ, which acts on all velocities. ξ grows when the system is too hot and shrinks (even becomes negative, i.e. heats) when it is too cold. Its "mass" Q sets how quickly it responds.

friction dξ/dt = (Σ v² − N_f T₀) / Q velocity dv/dt = F − ξ v mass Q = N_f T₀ τ² = 16 × 0.72 × 0.1² = 0.1152 N_f T₀ = 11.52 (the Σ v² we are aiming for) step 1 ξ = 0 + 0.005 × (32.000 − 11.52)/0.1152 = 0.8889 v × e^(−ξ dt) = × 0.99557 T = 1.9823 step 2 ξ = 0.8889 + 0.005 × (31.717 − 11.52)/0.1152 = 1.7655 v × 0.99121 T = 1.9476 step 3 ξ = 2.6180 v × 0.98700 T = 1.8973 step 4 ξ = 3.4356 v × 0.98297 T = 1.8332

The friction builds up step by step, cooling gets faster, and later ξ overshoots: T drops below 0.72, ξ turns negative and heats the system back. T oscillates around T₀ instead of being forced onto it. The long runs:

systemquantitycorrectNHNH chain
9 atomsKE fluctuation0.3540.3500.353
9 atomssliding-mode KE0.250.2490.246
1 oscillatortime with |v| > 1.50.1340.1150.132
1 oscillatorKE fluctuation1.4140.9041.428

What the numbers say: Merit: for the 9 atoms, Nosé–Hoover gets the fluctuation (0.350) and the energy sharing (0.249) right, and it is deterministic, so a run can be reproduced exactly. It is mathematically proven to give the canonical ensemble if the motion explores all states. Limitation: a very simple system, such as one harmonic oscillator (or a stiff, nearly harmonic solid), does not explore all states. Its fluctuation is 0.904 instead of 1.414 and fast velocities are too rare: in the widget you can see unvisited holes in the (x, v) plane. The fix is a chain: a second friction acting on the first one (NH chain, LAMMPS default tchain 3), which gives 1.428 and 0.132. Also, τ must not be too small or T oscillates strongly; 100 time steps is a common choice.

Step 5

Bussi (CSVR): Berendsen plus the missing randomness

Why: Berendsen fails because it pushes K towards its target smoothly, without any random kicks. Bussi, Donadio and Parrinello (2007) keep the same pull and add exactly the random part a heat bath would give, sized so that the fluctuations come out right.

target K₀ = N_f T₀ / 2 = 16 × 0.72 / 2 = 5.760 now K = Σ v² / 2 = 16.000 dK = (K₀ − K) dt/τ + 2 √(K K₀ dt / (N_f τ)) × R = −0.512 + 1.073 × R R is a fresh Gaussian random number each step: R = +1 -> dK = +0.561 (this step heats!) R = −1 -> dK = −1.585 R = 0 -> dK = −0.512 (= Berendsen) then all velocities × √((K + dK) / K)
thermostatKE fluctuationsliding KEdiffusion D
correct0.3540.25—
Berendsen τ 0.1 (t > 400)0.0020.99—
Nosé–Hoover0.3500.2490.0575
Bussi τ 0.10.3500.2500.0597

What the numbers say: Merit: with R = 0 it is exactly Berendsen (smooth equilibration), and the random term restores the correct fluctuation (0.350) and energy sharing (0.250). It is robust even for the oscillator-like systems where plain NH fails, and since all velocities are scaled by one common factor, the diffusion (0.0597) is close to the Nosé–Hoover value (0.0575). Limitation: the run depends on the random numbers, so it is reproducible only with the same seed; total momentum is kept, but there is no conserved "energy" in the usual sense (codes report an effective one). In GROMACS it is v-rescale, in LAMMPS fix temp/csvr.

Step 6

Langevin: friction and random kicks on every atom

Why: A real heat bath is made of solvent molecules that slow an atom down (friction γ) and hit it at random. Langevin dynamics adds exactly these two forces to every atom separately. Because the kicks are on each atom, it does not matter whether the motion explores all states.

friction γ = 1: c = e^(−γ dt) = e^(−0.005) = 0.99501 noise size √((1 − c²) T₀) = 0.08464 one velocity component v = 1.20, random R = −0.70 v_new = 0.99501 × 1.20 + 0.08464 × (−0.70) = 1.19401 − 0.05925 = 1.13477 total momentum is NOT conserved (kicks are independent) -> N_f = 2N = 18, correct fluctuation √(2/18) = 0.333 -> sliding modes 6 of 18 = 0.333
thermostatKE fluctuationsliding KEdiffusion D
correct (N_f = 18)0.3330.333—
Nosé–Hoover (reference)0.3500.2490.0575
Langevin γ = 10.3300.3300.0434
Langevin γ = 100.3310.3330.0148

What the numbers say: Merit: the fluctuations and the energy sharing are right (0.330 and 0.330 vs 0.333), it works for any system, including the single oscillator (0.135 vs 0.134), and it is stable even far from equilibrium. Limitation: the friction slows the atoms down. Diffusion drops from 0.058 to 0.043 at γ = 1 and to 0.015 at γ = 10, four times too slow. Momentum is not conserved, so collective flow is damped too. Use Langevin for sampling structures and energies, or with a small γ; do not take diffusion coefficients or viscosities from a strongly coupled Langevin run.

Step 7

Pressure and barostats: the same story for the volume

Why: To simulate at constant pressure (NPT), we first need the pressure of a configuration, and then a rule that changes the box size. The pressure has a kinetic part (atoms hitting the walls) and a virial part (forces between atoms, Lesson 3.6).

2D: P = (N T + ½ Σ_pairs r F) / A, A = L² = 12.96 lattice pairs inside r_c: 18 at r = 1.2, 18 at 1.697 F(1.2) = −2.2117 (negative = attraction) F(1.697) = −0.5425 Σ r F = 18 × 1.2 × (−2.2117) + 18 × 1.697 × (−0.5425) = −64.343 P = (9 × 0.72 + 0.5 × (−64.343)) / 12.96 = (6.48 − 32.17) / 12.96 = −1.982 Berendsen barostat towards P₀ = 0 (β = 1, τ_P = 1): μ = 1 − (dt/τ_P) β (P₀ − P) / 2 = 0.99504 -> box side × 0.99504 each step: it shrinks

What the numbers say: A negative pressure means the atoms pull on each other more than they push: at this density and temperature the box is too large, so the barostat shrinks it. Merit of Berendsen scaling: smooth and fast, ideal to bring the density to the right value. Limitation: exactly like the Berendsen thermostat, it suppresses the volume fluctuations, so the ensemble is not truly NPT and the compressibility comes out wrong. For production use a barostat with the correct fluctuations: C-rescale (Bernetti–Bussi, the barostat version of step 5), Parrinello–Rahman, or MTK (LAMMPS fix npt).

Summary

methodmerit (number)limitation (number)use it for
rescalingT₀ in one stepfluctuation 0.000 vs 0.354removing a huge initial excess
Berendsensmooth, 1/e in τfluctuation 0.15 vs 0.354; later 99 % KE in sliding modes (flying ice cube)equilibration only
Nosé–Hooverfluctuation 0.350, deterministicsingle oscillator 0.904 vs 1.414production, as a chain
NH chain0.353; oscillator 1.428needs τ ≈ 100 dtproduction (LAMMPS fix nvt)
Bussi (CSVR)0.350; D = 0.0597random, needs a seedproduction (GROMACS v-rescale)
Langevinworks for any systemD 0.058 -> 0.015 at γ = 10sampling; small γ if dynamics matter
Berendsen barostatP −1.98 -> 0 smoothlyvolume fluctuations suppressedequilibrating the density