FERRETGame engine over Babylon.js
Ferret

@ferret/physics-pneumatics

networks of gas volumes: tanks, pipes, valves, regulators, compressors, gas cylinders, mixtures (Dalton) and dissolved gas (Henry).

23 exports · source in packages/physics-pneumatics/src

Classes

Dissolver class

class Dissolver

Gas dissolved in a liquid under a gas head (Henry's law), exchanged at a rate both ways. The constant of each gas is the table of the aqueous set of physics-chemistry at the temperature of the head (or the henry given). With a vessel (the same liquid as an aqueous vessel of physics-chemistry) the dissolved gas is the vessel's X(aq): one amount for both solvers, the vessel reacts (CO2 to carbonic acid) and its pH follows the gas that went in.

readonly dissolved: Record<string, number>moles dissolved per species (the vessel's amounts when there is one)
readonly vessel?: Vessel
constructor(readonly o: { liquidVolume: number; henry?: Record<string, number>; /** gases that dissolve by the table */ gases?: string[]; /** 1/s */ rate: number; vessel?: Vessel }, init: 'equilibrium' | 'empty' = 'empty', node?: GasNode)
species(): string[]the gases this liquid takes
constant(sp: string, T = 298.15): numberHenry's constant of a gas at T, mol/(m3·Pa)
equilibrium(sp: string, partial: number, T = 298.15)
total(sp: string)all of the gas in the liquid, dissolved or turned into something else (the carbon of CO2 as carbonic acid, bicarbonate, carbonate)

packages/physics-pneumatics/src/network.ts:110

GasCylinder class

class GasCylinder

A gas cylinder: two chambers as nodes id.cap and id.rod; the piston is a mass moved by the pressures; the volumes follow it. An air spring, a pneumatic door, an air gun.

readonly cap: GasNode
readonly rod: GasNode
x: number
v: number
force: number
atStop: number
readonly area: number
readonly rodArea: number
readonly def: GasCylinderDef & { dead: number }
attach?: { read(): { x: number; v: number }; push(f: number): void }
constructor(private c: PneumaticCircuit, readonly id: string, def: GasCylinderDef)
maxStep()
advance(h: number)

packages/physics-pneumatics/src/network.ts:359

GasNode class

class GasNode
readonly id: string
volume: number
readonly n: Record<string, number>moles per species
U: numberinternal energy, J
wall?: { hA: number; T: number }
fixed: booleanthe atmosphere or a source that never changes
heatIn: numberheat that went through the wall so far, J (positive into the gas)
dissolver?: Dissolvera liquid with gas dissolved in it, see Dissolver
constructor(id: string, s: GasNodeSpec, fixed = false)
get moles()
uTotal(T: number)internal energy of the contents at T, J: the sum of the moles times u(T) of each gas
cvTotal(T = this.temperature)heat capacity at constant volume at T, J/K (at the temperature of the node when missing)
get temperature()the temperature at which the contents hold the energy U (Newton on the sum of u(T): one step for a gas of constant cp)
get pressure()
get gamma()mean ratio of specific heats at the temperature of the node
get molarMass()
partial(sp: string)partial pressure of one species, Pa
fraction(sp: string)
get energy()the energy of all gas in the node, J

packages/physics-pneumatics/src/network.ts:41

PneumaticCircuit class

class PneumaticCircuit
readonly nodes: Map<string, GasNode>
readonly links: Map<string, PneuLink>
readonly gasCylinders: Map<string, GasCylinder>
time: number
substeps: number
readonly air: GasNode
constructor(o: { atmosphere?: { pressure?: number; temperature?: number } } = {})
tank(id: string, s: GasNodeSpec): GasNode
node(id: string): GasNode
liquid(nodeId: string, o: { liquidVolume: number; henry?: Record<string, number>; gases?: string[]; rate?: number; equilibrium?: boolean; vessel?: Vessel }): Dissolvergas dissolved in a liquid of liquidVolume m3 under the node's gas head: henry constants, or the table of the aqueous set for gases (default the gases of the head)
link(id: string, spec: LinkSpec): PneuLink
orifice(id: string, from: string, to: string, cdA: number)
check(id: string, from: string, to: string, cdA: number)
regulator(id: string, from: string, to: string, cdA: number, set: number)
relief(id: string, from: string, to: string, cdA: number, crack: number)
compressor(id: string, from: string, to: string, c: { rate: number; maxPressure: number; efficiency?: number })
setOpen(id: string, x: number)
setOn(id: string, on: boolean)
cylinder(id: string, def: GasCylinderDef): GasCylinder
step(dt: number)
inventory(sp: string): numbertotal moles of a species in the circuit (nodes without the air, dissolved, cylinders' chambers counted as nodes)

packages/physics-pneumatics/src/network.ts:171

Functions

buildCircuit function

function buildCircuit(d: CircuitDef): BuiltCircuit

packages/physics-pneumatics/src/host.ts:49

pneumaticForms function

function pneumaticForms(br: FormBridge, cap: PneumaticsCapability): void

packages/physics-pneumatics/src/host.ts:128

pneumatics function

function pneumatics(): PneumaticsCapability

packages/physics-pneumatics/src/host.ts:66

validateCircuit function

function validateCircuit(d: unknown, path = 'pneumatics'): string[]

packages/physics-pneumatics/src/host.ts:24

Interfaces

AttachDef interface

interface AttachDef

The pneumatics capability: circuits of gas volumes stepped every fixed step in the field phase, cylinders that push two bodies apart, the commands and the forms to run valves and compressors.

Level block physics.pneumatics: a list of circuits

  { name, tanks: [{ id, volume, pressure?, temperature?, mix?, wall?, liquid?: { liquidVolume, henry, rate?, equilibrium? } }],
    links: [{ id, from, to, cdA | pipe | compressor, open?, check?, regulator?, relief? }],
    cylinders: [{ id, bore, rod, stroke, mass, vented?, ..., attach?: { a, b, axis } }] }

from/to name a tank, air (the atmosphere) or <cylinder>.cap / <cylinder>.rod.

a: string
b: string
axis: Vec3
offset?: number

packages/physics-pneumatics/src/host.ts:15

BuiltCircuit interface

interface BuiltCircuit
name: string
circuit: PneumaticCircuit
attached: Array<{ cyl: GasCylinder; def: AttachDef }>

packages/physics-pneumatics/src/host.ts:47

CircuitDef interface

interface CircuitDef
name: string
atmosphere?: { pressure?: number; temperature?: number }
tanks?: Array<{ id: string } & GasNodeSpec & { liquid?: { liquidVolume: number; henry: Record<string, number>; rate?: number; equilibrium?: boolean } }>
cylinders?: Array<{ id: string; attach?: AttachDef } & Omit<GasCylinderDef, 'load'>>
links?: Array<{ id: string } & LinkSpec>

packages/physics-pneumatics/src/host.ts:16

FormBridge interface

interface FormBridge

The words of the language for pneumatics (3.11): (pressure "circuit" "node"), (compressor "circuit" "link" #t), (regulator "circuit" "link" pa), (valve "circuit" "link" x).

define(name: string, sig: { args: string[]; returns?: string }, fn: (ctx: unknown, ...args: any[]) => unknown): unknown

packages/physics-pneumatics/src/host.ts:127

GasCylinderDef interface

interface GasCylinderDef
bore: number
rod: number
stroke: number
dead?: numberdead volume at each end, m3
mass: number
coulomb?: number
viscous?: number
x?: numberthe pressure the rod side faces outside (default atmosphere); not used with gas on both sides
pressure?: numberchamber start pressure, Pa
load?: (x: number, v: number, t: number) => numberexternal force on the rod along the extension, N, as a function of position, speed, time
mix?: Record<string, number>the working gas (default air)
vented?: booleanthe rod side is open to the atmosphere (an air spring, a gun barrel): no gas node there
wall?: { hA: number; T?: number }

packages/physics-pneumatics/src/network.ts:339

GasNodeSpec interface

interface GasNodeSpec
volume: number
pressure?: numbertotal pressure at the start, Pa (default atmosphere)
temperature?: number
mix?: Record<string, number>mole fractions at the start (default air)
wall?: { hA: number; T?: number }the wall: heat transfer conductance J/(s·K) and its temperature (default the room)

packages/physics-pneumatics/src/network.ts:30

LinkSpec interface

interface LinkSpec
from: string
to: string
cdA?: numbereffective flow area (Cd·A), m2
pipe?: { length: number; diameter: number; f?: number }a pipe: length, diameter and the Darcy friction factor (default 0.02) turn into an effective area
open?: number
check?: booleanonly from from to to
regulator?: { set: number }regulator: holds the downstream pressure at set (absolute), proportional band of 5 %
relief?: { crack: number }relief valve: opens fully at crack above the upstream pressure, ramps over 5 %
compressor?: { rate: number; maxPressure: number; efficiency?: number }compressor: inlet volume flow m3/s at inlet conditions, the largest outlet pressure, adiabatic efficiency

packages/physics-pneumatics/src/network.ts:146

PneumaticsCapability interface

interface PneumaticsCapability extends Capability
readonly circuits: Map<string, BuiltCircuit>
add(def: CircuitDef): BuiltCircuit
remove(name: string): void

packages/physics-pneumatics/src/host.ts:60

Species interface

interface Species

A network of gas volumes. A node is a closed volume of a gas mixture (Dalton: the pressure is the sum of the partial pressures, p·V = n·R·T with n the total moles, so Avogadro holds: moles, not mass, set the pressure). Links move moles between nodes: pipes, orifices, valves, check valves, regulators, relief valves, compressors. Flow is subsonic from the isentropic nozzle law and choked above the critical pressure ratio (gasMassFlow of physics-media). The state of a node is its moles per species and its internal energy U; flows carry the enthalpy cp·T of the donor, a volume that changes does p dV, and a wall (hA, Tw) exchanges heat, so a slowly filled tank stays near the room temperature and a fast one warms.

molarMass: number
gamma: number

packages/physics-pneumatics/src/network.ts:12

Types

LinkKind type

type LinkKind = 'orifice' | 'valve' | 'check' | 'regulator' | 'relief' | 'compressor' | 'pipe'

packages/physics-pneumatics/src/network.ts:145

Constants

AIR_MIX const

const AIR_MIX: Record<string, number>

dry air as a mixture

packages/physics-pneumatics/src/network.ts:24

P_ATM const

const P_ATM: 101325

packages/physics-pneumatics/src/network.ts:27

SPECIES const

const SPECIES: Record<string, Species>

The gases of the species library as a table (the old names keep working): SPECIES.CO2 is the molar mass of the formula and gamma at the room temperature from cp(T). The network itself reads cp(T) of each gas at the temperature of the node (see gasdata.ts).

packages/physics-pneumatics/src/network.ts:17

T_ROOM const

const T_ROOM: 293.15

packages/physics-pneumatics/src/network.ts:26