Is rainwater yield set by storage ratio rather than roof area?
Supplied working report; original verdicts not validated.
Review status: Needs review. This is an archival source note, not a passed proof.
Later supplied revision: code and scientific result payload changed since the inventory snapshot; this captured version has not been independently reviewed.
README.md
# Is rainwater yield set by storage ratio rather than roof area? **Incoprea hypothesis `rainwater-storage-demand`, Original Theories Volume X, entry 59.** Working test, October 2026. Not peer reviewed. AI-assisted. ## 1. The result in one paragraph In a 25-year model for 24 cities, the claim fails its decisive test. Across 1,728 configurations, storage ratio alone accounts for R² = 0.212 of reliability; catchment ratio — the roof-and-rainfall term the claim calls secondary — accounts for 0.656 (difference −0.444, 95% interval −0.616 to −0.201). With city fixed effects the standardised catchment coefficient (0.801) is twice the storage coefficient (0.346); in the claim's own terms roof area (0.397) exceeds tank volume (0.323). At fixed r = 0.25, mean reliability rises from 0.494 at 50 m² to 0.717 at 100 m² and 0.859 at 200 m² (200 − 50 = 0.365, interval 0.310 to 0.419). The all-city median curve never reaches 0.90 by r = 4.0 (maximum 0.803). Storage matters where c ≥ 1 (R² = 0.495 among 11 cities), but it is not the main term across climates. **Not supported as stated.** ## 2. What was tested Hypothesis: > "Rainwater harvesting yield is set by storage capacity relative to demand rather than by roof area." Mechanism: > "Yield depends on capturing events between draws; too little storage spills, and roof area only sets the upper bound." Predictions: > (1) "Yield should track the storage ratio." > (2) "Enlarging roofs without storage should add little." Refutation: > "Yield tracking roof area would remove the storage term." `hypothesis.md` fixed the model and criteria before simulation. Prediction 1 passes only if storage R² leads catchment R² by 0.10 and its standardised coefficient leads by 0.10. Prediction 2 passes only if, at r = 0.10, 0.25, 0.50 and 1.00, the 200 − 50 m² difference is at most 0.05 (interval upper bound 0.10). Refutation requires catchment R² to lead by 0.10, any fixed-r roof difference of 0.20, or a larger catchment coefficient. All three hold. ## 3. Method Daily precipitation for 24 cities on six continents comes from Open-Meteo (ERA5 reanalysis, UTC, 2000 to 2024, 9,132 days, no gaps). Climates span arid to boreal. Each configuration is one household tank: inflow = precipitation × roof × 0.85, with no first-flush or leaf loss. Roofs are 50, 100, 200 m²; tanks 0.5 to 20 m³; demand 100, 200, 300 litres/day. Reliability = 1 − unmet/total demand. r = V/(D×365/1000); c = (A × mean annual precipitation × 0.85)/(D×365). The main grid has 1,728 configurations; a 3,456-configuration probe sets r from 0.02 to 4.0 to locate thresholds; a 5,760-configuration regime grid maps r against c. Fits are OLS, the joint model with city fixed effects; intervals are cluster bootstraps over cities (2,000 resamples, seed 20261030). With simulated configurations, p-values are uninformative. ## 4. Result Joint R² is 0.778 without city effects and 0.903 with them; within-city R² is 0.383 for storage alone and 0.620 for catchment alone. `fig1_reliability_storage.png` shows median curves separating by roof area, with wide interquartile bands; `fig2_r2_comparison.png` gives the decisive bars. The all-city median never reaches 0.90 or 0.99; at r = 4.0 it is 0.803. Among 11 cities with c ≥ 1, median reliability reaches 0.90 at r = 0.131 but not 0.99 by r = 4.0 (maximum 0.989). Among 2 cities with c ≥ 1.5 the thresholds are 0.424 and 0.742. | Storage ratio | 50 m² | 100 m² | 200 m² | 200 − 50 (95% interval) | |---|---|---|---|---| | 0.10 | 0.463 | 0.658 | 0.790 | 0.327 (0.275 to 0.371) | | 0.25 | 0.494 | 0.717 | 0.859 | 0.365 (0.310 to 0.419) | | 0.50 | 0.511 | 0.751 | 0.898 | 0.387 (0.327 to 0.443) | | 1.00 | 0.516 | 0.759 | 0.907 | 0.391 (0.327 to 0.449) | Prediction 2 fails at every fixed ratio. At the smallest tank (0.5 m³), doubling roof from 100 to 200 m² adds 0.071; at the largest (20 m³), 0.147, a difference of 0.076 (0.030 to 0.126). Roof area matters more, not less, once storage can capture the water. ## 5. Where the claim holds and where it does not Reliability cannot exceed c: a roof cannot deliver more water than falls on it (maximum simulated violation 0.0). At r = 1, median reliability is 0.786 at c = 0.8 and 0.987 at c = 1.2. The smallest c at which the median city exceeds 0.90 is 0.970 (per-city 0.902 to 1.685). Median c at the reference roof and demand is 0.846, so that threshold does not exist. Where c ≥ 1 (800 configurations), storage R² is 0.495 and catchment R² 0.052: storage binds, and prediction 1 holds. Where c < 1 (928), storage R² is 0.120 and catchment R² 0.631: no tank compensates for a roof that collects less than demand. The reference slice (100 m², 200 litres/day) shows this weakly (0.191 against 0.516). `fig3_regime_map.png` maps the regions: high reliability needs c near or above 1 and enough storage. The mechanism survives; the comparison fails. Roof area imposes the upper bound, but that bound varies by more than an order of magnitude, so the roof term dominates a pooled test. ## 6. Sensitivity The ranking never changes. Storage-only R² is 0.199 with runoff 0.75, 0.224 with 0.95, 0.205 with seasonal demand (1.5 summer, 0.6 winter, normalised to mean 1), and 0.204 for 2010 to 2019; catchment R² is 0.670, 0.641, 0.682 and 0.662. Joint R² is 0.773 to 0.797, and roof area's standardised coefficient exceeds tank volume's in every run (0.420 against 0.303 at runoff 0.75). ## 7. What this test cannot see - Rainfall is ERA5 reanalysis on a grid, not a roof gauge; local extremes are smoothed. - Demand is constant in the main run, with one seasonal profile in sensitivity. - Water quality, treatment, first-flush and tank cleaning are absent; the model is generous to harvesting. - Costs, space, planning and maintenance are absent. - Overflow is modelled only as daily spill; real inlet and outlet behaviour is more complex. - The unit is one household; shared systems are outside the model. - No climate trend: 2000 to 2024 is treated as stationary; the 10-year window is a stability check. - The probe grid includes tanks and implied roofs beyond household scale (up to 13,083.8 m²); not installation advice. ## 8. Disclosure Designed and executed with AI assistance (DeepSeek), not peer reviewed. It is a simulation of a model household, not a measurement, and not engineering, financial or health advice. Code, hashes and every quoted number: `run.py`, `SOURCE.md`, `data.csv`, `results.json`.
hypothesis.md
# Hypothesis and pre-specified test plan
**Slug:** `rainwater-storage-demand`
**Source:** Incoprea research notebook, Original Theories, Volume X, entry 59.
**Test written:** 30 October 2026, before any simulation output was inspected.
This file fixes the model, the parameter grids, the outcome definitions, the
support/refute criteria and the analysis before the numbers are produced. Any
departure is reported in the README.
## The claim, quoted verbatim
> "Rainwater harvesting yield is set by storage capacity relative to demand rather than by roof area."
Mechanism:
> "Yield depends on capturing events between draws; too little storage spills, and roof area only sets the upper bound."
Predictions:
> (1) "Yield should track the storage ratio."
> (2) "Enlarging roofs without storage should add little."
Refutation:
> "Yield tracking roof area would remove the storage term."
## What is measured
"Yield" is operationalised as **reliability**: one minus total unmet household
demand divided by total demand over the full daily record. A secondary outcome
is the number and fraction of days on which no demand at all is met.
This is a simulation of a single household's daily water balance. Nothing here
measures an installed system, and no result is a causal estimate.
## Simulation (fixed before running)
Daily water balance, litres, one household:
- Catchment (projected roof) area `A` in {50, 100, 200} m²; `A = 100` is the
reference case.
- Runoff coefficient `0.85`. First-flush diversion and leaf/ gutter losses are
**ignored**; this makes the model generous to harvesting.
- Daily inflow (L) = `precip_mm × A × 0.85`.
- Tank capacity `V` in {0.5, 1, 2, 3, 5, 8, 12, 20} m³ (grid A).
- Constant daily demand `D` in {100, 200, 300} L/day. No seasonality in the
main run.
- Storage ratio `r = V / (D × 365 / 1000)` (tank volume as a fraction of one
year's demand).
- Catchment ratio `c = (A × mean annual precipitation_mm × 0.85) / (D × 365)`
(mean annual harvestable supply over annual demand). This is the roof-area
term.
Every day, in this order:
1. `accepted = min(inflow, V − stored)`; `spill = inflow − accepted`.
2. `stored = stored + accepted`.
3. `met = min(D, stored)`; `stored = stored − met`; `unmet = D − met`.
Initial storage is empty. The record is 2000-01-01 to 2024-12-31 (25 years,
9132 days). The first days are a spin-up in the sense that the tank starts
empty; no days are discarded, because a household tank genuinely starts empty
and the full-record denominator is fixed.
Two grids are pre-specified.
**Grid A (primary factorial, exactly the brief's grid).** `A` × `V` × `D` =
3 × 8 × 3 = 72 configurations per city. Used for all regression comparisons and
the roof-by-tank interaction.
**Grid B (storage-ratio probe).** Grid A tops out at `r = 0.548` (V = 20 m³,
D = 100 L/day), which cannot locate a 0.90 or 0.99 reliability threshold and
cannot reach the requested fixed ratios of 0.5 and 1.0. Grid B therefore sets
`r` directly on
`r ∈ {0.02, 0.05, 0.075, 0.10, 0.15, 0.20, 0.25, 0.30, 0.40, 0.50, 0.75, 1.00, 1.50, 2.00, 3.00, 4.00}`
with `V = r × D × 365 / 1000` m³, for the same `A` and `D` values. This is
3 × 16 × 3 = 144 configurations per city. Grid B volumes above 20 m³ exceed the
household tank envelope in Grid A; they are a model probe used only to locate
thresholds and regime boundaries, and the README says so.
## Analysis (fixed before running)
1. **Descriptive.** Reliability by storage ratio, pooled and per city. The
primary median curve is the median across the 24 cities at `A = 100`,
`D = 200` on Grid B (reference case). Find the smallest `r` at which this
median first reaches 0.90 and 0.99, by linear interpolation in `log10(r)`
between the bracketing grid points. If a level is not reached by `r = 4`,
record it as not reached rather than extrapolating. Report the same
thresholds for the subsets of cities with `c ≥ 1` and `c ≥ 1.5` at the
reference case, where storage rather than supply is the binding constraint.
2. **Decisive comparison.** On Grid A, pooled over city × A × V × D, fit by OLS:
reliability on `log10(r)` alone; on `log10(c)` alone; on both jointly; and on
both with city fixed effects. Report R² for each, standardised coefficients
in the joint models, and the difference in R² between the storage-only and
catchment-only models with a cluster bootstrap over cities. Also fit
reliability on `log10(V)` and `log10(A)` (the claim's own terms) with city
fixed effects, and report which standardised coefficient is larger. Report
n and note that p-values are not informative here.
3. **Prediction 2.** On Grid B, at fixed `r ∈ {0.10, 0.25, 0.50, 1.00}`, compute
mean reliability across cities and the three demand levels for `A = 50, 100,
200`; report the pairwise differences and their 95% cluster-bootstrap
intervals over cities (2000 resamples, seed 20261030). Separately report the
interaction on Grid A at `D = 200`: the reliability gain from doubling `A`
from 100 to 200 at the smallest tank (V = 0.5 m³) versus the largest
(V = 20 m³).
4. **Regime boundary.** At `r = 1` (Grid B formulation, `D = 200`, so
`V = 73 m³`), evaluate reliability on a common `c` grid
{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.5, 2.0, 2.5, 3.0,
4.0, 5.0}, with the implied roof area `A = c × 73 000 / (MAP × 0.85)` per
city. Report the smallest `c` at which the median across cities exceeds 0.90,
the per-city crossing values, and the hard model bound `reliability ≤ c`.
5. **Sensitivity.** Re-run Grid A with (i) runoff coefficient 0.75, (ii) runoff
coefficient 0.95, (iii) a seasonal demand profile for every city (1.5× in
the five summer months, 0.6× in the five winter months, 1.0× in the two
shoulder months, normalised to mean 1.0 over the record; northern summer is
May–September, southern summer November–March, Nairobi treated as southern),
and (iv) the 2010–2019 window instead of the full record. For each, report
the storage-only, catchment-only and joint R² and whether their ranking
changes.
6. **Statistical honesty.** Configurations are simulated, not sampled, so n is
large, p-values are near-zero and uninformative. Effect sizes, R² and
bootstrap intervals are reported instead. The uncertainty that matters is
model structure, not sampling error. All bootstrap draws are seeded
(20261030, 2000 resamples) and clustered on city.
## Support and refute criteria (fixed before running)
Let `R²r` be the storage-only R² and `R²c` the catchment-only R² on Grid A.
Let `βr` and `βc` be the standardised coefficients on `log10(r)` and `log10(c)`
in the joint model with city fixed effects. Let `Δ_A(r)` be the mean
reliability difference between `A = 200` and `A = 50` at fixed `r`.
**Prediction 1 is supported** only if both hold:
- `R²r − R²c ≥ 0.10`; and
- `|βr| − |βc| ≥ 0.10`, with `βr > 0`.
**Prediction 2 is supported** only if, at every one of `r = 0.10, 0.25, 0.50,
1.00`, `|Δ_A(r)| ≤ 0.05` and the upper bound of its 95% bootstrap interval is
≤ 0.10.
**Overall verdict.**
- *Supported*: predictions 1 and 2 both meet their criteria.
- *Refuted*: `R²c ≥ R²r + 0.10`, or `|Δ_A(r)| ≥ 0.20` at any of the four fixed
ratios (the opposite of prediction 2 by a wide margin), or `|βc| > |βr|` in
the city-fixed-effects joint model.
- *Partly supported*: anything else. In particular, the claim is partly
supported if storage dominates pooled R² but roof area still moves
reliability materially at fixed storage ratio, or if either prediction passes
and the other does not.
**Claim failure region.** The model implies `reliability ≤ c` for any storage:
if `c < 0.9`, reliability 0.90 is arithmetically impossible, and if `c < 1`,
full demand can never be met. Any configuration with `c < 1` is reported as a
supply-limited regime in which "storage is the only constraint" is false. The
claim is treated as holding only where `c ≥ 1` and `r` is large enough to
capture events between draws.
## Cities (fixed before fetching)
Twenty-four cities, six continents. Coordinates are the requested decimal
degrees passed to the API; the API's returned grid point is recorded in
`SOURCE.md`.
| City | Continent | Climate role | Lat | Lon |
|---|---|---|---|---|
| New York | North America | temperate humid | 40.71 | −74.01 |
| Los Angeles | North America | Mediterranean dry | 34.05 | −118.24 |
| Phoenix | North America | hot arid | 33.45 | −112.07 |
| Seattle | North America | temperate marine | 47.61 | −122.33 |
| Miami | North America | subtropical wet | 25.76 | −80.19 |
| Chicago | North America | continental | 41.88 | −87.63 |
| Mexico City | North America | tropical highland | 19.43 | −99.13 |
| São Paulo | South America | subtropical wet | −23.55 | −46.63 |
| Buenos Aires | South America | temperate humid | −34.60 | −58.38 |
| London | Europe | temperate marine | 51.51 | −0.13 |
| Madrid | Europe | Mediterranean dry | 40.42 | −3.70 |
| Rome | Europe | Mediterranean | 41.90 | 12.50 |
| Athens | Europe | Mediterranean dry | 37.98 | 23.73 |
| Berlin | Europe | continental | 52.52 | 13.41 |
| Stockholm | Europe | boreal | 59.33 | 18.07 |
| Cairo | Africa | hot arid | 30.04 | 31.24 |
| Nairobi | Africa | tropical highland | −1.29 | 36.82 |
| Cape Town | Africa | Mediterranean dry | −33.92 | 18.42 |
| Mumbai | Asia | tropical monsoon | 19.08 | 72.88 |
| Chennai | Asia | tropical monsoon | 13.08 | 80.27 |
| Beijing | Asia | continental monsoon | 39.90 | 116.41 |
| Tokyo | Asia | humid subtropical | 35.68 | 139.69 |
| Sydney | Oceania | humid subtropical | −33.87 | 151.21 |
| Perth | Oceania | Mediterranean dry | −31.95 | 115.86 |
Climates covered: arid (Phoenix, Cairo), Mediterranean (Los Angeles, Madrid,
Rome, Athens, Cape Town, Perth), monsoon (Mumbai, Chennai, Beijing), temperate
(New York, Seattle, Chicago, London, Berlin, Stockholm), tropical/subtropical
(Miami, Mexico City, São Paulo, Buenos Aires, Nairobi, Tokyo, Sydney) and
boreal (Stockholm). Twenty-four cities is a purposive climate span, not a
random sample.
## Data rules
- Open-Meteo historical archive, daily `precipitation_sum`, UTC, 2000-01-01 to
2024-12-31. One raw JSON per city, cached in `data/rainwater/` at project
root and hashed once.
- A city is excluded if the response is missing more than 1% of days; null
daily values are treated as 0.0 mm and counted. An excluded city reduces the
city count and is reported; it is not silently replaced.
- A failed fetch is reported and the test stops; no substitute dataset is used.
- ERA5 precipitation is a reanalysis, not a gauge. This is a limitation of the
test, not a detail to bury.
## Amendment log
- **Before the analysis run:** `r = 0.25` was added to the Grid B probe list
(making it 16 ratios and 144 configurations per city). The pre-specified
fixed-ratio comparison in analysis point 3 requires 0.25; omitting it from the
grid was a transcription error. No test statistic (R², threshold, bootstrap)
had been computed when the point was added.