# @ferret/physics-engines: API

steam cylinders with valve gear by crank angle, multi-cylinder piston engines with firing order, ignition and fuel controls, inertia forces on the mounts, and the engine words of the motion language.

16 exports. Generated from the source (`packages/physics-engines/src`), so it matches the code.

## Classes

### MultiCylinderEngine

*class* · `packages/physics-engines/src/engines.ts:83`

```ts
class MultiCylinderEngine implements EngineControl
```

- `readonly engines: PistonEngine[]`
- `readonly firing: number[]` — the crank angle (rad) at which each cylinder fires, within the cycle
- `readonly spec: MultiEngineSpec`
- `throttleNow: number`
- `constructor(spec: MultiEngineSpec)`
- `torque: (omega: number, theta: number) => number`
- `throttle(v: number)`
- `ignition(advance: number)` — spark advance before top dead centre for every cylinder, rad
- `fuel(on: boolean)` — fuel supply on or off for the whole engine: off is the ignition cut
- `fuelOn: boolean`
- `cutCylinder(i: number, cut: boolean)` — cut or restore one cylinder
- `rpm()`
- `get work()`
- `state()`
- `pin(i: number): number` — the crank pin angle of cylinder i within the turn: it follows from the firing order (1-3-4-2 puts the pins at 0, pi, pi, 0)
- `applyInertia(omega: number, theta: number, mount: MountLike)`

### SteamCylinder

*class* · `packages/physics-engines/src/steam.ts:63`

```ts
class SteamCylinder
```

- `readonly spec: SteamCylinderSpec`
- `readonly gear: ValveGear` — the valve gear: the controls change it while the engine runs
- `regulator: number` — admission opening 0..1 (the regulator)
- `readonly area: number`
- `readonly rodArea: number`
- `readonly swept: number`
- `readonly clearanceVolume: number`
- `work: number` — work the gas did on the piston, J; steam taken from the boiler, kg; steam exhausted, kg
- `steamUsed: number`
- `steamExhausted: number`
- `get pressures(): [number, number]` — the pressure in each end now, Pa
- `constructor(spec: SteamCylinderSpec)`
- `stroke(th: number)` — distance the piston has moved from the head-end dead centre, m
- `vol(end: number, th: number): number` — volume of end 0 (head) or 1 (crank end) at crank angle th (without the cylinder's own phase)
- `angleFor(share: number): number` — the crank angle (0..pi, from the head-end dead centre) at which the piston has covered `share` of the stroke
- `torque(_omega: number, theta: number, t: number): number` — The torque on the shaft at its angle `theta` (the cylinder advances its cycle from the angle of the last call); the same shape as a drivetrain source.
- `inertiaForce(omega: number, theta: number, mass: number): number` — the inertia force of the reciprocating mass and the rod along the cylinder axis, N (positive toward the head), at shaft speed omega and angle theta

### SteamEngine

*class* · `packages/physics-engines/src/engines.ts:39`

```ts
class SteamEngine implements EngineControl
```

- `readonly cylinders: SteamCylinder[]`
- `readonly spec: SteamEngineSpec`
- `throttleNow: number`
- `constructor(spec: SteamEngineSpec)`
- `torque: (omega: number, theta: number, t: number) => number` — a torque source for the drivetrain
- `throttle(v: number)`
- `cutoff(v: number)`
- `reverse(on: boolean)`
- `rpm()`
- `get work()`
- `get steamUsed()`
- `state()`
- `applyInertia(omega: number, theta: number, mount: MountLike)` — the inertia forces of the cylinders on the mounts (each along its axis, at its point)

## Functions

### engineForms

*function* · `packages/physics-engines/src/forms.ts:18`

```ts
function engineForms(br: MotionBridge, reg: EngineRegistry): void
```

### inertiaAlong

*function* · `packages/physics-engines/src/engines.ts:136`

```ts
function inertiaAlong(r: number, l: number, omega: number, theta: number, mass: number): number
```

The inertia force of a reciprocating mass along its cylinder axis (positive toward the head): minus mass times the piston's acceleration at constant speed.

## Interfaces

### BoilerLike

*interface* · `packages/physics-engines/src/steam.ts:13`

```ts
interface BoilerLike
```

The steam cylinder. A double-acting piston on a crank: a chamber on each side of the piston, each a mass of
steam as a perfect gas (gamma 1.3, the model of `steamWork`), fed from a boiler through a port whose opening is a function of the **crank angle**
(the valve gear: lead, cut-off, release, compression) and exhausting to the atmosphere or a condenser. The torque on the crank is the work the gas
does over the angle it turned, so the pulsation, the dead centre and the indicator diagram come out of the cycle, not from an averaged power.

Energy: steam admitted brings the enthalpy cp*T of a perfect gas at the boiler's temperature (the boiler itself loses the real enthalpy; the latent
heat the model does not use leaves with the exhaust, as it does in a real engine), steam exhausted takes cp*T of the chamber, and the gas does
p dV on the piston. The work per cycle is the area of the indicator diagram.

- `readonly pressure: number`
- `readonly T: number`
- `readonly quality: number`
- `flowThrough(area: number, outside?: number): number`
- `take(kg: number): number`

### BoilerSensor

*interface* · `packages/physics-engines/src/forms.ts:12`

```ts
interface BoilerSensor
```

The words of the language for engines and boilers, registered through the bridge so their arguments are
checked when a program loads:
  controls (owner only)  (throttle e v) (cutoff e v) (reverse e on) (ignition e rad) (fuel e on)
  sensors                (engine-rpm e) (pressure b) (level b)
A centrifugal governor is then a program: `(loop (throttle "engine" (clamp (* 0.002 (- 300 (engine-rpm "engine"))) 0 1)) (wait 0.05))`.

- `readonly pressure: number`
- `readonly volume: number`
- `readonly T: number`
- `readonly water: number`

### CylinderMount

*interface* · `packages/physics-engines/src/engines.ts:24`

```ts
interface CylinderMount
```

- `axis?: Vec3` — the direction of the cylinder's axis from the crank to the head, in the housing's frame (default up)
- `point?: Vec3` — where the cylinder acts on the housing, in the world (or already transformed by the caller)

### EngineControl

*interface* · `packages/physics-engines/src/engines.ts:14`

```ts
interface EngineControl
```

The controls and sensors an engine offers to programs and forms. All are optional: an engine has what makes sense for it.

- `throttle?(v: number): void`
- `cutoff?(v: number): void`
- `reverse?(on: boolean): void`
- `ignition?(advance: number): void`
- `fuel?(on: boolean): void`
- `rpm?(): number`
- `state?(): Record<string, unknown>`

### EngineRegistry

*interface* · `packages/physics-engines/src/forms.ts:13`

```ts
interface EngineRegistry
```

- `engines: Map<string, EngineControl>`
- `boilers?: Map<string, BoilerSensor>`

### MountLike

*interface* · `packages/physics-engines/src/engines.ts:11`

```ts
interface MountLike
```

where the forces of an engine go: a body (or a vessel) at a point of its frame

- `applyForce(f: Vec3, worldPoint?: Vec3): void`

### MultiEngineSpec

*interface* · `packages/physics-engines/src/engines.ts:72`

```ts
interface MultiEngineSpec
```

- `cylinder: EngineSpec` — the cylinders are copies of this one
- `count: number`
- `order?: number[]` — firing order, cylinder numbers from 1: [1, 3, 4, 2]; default 1..count
- `reciprocatingMass?: number`
- `mounts?: CylinderMount[]`
- `cycle?: 'four' | 'two'` — the four-stroke cycle takes two turns, the two-stroke one

### SteamCylinderSpec

*interface* · `packages/physics-engines/src/steam.ts:35`

```ts
interface SteamCylinderSpec
```

- `bore: number` — bore and crank radius (half the stroke) and rod length, m
- `crank: number`
- `rod: number`
- `clearance?: number` — dead volume at each end as a share of the swept volume (default 0.08)
- `rodDiameter?: number` — piston rod diameter on the crank end (takes area from that side), m (default 0)
- `boiler: BoilerLike`
- `inlet: number` — port areas: inlet and exhaust, m2, with the valve open
- `exhaustPort: number`
- `back?: number` — pressure the steam is exhausted into, Pa (atmosphere 101325, or a condenser)
- `gear?: Partial<ValveGear>`
- `phase?: number` — crank angle of this cylinder's pin relative to the shaft, rad (a locomotive's two cylinders stand 90 degrees apart)
- `gamma?: number`
- `Cd?: number` — discharge coefficient of the ports

### SteamEngineSpec

*interface* · `packages/physics-engines/src/engines.ts:32`

```ts
interface SteamEngineSpec extends Omit<SteamCylinderSpec, 'phase'>
```

- `phases?: number[]` — the crank angle of each cylinder's pin: a locomotive has two at 90 degrees (default one)
- `reciprocatingMass?: number` — mass of the piston, crosshead and the rod that moves with them, kg (for the inertia force on the mounts)
- `mounts?: CylinderMount[]`

### ValveGear

*interface* · `packages/physics-engines/src/steam.ts:22`

```ts
interface ValveGear
```

The valve events of one end of the cylinder, in fractions of the stroke (cut-off, release, compression) and radians of crank (lead).

- `cutoff: number` — share of the stroke at which the steam is cut off, 0..1 (the Johnson bar or the link notch)
- `lead: number` — crank angle before the dead centre at which the port opens, rad
- `release: number` — share of the stroke at which the exhaust opens
- `compression: number` — share of the return stroke left when the exhaust closes (what is compressed into the clearance)
- `reverse: boolean` — the engine runs backwards: the events are taken in the other turning direction

## Types

### Vec3

*type* · `packages/physics-engines/src/engines.ts:9`

```ts
type Vec3 = [number, number, number]
```

Whole engines: several cylinders on one crank, with the controls a driver or a program has. Both engines are a
`TorqueSource` for a drivetrain shaft (`engine.torque`); the reaction on the housing's torque comes from the drivetrain's housings (A0), and
`applyInertia` puts the unbalanced forces of the reciprocating masses on the mounts.

