import type { Hammer, Material, PlateGeometry, ProblemSpec } from "./types"; /** * Material presets. E, nu and rho are room-temperature handbook figures for * the named alloy (ASM Handbook, MatWeb) and typical rather than certified. * The quality factor Q is the internal, structural loss alone; it is an * order-of-magnitude figure, and the air loading and the thread's dashpot are * added to it per mode (plate_damping.m). The default 6061-T6 values are * those of the simulators this lab follows. */ export interface MaterialPreset { id: string; material: Material; source: string; } export const MATERIAL_PRESETS: MaterialPreset[] = [ { id: "6061-t6", material: { name: "6061-T6 aluminium", E: 68.9e9, nu: 0.33, rho: 2700, Q: 1400 }, source: "6061-T6 sheet, typical values; Q = 1400 is the reference simulators' figure.", }, { id: "a36-steel", material: { name: "A36 structural steel", E: 200e9, nu: 0.26, rho: 7850, Q: 2500 }, source: "Hot-rolled low-carbon steel; steel rings longer than aluminium.", }, { id: "304-stainless", material: { name: "304 stainless steel", E: 193e9, nu: 0.29, rho: 8000, Q: 2000 }, source: "Annealed 304 sheet, typical values.", }, { id: "c260-brass", material: { name: "C260 cartridge brass", E: 110e9, nu: 0.375, rho: 8530, Q: 1500 }, source: "70/30 brass, half-hard sheet, typical values.", }, { id: "b20-bronze", material: { name: "B20 bell bronze (CuSn20)", E: 105e9, nu: 0.34, rho: 8800, Q: 4000 }, source: "Bell and cymbal bronze; its low internal loss is what makes it ring.", }, { id: "ti-6al-4v", material: { name: "Ti-6Al-4V titanium", E: 113.8e9, nu: 0.342, rho: 4430, Q: 3000 }, source: "Annealed Grade 5 titanium sheet, typical values.", }, ]; export interface PlatePreset { id: string; name: string; plate: PlateGeometry; note: string; } export const PLATE_PRESETS: PlatePreset[] = [ { id: "coupon-30x30x1", name: "30 x 30 x 1 mm coupon", plate: { width: 0.03, height: 0.03, thickness: 0.001 }, note: "The reference plate: a square coupon whose lowest partial is near 3.6 kHz and whose highest kept mode is ultrasonic.", }, { id: "coupon-40x30x1", name: "40 x 30 x 1 mm coupon", plate: { width: 0.04, height: 0.03, thickness: 0.001 }, note: "Not square: the degenerate pairs of the square split into distinct partials.", }, { id: "coupon-30x30x0p5", name: "30 x 30 x 0.5 mm shim", plate: { width: 0.03, height: 0.03, thickness: 0.0005 }, note: "Half the thickness: every partial at half the frequency, and twice as many below the cutoff.", }, { id: "plate-60x60x1", name: "60 x 60 x 1 mm plate", plate: { width: 0.06, height: 0.06, thickness: 0.001 }, note: "Four times the area: partials a quarter as high, four times as many modes, and a longer eigensolve.", }, { id: "plate-50x30x2", name: "50 x 30 x 2 mm bar", plate: { width: 0.05, height: 0.03, thickness: 0.002 }, note: "Thicker and oblong; the thin-plate assumption of the Rayleigh-Ritz method is at its edge here.", }, ]; export interface HammerPreset { id: string; name: string; hammer: Hammer; note: string; } export const HAMMER_PRESETS: HammerPreset[] = [ { id: "steel-10g", name: "10 g steel hammer, 2 mm tip", hammer: { mass: 0.01, tip_radius: 0.002, speed: 0.45, E: 200e9, nu: 0.29, restitution: 0.62 }, note: "The reference strike: a small steel hammer at 0.45 m/s.", }, { id: "steel-5g-sharp", name: "5 g steel hammer, 1 mm tip", hammer: { mass: 0.005, tip_radius: 0.001, speed: 0.6, E: 200e9, nu: 0.29, restitution: 0.62 }, note: "Lighter and sharper: a shorter contact excites the high partials more.", }, { id: "brass-20g", name: "20 g brass hammer, 4 mm tip", hammer: { mass: 0.02, tip_radius: 0.004, speed: 0.3, E: 110e9, nu: 0.35, restitution: 0.55 }, note: "Heavier, softer and rounder: a longer contact that favours the lowest partials.", }, ]; export interface ScenarioPreset { id: string; name: string; note: string; spec: ProblemSpec; } const mat = (id: string) => ({ ...MATERIAL_PRESETS.find((m) => m.id === id)!.material }); const plate = (id: string) => ({ ...PLATE_PRESETS.find((p) => p.id === id)!.plate }); const hammer = (id: string) => ({ ...HAMMER_PRESETS.find((h) => h.id === id)!.hammer }); const COMMON = { hole: { diameter: 0.8e-3, edge_offset: 1.5e-3 }, thread: { length: 0.2, dashpot: 7.5e-4 }, probe: { x: 0.008, y: -0.006 }, mic: { distance: 0.35, air_density: 1.204, sound_speed: 343 }, render: { fs: 96000, duration: 4, modes: 72, normalize_dbfs: -1, nframes: 120, frame_span: 0.002, }, rr: { basis_order: 12, quadrature_order: 30, grid: 49 }, fem: { mesh_x: 48, mesh_y: 48 }, }; /** * Whole problems. The first is the reference centre hit of the simulators * this lab follows; the others move the strike, change the hammer or the * plate. Each note says what to look for. */ export const SCENARIO_PRESETS: ScenarioPreset[] = [ { id: "center-hit", name: "Centre hit (the reference)", note: "The 30 mm 6061-T6 coupon struck at its centre. The centre lies on both symmetry axes, so most asymmetric modes are silent; the strong partials are near 6.7, 17.2 and 33.5 kHz (Rayleigh-Ritz) and a percent or two away from those in the finite-element model.", spec: { plate: plate("coupon-30x30x1"), material: mat("6061-t6"), hammer: hammer("steel-10g"), strike: { x: 0, y: 0 }, ...COMMON, }, }, { id: "off-center-hit", name: "Off-centre hit, (6, -4) mm", note: "The same coupon struck 6 mm right of and 4 mm below the centre. The modes the centre hit could not reach now sound, including the lowest at 3.6 kHz; the finite-element contact is shorter and lighter than at the centre because the plate under the hammer is more compliant there.", spec: { plate: plate("coupon-30x30x1"), material: mat("6061-t6"), hammer: hammer("steel-10g"), strike: { x: 0.006, y: -0.004 }, ...COMMON, }, }, { id: "sharp-tap", name: "Sharp tap near a corner", note: "A light, sharp hammer near the lower-right corner: a short contact that excites the high partials, on the part of the plate that moves most.", spec: { plate: plate("coupon-30x30x1"), material: mat("6061-t6"), hammer: hammer("steel-5g-sharp"), strike: { x: 0.011, y: -0.011 }, ...COMMON, }, }, { id: "brass-plate", name: "Brass coupon, oblong", note: "A 40 x 30 mm brass coupon struck off-centre with the heavier brass hammer. Denser and softer than aluminium, brass rings lower; the oblong outline splits the square's degenerate pairs into distinct partials.", spec: { plate: plate("coupon-40x30x1"), material: mat("c260-brass"), hammer: hammer("brass-20g"), strike: { x: 0.008, y: -0.005 }, ...COMMON, }, }, { id: "thin-shim", name: "Thin shim", note: "A 0.5 mm shim of the same outline: every partial at half the frequency, twice as many below the cutoff, and a contact the plate yields to much more, so the two contact models differ most here.", spec: { plate: plate("coupon-30x30x0p5"), material: mat("6061-t6"), hammer: hammer("steel-10g"), strike: { x: 0.005, y: -0.003 }, ...COMMON, }, }, { id: "bronze-bell-plate", name: "Bell-bronze plate, 60 mm", note: "A 60 mm bronze square: four times the area, partials a quarter as high, many more modes below the cutoff, and bronze's low loss keeps it ringing for the whole four seconds. The eigensolve takes longer.", spec: { plate: plate("plate-60x60x1"), material: mat("b20-bronze"), hammer: hammer("steel-10g"), strike: { x: 0.012, y: -0.008 }, ...COMMON, probe: { x: 0.016, y: -0.012 }, }, }, ]; export function scenarioPreset(id: string): ScenarioPreset { const s = SCENARIO_PRESETS.find((x) => x.id === id); if (!s) throw new Error(`unknown scenario ${id}`); return s; }