Resources Numerical accuracy Calculation policy

Rainfall run read-outs: deepest water and depth scale

The deepest-water figure, the depth scale of the picture, and the unit factors in the rainfall run window.

How the precision is kept

The rainfall solver keeps its water depth in 64-bit numbers, but the maximum depth map it hands back is a Float32Array. The window takes the deepest-water figure and the color scale top from that 32-bit map. Volumes, peak flow and pond figures come from 64-bit values and are only formatted here.

Open item. Keep the running maximum depth in a Float64Array in rain.js so the deepest-water figure is taken from 64-bit values, and write the inch factor as 1 / 0.0254.

Calculations under this policy

3 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.

rain-ui.js CivilCraft 0.8.1 32-bit in part 3 calculations Reviewed

Tests None found by the review

Depth, volume and flow unit factors

64-bit

Converts the solver's meters, cubic meters and cubic meters per second to the units the window shows.

mm = m × 1000; in = m × 39.3700787; yd³ = m³ ÷ 0.028316846592 ÷ 27; ft³/s = m³/s ÷ 0.028316846592

0.028316846592 is exactly 0.3048³, so the volume and flow factors are exact. The inch depth factor is rounded to 9 digits (39.3700787 against 39.37007874015748).

  • rain-ui.js
  • lines 25 to 27
  • CivilCraft 0.8.1
const dFromM = (d) => (M() ? d * 1000 : d * 39.3700787);
const cuOf = (m3) => (M() ? m3 : m3 / 0.028316846592 / 27), cuU = () => (M() ? 'm³' : 'yd³');   // i18n-ignore: unit symbols
const flowOf = (q) => (M() ? q : q / 0.028316846592), flowU = () => (M() ? 'm³/s' : 'ft³/s');   // i18n-ignore: unit symbols

Deepest water

32-bit in part

The deepest water anywhere in the run, as shown in the facts list.

deepest = max over cells of maxDepth, converted to mm or in

Every cell of res.maxDepth was stored as a 32-bit number in the solver before the maximum is taken here, so the figure carries about 7 digits. It is shown to 1 decimal.

  • rain-ui.js
  • line 173
  • CivilCraft 0.8.1
[t('eg.rain.f.deep'), fixed(dFromM(Math.max(...res.maxDepth)), 1) + ' ' + depthUnit()]].flatMap(([k, val]) => [el('span', { className: 'k' }, k), el('span', { className: 'v' }, val)]));

Depth scale of the picture

32-bit in part

The depth at which the picture reaches its deepest color, printed in the legend.

top = max(0.02, 99.5th percentile of wet maxDepth cells)

The values sorted are read from the 32-bit maximum-depth map and sampled at a stride of floor(cells ÷ 20000) when there are more than 20000 cells. The legend figure printed from it is therefore a sampled value of 32-bit numbers.

  • rain-ui.js
  • lines 190 to 194
  • CivilCraft 0.8.1
function percentile(arr, q) {
  const a = []; for (let k = 0; k < arr.length; k += Math.max(1, Math.floor(arr.length / 20000))) if (arr[k] > 0) a.push(arr[k]);
  if (!a.length) return 0.02;
  a.sort((x, y) => x - y); return a[Math.min(a.length - 1, Math.floor(q * a.length))];
}

In detail

Method
Maximum over the cells of the stored maximum-depth map, converted from meters to millimeters or inches; the scale top is the 99.5th percentile of the wet cells.
Number types
res.maxDepth is a Float32Array written in rain.js (this.maxDepth = new Float32Array(N)); the working depth this.h is a Float64Array. The factors are 64-bit numbers.
Tolerances
None. The scale top is never below 0.02 m.
Limits
The inch factor is written 39.3700787, which is 1 / 0.0254 cut to 9 digits (39.37007874015748), so inch depths carry a relative error of about 1e-9. The percentile reads at most about 20000 evenly spaced cells.

Approach: 32-bit step, flagged

One step stores or exchanges 32-bit values that reach a number a person reads. It is listed here with its open item, and the step is either moved to 64-bit or the app will warn where the number is read.

Every policy that takes this approach