---
tags: [video, hyperframes, thermodynamics, first-law, adiabatic, science-qa]
confidence: high
sources: [js/physics.js, js/sim.js, tools/check.mjs, tools/mutation_test.mjs, review/VERIFY_CODEX.md, review/VERIFY_CODEX_revision.md, review/VERIFY_REVISION_PROBE.json, Atkins Physical Chemistry 12e (Focus 2: adiabatic changes; Focus 1: kinetic model)]
last_updated: 2026-10-29
---

# HF-PCHEM-001 Science QA

Video: *Why Does a Gas Cool Down Without Losing Heat?* (reversible adiabatic expansion vs. free expansion).
All physical values on screen come from `js/physics.js` (axis tick labels are plot geometry, not results). `tools/check.mjs` recomputes them with its own constants and formulas, runs the real drawing code against a stub DOM and reads the screen values back every 0.5 s (100 checks, all passing). `tools/mutation_test.mjs` breaks the code in 17 ways and confirms that the gate catches every one.
The content was reviewed by an external model in two rounds, plus a targeted re-review of the revised simulation (Codex, `review/`); every finding was verified against the code (`review/VERIFY_CODEX.md`, `review/VERIFY_CODEX_revision.md`) before changes were made.

## 1. Model and assumptions

| Item | Choice | Why |
|---|---|---|
| Gas | 1 mol monatomic ideal gas, labelled Ar | All internal energy is translational, so U = n C<sub>V,m</sub> T and <E<sub>k</sub>> = 3/2 k<sub>B</sub>T describe the same energy. Ar at 189-300 K is far above its boiling point (87 K). |
| Heat capacities | C<sub>V,m</sub> = 3/2 R = 12.47 J K<sup>-1</sup> mol<sup>-1</sup>, gamma = 5/3, constant | Exact for a monatomic ideal gas. |
| Volumes | V<sub>1</sub> -> 2V<sub>1</sub> for both | Same initial and final volume, so only the path differs. |
| System | Closed, insulated (q = 0), no other work, no other energy transfer | As specified. |
| Sign convention | **dU = q + w, w = work done ON the gas** | Stated on screen in scene 4 next to the equation. |
| Reversible expansion | Frictionless piston; the external load is eased off slowly so that p<sub>ext</sub> = p at every step (the reversible limit) | Stated on screen in the scene 2 caption. |

The pressure p<sub>1</sub> never enters the displayed numbers (they depend only on T<sub>1</sub>, n and V<sub>2</sub>/V<sub>1</sub>). For reference, p<sub>1</sub> = 1 bar gives V<sub>1</sub> = 24.9 L.

## 2. Displayed numbers, derived three ways

**A. Reversible adiabatic expansion (q = 0, p<sub>ext</sub> = p at every step)**

| Quantity | Formula | Value | On screen |
|---|---|---|---|
| T<sub>2</sub> | T<sub>1</sub>(V<sub>1</sub>/V<sub>2</sub>)<sup>gamma-1</sup> = 300 x 2<sup>-2/3</sup> | 188.99 K | 189 K |
| dT | T<sub>2</sub> - T<sub>1</sub> | -111.01 K | -111 K |
| w (route 1) | n C<sub>V,m</sub> dT (first law with q = 0) | -1384.5 J | -1.38 kJ |
| w (route 2) | nR(T<sub>2</sub> - T<sub>1</sub>)/(gamma - 1) = (p<sub>2</sub>V<sub>2</sub> - p<sub>1</sub>V<sub>1</sub>)/(gamma - 1) | -1384.5 J | |
| w (route 3) | numerical -integral p dV with p = p<sub>1</sub>(V<sub>1</sub>/V)<sup>gamma</sup>, 200 000 steps | -1384.5 J | |
| dU | q + w = 0 + w | -1384.5 J | -1.38 kJ |
| U<sub>1</sub>, U<sub>2</sub> | n C<sub>V,m</sub> T (from 0 K; translational only) | 3741.5 J, 2357.0 J | 3.74 kJ -> 2.36 kJ |
| p<sub>2</sub>/p<sub>1</sub> | 2<sup>-5/3</sup> | 0.315 | P-V endpoint, on the 189 K isotherm |
| <E<sub>k</sub>> | 3/2 k<sub>B</sub>T | 6.21 x 10<sup>-21</sup> J -> 3.91 x 10<sup>-21</sup> J | both shown |
| v<sub>rms</sub> (Ar) | (3k<sub>B</sub>T/m)<sup>1/2</sup>, m = M/N<sub>A</sub> | 432.8 -> 343.5 m/s | marker on the speed distribution |

Consistency: U<sub>1</sub> - U<sub>2</sub> = 1384.5 J = |w|, so the energy bar's lost length equals the work term exactly; 3.74 - 2.36 = 1.38 also holds after rounding.

**Live values during the expansion (rounding, disclosed).** The energy panel shows U rounded to 0.01 kJ and shows w = dU as (shown U - shown U<sub>1</sub>), so the subtraction on screen always adds up. The price is that this w can differ by one unit in the last digit from the exact work rounded on its own: at 10 of 181 sampled moments, e.g. at 58 s the exact work is -0.886 kJ and the screen shows 2.86 - 3.74 = -0.88 kJ. Rounding w independently would instead make the on-screen subtraction fail at those moments (2.86 - 3.74 shown next to -0.89). The end values (-1.38 kJ, 2.36 kJ) are correctly rounded either way. `tools/check.mjs` verifies both properties: the shown U is the correctly rounded exact U, and the shown w is within 0.01 kJ of the exact work.

**B. Adiabatic free expansion of an ideal gas (q = 0, p<sub>ext</sub> = 0)**

w = -p<sub>ext</sub> dV = 0, so dU = q + w = 0. For an ideal gas U depends on T only, so the final temperature equals the initial one: 300 K, <E<sub>k</sub>> = 6.21 x 10<sup>-21</sup> J, and the final state (2V<sub>1</sub>, p<sub>1</sub>/2) lies on the 300 K isotherm. In between, the gas is not in equilibrium (section 4).

## 3. Scientific accuracy requirements

| Requirement | How the video meets it |
|---|---|
| Sign convention dU = q + w consistent | One convention everywhere: "w = work done **on** the gas" on screen. A shows "Work done by the gas", w < 0, dU < 0; B shows w = 0 (p<sub>ext</sub> = 0), dU = 0. Checked by `tools/check.mjs` (sign rows in the energy panels and the summary). |
| Reversible vs. irreversible distinguished | Tags "slow, quasi-static" vs. "sudden, irreversible"; captions "Frictionless piston, load eased off slowly: p<sub>ext</sub> = p at every step" vs. "Expands into vacuum: p<sub>ext</sub> = 0"; the piston travels over 14 s while the partition is gone in 0.5 s; B is tagged "not yet in equilibrium" while it streams into the vacuum. |
| Free expansion not drawn as an equilibrium path | P-V panel for B plots only the initial and final states (i, f) with no connecting line and the note "No equilibrium path: only i and f are equilibrium states". A's reversible adiabat is drawn as a continuous curve. Both end points are computed from `PHYS` (V<sub>2</sub>/V<sub>1</sub>, the isotherm of the final temperature). |
| Constant-T result tied to an ideal gas | Reveal reads "300 K -> 300 K (ideal gas)"; summary card is titled "Ideal-Gas Free Expansion". |
| Kinetic energy and temperature shown statistically | (1) Each molecule is coloured by its own in-plane speed, so the whole population shifts while the spread remains. (2) The Maxwell-Boltzmann curve at the current T is plotted against the 300 K reference, headed "Maxwell-Boltzmann (theory)". (3) In scene 5, five molecules per box carry their stored velocity vectors; their speeds differ and change at every collision. (4) Note: "Speeds still vary widely; the distribution shifts lower." In the simulation 18 of 48 molecules in A end the expansion faster than they started it (17/48 in the replay); the check fails if fewer than 5 do. |
| No heat transfer depicted | No flames, heat arrows or heat sources; hatched insulated walls with a "q = 0 INSULATED" chip on both systems throughout scenes 1-5. The only energy arrow is "work done by the gas", shown only while the piston moves. |
| Numerical temperatures physically consistent | 189 K comes from T V<sup>2/3</sup> = const with gamma = 5/3; the live thermometer during the expansion uses the same law at the instantaneous piston position; B's dT reading is replaced by "not yet in equilibrium" while the gas streams into the vacuum; all values rechecked in `tools/check.mjs`, including the values read back from the drawn screen. |

## 4. The molecular picture: what is physics and what is a correction

`js/sim.js` precomputes a deterministic gas of **3D hard spheres in a thin slab, seen from above** (48 molecules per box, seeded generator, 4 substeps per frame):

- **Model.** Each molecule has a position and a velocity in x, y and z; the screen shows x and y (a top view of 3D spheres). Collisions are 3D hard-sphere collisions, so momentum and kinetic energy are conserved exactly, and whether two molecules collide depends on their 3D separation: discs that overlap on screen need not touch, and in the top view this is common. Because the slab is only two diameters deep (z of the centres within a 2r range), two centres cannot pass straight over each other without colliding. Kinetic energy is therefore shared among x, y and z as in any 3D gas. Measured: the in-plane share of the kinetic energy averages 0.65-0.66 (ideal 2/3) for A after the expansion and for B throughout.
- **Time step.** Positions advance in fixed steps (4 substeps per frame), and one pairwise push per substep separates spheres that have moved into each other. A later push can undo an earlier one, so the recorded frames keep a residual 3D overlap of at most 1.0 px (7% of the 14 px diameter); `tools/check.mjs` requires it to stay at or below 1.5 px and the centres to stay inside the slab. Repeating the push until no overlap remains removes it, but it changes the (chaotic) trajectory; it was tested and not adopted (`review/VERIFY_CODEX_revision.md`, R3). The time step is not converged either (next bullets).
- **Piston.** Molecules reflect off the moving piston with v<sub>x</sub>' = 2u - v<sub>x</sub>, so they lose speed when they strike the receding piston: this is the microscopic origin of the cooling, and cyan ripples mark these impacts. The piston acts on v<sub>x</sub> only, which holds one third of the energy, as in 3D. During the stroke the x share averages 0.318 instead of 1/3 (uncorrected runs, 30 initial states): collisions pass the loss in x on to y and z with a short lag.
- **Energy ledger of A** (K<sub>0</sub> = initial kinetic energy of the 48 molecules; the ideal-gas reversible value of the loss is -0.370 K<sub>0</sub>):

| Run | Piston impacts | Correction, net (summed size) | Piston share of the loss | A without any correction ends at | Largest per-frame factor on speeds |
|---|---:|---:|---:|---:|---:|
| Scene 2 | -0.390 K<sub>0</sub> | +0.020 K<sub>0</sub> (0.189 K<sub>0</sub>) | 105% | 187.6 K | 0.15% |
| Replay | -0.384 K<sub>0</sub> | +0.014 K<sub>0</sub> (0.177 K<sub>0</sub>) | 104% | 191.1 K | 0.22% |

- **The correction.** Each frame nudges the ensemble kinetic energy of A 10% of the way toward the ideal-gas reversible curve T = 300 (V<sub>1</sub>/V)<sup>2/3</sup> with one common factor on all speeds (at most 0.22% per frame). At the recorded frames the kinetic energy of the dots stays within 2.6% (scene 2) and 3.8% (replay) of the curve and lands on it within 0.5% two seconds after the piston stops. Small per frame does not mean negligible: the net correction is +0.020 and +0.014 K<sub>0</sub>, but its ups and downs add up to 0.189 and 0.177 K<sub>0</sub>, about half of the net loss, because each piston impact lowers the energy in a step and the correction pulls it back between impacts. Removing 10% of a deviation per frame shrinks it by 1/e in 0.32 s, short compared with the 14 s and 9 s strokes, so the correction acts like a weak thermostat that keeps A on the ideal-gas curve (the same idea as fractional velocity rescaling in molecular dynamics). A's molecular motion is therefore illustrative, not a pure adiabatic trajectory, and the screen says so (next bullet).
- **Disclosed on screen.** From 13.2 s, when the piston starts, until the cards leave at 82.6 s (hidden under the scene 3 pause card), a footnote under the cards reads: "Molecules are illustrative: in A, their speeds are gently scaled to follow the ideal-gas temperature. B has no correction." It says "temperature" rather than "curve" on purpose: the only curve next to the molecules is the Maxwell-Boltzmann distribution, and the correction does not shape the distribution, it only scales all speeds together.
- **What the uncorrected run shows.** Without the correction, the piston impacts alone carry this run (seed 7919) to 187.6 K (scene 2) and 191.1 K (replay). Over 30 independent initial states the uncorrected run ends at 183 ± 4 K and 186 ± 7 K (mean ± SD), and about 178-179 K once the time step is converged (16 or 32 substeps instead of 4). Finite density, the slab walls, the finite piston speed, the time step, and the rate at which collisions pass the piston's loss in x on to y and z all shift the result by a few kelvin, in both directions; their separate effects have not been established. In particular the result is not explained by the excluded volume of the spheres alone: halving the radius (one eighth of the excluded volume) raises the uncorrected result to about 200 K, above the ideal 189 K. Across 5 other z seeds (only the depths and v<sub>z</sub> change) the piston impacts account for 89-116% of the loss. The video's thermodynamic numbers do not depend on any of this; they come from `js/physics.js`. Data and method: `review/VERIFY_REVISION_PROBE.json`, `review/VERIFY_CODEX_revision.md` (R4).
- **History.** The first version used 2D discs (no z motion) with an exact per-frame rescale; because a 2D gas cools faster (gamma = 2), that rescale returned +26% (scene 2) and +22% (replay) of K<sub>0</sub> to the gas, an energy source the viewer could not see. The external review flagged it (Codex round 2, N2), and the slab model replaced it. A targeted re-review of the slab model (Codex, 2026-10-28) then found four further problems, all verified and corrected here: an earlier version of this section claimed that discs meeting on screen always collide (false, see Model); the residual 3D overlap was untested; the correction was not disclosed on screen; and the >100% piston share had been attributed to the excluded volume, which the controls above do not support (`review/CODEX_REVIEW_revision_2026-10-28.md`, `review/VERIFY_CODEX_revision.md`).
- **The distribution curve is theory.** The plotted curve is the 3D Maxwell-Boltzmann speed distribution for Ar at the displayed temperature, headed "Maxwell-Boltzmann (theory)"; it is not a histogram of the 48 dots. (The in-plane speeds of a 3D Maxwellian gas follow the 2D Rayleigh distribution, which is why the moving dots look right, but the video does not claim that 48 molecules stay Maxwellian at every instant of a process.)
- **B: free expansion.** Only fixed walls; no correction of any kind is applied, and the kinetic energy is conserved by the dynamics alone (largest drift 2 x 10<sup>-15</sup>). The gas first streams into the vacuum: the bulk flow carries up to 42-43% of the in-plane kinetic energy and stays above 25% for about 3-3.5 s (measured in 8 slices). During that time the thermodynamic temperature is not defined, and the kinetic energy relative to the local flow (the thermal part) is lower than the total. The thermometer keeps reading 300 K (the brief asks for it; the total kinetic energy, and the initial and final equilibrium temperatures, all correspond to 300 K), and the dT slot shows the tag "not yet in equilibrium" for 4.0 s after the partition starts to move (13.0-17.0 s and 53.5-57.5 s). `tools/check.mjs` measures the flow and fails if the tag is shorter than it. The 25% threshold in 8 slices is a display rule that makes the tag cover the visible streaming; it is not a test of local equilibrium.
- **Speed scale:** screen speeds are slowed for visibility. The piston peaks at 38 px/s in scene 2 and 59 px/s in the replay, against a mean in-plane molecular speed of 168 px/s at 300 K, so it is slower than the molecules but not by the orders of magnitude a truly quasi-static process requires. The process is labelled quasi-static and its thermodynamics is computed as reversible.
- **Replay:** scenes 4-5 restart both systems from the identical initial state at t = 50 s so that the energy bars can be shown growing and shrinking in step with the piston; a "Replay" badge marks the cut.

## 5. Limits worth knowing (not shown in the video)

- A real gas changes temperature slightly in a free (Joule) expansion, and the sign depends on the gas and the conditions: (dT/dV)<sub>U</sub> = -[T(dp/dT)<sub>V</sub> - p]/C<sub>V</sub>, so a gas cools below its Joule inversion temperature (attractions dominate) and warms above it. For Ar near room temperature a van der Waals model (which always predicts cooling) with a = 1.355 L<sup>2</sup> bar mol<sup>-2</sup>, expanding from V<sub>m</sub> = 24.9 to 49.9 L mol<sup>-1</sup> at 300 K, gives dT = (a/C<sub>V,m</sub>)(1/V<sub>m,2</sub> - 1/V<sub>m,1</sub>) = -0.22 K, invisible at the displayed precision. This is a model estimate, not a measurement.
- Diatomic gases (gamma = 7/5) would end at 300 x 2<sup>-0.4</sup> = 227 K; the video's 189 K is specific to a monatomic gas, which is why the setup line states "monatomic ideal gas (Ar)".
- U is quoted from 0 K for the translational energy of a monatomic ideal gas (U = 3/2 nRT); only differences in U are thermodynamically meaningful, and the bar is used for the change.

## 6. Verification record (2026-10-29)

**Content gate** `node tools/check.mjs` -> **100/100 passed** (full log: `renders/check_content.txt`). **Mutation test** `node tools/mutation_test.mjs` -> **17/17 broken versions caught**, unmodified copy passes (log: `renders/mutation_test.txt`); the two newest mutants (overlap push removed; on-screen disclosure removed) are caught only by the two checks added after the targeted re-review, which the previous 97 checks lacked. Highlights:

| Check | Result |
|---|---|
| No CJK characters (index.html, all js, STORYBOARD_EN.md) | none |
| No clock, timer, network or unseeded-random API | none in any script; a rerun reproduces the trajectory bit for bit |
| No physical numbers typed into the markup | 0 found; all 7 data-v placeholders filled with values formatted independently by the check |
| Physics core vs. constants written out in the check (Ar mass from M/N<sub>A</sub>) | gamma, m, T<sub>2</sub>, w (numeric integral), U, <E<sub>k</sub>>, v<sub>rms</sub>, v<sub>mp</sub>, Maxwell-Boltzmann normalization, <v<sup>2</sup>> and peak, P-V end points; relative tolerances |
| Screen read back from the real draw.js, every 0.5 s | thermometers, dT, U, w, dU, <E<sub>k</sub>>, v<sub>rms</sub> marker, distribution peaks, P-V end points, work arrow, B tag |
| Live energy panel | shown U = exact U rounded; shown U - shown U<sub>1</sub> = shown w = shown dU; shown w within 0.01 kJ of the exact work |
| Sign rows (energy panels and summary) | A: q = 0, w < 0, dU < 0, dT < 0; B: q = 0, w = 0, dU = 0, dT = 0 |
| A energy ledger (this run) | piston impacts 105% / 104% of the loss; correction net +0.020 / +0.014 K<sub>0</sub>, summed 0.189 / 0.177 K<sub>0</sub>, <= 0.22% per frame; without correction 187.6 K / 191.1 K; 5 other z seeds 89-116% |
| A's speed correction disclosed on screen | footnote from 13.2 s (piston starts at 13.0 s) to 82.6 s |
| Residual 3D overlap of the spheres (limit 1.5 px) | at most 0.77 px (scene 2) and 1.00 px (replay) of a 14 px diameter; centres inside the slab |
| Equipartition (x, y, z share the energy) | in-plane share 0.645-0.662 (ideal 0.667) |
| B kinetic energy, no correction | conserved to 2 x 10<sup>-15</sup> |
| B tag vs. measured streaming | flow above 25% until +3.5 s / +3.0 s; tag 4.0 s |
| Molecules inside walls / behind the piston, every frame; B confined until the partition is pulled | pass |
| B gas present in both halves at the end | 26/48 and 30/48 in the right half |
| Some molecules end A's expansion faster | 18/48 (scene 2) and 17/48 (replay) |
| A and B start from identical positions and velocities; partition and piston start on the same frame | pass (both runs) |
| Scene 3 pause freezes the simulation clock; replay restarts from the initial state at 50 s | pass |

**HyperFrames check** `npx hyperframes check` -> **passed** (log: `renders/check_hyperframes.txt`): 0 lint errors, 0 runtime errors, 0 layout errors, 160/160 text elements pass WCAG AA contrast; the 35 layout notes are all text deliberately covered by the scene 3 pause card. Two craft warnings remain by design: *film_silent* (the brief makes narration optional; the film is built to be read without sound) and *text_below_floor* (the tool's 28 px phone floor; the target is a projector, reading text is >= 24 px and only sub/superscripts are smaller).

**Render and frame inspection:** see section 7.

## 7. Render commands and results

```bash
npm install                      # hyperframes 0.8.208 (pinned)
node tools/check.mjs > renders/check_content.txt            # content gate: 100/100
node tools/mutation_test.mjs > renders/mutation_test.txt    # gate catches 17/17 broken versions
npx hyperframes check > renders/check_hyperframes.txt       # lint, runtime, layout, contrast: passed
npx hyperframes render --quality delivery --fps 30 -o renders/adiabatic_expansion_EN.mp4
node tools/verify_render.mjs > renders/verify_render.json   # probe + full decode + key frames from the MP4
```

The scripts print their results; the redirects keep the logs that `npm run showcase` reads (it warns when a log is older than the newest source file).

`renders/verify_render.json` (final render after the targeted re-review, 2026-10-29: 1 min 39 s on this machine, hardware GPU capture):

| Property | Value |
|---|---|
| File | `renders/adiabatic_expansion_EN.mp4`, 26.6 MB |
| Video | H.264, yuv420p, 1920 x 1080, 30 fps |
| Duration / frames | 90.000 s / 2700 frames |
| Audio | none (silent by design) |
| Full decode (`ffmpeg -v error -f null`) | no errors |
| Verdict | PASS |

Key frames were extracted **from the MP4 itself** (not from the browser preview) into `screenshots/` and inspected one by one:
`01_title_2.5s`, `02_identical_start_9s`, `03_two_expansions_20s`, `04_pause_and_explain_34s`, `05_reveal_pv_45s`, `06_first_law_live_58s`, `07_first_law_result_66s`, `08_molecular_picture_78s`, `09_takeaway_89.5s`; the review pack adds one frame every 3 s (`review/frames/`, two contact sheets).
Checked in them: all text is English and legible; the piston and the partition are clearly different; T, dT, w and U agree with each other in a mid-process frame (58 s: T = 229 K, dT = -71 K, U = 2.86 kJ of 3.74 kJ, w = -0.88 kJ) and at the end (189 K, -111 K, 2.36 kJ, -1.38 kJ); no heat symbols appear; B has no P-V path. B shows "not yet in equilibrium" in the 15, 54 and 57 s frames and dT = 0 K again at 18 and 60 s; the work arrow is present while the piston moves (15-27 s, 54-60 s) and gone at 30 s and 63 s; the scene 3 card reads "PAUSE AND EXPLAIN"; the scene 5 notes ("the distribution shifts lower" / "is unchanged") do not touch the dT readings; the scene 4 guiding line is on screen at 58 s; the footnote disclosing the correction in A is legible and clear of the bottom-zone text at 20, 45, 58, 66 and 78 s and dimmed under the pause card at 34 s.
