// Configuration types mirroring the Python package's dataclasses (cymsim/config.py), with the // same field names, units (SI) and defaults, so that a YAML file is valid for both. export interface Material { E: number; nu: number; rho: number; sigma0: number; sigma1: number } export interface Profile { radius: number; bell_height: number; bell_top_radius: number; bell_shoulder_radius: number; bow_height: number; bow_power: number; h_rim: number; h_shoulder: number; h_bell: number; max_slope: number; } export interface Imperfections { seed: number; n_dents: number; dent_depth: number; dent_sigma: number; dent_margin: number; rim_warp: number; rim_warp_modes: number[]; shoulder_ovality: number; bell_offset: number; } export interface MeshConfig { element_size: number; smoothing: number } export interface StickExciter { kind: "stick"; mass: number; k: number; alpha: number; patch_length: number; patch_points: number; patch_angle: number; gap: number; } export interface MalletExciter { kind: "mallet"; mass: number; alpha: number; compression: number; radius: number; gap: number } export type Exciter = StickExciter | MalletExciter; export interface Hit { time: number; r: number; phi: number; velocity: number; exciter: Exciter } export interface Listener { position: [number, number, number]; c_air: number; rho_air: number; back_diffraction_gain: number } export interface Numerics { fs: number; duration: number; cfl_safety: number; rot_inertia_factor: number; inplane_mass_scale: number; steps_per_block: number; dtype: string; nonlinear: boolean; n_progress: number; } export interface Output { prefix: string; wav: boolean; npz: boolean; cascade_plot: boolean } export interface SimulationConfig { material: Material; profile: Profile; imperfections: Imperfections; mesh: MeshConfig; hits: Hit[]; listener: Listener; numerics: Numerics; output: Output; } export const defaultMaterial = (): Material => ({ E: 1.1e11, nu: 0.34, rho: 8700, sigma0: 0.9, sigma1: 5e-4 }); export const defaultProfile = (): Profile => ({ radius: 0.2286, bell_height: 0.013, bell_top_radius: 0.025, bell_shoulder_radius: 0.08, bow_height: 0.03, bow_power: 1.4, h_rim: 1.0e-3, h_shoulder: 1.7e-3, h_bell: 2.6e-3, max_slope: 0.4, }); export const defaultImperfections = (): Imperfections => ({ seed: 1, n_dents: 400, dent_depth: 0.25e-3, dent_sigma: 7e-3, dent_margin: 0.01, rim_warp: 0.6e-3, rim_warp_modes: [2, 3, 4, 5], shoulder_ovality: 0.03, bell_offset: 1.5e-3, }); export const defaultMesh = (): MeshConfig => ({ element_size: 6e-3, smoothing: 1 }); export const defaultStick = (): StickExciter => ({ kind: "stick", mass: 0.03, k: 5e8, alpha: 1.5, patch_length: 0.03, patch_points: 7, patch_angle: 0.6, gap: 1e-4, }); export const defaultMallet = (): MalletExciter => ({ kind: "mallet", mass: 0.3, alpha: 2.5, compression: 12e-3, radius: 0.012, gap: 1e-4 }); export const defaultHit = (): Hit => ({ time: 0, r: 0.137, phi: 0.3, velocity: 8, exciter: defaultMallet() }); export const defaultListener = (): Listener => ({ position: [0.4, 0.3, 0.9], c_air: 343, rho_air: 1.2, back_diffraction_gain: 1 }); export const defaultNumerics = (): Numerics => ({ fs: 44100, duration: 2, cfl_safety: 0.6, rot_inertia_factor: 1 / 64, inplane_mass_scale: 1, steps_per_block: 20000, dtype: "float32", nonlinear: true, n_progress: 20, }); export const defaultOutput = (): Output => ({ prefix: "crash", wav: true, npz: true, cascade_plot: true }); export const defaultConfig = (): SimulationConfig => ({ material: defaultMaterial(), profile: defaultProfile(), imperfections: defaultImperfections(), mesh: defaultMesh(), hits: [defaultHit()], listener: defaultListener(), numerics: defaultNumerics(), output: defaultOutput(), });