/ concept-collection / acoustic-scattering-2d
Sign in
concept-collection / acoustic-scattering-2d
acoustic-scattering-2d / scenes / room.m
46 lines · 2.3 KBCodeBlameHistory
cbf6d88Initial commit: 2D acoustic scattering, live on WebGPUJeremy Magland 1% A room: a square enclosure with a doorway in one wall.
2%
3% Close the doorway (gap = 0) and it is a sealed cavity, where a pulse never
4% leaves and the sound settles into the room's own modes. Open it and the room
5% becomes a resonator that leaks: sound escapes through the aperture, and the
6% ringing decays. This is the scene the microphone is for. Put the source and
7% the microphone inside, listen to a click, and what comes back is a direct
8% arrival followed by echoes closing up into reverberation.
9%
10% `side`, `gap` and `thick` are in metres — a real room, not a fraction of the
11% domain — so `side` is the half-width and the room is `2*side` across.
13% The walls are *slower* than the background rather than faster, and that is a
14% deliberate trade. Reflection at an interface goes as |c2 - c1|/(c2 + c1)
15% with the density constant, so a wall at cwall = 0.15 reflects about 75% of
16% the pressure amplitude, as one at cwall = 7 would. But the timestep is set
17% by the *fastest* speed anywhere on the grid, so a hard wall would make every
18% step of the whole simulation several times smaller, while a slow one is
19% free. What a slow wall costs instead is resolution inside itself: the
20% wavelength there is shorter by the same factor, and the grid barely
21% resolves it. That is what the absorption is for. It damps what gets into
22% the wall so that the badly resolved part never comes back out, which is
23% also what a real wall does.
25% Turn `cwall` above 1 for a genuinely rigid room and watch the timestep in
26% the readout drop to match.
27function [c, sig] = medium(x, y, L, h, c0, cwall, side, gap, thick, absorb)
28 s = 1.5*h;
30 % The shell between two concentric squares: |x| and |y| both within `side`
31 % is the room, and out to side + thick is the wall.
32 r = max(abs(x), abs(y));
33 outer = 0.5 * (1 - tanh((r - (side + thick)) / s));
34 inner = 0.5 * (1 - tanh((r - side) / s));
35 wall = outer - inner;
37 % The doorway, cut out of the right-hand wall. Written so that gap = 0 shuts
38 % it exactly: max(0, ...) is identically zero there, where a tanh of the same
39 % thing would leave a half-open cell behind and quietly ruin the seal.
40 through = min(1, max(0, gap/2 - abs(y)) / s);
41 right = 0.5 * (1 + tanh((x - side) / s));
42 wall = max(0, wall - through .* right);
44 c = c0 * (1 + (cwall - 1) * wall);
45 sig = sponge(x, y, L, 0.2*L, 1700) + absorb * wall;
46end
moveopenescclose