Resources Numerical accuracy Calculation policy

Reverberation time of a box room

Works out the reverberation time of a box-shaped room in each frequency band by four formulas: Sabine, Eyring, Fitzroy and Arau-Puchades.

How the precision is kept

Each formula is evaluated directly in 64-bit from the room's three sizes and the absorption of its six surfaces. The formulas themselves are statistical models with the conventional constant 0.161, so the result is as good as the model and the absorption data, not as the arithmetic.

Calculations under this policy

2 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.

stat.js BimCraft 0.8.1 64-bit 2 calculations Reviewed

Tests tools/acoustics-test/geo-test.mjs

Surface areas and mean absorption of each pair

64-bit

The area of each pair of opposite surfaces and their mean absorption in a band.

S_x = 2 L_y L_z; ᾱ_x = (α_west + α_east) ÷ 2; −ln(1 − ᾱ)

Math.log(1 − ᾱ) is used with ᾱ limited to [1e-4, 0.999]. At the lower limit the subtraction's rounding of about 1e-16 is about 1e-12 of the result; Math.log1p is not used.

  • stat.js
  • lines 23 to 30
  • BimCraft 0.8.1
const SX = 2 * ly * lz, SY = 2 * lx * lz, SZ = 2 * lx * ly, S = SX + SY + SZ;
const A = (a, i) => a[i];
const notes = [];
const bands = BANDS.map((f, i) => {
  // mean absorption of each pair, area-weighted (opposite surfaces have the same area)
  const ax = (A(p.west, i) + A(p.east, i)) / 2, ay = (A(p.south, i) + A(p.north, i)) / 2, az = (A(p.floor, i) + A(p.ceiling, i)) / 2;
  const cl = (a) => Math.min(0.999, Math.max(1e-4, a)), air = env.air === false ? 0 : 4 * airM(f, env) * V;
  const lx_ = -Math.log(1 - cl(ax)), ly_ = -Math.log(1 - cl(ay)), lz_ = -Math.log(1 - cl(az));

Sabine, Eyring, Fitzroy and Arau-Puchades times

64-bit

The four reverberation times of the room in a band.

Sabine: 0.161 V ÷ (S ᾱ + A_air); Eyring: 0.161 V ÷ (−S ln(1 − ᾱ) + A_air); Fitzroy: 0.161 V ÷ S² × Σ Sᵢ ÷ (−ln(1 − ᾱᵢ)); Arau: Π [0.161 V ÷ (−S ln(1 − ᾱᵢ) + A_air)]^(Sᵢ ÷ S)

The constant is written 0.161. Sabine divides by S ᾱ + air with the mean absorption not clamped, so it is infinite when both are zero. The Arau product uses Math.pow with exponents Sᵢ ÷ S that add up to 1.

  • stat.js
  • lines 31 to 35
  • BimCraft 0.8.1
const aMean = (SX * ax + SY * ay + SZ * az) / S, sabine = K * V / (S * aMean + air), eyring = K * V / (-S * Math.log(1 - cl(aMean)) + air);
const fitzroy = K * V / (S * S) * (SX / lx_ + SY / ly_ + SZ / lz_);
const arau = Math.pow(K * V / (S * lx_ + air), SX / S) * Math.pow(K * V / (S * ly_ + air), SY / S) * Math.pow(K * V / (S * lz_ + air), SZ / S);
// air: the same term joins each pair's −ln(1−ᾱ_i) as air / S (so the sum reduces to Eyring-with-air when the pairs are equal)
const fz = air ? K * V / (S * S) * (SX / (lx_ + air / S) + SY / (ly_ + air / S) + SZ / (lz_ + air / S)) : fitzroy;

In detail

Method
Sabine T = 0.161 V ÷ (S ᾱ + 4mV); Eyring with −S ln(1 − ᾱ); Fitzroy (1959) and Arau-Puchades (1988) on the mean absorption of each pair of opposite surfaces, as the file's header cites them.
Number types
64-bit numbers.
Tolerances
Absorption is limited to between 1e-4 and 0.999 before a logarithm is taken. A note is raised when the pairs' absorption differs by more than a factor of 3.
Limits
The constant 0.161 is the conventional rounded value. The Sabine line uses the unclamped mean absorption, so zero absorption with no air term divides by zero.

Approach: 64-bit, stated limit

The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.

Every policy that takes this approach