/ proof-of-concept / bead-percussion
Sign in
proof-of-concept / bead-percussion
bead-percussion / src / sim / types.ts
77 lines · 2.8 KBBlameHistoryRaw
1// The bead system as the solver sees it. Indices are 0-based here; the
2// script uses 1-based indices and parse.ts converts them.
4export type Method = "verlet" | "yoshida4";
6export interface Hit {
7 t: number; // start time (s)
8 beads: Int32Array;
9 // Impulse: velocity added to each bead at time t (m/s). Used when duration == 0.
10 velocity: [number, number, number];
11 // Force pulse: raised-cosine force on each bead, peak `force` (N), lasting `duration` (s).
12 force: [number, number, number];
13 duration: number;
16export interface BeadSystem {
17 n: number;
18 pos0: Float64Array; // 3n, interleaved x,y,z (m)
19 mass: Float64Array; // n (kg)
20 pinned: Uint8Array; // n, 1 = held fixed
21 // Springs: f = k e + k3 e^3, e = L - L0
22 si: Int32Array;
23 sj: Int32Array;
24 sk: Float64Array;
25 sL0: Float64Array;
26 sk3: Float64Array;
27 // Dashpots on relative velocity: F_i = c (v_j - v_i)
28 di: Int32Array;
29 dj: Int32Array;
30 dc: Float64Array;
31 friction: Float64Array; // n, F_i = -c0_i v_i (N s/m)
32 hits: Hit[];
33 listenBeads: Int32Array;
34 listenDir: [number, number, number]; // unit vector
35 duration: number; // s
36 sampleRate: number; // Hz, audio output
37 dt: number; // s; 0 = automatic
38 safety: number; // fraction of the stability limit used when dt is automatic
39 method: Method;
40 frameRate: number; // Hz, snapshots for animation and mode energies
41 modes: boolean; // compute linear transverse modes and track their energies
44export interface SimProgress {
45 t: number;
46 duration: number;
49export interface Modes {
50 freqs: Float64Array; // Hz, ascending
51 // psi: orthonormal eigenvectors of M^{-1/2} K M^{-1/2} over free beads,
52 // column-major (nFree x nModes)
53 psi: Float64Array;
54 free: Int32Array; // bead index of each row of psi
57export interface SimResult {
58 audio: Float32Array; // listener displacement at sampleRate (m)
59 sampleRate: number;
60 dt: number;
61 substeps: number; // solver steps per audio sample
62 omegaMax: number; // rad/s, highest linearized frequency
63 frameTimes: Float64Array; // times of the energy records (s)
64 energy: Float64Array; // mechanical energy above the rest state at each frame (J)
65 animTimes: Float64Array; // times of the stored displacement snapshots (s)
66 animFrames: Float32Array[]; // displacement (3n) at each snapshot (m)
67 dissipated: Float64Array; // cumulative energy removed by damping (J)
68 // mode energies (nModes per frame, frame-major), present when modes were computed
69 modeEnergy: Float32Array | null;
70 residualForce: number; // max |F| on free beads at rest (N)
71 maxTension: number; // max spring force at rest (N)
72 energyDrift: number; // max relative change in E + dissipated after the last excitation
73 freqErrors: { hz: number; cents: number }[]; // integrator frequency error at a few frequencies
74 elapsedMs: number;
75 aborted: string | null; // reason if the run stopped early
76 warnings: string[];
↑↓ move↵openescclose