# Thermodynamic equilibrium
## Microsim
### Live player
<div class="microsim-player">
<iframe src="https://editor.p5js.org/sciencenibber/full/dPYboO9TR" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe>
</div>
<div class="microsim-fallback">
<img src="Microsims/thumbs/Thermodynamic_equilibrium.png" alt="Thermodynamic_equilibrium microsim poster" style="width:100%;border:1px solid #4445;border-radius:6px;">
<p><em>Live microsim (desktop) · <a href="https://editor.p5js.org/sciencenibber/sketches/dPYboO9TR">open sketch in the p5.js editor</a></em></p>
</div>
**Editor URL:** https://editor.p5js.org/sciencenibber/sketches/dPYboO9TR
**Description (100 words):**
The reader sees two ideal-gas compartments A (hot, dense, orange) and B (cool, sparse, blue) separated by a sliding wall, with three toggle buttons — Heat, Work, Matter — that selectively open each exchange channel. A right-hand gauge column tracks T, P, N, V for both sides plus the three differences (dT, dP, dmu) that drive each equilibration; a lower scope plots the total entropy S_A + S_B alongside T_A(t) and T_B(t), making the second law visible as a monotonically rising green curve. With Heat alone enabled, only temperatures equalize; enable Work and the wall slides until pressures match; add Matter and the densities (chemical potentials) merge. Pause and Reset restart the experiment.
```js
// =====================================================================
// Thermodynamic_equilibrium.js -- Wikitube microsim
// Article: Thermodynamic_equilibrium en.wikitube.io/wiki/Thermodynamic_equilibrium
// Room: Helium Pattern: A (state transitions, equilibration)
// ---------------------------------------------------------------------
// Idea: two ideal-gas compartments A and B sit either side of a wall
// whose three permissions -- heat, work, matter -- are togglable by
// the reader. The simulation watches them relax to thermodynamic
// equilibrium as each enabled exchange channel drives the relevant
// intensive variable (T, P, mu) toward a common value.
//
// * thermal equilibrium heat exchange ON -> T_A = T_B
// * mechanical equilibrium work exchange ON -> P_A = P_B (wall slides)
// * chemical equilibrium matter exchange ON -> mu_A = mu_B (densities equalize)
//
// Full thermodynamic equilibrium = all three holding simultaneously.
// The zeroth law (transitivity of thermal equilibrium) is the empirical
// ground for defining a temperature scale; this sketch makes it
// visible: turn ON only the heat permission and watch only the
// temperatures equalize while pressure and composition stay frozen.
//
// Energy is conserved across the diathermal wall by relaxing T_A and
// T_B toward a common U-conserving target T_eq:
//
// T_eq = (N_A * T_A + N_B * T_B) / (N_A + N_B)
//
// Volume relaxes toward the pressure-equilibrium target
//
// V_A_eq = V_TOTAL * (N_A * T_A) / (N_A * T_A + N_B * T_B)
//
// and matter relaxes toward N_A_eq = (N_A + N_B) * V_A / V_TOTAL
// (density equalization, which equals chemical-potential equalization
// for an ideal gas at uniform T). Entropy of each compartment is
// computed from the ideal-gas form
//
// S = N * ( (3/2) * R * ln(T) + R * ln(V / N) )
//
// up to additive constants, and the total S_A + S_B is plotted in
// the lower scope. The second law -- dS_total >= 0 for any spontaneous
// exchange across an isolated boundary -- is what the curve shows.
//
// Visual layout (720 x 520 canvas):
// * top-left: HUD title + en.wikitube.io/wiki/Thermodynamic_equilibrium
// * top-right: instruction hints
// * row at y~78: three toggle buttons (Heat / Work / Matter)
// plus Pause / Reset
// * middle band: System A (left) + sliding wall + System B (right)
// with right-side gauge column (T, P, N, dT, dP, dmu)
// * lower band: S_total(t), T_A(t), T_B(t) on a shared scope
// * bottom-right: canonical equilibrium conditions
//
// Conventions (Wikitube Betterfire Standard v0):
// * single ARTICLE constant at the top, single quotes
// * p5.disableFriendlyErrors = true to keep the editor console clean
// * non-ASCII characters (Greek mu, delta, lambda) live in COMMENTS
// only; every text() string literal is pure ASCII. The editor
// preview pipeline mangles non-ASCII in displayed strings.
// * Energy-room palette (P5_JS_EDITOR section 4): dark BG, HOT/COLD
// tones, STRUCT grey, TRAJ yellow, GAUGE green.
// =====================================================================
const ARTICLE = 'Thermodynamic_equilibrium';
const TITLE = ARTICLE.replace(/_/g, ' ');
p5.disableFriendlyErrors = true;
// ----- Energy room palette (P5_JS_EDITOR section 4, line 165) --------
const BG = 18;
const FG = 240;
const DIM = [240, 240, 240, 140];
const HOT = [220, 110, 60]; // warm: high-T compartment
const COLD = [60, 130, 220]; // cool: low-T compartment
const STRUCT = [120, 130, 150]; // structural grey: wall + axes
const TRAJ = [240, 220, 80]; // accent: equilibrium-line marker
const SCRATCH = [120, 120, 120, 90]; // grid / scratch lines
const GAUGE = [120, 220, 140]; // entropy curve
const ACCENT = [200, 100, 220]; // wall-permission tag
// ----- Physical constants -------------------------------------------
// Gas constant (J / (mol * K)). Used directly in pressure and entropy
// formulas; absolute values are arbitrary for the demo, only ratios
// and equalities matter.
const R = 8.314;
const CV = 1.5 * R; // monatomic ideal-gas c_v
// ----- Total conserved quantities (set at reset) --------------------
// The wall moves but V_A + V_B is fixed; particles cross but N_A + N_B
// is fixed. Energy U_A + U_B is conserved across diathermal exchanges.
const V_TOTAL_INIT = 2.0; // L (compartment volumes sum to this)
const N_TOTAL_INIT = 0.20; // mol (total moles across both)
// ----- State of compartments A and B --------------------------------
// Each carries (T [K], V [L], N [mol]). The integrator nudges them
// toward equilibrium per the three permissions.
let A, B;
let V_TOTAL; // captured at reset (== V_TOTAL_INIT)
// ----- Wall position (fraction in [0, 1]; V_A = V_TOTAL * wallPos) ---
let wallPos = 0.5;
// ----- Wall permission flags (driven by the three toggle buttons) ----
let allowHeat = true;
let allowWork = true;
let allowMatter = false;
// ----- Simulation control -------------------------------------------
let running = true;
let t = 0; // simulated time in seconds
const buf = []; // ring buffer of {t, S, TA, TB, PA, PB}
const BUF_MAX = 600;
// ----- Layout rectangles (set in setup) ------------------------------
let boxY, boxH, boxXmin, boxXmax; // compartment band
let plotX, plotY, plotW, plotH; // S(t) scope band
// ----- DOM controls (created in setup) -------------------------------
let btnHeat, btnWork, btnMatter, btnRun, btnReset;
// ----- Decorative particle field (just a visual cue for density) ----
// Each compartment has up to PARTS_PER particles drawn at randomized
// positions; the displayed fraction tracks N / N_TOTAL_INIT for visual
// "density". This is decoration only; the physics runs on bulk state.
const PARTS_PER = 40;
let parts;
function setup() {
createCanvas(720, 520);
pixelDensity(2);
textFont('system-ui');
// Compartment band: leave room for HUD top + button row + scope below.
boxY = 120;
boxH = 210;
boxXmin = 80;
boxXmax = 520;
// Scope band
plotX = 80;
plotY = 360;
plotW = 560;
plotH = 120;
// Toggle buttons -- single row at y = 78.
btnHeat = createButton('Heat exchange: ON').position(80, 78).size(150, 22);
btnWork = createButton('Work exchange: ON').position(238, 78).size(150, 22);
btnMatter = createButton('Matter exchange: OFF').position(396, 78).size(170, 22);
btnRun = createButton('Pause').position(574, 78).size(60, 22);
btnReset = createButton('Reset').position(642, 78).size(60, 22);
btnHeat.mousePressed(() => {
allowHeat = !allowHeat;
btnHeat.html('Heat exchange: ' + (allowHeat ? 'ON' : 'OFF'));
});
btnWork.mousePressed(() => {
allowWork = !allowWork;
btnWork.html('Work exchange: ' + (allowWork ? 'ON' : 'OFF'));
});
btnMatter.mousePressed(() => {
allowMatter = !allowMatter;
btnMatter.html('Matter exchange: ' + (allowMatter ? 'ON' : 'OFF'));
});
btnRun.mousePressed(() => {
running = !running;
btnRun.html(running ? 'Pause' : 'Run');
});
btnReset.mousePressed(resetSim);
resetSim();
}
function resetSim() {
// Initial conditions: A is hot and dense (more moles + higher T),
// B is cool and sparse. With equal initial volumes the wall starts
// at the center. Pressure difference is large -> wall will slide
// toward B once Work is enabled; temperatures equalize quickly when
// Heat is enabled; densities equalize when Matter is enabled.
V_TOTAL = V_TOTAL_INIT;
A = { T: 500, V: 1.0, N: 0.12 };
B = { T: 250, V: 1.0, N: 0.08 };
wallPos = A.V / V_TOTAL;
buf.length = 0;
t = 0;
running = true;
if (btnRun) btnRun.html('Pause');
parts = makeParticles(PARTS_PER, PARTS_PER);
}
function makeParticles(nA, nB) {
const a = [], b = [];
for (let i = 0; i < nA; i++) {
a.push({ x: Math.random(), y: Math.random(),
vx: Math.random() * 2 - 1, vy: Math.random() * 2 - 1 });
}
for (let i = 0; i < nB; i++) {
b.push({ x: Math.random(), y: Math.random(),
vx: Math.random() * 2 - 1, vy: Math.random() * 2 - 1 });
}
return { a, b };
}
// =====================================================================
// Thermodynamic state functions
// =====================================================================
// Pressure of compartment s, ideal-gas law in P = N R T / V form.
// Volumes are in L, so the numerical result is in (J / L) which is
// proportional to pressure; the gauge displays it in arbitrary
// "kPa-like" units after dividing by 1000.
function pressure(s) {
return s.N * R * s.T / Math.max(s.V, 1e-6);
}
// Ideal-gas entropy (Sackur-Tetrode-shaped, additive constants dropped):
// S = N * ( c_v * ln(T) + R * ln(V / N) )
// Monotone in S_total for the relaxation dynamics below.
function entropy(s) {
const ratio = Math.max(s.V / Math.max(s.N, 1e-6), 1e-6);
return s.N * (CV * Math.log(Math.max(s.T, 1)) + R * Math.log(ratio));
}
// Chemical potential proxy (ideal gas, additive constants dropped).
// At equal T, mu_A = mu_B iff N_A / V_A = N_B / V_B (density match).
function muChem(s) {
const ratio = Math.max(s.N / Math.max(s.V, 1e-6), 1e-6);
return CV * s.T - s.T * R * Math.log(ratio);
}
// =====================================================================
// Relaxation step: nudge A and B toward equilibrium per permissions
// =====================================================================
function step(dt) {
// 1. Heat exchange. Relax T_A and T_B toward the U-conserving target
// T_eq = (N_A T_A + N_B T_B) / (N_A + N_B). This keeps internal
// energy U = (N_A + N_B) c_v T_eq constant -- the diathermal wall
// transmits heat but conserves total energy.
if (allowHeat) {
const T_eq = (A.N * A.T + B.N * B.T) / Math.max(A.N + B.N, 1e-6);
const kT = 0.7;
A.T += -kT * (A.T - T_eq) * dt;
B.T += -kT * (B.T - T_eq) * dt;
}
// 2. Work exchange. Relax V toward the pressure-equilibrium target
// V_A_eq = V_TOTAL * (N_A T_A) / (N_A T_A + N_B T_B). The wall is
// movable but volumes still sum to V_TOTAL.
if (allowWork) {
const num = A.N * A.T;
const denom = A.N * A.T + B.N * B.T;
const V_A_eq = V_TOTAL * num / Math.max(denom, 1e-6);
const kV = 0.6;
A.V += -kV * (A.V - V_A_eq) * dt;
A.V = constrain(A.V, 0.1, V_TOTAL - 0.1);
B.V = V_TOTAL - A.V;
wallPos = A.V / V_TOTAL;
}
// 3. Matter exchange. Relax N_A toward N_A_eq = N_total * V_A / V_TOTAL
// (density equalization). At common T this is exactly chemical-
// potential equalization for an ideal gas; off-temperature it is
// a first-order approximation -- the heat exchange runs to T_eq
// on a faster time scale so this approximation is benign in
// practice.
if (allowMatter) {
const N_total = A.N + B.N;
const N_A_eq = N_total * A.V / V_TOTAL;
const kN = 0.35;
A.N += -kN * (A.N - N_A_eq) * dt;
A.N = constrain(A.N, 0.01, N_total - 0.01);
B.N = N_total - A.N;
}
// Snapshot for the lower scope
buf.push({
t,
S: entropy(A) + entropy(B),
TA: A.T, TB: B.T,
PA: pressure(A), PB: pressure(B)
});
if (buf.length > BUF_MAX) buf.shift();
t += dt;
}
function updateParticles(dt) {
for (const p of parts.a) advanceParticle(p, dt, A.T);
for (const p of parts.b) advanceParticle(p, dt, B.T);
}
// Each decorative particle moves with a speed proportional to sqrt(T)
// (kinetic-theory thermal speed), and bounces off the [0,1]x[0,1]
// unit square. Pixel mapping happens at draw time.
function advanceParticle(p, dt, T) {
const v = Math.sqrt(Math.max(T, 0)) * 0.07;
p.x += p.vx * v * dt;
p.y += p.vy * v * dt;
if (p.x < 0) { p.x = 0; p.vx = -p.vx; }
if (p.x > 1) { p.x = 1; p.vx = -p.vx; }
if (p.y < 0) { p.y = 0; p.vy = -p.vy; }
if (p.y > 1) { p.y = 1; p.vy = -p.vy; }
}
// =====================================================================
// Main draw loop
// =====================================================================
function draw() {
background(BG);
if (running) {
const dt = Math.min(deltaTime / 1000, 0.05);
step(dt);
updateParticles(dt);
}
drawCompartments();
drawWall();
drawParticles();
drawGauges();
drawScope();
drawHUD();
}
// Draw the two compartment rectangles, tinted by temperature.
function drawCompartments() {
const xWall = lerp(boxXmin, boxXmax, wallPos);
const xA0 = boxXmin, xA1 = xWall - 2;
const xB0 = xWall + 2, xB1 = boxXmax;
// Tint each compartment by temperature: lerp COLD -> HOT over 100..700 K
const cA = lerpColor(color(...COLD), color(...HOT),
constrain((A.T - 100) / 600, 0, 1));
const cB = lerpColor(color(...COLD), color(...HOT),
constrain((B.T - 100) / 600, 0, 1));
noStroke();
fill(red(cA), green(cA), blue(cA), 100);
rect(xA0, boxY, xA1 - xA0, boxH);
fill(red(cB), green(cB), blue(cB), 100);
rect(xB0, boxY, xB1 - xB0, boxH);
// Outlines + label
noFill();
stroke(SCRATCH);
strokeWeight(1);
rect(xA0, boxY, xA1 - xA0, boxH);
rect(xB0, boxY, xB1 - xB0, boxH);
noStroke();
fill(...DIM);
textSize(11);
textAlign(CENTER, BOTTOM);
text('System A', (xA0 + xA1) / 2, boxY - 4);
text('System B', (xB0 + xB1) / 2, boxY - 4);
}
// Draw the sliding wall between compartments with a permission tag.
function drawWall() {
const xWall = lerp(boxXmin, boxXmax, wallPos);
push();
stroke(...STRUCT);
strokeWeight(allowWork ? 2 : 5);
line(xWall, boxY - 4, xWall, boxY + boxH + 4);
// Permission tag: "Q W N" with dashes for disabled channels.
// Q = heat, W = work, N = matter.
const tag =
(allowHeat ? 'Q' : '-') +
(allowWork ? 'W' : '-') +
(allowMatter ? 'N' : '-');
noStroke();
fill(...ACCENT);
textSize(11);
textAlign(CENTER, BOTTOM);
text(tag, xWall, boxY - 18);
pop();
}
// Decorative particle field. Count tracks N / N_TOTAL_INIT per
// compartment so a density change reads as a sparser or denser cloud.
function drawParticles() {
const xWall = lerp(boxXmin, boxXmax, wallPos);
noStroke();
// A side
fill(...HOT, 210);
const xA0p = boxXmin + 6, xA1p = xWall - 6;
const showA = Math.round(parts.a.length *
constrain(A.N / N_TOTAL_INIT, 0, 1));
for (let i = 0; i < showA; i++) {
const p = parts.a[i];
if (xA1p - xA0p < 10) continue;
circle(lerp(xA0p, xA1p, p.x),
lerp(boxY + 8, boxY + boxH - 8, p.y), 4);
}
// B side
fill(...COLD, 210);
const xB0p = xWall + 6, xB1p = boxXmax - 6;
const showB = Math.round(parts.b.length *
constrain(B.N / N_TOTAL_INIT, 0, 1));
for (let i = 0; i < showB; i++) {
const p = parts.b[i];
if (xB1p - xB0p < 10) continue;
circle(lerp(xB0p, xB1p, p.x),
lerp(boxY + 8, boxY + boxH - 8, p.y), 4);
}
}
// Right-side gauge column: T, P, N for each system, plus the three
// equilibration deltas (dT, dP, dmu). When all three deltas read zero
// the system is in full thermodynamic equilibrium.
function drawGauges() {
push();
const xg = 540;
let yg = boxY;
noStroke();
fill(...DIM); textSize(11); textAlign(LEFT, TOP);
text('System A', xg, yg); yg += 14;
fill(FG); textSize(12);
text('T_A = ' + nf(A.T, 0, 1) + ' K', xg, yg); yg += 14;
text('P_A = ' + nf(pressure(A) / 1000, 0, 2) + ' kPa', xg, yg); yg += 14;
text('N_A = ' + nf(A.N, 0, 3) + ' mol', xg, yg); yg += 14;
text('V_A = ' + nf(A.V, 0, 2) + ' L', xg, yg); yg += 22;
fill(...DIM); textSize(11);
text('System B', xg, yg); yg += 14;
fill(FG); textSize(12);
text('T_B = ' + nf(B.T, 0, 1) + ' K', xg, yg); yg += 14;
text('P_B = ' + nf(pressure(B) / 1000, 0, 2) + ' kPa', xg, yg); yg += 14;
text('N_B = ' + nf(B.N, 0, 3) + ' mol', xg, yg); yg += 14;
text('V_B = ' + nf(B.V, 0, 2) + ' L', xg, yg); yg += 22;
fill(...DIM); textSize(11);
text('Drives to zero at equilibrium:', xg, yg); yg += 14;
fill(...TRAJ); textSize(12);
text('dT = ' + nf(A.T - B.T, 0, 1) + ' K', xg, yg); yg += 14;
text('dP = ' + nf((pressure(A) - pressure(B)) / 1000, 0, 2) + ' kPa', xg, yg); yg += 14;
text('dmu = ' + nf(muChem(A) - muChem(B), 0, 1) + ' J/mol', xg, yg);
pop();
}
// Bottom scope: S_total(t), T_A(t), T_B(t) on a shared time axis.
// S_total is rendered in GAUGE green and is the headline -- the
// second-law plot. T_A and T_B are overlaid so the reader sees the
// temperature crossover happen during thermal equilibration.
function drawScope() {
push();
// Axes + frame
noFill();
stroke(SCRATCH);
strokeWeight(1);
rect(plotX, plotY, plotW, plotH);
noStroke();
fill(...DIM);
textSize(10);
textAlign(LEFT, BOTTOM);
text('Total entropy S_A + S_B (the second law says this must rise)',
plotX + 4, plotY - 2);
if (buf.length >= 2) {
const tMin = buf[0].t, tMax = buf[buf.length - 1].t;
const dt = Math.max(tMax - tMin, 1e-6);
// S range
let sMin = Infinity, sMax = -Infinity;
for (const r of buf) {
if (r.S < sMin) sMin = r.S;
if (r.S > sMax) sMax = r.S;
}
if (sMax - sMin < 1e-3) sMax = sMin + 1;
// T range (over both compartments)
let TMin = Infinity, TMax = -Infinity;
for (const r of buf) {
if (r.TA < TMin) TMin = r.TA;
if (r.TB < TMin) TMin = r.TB;
if (r.TA > TMax) TMax = r.TA;
if (r.TB > TMax) TMax = r.TB;
}
if (TMax - TMin < 1) TMax = TMin + 1;
// S_total curve (green)
stroke(...GAUGE);
strokeWeight(2);
noFill();
beginShape();
for (const r of buf) {
const x = map(r.t, tMin, tMin + dt, plotX + 4, plotX + plotW - 4);
const y = map(r.S, sMin, sMax, plotY + plotH - 6, plotY + 8);
vertex(x, y);
}
endShape();
// T_A curve (warm)
stroke(...HOT, 220);
strokeWeight(1.5);
noFill();
beginShape();
for (const r of buf) {
const x = map(r.t, tMin, tMin + dt, plotX + 4, plotX + plotW - 4);
const y = map(r.TA, TMin, TMax, plotY + plotH - 6, plotY + 8);
vertex(x, y);
}
endShape();
// T_B curve (cool)
stroke(...COLD, 220);
strokeWeight(1.5);
noFill();
beginShape();
for (const r of buf) {
const x = map(r.t, tMin, tMin + dt, plotX + 4, plotX + plotW - 4);
const y = map(r.TB, TMin, TMax, plotY + plotH - 6, plotY + 8);
vertex(x, y);
}
endShape();
// Legend
noStroke();
textSize(10);
textAlign(LEFT, BOTTOM);
fill(...GAUGE); text('S_tot', plotX + 470, plotY + plotH - 4);
fill(...HOT); text('T_A', plotX + 510, plotY + plotH - 4);
fill(...COLD); text('T_B', plotX + 540, plotY + plotH - 4);
}
pop();
}
// =====================================================================
// HUD: title block + control hints + canonical equilibrium conditions
// =====================================================================
function drawHUD() {
// Top-left: title + Wikitube URL (Betterfire Standard rule 2)
noStroke();
fill(FG);
textAlign(LEFT, TOP);
textSize(22);
text(TITLE, 14, 12);
fill(...DIM);
textSize(12);
text('Wikitube microsim . en.wikitube.io/wiki/Thermodynamic_equilibrium',
14, 42);
// Top-right: control hints
textAlign(RIGHT, TOP);
textSize(10);
text('toggle Heat / Work / Matter to allow each exchange channel',
width - 14, 12);
text('watch T, P, density (mu) equalize when each channel is ON',
width - 14, 24);
text('S_total must monotonically rise -- the second law',
width - 14, 36);
// Bottom-right: canonical equilibrium conditions (Betterfire rule 4)
textAlign(RIGHT, BOTTOM);
fill(FG);
textSize(13);
text('equilibrium: T_A = T_B, P_A = P_B, mu_A = mu_B (dS_total >= 0)',
width - 14, height - 6);
}
// =====================================================================
// End of Thermodynamic_equilibrium.js -- Wikitube microsim, Helium room,
// Pattern A. Two-compartment relaxation to thermal, mechanical, and
// chemical equilibrium with the second-law entropy curve as headline.
// =====================================================================
```
## Links (Wikipedia order)
<!-- injected from _registry/childlinks/Thermodynamic_equilibrium.json (2026-07-30T02:09:12Z) -->
`Absorption_refrigerator` · `Acid_dissociation_constant` · `Adiabatic_process` · `An_Inquiry_Concerning_the_Source_of_the_Heat_Which_Is_Excited_by_Friction` · `Atkinson_cycle` · `Axiom` · `Benjamin_Thompson` · `Binding_constant` · `Binding_selectivity` · `Black_hole_thermodynamics` · `Bond_graph` · `Brayton_cycle` · `Brian_Pippard` · `Bridgman's_thermodynamic_equations` · `Brownian_ratchet` · `Buffer_solution` · `Caloric_theory` · `Carnot's_theorem_(thermodynamics)` · `Carnot_cycle` · `Carnot_heat_engine` · `Chelation` · `Chemical_equilibrium` · `Chemical_oscillator` · `Chemical_potential` · `Chemical_stability` · `Chemical_thermodynamics` · `Cheng_cycle` · `Clausius_theorem` · [[Closed_system]] · `Coefficient_diagram_method` · `Combined-cycle_power_plant` · `Common-ion_effect` · `Compressibility` · `Compressibility_factor` · `Conjugate_variables_(thermodynamics)` · `Constantin_Carathéodory` · [[Control_engineering]] · `Control_reconfiguration` · `Control_volume` · `Control–feedback–abort_loop` · [[Cybernetics]] · `Daniel_Bernoulli` · `Determination_of_equilibrium_constants` · `Diesel_cycle` · [[Diffusion]] · `Dirk_ter_Haar` · `Dissociation_constant` · `Distribution_function_(physics)` · `Dynamic_equilibrium` · `Ecological_economics` · `Edward_A._Guggenheim` · `Einstein_refrigerator` · `Endoreversible_thermodynamics` · [[Energy]] · `Enthalpy` · [[Entropy]] · `Entropy_(energy_dispersal)` · `Entropy_and_life` · `Equation_of_state` · `Equilibrium_chemistry` · `Equilibrium_constant` · `Equilibrium_thermodynamics` · `Equilibrium_unfolding` · `Ericsson_cycle` · `Expander_cycle` · `External_combustion_engine` · [[Feedback]] · `First_law_of_thermodynamics` · `Flow_(mathematics)` · `François_Massieu` · `Free_entropy` · `Fundamental_thermodynamic_relation` · `Gas-generator_cycle` · `Gas_laws` · `Georg_Ernst_Stahl` · `George_Uhlenbeck` · `Gibbs_free_energy` · `Gilbert_N._Lewis` · `Hammett_acidity_function` · `Hampson–Linde_cycle` · `Hankel_singular_value` · `Harald_Wergeland` · `Heat` · `Heat_capacity` · `Heat_capacity_ratio` · `Heat_death_paradox` · `Heat_engine` · `Heat_equation` · `Heat_pump_and_refrigeration_cycle` · `Helmholtz_free_energy` · `Henry's_law` · `Herbert_Callen` · `Hermann_von_Helmholtz` · `High-efficiency_hybrid_cycle` · `History_of_entropy` · `History_of_perpetual_motion_machines` · `History_of_thermodynamics` · `Homogeneous_charge_compression_ignition` · `Hot_air_engine` · `Humphrey_cycle` · `Hydrolysis_constant` · `Hygroscopic_cycle` · `Ice_cube` · `Ideal_gas` · `Ideal_gas_law` · [[Ilya_Prigogine]] · `Inexact_differential` · `Intelligent_control` · `Intensive_and_extensive_properties` · `Internal_combustion_engine` · `Internal_energy` · `Internal_pressure` · `Introduction_to_entropy` · `Ionocaloric_refrigeration` · `Irreversible_process` · `Isenthalpic_process` · `Isentropic_process` · `Isobaric_process` · `Isochoric_process` · [[Isolated_system]] · `Isothermal_flow` · `Isothermal_process` · `J._R._Partington` · `James_Clerk_Maxwell` · `James_Prescott_Joule` · `Johannes_Diderik_van_der_Waals` · `John_Gamble_Kirkwood` · `John_James_Waterston` · `John_Smeaton` · [[Josiah_Willard_Gibbs]] · `Julius_von_Mayer` · `Kalina_cycle` · `Kleemenko_cycle` · `Krener's_theorem` · `Lars_Onsager` · `Latent_heat` · `Laws_of_thermodynamics` · `Le_Chatelier's_principle` · `Lenoir_cycle` · `Liquid–liquid_extraction` · `List_of_thermodynamic_properties` · `Lord_Kelvin` · `Loschmidt's_paradox` · `Ludwig_Boltzmann` · `László_Tisza` · `Magnetic_Thermodynamic_Systems` · `Manson_engine` · `Mark_Zemansky` · `Markov_chain_approximation_method` · `Material_properties_(thermodynamics)` · [[Mathematical_model]] · `Mathematische_Annalen` · `Max_Planck` · `Maxwell's_demon` · `Maxwell's_thermodynamic_surface` · `Maxwell_relations` · `Maxwell–Boltzmann_distribution` · `Mechanical_equilibrium` · `Mechanical_equivalent_of_heat` · `Miller_cycle` · `Minor_loop_feedback` · `Mixed/dual_cycle` · `Molecular_autoionization` · `Nicolas_Léonard_Sadi_Carnot` · `Non-equilibrium_thermodynamics` · `Nucleation` · `On_the_Equilibrium_of_Heterogeneous_Substances` · `Onsager_reciprocal_relations` · `Organic_Rankine_cycle` · `Otto_cycle` · `Particle_number` · `Partition_coefficient` · `Partition_equilibrium` · [[Perceptual_control_theory]] · `Percy_Williams_Bridgman` · `Phase_(matter)` · `Phase_diagram` · `Phase_rule` · `Phase_separation` · `Philip_M._Morse` · [[Photon]] · `Pierre_Duhem` · `Piobert's_law` · `Polytropic_process` · `Positive_systems` · `Power_(physics)` · `Predominance_diagram` · `Pressure` · `Pressure_gain_combustion` · `Pressure–volume_diagram` · `Primitive_notion` · `Process_function` · `Pseudo_Stirling_cycle` · `Pulse_tube_refrigerator` · `Quantum_statistical_mechanics` · `Quantum_thermodynamics` · `Quasistatic_process` · `Radial_basis_function` · `Radiation` · `Radiative_equilibrium` · `Rankine_cycle` · `Reaction_quotient` · `Real_gas` · `Reduced_properties` · `Reflections_on_the_Motive_Power_of_Fire` · `Regenerative_cooling` · `Reversible_process_(thermodynamics)` · `Reversible_reaction` · `Robert_A._Alberty` · [[Rudolf_Clausius]] · `Scuderi_cycle` · [[Second_law_of_thermodynamics]] · `Self-assembly` · `Self-ionization_of_water` · [[Self-organization]] · `Sensible_heat` · `Siemens_cycle` · [[Signal-flow_graph]] · `Solubility_equilibrium` · `Stability_constants_of_complexes` · `Stable_polynomial` · `Staged_combustion_cycle` · `State_function` · `State_of_matter` · `Statistical_mechanics` · `Steady_state` · `Stirling_cycle` · `Stoddard_engine` · `Sydney_Chapman_(mathematician)` · `Synergetics_(Haken)` · [[Systems_theory]] · `Table_of_thermodynamic_equations` · `Temperature` · `Temperature–entropy_diagram` · `Theorem_of_corresponding_states` · `Thermal_contact` · `Thermal_efficiency` · `Thermal_equilibrium` · `Thermal_expansion` · `Thermodynamic_activity` · `Thermodynamic_cycle` · `Thermodynamic_databases_for_pure_substances` · `Thermodynamic_diagrams` · `Thermodynamic_equations` · `Thermodynamic_free_energy` · `Thermodynamic_instruments` · `Thermodynamic_operation` · `Thermodynamic_potential` · `Thermodynamic_process` · `Thermodynamic_state` · [[Thermodynamic_system]] · `Thermodynamic_temperature` · [[Thermodynamics]] · `Third_law_of_thermodynamics` · `Time_crystal` · `Timeline_of_heat_engine_technology` · `Timeline_of_thermodynamics` · `Transcritical_cycle` · `Transient_state` · `Transport_phenomena` · `UNIQUAC` · `Underactuation` · `Vapor-compression_refrigeration` · `Vapor_quality` · `Vapor–liquid_equilibrium` · `Vis_viva` · `Volume_(thermodynamics)` · `Volumetric_flow_rate` · `Vuilleumier_cycle` · `Walther_Nernst` · `Work_(thermodynamics)` · `Youla–Kucera_parametrization` · `Zeroth_law_of_thermodynamics`
## From the Real GENERATIVE library

*Thermodynamic equilibrium — placed from the Real G.E.N.E.R.A.T.I.V.E. course library (Nuclear room). Source: Wikimedia Commons (via Wikipedia article media). [Details & license](https://commons.wikimedia.org/wiki/File:Carnot_heat_engine_2.svg).*
> Thermodynamic equilibrium is an axiomatic concept of thermodynamics. It is an internal state of a single thermodynamic system, or a relation between several thermodynamic systems connected by more or less permeable or impermeable walls. ([Wikipedia](https://en.wikipedia.org/wiki/Thermodynamic_equilibrium))
<!-- REAL-GENERATIVE-MEDIA:END -->
<!-- LOCAL-MEDIA-PASS:START -->
## From the vault media library
!Thermodynamic equilibrium thumb.png
*Thermodynamic Equilibrium — from the vault's own media holdings, placed 2026-07-09. MTN / Wikitube.io original · CC BY-SA 4.0.*
<!-- LOCAL-MEDIA-PASS:END -->
> **Room:** [[Helium]] · **Status:** ✅ shipped
## Overview
Thermodynamic equilibrium is the macroscopic state in which a [[System|system]] has no net flows of matter, [[Energy|energy]], momentum, or any other extensive quantity, and its intensive variables — temperature, pressure, and chemical potential — are uniform throughout. The full condition requires three simultaneous equilibria: thermal (no net heat flow, equal temperature), mechanical (no unbalanced forces, equal pressure across mobile boundaries), and chemical (no net particle transfer, equal chemical potential for every species in every phase that can exchange it). The zeroth law of [[Thermodynamics|thermodynamics]] — if A is in thermal equilibrium with B and B with C, then A is with C — is the empirical foundation that lets temperature be defined as a single number on a universal scale.
For an [[Isolated_system|isolated system]] the second law identifies equilibrium with the maximum of [[Entropy|entropy]]. Under controlled boundary conditions equivalent extremum principles select different potentials: Helmholtz free energy is minimized at fixed temperature and volume, and Gibbs free energy at fixed temperature and pressure. From this last condition follows the equality of chemical potential across coexisting phases, and differentiating it yields the Clausius–Clapeyron relation for any first-order phase boundary:
dP/dT = ΔS / ΔV = L / (T · ΔV)
Equilibrium thermodynamics anchors phase diagrams (including helium's superfluid lambda transition), chemical-reaction equilibria via the law of mass action, osmotic and electrochemical cells, atmospheric and stellar models (through local thermodynamic equilibrium, LTE), and the calibration of every secondary thermometer. Deviations from it define the entire field of non-equilibrium thermodynamics.
## See also
- Room hub: [[Helium]]
- p5.js Editor conventions: P5 JS EDITOR
- Wiki root: MAIN
---
*Scaffolded by `generative-microsim` from row 28 of the Helium sheet on 2026-05-11T22:20:27Z.*
<!-- REAL-GENERATIVE-MEDIA:START -->
<!-- CRAFT-LINK:START g12 -->
*Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].*
<!-- CRAFT-LINK:END -->
## Wikipedia : Wikitube
**Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Thermodynamic_equilibrium) : [Wikitube](https://en.wikitube.io/wiki/Thermodynamic_equilibrium)
## Previous hub tags
Tree parents: [[Complex_system]] · [[Self-organization]].
Legacy hubs: none.
---
*Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*