/ proof-of-concept / steelsim21
Sign in
proof-of-concept / steelsim21
steelsim21
Go to fileHistoryFork
.githubDeploy workflow: plain npm ci (rollup's native binary is an optional dependency)
docsDeploy workflow: plain npm ci (rollup's native binary is an optional dependency)
scriptsDeploy workflow: build, test, and publish the app and gallery as the repository site
srcCLI: import the optional Dawn binding by name so the type check passes without it
testsInitial-shape imperfection (Marguerre shallow-shell strains)
.gitignoreCommand-line renderer (Node WebGPU via Dawn) and gallery generator
index.htmlNonlinear steel sheet gong simulator with WebGPU
package-lock.jsonCLI: Chrome engine (Playwright) as default, Dawn optional; gallery fixes
package.jsonDeploy workflow: build, test, and publish the app and gallery as the repository site
README.mdDeploy workflow: build, test, and publish the app and gallery as the repository site
THEORY.mdAbsolute playback level with gain slider and peak readout
tsconfig.jsonCommand-line renderer (Node WebGPU via Dawn) and gallery generator
vite.cli.config.tsCommand-line renderer (Node WebGPU via Dawn) and gallery generator
vite.config.tsNonlinear steel sheet gong simulator with WebGPU

steelsim21#

A browser simulation of the sound of a thin rectangular stainless steel sheet that hangs from a thread, is pushed by hand at the far corner, held until it settles, and released. The sheet rings like a gong, so the simulator solves the geometrically nonlinear (von Karman) plate equations with in-plane inertia retained, stepped explicitly on the GPU through WebGPU. The model and the numerical method are described in THEORY.md.

The app and the gallery are deployed by the deploy workflow on every push to main: https://steelsim21--proof-of-concept.vault1-sites.magland.org/ (gallery at /docs/gallery/index.html).

Running#

Requires Node 20 or later and a browser with WebGPU (Chrome or Edge 113+; Firefox and Safari with WebGPU enabled).

npm install
npm run dev        # development server
npm run build      # static site in dist/
npm test           # discretization tests (Node, no GPU needed)

Using the simulator#

Press Start. With the default excitation the sheet is pushed at the bottom-right corner over the ramp time, held with heavy artificial damping until it settles, and then released by ramping the finger force to zero over the release time; the recording of audio and movie frames starts at the release. The other excitation is a drumstick strike (Hertz contact with a free mass) at a configurable point and speed; the recording then starts at the impact. The view shows the transverse displacement as a color map (2D) or a lit height field (3D, drag to orbit and wheel to zoom), the spectrogram shows the listener signal, and the audio can be played or downloaded as a 16-bit WAV at any time.

  • The sheet has a stress-free initial bow (default 3 mm across the width; set the shape to Flat for the ideal plate). A negative push amount pushes against the bow.
  • Plate, initial shape, excitation, and numerics parameters take effect at the next Start. Damping, listener position, and the radiation model can be changed while a simulation runs.
  • Pause halts the run temporarily; Stop ends it, keeps the audio and movie, and unlocks the parameter fields for the next Start.
  • Playback level: "Absolute" maps 1 Pa to full scale, shifted by the gain slider, so different runs can be compared by ear (the peak level in dBFS is shown, with a clipping warning); "Loudness" and "Peak" normalize each run instead. The WAV download uses the same setting.
  • After the simulation completes, drag the time slider to explore the movie; Play starts audio from the slider position and moves the movie and the spectrogram cursor with it. Live returns to the running view.
  • To extend a finished simulation, raise the duration and press Continue; the state is kept on the GPU.
  • Any parameter can be preset in the URL in SI units, for example ?spacing=0.006&duration=2&autostart=1.

The default grid spacing of 4 mm (about 8.9k nodes) resolves bending waves to about 20 kHz. With in-plane inertia the stable time step is set by the in-plane wave speed, about 0.65 microseconds, so four seconds of sound take about six million steps. This runs at roughly 35k steps per second on an Intel Iris Xe integrated GPU (about three minutes for four seconds) and considerably faster on a discrete GPU. A spacing of 6 mm is about three times faster and adequate below 10 kHz.

docs/gallery/index.html is a generated page with audio clips, spectrograms, and summary numbers for sweeps of the main parameters (stick speed, mass, tip hardness, strike position, push amount and release, bow, thickness, size, material, damping). Open it directly or through the dev server at /docs/gallery/index.html; the "Open in simulator" links need the dev server.

The clips are produced by the command-line renderer, which runs the same simulation code in a headless Chromium through Playwright (the webgpu Node bindings of Dawn are available as an experimental --engine dawn, but the prebuilt binary needs glibc 2.38 and was unstable in testing):

npm run build && npm run build:cli
npx playwright install chromium               # once, or pass --chrome /usr/bin/google-chrome
node dist-cli/steelsim.js render --out out --name hit excitation=strike strikeVelocity=4
node dist-cli/steelsim.js gallery docs/gallery/manifest.json spacing=0.004

render writes a WAV (absolute level, --gain dB relative to 1 Pa), a spectrogram PNG, and a JSON summary. gallery renders every sweep of the manifest (skipping clips whose raw signal is already cached under docs/gallery/raw/), applies one playback gain per sweep so loudness differences within a sweep are preserved, and regenerates the page. Any key=value on the command line overrides that parameter for every clip.

Layout#

  • src/params.ts: physical and numerical parameters, derived quantities.
  • src/sim/cpuRef.ts: float64 reference implementation of the spatial discretization; used for the time-step estimate and the tests.
  • src/sim/shaders/: WGSL kernels (time step, rigid-body projection, listener sum, display extraction).
  • src/sim/simulation.ts: WebGPU driver (buffers, batch encoding, phases, readback).
  • src/render/: 2D and 3D WebGPU rendering of the displacement field.
  • src/audio/: FFT, spectrogram, WAV encoder, playback.
  • src/main.ts: user interface.
  • src/cli/: command-line renderer (Chrome and Dawn engines, PNG and WAV writers, metrics, gallery generator).
  • docs/gallery/: sweep manifest and the generated gallery.
  • tests/: symmetry, rigid modes, energy-gradient consistency, and free-plate frequencies against the Leissa reference values.
↑↓ move↵openescclose