% A room: a square enclosure with a doorway in one wall. % % Close the doorway (gap = 0) and it is a sealed cavity, where a pulse never % leaves and the sound settles into the room's own modes. Open it and the room % becomes a resonator that leaks: sound escapes through the aperture, and the % ringing decays. This is the scene the microphone is for. Put the source and % the microphone inside, listen to a click, and what comes back is a direct % arrival followed by echoes closing up into reverberation. % % `side`, `gap` and `thick` are in metres — a real room, not a fraction of the % domain — so `side` is the half-width and the room is `2*side` across. % % The walls are *slower* than the background rather than faster, and that is a % deliberate trade. Reflection at an interface goes as |c2 - c1|/(c2 + c1) % with the density constant, so a wall at cwall = 0.15 reflects about 75% of % the pressure amplitude, as one at cwall = 7 would. But the timestep is set % by the *fastest* speed anywhere on the grid, so a hard wall would make every % step of the whole simulation several times smaller, while a slow one is % free. What a slow wall costs instead is resolution inside itself: the % wavelength there is shorter by the same factor, and the grid barely % resolves it. That is what the absorption is for. It damps what gets into % the wall so that the badly resolved part never comes back out, which is % also what a real wall does. % % Turn `cwall` above 1 for a genuinely rigid room and watch the timestep in % the readout drop to match. function [c, sig] = medium(x, y, L, h, c0, cwall, side, gap, thick, absorb) s = 1.5*h; % The shell between two concentric squares: |x| and |y| both within `side` % is the room, and out to side + thick is the wall. r = max(abs(x), abs(y)); outer = 0.5 * (1 - tanh((r - (side + thick)) / s)); inner = 0.5 * (1 - tanh((r - side) / s)); wall = outer - inner; % The doorway, cut out of the right-hand wall. Written so that gap = 0 shuts % it exactly: max(0, ...) is identically zero there, where a tanh of the same % thing would leave a half-open cell behind and quietly ruin the seal. through = min(1, max(0, gap/2 - abs(y)) / s); right = 0.5 * (1 + tanh((x - side) / s)); wall = max(0, wall - through .* right); c = c0 * (1 + (cwall - 1) * wall); sig = sponge(x, y, L, 0.2*L, 1700) + absorb * wall; end