@ferret/physics-pneumatics
networks of gas volumes: tanks, pipes, valves, regulators, compressors, gas cylinders, mixtures (Dalton) and dissolved gas (Henry).
Read the guide: how to use it →
Classes
Dissolver class
class DissolverGas 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): number | Henry'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 GasCylinderA 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 GasNodereadonly id: string | |
volume: number | |
readonly n: Record<string, number> | moles per species |
U: number | internal energy, J |
wall?: { hA: number; T: number } | |
fixed: boolean | the atmosphere or a source that never changes |
heatIn: number | heat that went through the wall so far, J (positive into the gas) |
dissolver?: Dissolver | a 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 PneumaticCircuitreadonly 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 }): Dissolver | gas 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): number | total 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): BuiltCircuitpackages/physics-pneumatics/src/host.ts:49
pneumaticForms function
function pneumaticForms(br: FormBridge, cap: PneumaticsCapability): voidpackages/physics-pneumatics/src/host.ts:128
pneumatics function
function pneumatics(): PneumaticsCapabilitypackages/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 AttachDefThe 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 BuiltCircuitname: string | |
circuit: PneumaticCircuit | |
attached: Array<{ cyl: GasCylinder; def: AttachDef }> |
packages/physics-pneumatics/src/host.ts:47
CircuitDef interface
interface CircuitDefname: 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 FormBridgeThe 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 GasCylinderDefbore: number | |
rod: number | |
stroke: number | |
dead?: number | dead volume at each end, m3 |
mass: number | |
coulomb?: number | |
viscous?: number | |
x?: number | the pressure the rod side faces outside (default atmosphere); not used with gas on both sides |
pressure?: number | chamber start pressure, Pa |
load?: (x: number, v: number, t: number) => number | external 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?: boolean | the 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 GasNodeSpecvolume: number | |
pressure?: number | total 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 LinkSpecfrom: string | |
to: string | |
cdA?: number | effective 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?: boolean | only 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
PneuLink interface
interface PneuLinkid: string | |
spec: LinkSpec | |
a: GasNode | |
b: GasNode | |
flow: number | moles per second now (positive from a to b) |
moved: number | |
open: number | |
on: boolean | |
work: number | work a compressor put into the gas so far, J |
packages/physics-pneumatics/src/network.ts:162
PneumaticsCapability interface
interface PneumaticsCapability extends Capabilityreadonly circuits: Map<string, BuiltCircuit> | |
add(def: CircuitDef): BuiltCircuit | |
remove(name: string): void |
packages/physics-pneumatics/src/host.ts:60
Species interface
interface SpeciesA 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: 101325packages/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.15packages/physics-pneumatics/src/network.ts:26