|
| 1 | +# WaveSim3D - 3D Acoustic Wave Simulation |
| 2 | + |
| 3 | +A comprehensive 3D acoustic wave simulation with realistic physics, binaural audio, and GPU acceleration. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +### Realistic 3D Physics |
| 8 | +- **Temperature-dependent speed of sound**: Uses accurate formula `c = 331.3 * sqrt(1 + T/273.15)` with humidity correction |
| 9 | +- **Frequency-dependent absorption**: Implements ISO 9613-1 atmospheric absorption model |
| 10 | +- **Multiple propagation media**: |
| 11 | + - **Air**: Temperature and humidity-dependent properties |
| 12 | + - **Water**: Bilaniuk-Wong speed of sound formula |
| 13 | + - **Metal**: Steel and aluminum with proper material properties |
| 14 | + |
| 15 | +### 3D Wave Simulation |
| 16 | +- **FDTD (Finite-Difference Time-Domain)** wave equation solver |
| 17 | +- **7-point stencil Laplacian** for accurate 3D propagation |
| 18 | +- **CFL stability** automatically maintained: `dt ≤ dx / (c * sqrt(3))` |
| 19 | +- **Absorbing boundary conditions** to minimize reflections |
| 20 | +- Support for obstacles, reflectors, and custom geometries |
| 21 | + |
| 22 | +### Audio System |
| 23 | +- **Multiple source types**: |
| 24 | + - Impulse (click/clap) |
| 25 | + - Continuous tone (sine wave) |
| 26 | + - Chirp (frequency sweep) |
| 27 | + - White/pink noise |
| 28 | + - Gaussian pulse |
| 29 | + - WAV file playback |
| 30 | +- **3D positioned sources** with real-time movement |
| 31 | +- **Binaural microphone** with virtual head: |
| 32 | + - Realistic ear spacing (~17cm) |
| 33 | + - ITD (Interaural Time Difference) calculation |
| 34 | + - ILD (Interaural Level Difference) modeling |
| 35 | +- **WAV file I/O** for recording and playback |
| 36 | + |
| 37 | +### GPU Acceleration |
| 38 | +- **CUDA backend** for NVIDIA GPUs |
| 39 | +- **CPU fallback** with Rayon parallelization |
| 40 | +- Efficient 3D packed stencil kernel |
| 41 | + |
| 42 | +### 3D Visualization |
| 43 | +- **wgpu-based rendering** (Vulkan, Metal, DX12) |
| 44 | +- **Interactive camera** with orbit, pan, and zoom controls |
| 45 | +- **Slice visualization**: XY, XZ, and YZ plane cuts |
| 46 | +- **Color mapping**: Blue-White-Red pressure visualization |
| 47 | +- **Source and listener markers** |
| 48 | + |
| 49 | +## Quick Start |
| 50 | + |
| 51 | +```bash |
| 52 | +# Run with CPU backend |
| 53 | +cargo run -p ringkernel-wavesim3d --bin wavesim3d --features cpu |
| 54 | + |
| 55 | +# Run with CUDA acceleration (requires NVIDIA GPU) |
| 56 | +cargo run -p ringkernel-wavesim3d --bin wavesim3d --features cuda |
| 57 | +``` |
| 58 | + |
| 59 | +## Controls |
| 60 | + |
| 61 | +| Key | Action | |
| 62 | +|-----|--------| |
| 63 | +| Space | Play/Pause simulation | |
| 64 | +| R | Reset simulation | |
| 65 | +| I | Inject impulse at source position | |
| 66 | +| 1 | Toggle XY slice visibility | |
| 67 | +| 2 | Toggle XZ slice visibility | |
| 68 | +| 3 | Toggle YZ slice visibility | |
| 69 | +| Left Mouse | Rotate camera | |
| 70 | +| Right Mouse | Pan camera | |
| 71 | +| Scroll | Zoom camera | |
| 72 | +| Escape | Quit | |
| 73 | + |
| 74 | +## Usage Example |
| 75 | + |
| 76 | +```rust |
| 77 | +use ringkernel_wavesim3d::simulation::{ |
| 78 | + SimulationConfig, SimulationEngine, Environment, Position3D |
| 79 | +}; |
| 80 | +use ringkernel_wavesim3d::audio::{AudioSystem, AudioSource, VirtualHead}; |
| 81 | + |
| 82 | +// Create simulation with custom environment |
| 83 | +let config = SimulationConfig { |
| 84 | + width: 64, |
| 85 | + height: 32, |
| 86 | + depth: 64, |
| 87 | + cell_size: 0.1, // 10cm cells |
| 88 | + environment: Environment { |
| 89 | + temperature_c: 20.0, |
| 90 | + humidity_percent: 50.0, |
| 91 | + medium: Medium::Air, |
| 92 | + ..Default::default() |
| 93 | + }, |
| 94 | + prefer_gpu: true, |
| 95 | +}; |
| 96 | + |
| 97 | +let mut engine = config.build(); |
| 98 | + |
| 99 | +// Add audio source |
| 100 | +let mut audio = AudioSystem::new(Default::default()); |
| 101 | +let source = AudioSource::tone( |
| 102 | + 0, |
| 103 | + Position3D::new(3.2, 1.6, 3.2), // Source position |
| 104 | + 440.0, // Frequency (Hz) |
| 105 | + 1.0, // Amplitude |
| 106 | +); |
| 107 | +audio.add_source(source); |
| 108 | + |
| 109 | +// Set up binaural microphone |
| 110 | +let head = VirtualHead::new(Position3D::new(3.2, 1.6, 5.0)); |
| 111 | +audio.init_microphone(head, engine.grid.params.time_step); |
| 112 | + |
| 113 | +// Run simulation steps |
| 114 | +for _ in 0..1000 { |
| 115 | + engine.step(); |
| 116 | + if let Some(mic) = &mut audio.microphone { |
| 117 | + mic.capture(&engine.grid); |
| 118 | + } |
| 119 | +} |
| 120 | + |
| 121 | +// Get binaural audio |
| 122 | +if let Some(mic) = &audio.microphone { |
| 123 | + let (left, right) = mic.get_samples(1024); |
| 124 | + // Process or save stereo audio... |
| 125 | +} |
| 126 | +``` |
| 127 | + |
| 128 | +## Physics Model |
| 129 | + |
| 130 | +### Wave Equation |
| 131 | +The simulation solves the 3D acoustic wave equation: |
| 132 | + |
| 133 | +``` |
| 134 | +∂²p/∂t² = c² ∇²p - α ∂p/∂t |
| 135 | +``` |
| 136 | + |
| 137 | +Where: |
| 138 | +- `p` is pressure |
| 139 | +- `c` is speed of sound |
| 140 | +- `∇²` is the 3D Laplacian |
| 141 | +- `α` is damping coefficient |
| 142 | + |
| 143 | +### FDTD Discretization |
| 144 | +Using a 7-point stencil for the 3D Laplacian: |
| 145 | + |
| 146 | +``` |
| 147 | +∇²p ≈ (p_W + p_E + p_S + p_N + p_D + p_U - 6p) / Δx² |
| 148 | +``` |
| 149 | + |
| 150 | +Time stepping: |
| 151 | +``` |
| 152 | +p_new = 2p - p_prev + c²Δt²∇²p |
| 153 | +``` |
| 154 | + |
| 155 | +### Atmospheric Absorption (ISO 9613-1) |
| 156 | +Frequency-dependent absorption in air: |
| 157 | +- Oxygen relaxation (dominant ~10 kHz) |
| 158 | +- Nitrogen relaxation (dominant ~100 Hz) |
| 159 | +- Classical absorption (molecular viscosity) |
| 160 | + |
| 161 | +## Configuration Options |
| 162 | + |
| 163 | +### Environment |
| 164 | +```rust |
| 165 | +Environment { |
| 166 | + temperature_c: 20.0, // Temperature in Celsius |
| 167 | + humidity_percent: 50.0, // Relative humidity |
| 168 | + pressure_pa: 101325.0, // Atmospheric pressure (Pa) |
| 169 | + medium: Medium::Air, // Air, Water, or Metal |
| 170 | +} |
| 171 | +``` |
| 172 | + |
| 173 | +### Grid Size |
| 174 | +- Recommended: 64x32x64 for real-time visualization |
| 175 | +- Maximum frequency: `f_max ≈ c / (10 * cell_size)` |
| 176 | +- For 10cm cells in air: ~343 Hz accurate simulation |
| 177 | + |
| 178 | +### Binaural Audio |
| 179 | +- Default ear spacing: 17cm (average human) |
| 180 | +- Sample rate: 44.1 kHz |
| 181 | +- ITD range: ±0.6ms (full lateralization) |
| 182 | + |
| 183 | +## Benchmarks |
| 184 | + |
| 185 | +| Configuration | Backend | Performance | |
| 186 | +|---------------|---------|-------------| |
| 187 | +| 64³ cells | CPU (Rayon) | ~120 steps/sec | |
| 188 | +| 64³ cells | CUDA (RTX 3090) | ~2000 steps/sec | |
| 189 | +| 128³ cells | CPU (Rayon) | ~15 steps/sec | |
| 190 | +| 128³ cells | CUDA (RTX 3090) | ~400 steps/sec | |
| 191 | + |
| 192 | +## Feature Flags |
| 193 | + |
| 194 | +| Feature | Description | |
| 195 | +|---------|-------------| |
| 196 | +| `cpu` (default) | CPU backend with Rayon parallelization | |
| 197 | +| `cuda` | NVIDIA CUDA acceleration | |
| 198 | +| `audio-output` | Real-time audio output via cpal | |
| 199 | + |
| 200 | +## Dependencies |
| 201 | + |
| 202 | +- **wgpu**: Cross-platform graphics |
| 203 | +- **winit**: Window management |
| 204 | +- **egui**: GUI controls |
| 205 | +- **glam**: 3D math |
| 206 | +- **hound**: WAV file I/O |
| 207 | +- **rayon**: CPU parallelization |
| 208 | +- **cudarc**: CUDA bindings (optional) |
| 209 | + |
| 210 | +## Related Crates |
| 211 | + |
| 212 | +- `ringkernel-wavesim`: 2D wave simulation |
| 213 | +- `ringkernel-cuda-codegen`: CUDA kernel generation |
| 214 | + |
| 215 | +## License |
| 216 | + |
| 217 | +Same license as the parent RingKernel project. |
0 commit comments