Cookbook: reactions, reactors and radiation
The guides behind these: nuclear, chemistry, combustion. Each recipe says what to build and what to expect; the runnable versions, with the numbers they must produce, are in tests/unit/examples/physics-cookbook-reactions-and-radiation.test.ts.
1. How much lead?#
Shielding halves the dose per half-value layer. To cut a source by a factor of a thousand you need about ten layers. The dose model takes the source and the walls in the way:
const inv = new Inventory(lib);
inv.addActivity('G', 1e10);
const bare = totalOf(doseRate(inv, 2, [], shields));
const behind = totalOf(doseRate(inv, 2, [{ material: 'lead', thickness: 0.086 }], shields));
For these photons about 9 cm of lead, 47 cm of concrete or a metre of water cut the dose by a thousand. Walls in a scene shield by the thickness the ray crosses, so a thick wall at an angle shields more: the slant length is counted, and a pillar between source and player is a hiding place.
2. A hot patch that fades and washes#
Fallout is a grid of cells that decay on their own; Cs-137 halves every 30 years and its daughter grows in beside it. Rain or a hose takes a share off.
const f = new Fallout(2);
f.deposit_disc(10, 10, 5, 'Cs-137', 1e9); // 1 GBq spread over a 5 m disc
f.decay(3600); // the Ba-137m daughter grows in and emits the gamma
f.doseRate(10, 10);
f.wash(0.25); // rain takes a quarter
Cs-137 itself emits beta only, so a fresh patch gives no gamma dose until the daughter has grown in, about an hour. After one half-life the surface activity is half. f.doseRate(x, z, height) is the gamma dose rate at a point from every cell around it; a patch far away gives the inverse square. Put it in a hazard map with the capability's radiation.map command.
3. A reactor without cooling#
After a scram the fuel still makes decay heat, 6 to 7 % at once, falling slowly. With the coolant flowing it is carried away; without it, the fuel heats until it melts. This is the accident every reactor scenario ends in.
const r = new Reactor({ power: 1e6, generation: 1e-4, rodWorth: 0.05, rodsCritical: 0.5, fuelHeat: 5e5,
coolantHeat: 2e5, exchange: 5e4, flow: 0, inlet: 290, fuelCoefficient: -2e-5, melt: 370 });
r.onEvent = e => { if (e.type === 'melt') { /* once */ } };
r.scram();
r.maxSubstep = 0.25;
r.step(1);
With flow at its normal value the fuel stays below its melting point; with flow: 0 it melts and the event fires once. Give a pump failure a time, a backup pump a cost, and a trip in the spec that scrams on a high fuel temperature: that is a full scenario. links reactorHeatsPart moves the heat to a pool or a containment so it is not lost.
4. Squeeze an equilibrium#
N₂O₄ ⇌ 2 NO₂ makes more gas as it dissociates; squeeze the vessel and the balance shifts back toward the single molecule (Le Chatelier). The equilibrium constant itself does not change.
chem.add('diss', { reactants: { N2O4: 1 }, products: { NO2: 2 }, A: 1, Ea: 0, reversible: true });
const v = new Vessel(chem, { volume: 0.0247, isothermal: true, T: 298.15, contents: { N2O4: 1 } });
v.react(80);
Halve the volume and both settle at the same Kp, but the squeezed one has dissociated less. The same code with a temperature change (the reaction is endothermic) shifts the other way. A game can use it as a pressure-and-heat puzzle: the colour of the gas (brown NO₂) tells the player where the balance sits.
5. A rocket gains with altitude#
The thrust of a nozzle is ṁ vₑ + (pₑ − pₐ) Aₑ. As the ambient pressure falls with height, the thrust grows by exactly Δpₐ Aₑ.
const gas = { molarMass: 0.024, gamma: 1.2 }, geometry = { throatArea: 1e-3, exitArea: 8e-3 };
const at = (h: number) => nozzle(gas, 7e6, 3200, geometry, standardAtmosphere.at(h).pressure);
at(0).thrust; at(10000).thrust; nozzle(gas, 7e6, 3200, geometry, 0).thrust; // sea level, 10 km, vacuum
Mass flow is set by the chamber and the throat, not by the altitude. Feed thrust and mdot to a body each step and subtract mdot dt from its mass: that is the rocket equation, and a rocket with a bell sized for sea level wastes thrust in vacuum.
6. A barrel that bursts#
Fire the same round in a weak barrel and in a strong one. The strong one gives the muzzle velocity; the weak one bursts at the peak pressure, and the report says so.
const sound = fireGun(spec);
const weak = fireGun({ ...spec, burstPressure: 0.3 * sound.peakPressure });
weak.burst; // true
A barrel without a rating does not burst. A bigger charge gives a higher peak pressure and, if the barrel holds, a faster round. On a burst, hand peakPressure and the chamber volume to explosions.detonate({ vessel }) for the blast of a ruptured barrel, with a casing for the fragments.