/ proof-of-concept / plate-dynamics-lab-2
Sign in
proof-of-concept / plate-dynamics-lab-2
Go to fileHistoryFork
.mochiPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
appsPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
packagesPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
.gitignorePlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
.prettierrcPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
package-lock.jsonPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
package.jsonPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
README.mdPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
tsconfig.base.jsonPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
tsconfig.jsonPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
vite.shared.tsPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements
vitest.config.tsPlate dynamics lab 2: a hammer on a hung plate by Rayleigh-Ritz and by Mindlin-Reissner finite elements

Plate Dynamics Lab 2#

An interactive lab for the sound of a small metal plate hung from a thread and struck by a hammer: a 30 mm square of 1 mm 6061-T6 aluminium, a thread through a hole near its top edge, a 10 g steel hammer at 0.45 m/s. The lab solves the problem two independent ways and lets you compare them: a Rayleigh-Ritz solution of the Kirchhoff-Love thin-plate energy on a tensor-Legendre basis with the strike applied as a prescribed Hertz pulse, and a Mindlin-Reissner finite-element mesh whose modes are struck by a hammer integrated against the moving plate. Both are modal: the modes of the plate on its thread are solved once and kept, and every strike is a sum of damped oscillators, so trying strike points, hammers and microphones is near instant. The app shows the plate on its thread, its modes and their shapes, the contact force and the hammer's motion, the displacement and surface-stress fields of the strike transient, a probe time series and spectrum, and the radiated sound, which you can play or save; the comparison tab lines up the two methods' modes, contact numbers, spectra and sounds.

The numerics run in numbl, a MATLAB-syntax environment executing in the browser, in double precision. The MATLAB source shown on screen is the source that ran: edit any file and rerun. No physics is computed in JavaScript; the host draws arrays and plays samples.

This lab succeeds plate-dynamics-lab, whose explicit finite-difference time stepping under gravity turned out to be a less realistic model of a struck plate than the two modal simulators in sim-docs, which this lab follows constant for constant. The old lab's WebGPU time loop has no counterpart here: nothing in a modal method is expensive enough to need it, except a very large finite-element eigensolve, and that is done in double precision in numbl instead (see below).

Layout#

packages/core        problem spec, .m generation, numbl runner, result typing, field primitives (no UI)
packages/core/src/m  the MATLAB library: plate_rr_modes.m, plate_fem_modes.m, plate_synthesize.m, ...
packages/components  React components: code view, parameter panel, 2-D field view, 3-D scene, plots, equations, run status, audio, movie
apps/lab             the app: one arrangement of the components

The object#

A rectangular plate of width W, height H and thickness h with a hole of diameter 0.8 mm on its centreline 1.5 mm below the top edge, hung from a thread of length L. The thread holds the hole with the linearized pendulum stiffness m g / L against transverse motion, a soft point spring and not a clamp, and a dashpot at the hole stands for the loss where the thread rubs it. Coordinates are metres from the plate's centre, x to the right and y towards the top edge, as in the simulators this lab follows. A steel hammer with a rounded tip strikes the plate at a chosen point; a microphone sits on the plate's normal.

The two methods#

Rayleigh-Ritz, Kirchhoff-Love (plate_rr_modes.m, plate_rr_strike.m). The bending energy of a thin plate, with no shear deformation or rotary inertia, is minimized over products of Legendre polynomials up to order 12 per side, 169 coefficients, integrated by 30-point Gauss-Legendre quadrature per side. The hole subtracts its mass at its position and the thread adds its spring there; the generalized eigenproblem is solved densely after a Cholesky reduction. The rigid rotations and the pendulum mode are dropped. The strike is the force history of a Hertz contact on a rigid target, a sin^(3/2) pulse of the duration and impulse the Hertz formulas give, applied to every mode through Duhamel's integral by quadrature. The plate does not push back on the hammer.

Finite elements, Mindlin-Reissner (plate_fem_modes.m, plate_fem_strike.m). Bilinear four-node elements with three unknowns per node (the deflection and two rotations) carry the bending and transverse-shear energies, both integrated with 2 x 2 Gauss points, and the mass with rotary inertia. This is the element of the reference simulator, kept as it is: full integration of the shear term locks on a thin plate, so the partials converge from above as the mesh is refined, by several percent between 32 x 32 and 80 x 80. The default mesh is 48 x 48, about 3 percent high on the main partial and a few seconds to solve; 80 x 80, where the reference was run, is one setting away and takes tens of seconds. The three rigid-body modes (two free rotations about the hole and the pendulum) are kept, so that the collision can put momentum into the freely hanging plate, and left out of the sound. The hammer and the plate are integrated together as one system, the hammer's Hertz spring with a Hunt-Crossley loss against the sum of all the modes under it, by fourth-order Runge-Kutta until they separate; the very light plate moves away under the hammer, so the contact is longer, the force far lower and the impulse smaller than the rigid-target pulse.

The two share the plate, the hammer, the damping constants and the radiation model, and nothing else. Each mode is damped by three losses: the material's structural Q, an air-loading term that grows with frequency, and the thread's dashpot acting on the mode's displacement at the hole. The pressure at the microphone is a compact-source estimate, each mode's volume velocity reduced below the plate's coincidence frequency by the front/back cancellation of a small unbaffled plate; it is meaningful in timbre and decay, approximate in level, so the export is peak-normalized. All of this is the reference simulators' modelling, constant for constant, and the tests check it against their diagnostics (see below).

Two stages, and what is kept#

The modes depend on the plate, its elastic constants, the hole, the thread's length, the sample rate (modes are kept below 0.47 fs) and the method's numerics. The strike depends on everything else: the hammer, the strike point, the probe, the microphone, the material's Q, the dashpot and the render settings. The generated script main.m calls the two stages in turn, and the lab runs them as two scripts: the modes struct comes back to the host and is kept, and a later run whose modes key is unchanged goes straight to the strike, which takes a couple of seconds for four seconds of sound at 96 kHz. Editing main.m runs it as written, in one go.

The eigensolver#

numbl's own eigs is far too slow on the finite-element problem (twenty thousand unknowns at 80 x 80), but its sparse Cholesky after an approximate-minimum-degree ordering is fast, so plate_fem_eigs.m is a subspace iteration written on top of it: one factorization of K - sigma M with a negative shift, which keeps the matrix positive definite, then repeated block solves and Rayleigh-Ritz projections until the lowest eigenvalues settle. It is a block method, which matters for a square plate, whose spectrum is full of degenerate pairs. The block is sized from the modal density of a thin plate and enlarged if the wanted set does not reach past the cutoff; the count of iterations and the largest residual are reported under Run details. Everything stays in double precision.

Verification#

packages/core/test/fixtures holds the diagnostics the two Python simulators in sim-docs write, at the reference centre hit and an off-centre hit, for the Rayleigh-Ritz method at orders 12 and 8 and for the finite-element method at meshes of 16, 24, 32 and 48, together with the first 50 ms of each reference WAV. The tests run the library in numbl under Node against them: the mode frequencies agree to a part in ten million, the contact time, peak force, impulse and exit velocities to a part in a hundred thousand (the contact integrators differ), and the peak-normalized sound to the quantization of the WAV for Rayleigh-Ritz and to a few parts in ten thousand for the finite elements, where the two eigensolvers mix the degenerate pairs differently. The finite-element method is also checked to converge from above with mesh refinement, and the two-stage run to equal the single script bit for bit.

Saving a run#

  • The sound, as a 24-bit mono WAV at the simulation's own sample rate, peak-normalized to the render's dBFS setting, as the reference simulators write theirs.
  • The movie, as WebM (VP9 and Opus) or MP4 where the browser records it: the 3-D scene as it stands, with a title bar carrying the simulated time and a caption bar carrying the field and its colour scale. With the sound it is recorded in real time, so the frames, which cover the first two milliseconds of the strike, flash by at the start; the slow-motion option plays the frames one after another at thirty a second without the sound, which could not be slowed a thousandfold. The recorder is the browser's own MediaRecorder, so the tab has to stay in front, and a machine that cannot keep up drops frames rather than slowing down.

The live app#

The lab is deployed at https://plate-dynamics-lab-2.vault1-sites.magland.org/. .mochi/workflows/deploy.yml typechecks, runs the tests and builds apps/lab on every push to main, then publishes it; a regression against the reference diagnostics stops the deployment. The site sits at the root of an origin of its own, which the repository's site label gives it, so the build's base path comes from configure-pages rather than being written into the Vite config, and the page can use localStorage for your settings and source edits.

Running#

npm install
npm run dev              # the lab, http://localhost:5173
npm test                 # vitest: the .m files in numbl under Node against the reference diagnostics
npm run typecheck
npm run build

The .m files also run unchanged from the numbl CLI, Octave or MATLAB:

npx numbl run --path packages/core/src/m my_script.m

Honest limits#

  • Both models are linear: no denting of the plate, no chatter of the hammer, no thread buzz, no room, no microphone colouring. A hard strike on aluminium would dent it, and the model does not know.
  • Kirchhoff-Love theory has no shear deformation or rotary inertia, so the Rayleigh-Ritz partials in the tens of kHz run a little high; the Mindlin-Reissner element carries the shear but locks on a thin plate, so its partials converge from above with the mesh. The two are a percent or two apart on this plate, and neither is the truth.
  • Neither contact model has been checked against a measured hammer; the prescribed pulse ignores the plate's motion, and the coupled model's loss is a rule of thumb tuned to the nominal restitution.
  • The damping constants are the reference simulators' order-of-magnitude figures, chosen, not measured. The thread is a point spring; the hole is a point mass correction (Rayleigh-Ritz) or not cut at all (finite elements).
  • The radiated sound is a compact-source estimate with a smooth cancellation below coincidence, not a solution of the diffraction problem: right in timbre and decay, approximate in level.
  • The finite-element method's rigid-body modes have no gravitational restoring force, so after the strike the plate drifts in rotation at a constant rate rather than swinging; they are shown in the total displacement and kept out of the sound.
  • Stresses are second derivatives of the fields (for the finite elements, first-order gradients of the rotations) and converge more slowly than the frequencies.
↑↓ move↵openescclose