FERRETGame engine over Babylon.js
Ferret

Combustion

Package @ferret/physics-combustion, capability combustion.

What it is for#

Everything that burns something in a closed space and uses the pressure: a gun, a rocket motor, a petrol or diesel engine, a jet engine, a steam boiler, a gas cylinder that gets hot and bursts.

How it works#

The model is a lumped one. A chamber is one volume of ideal gas with a mass, a temperature and a pressure. Fuel burns by a law, heat leaves through the wall, and gas leaves through an opening. Because the state is mass and energy, every process closes its energy balance: nothing appears from nowhere.

A Chamber holds gas (AIR, COMBUSTION_GAS, a GasSpec, or any gas or mixture of the species library of chemistry: gas: 'CO2', gas: { N2: 0.5, CO2: 0.5 }, with the molar mass from the formula and gamma from cp(T) at the chamber's temperature; gasSpec(gas, T) gives the same numbers) and can hold:

  • a premixed fuel, with a heating value, an efficiency (premixFuel('CH4'), 'C3H8', 'H2', 'C2H5OH(l)', 'C8H18(l)' take the heating value and the oxygen per kilogram from the reaction enthalpy of the library: the lower heating values of the tables), the oxygen it needs per kilogram, and flammability limits. ignite() only lights a mixture inside the limits and with oxygen. A lit chamber that runs out of oxygen goes out (combustion:out);
  • a solid propellant that burns on its surface at a rate that rises with pressure, which is why a rocket grain finds its own pressure where burning meets the flow through the throat;
  • a wall that takes heat, and a burstPressure above which it ruptures.

Gas leaves through an Orifice { area, Cd }, with choked flow at high pressure; the pressure outside is the capability's ambient (101325 Pa).

When the chamber burns its fuel, the pressure rises by (γ − 1)·m·Q / V: the energy released, spread over the volume. A mixture outside its limits does not light, and with no oxygen nothing burns, which is how a sealed room smothers a fire.

What you can build from it#

PieceWhat it gives
fireGuna shot from a barrel: muzzle velocity, peak pressure, recoil, wall loss
nozzle, exitMachrocket thrust, with the correction for ambient pressure
PistonEnginefour-stroke, two-stroke and diesel engines on a crank
turbojet, turbofanjet engines: thrust, fuel use, efficiencies
Boilera drum of water and steam with a safety valve and steam taken out

A gun#

Give it the barrel, the projectile and the charge, and get the shot.

import { fireGun } from '@ferret/physics-combustion';

const charge = { density: 1600, a: 6e-7, n: 0.8, Q: 3e6, surface: () => 0.06, mass: 0.015 };
const shot = fireGun({ bore: 0.02, length: 0.6, projectile: 0.1, chamberVolume: 4e-5, charge,
                       efficiency: 0.9, startForce: 3000, friction: 500 });
shot.muzzleVelocity;   // m/s

The result has muzzleVelocity, peakPressure, muzzlePressure, the projectile's kinetic energy against the chemical energy of the charge (well under 40 %: a gun is not efficient), the momentum of the projectile and of the gas, the recoilImpulse, the wallLoss and a trace of time, position, velocity and pressure. A longer barrel gives a higher velocity; a burstPressure under the peak makes the barrel burst. covolume adds the room molecules take at high density, which raises the peak pressure; wallHeat lets the bore take heat.

In a world, cap.fire(name, spec, { body, direction }) applies the recoil to the body, opposite to direction, and spawns a projectile with the muzzle velocity (spawn: false skips that). Event gun:fired { name, shot }; command gun.fire.

A rocket#

import { nozzle } from '@ferret/physics-combustion';

const gas = { molarMass: 0.024, gamma: 1.2 };
const geometry = { throatArea: 1e-3, exitArea: 8e-3 };
const vacuum = nozzle(gas, 7e6, 3200, geometry, 0);
const seaLevel = nozzle(gas, 7e6, 3200, geometry, 101325);

Thrust is the mass flow times the exit speed, plus the pressure difference at the exit times the exit area. So thrust rises with altitude by exactly what the ambient pressure took away. The speed a burn gives follows the rocket equation, c·ln(m₀/m₁).

A piston engine#

const engine = new PistonEngine({ bore: 0.08, crank: 0.04, rod: 0.14, compressionRatio: 9,
                                  fuel: PETROL, airFuelRatio: 14.7 });
drivetrain.drive(crank, (w, th) => engine.torque(w, th));     // see Machines

Everything else comes from the cycle: idle, the torque curve, the stall. An engine that breathes no oxygen dies (air: () => ({ pressure, temperature, oxygen: 0 })). Plug air into media (standardAtmosphere.at(h)) and the engine loses power with altitude by itself.

OptionMeaning
cycle'four' or 'two'
ignition'spark' or 'compression'
advance, burnDurationwhen the burn starts and how long it lasts
throttle0 to 1; with a diesel it is the quantity of fuel injected

A diesel draws air alone, injects fuel at the advance, and lights only if the compressed air is hot enough (about 750 K); misfires counts cycles that did not light. Commands: engine.start, engine.stop, engine.throttle { value }.

A jet#

const real = turbojet({ pressureRatio: 12, T4: 1500, etaCompressor: 0.85, etaTurbine: 0.9, etaNozzle: 0.97 }, 0);
real.specificThrust;      // per kg/s of air
real.tsfc;                // fuel per unit thrust

The second argument is the flight speed. Losses cost thrust and fuel; propulsive efficiency rises with speed. Values are per kilogram per second of air; multiply by the mass flow of your engine. turbofan adds a bypass ratio.

A boiler#

import { Boiler } from '@ferret/physics-combustion';

const boiler = new Boiler({ volume: 0.2, water: 100, T: 450, safety: { pressure: 1e6, area: 2e-4 } });
boiler.step(0.5, 80e3);       // half a second at 80 kW

The drum sits on the saturation line, so heating it raises pressure and temperature together. The safety valve holds the pressure and vents steam. take(kg) draws steam out with its enthalpy (to feed a turbine, steamWork(p1, p2, efficiency) gives the work per kilogram of an expansion); feed(kg, T) adds water, and cold feed cools the drum; flowThrough(area, outside) is the choked steam flow. The steam tables behind it match the real ones to a fraction of a percent up to a few percent.

In a world#

cap.addChamber(name, chamber, { vent?, entity?, casing? }) puts a chamber under the world step: the premix burns, the propellant burns, heat goes into the wall, gas leaves through the vent.

Past its burst pressure the chamber turns into the blast of explosions, when that capability is on and the chamber has an entity. The blast carries the energy of the gas at the burst, and casing is the mass that becomes fragments.

Events: chamber:burst { name, pressure, energy, volume, mass, T }, combustion:out { name }. Commands: chamber.state, chamber.ignite, chamber.vent { name, area?, Cd? }, combustion.info.

Parameters#

ValueDefaultEffect
ambient101325 Papressure outside the chambers; set another on a zone for a vacuum or a deep level

Works with#

explosions: a burst chamber is an air blast with fragments. heat and links: gasInPart connects a heat part to a chamber's gas, so a hot wall raises a closed tank's pressure. mechanisms: an engine drives a drive train, and a turbine takes steamWork. media: the atmosphere supplies the air an engine breathes and the ambient pressure of a nozzle.

Cost#

A few operations per chamber per step. A gun is computed whole, at the call (a few milliseconds of simulated time), so do not call it every frame for show.

When it does not behave#

SymptomCause
ignite() returns falseoutside the flammability limits (check the equivalence ratio), no oxygen, or no fuel
A lit chamber goes outthe oxygen was used up; leftover fuel is correct
The gun burstsburstPressure is below the peak (read peakPressure), or the charge is too big for the chamber
The muzzle velocity is too highefficiency 1 means no wall loss; use 0.8 to 0.9, or set wallHeat
A chamber never bursts in a worldno entity, or the explosion capability is off (the event still comes)
An engine stalls on startgive the shaft a starter torque for the first fraction of a second

Worked numbers (pressure rise of a closed burn, gun momentum, rocket thrust at sea level, jet losses, boiler mass and energy balance) are in tests/unit/examples/physics-combustion.test.ts.

Reference#

combustion, CombustionCapability, Chamber, Propellant, Orifice, fireGun, PistonEngine, turbojet, Boiler.