import type { MethodDefinition } from "./types"; import { ALL_GROUPS } from "./common"; export const FD_METHOD: MethodDefinition = { id: "fd", name: "Explicit finite differences", shortName: "Explicit FD", summary: "Explicit second-order time stepping on the energy-method operators, rigid-body coordinates plus flexural field, gravity through the self-weight prestress.", solverFunction: "plate_fd", planFunction: "plate_fd_plan", supports: { shape: ["rectangle", "ellipse"], mount: ["thread", "threads", "pads", "cymbal", "vise", "pinched"], excitation: ["impulse", "release"], }, readingOrder: [ "plate_fd.m", "plate_fd_setup.m", "plate_fd_loop.m", "plate_fd_output.m", "plate_fd_plan.m", "plate_model.m", "plate_setup.m", "plate_domain.m", "plate_mount.m", "plate_bending.m", "plate_prestress.m", "plate_static.m", "plate_rigid_basis.m", "plate_force_time.m", "plate_force_footprint.m", "plate_stress.m", "plate_listener.m", "plate_spectrum.m", "plate_curvature_free.m", "plate_curvature_domain.m", "plate_result_schema.m", ], equationGroups: ALL_GROUPS, validity: [ "Kirchhoff-Love thin-plate theory: no shear deformation or rotary inertia, so thick plates and very high modes are wrong.", "Small-angle theory throughout: the threads are linear springs, the pendulum motion is linearized, and the plate's in-plane motion (a swing in its own plane, a rotation about the normal) is not part of the model. A pull beyond a few degrees of swing or a hard strike on a light plate leaves this regime.", "Second-order truncation error in dx, dy and dt; the top modes on the grid are dispersive and their frequencies are too low. Free edges and curved edges are first order at the boundary.", "Mounts are idealizations: a thread has one tension, a pad or felt is a spring and dashpot per unit area with order-of-magnitude constants, a vise is perfectly rigid, a hand is a guess. The rod and the hole of a cymbal stand are not modelled, nor is the cymbal's curvature.", "The self-weight prestress is exact for the discrete model, but the stress at a hole or a jaw is the stress of a point or a line constraint on the grid, and depends on the spacing.", "Damping is a two-parameter model plus the mount's dashpots, chosen, not measured. The sigma1 loss acts on the flexural part only.", "The probe is snapped to the nearest grid node with a full stencil, and the series are averaged over each output sample.", "Stress fields are evaluated only at the saved frames, so the envelope samples the true peak; near a strike the stress depends on the load footprint.", "Radiated sound is an estimate of the waveform, not a calibrated level: Rayleigh's integral in a baffle, or a rough front-back cancellation for an unbaffled plate.", "With the GPU option the time loop runs in single precision (a WebGPU port of plate_fd_loop.m); setup, statics, stresses, sound and spectra stay in double precision in numbl. Rigid-body coordinates and flexural field are carried separately, which is what keeps the swing and the vibration both accurate in single precision.", ], durationOf: (spec) => spec.fd.duration, gridOf: (spec) => [spec.fd.nx, spec.fd.ny], usPerCellStep: 0.8, gpu: { loopFile: "plate_fd_loop.m", setupFunction: "plate_fd_setup", outputFunction: "plate_fd_output", usPerCellStep: 0.03, }, };