AValidation record · Rev A · 2026-08
Daylight software usually asks you to trust it. We'd rather show the working. Below is the complete cross-validation of this engine against Radiance (the reference ray-tracer used in daylight research), exact analytic solutions, NREL's solar position algorithm, and the original published papers behind each metric — with the deviations, the method, and the one place the reference needed correcting.
Plus Part B, run live against Radiance and IfcOpenShell: the annual sDA/ASE metric matches Radiance two-phase exactly on the reference case; mesh and IFC per-point VSC agree to ≤ 0.27 pp on a real multi-storey building; and the reflected-light term is characterised in full and defaulted off.
BMethod
Radiance (official LBNL binaries): the same geometry rebuilt as Radiance polygons, illuminance ratios traced with rtrace at up to 10⁶ ambient divisions. Analytic solutions: where a closed form exists — the CIE overcast sky integrals, the Lynes average-DF formula, the SGHAT retinal-irradiance equation — we evaluate it exactly and require agreement to the last decimal. Published papers: Perez et al. 1993 coefficients, Wienold & Christoffersen 2006 (DGP), Ho et al. 2010/2011 (SGHAT) re-implemented independently from the tables in print.
Solar position is checked against NREL SPA (via pvlib) across random dates and latitudes. Weather-file ingestion is checked by round-tripping an EPW with a unique value encoded in every field of all 8,760 hours.
CResults — core daylight verbs
| Check | Reference | Result |
|---|---|---|
| VSC · unobstructed vertical, CIE overcast | Analytic quadrature + Radiance (pure CIE sky) | 39.6297 vs 39.6177 vs 39.6263 % — spread 0.012 pp |
| VSC · five obstructed wall cases | Radiance, physical wall geometry | max dev 0.13 pp; BRE unobstructed-denominator convention confirmed |
| VSC · 3D mesh ray-cast, 3 scenes | Radiance, identical triangles | max dev 0.09 pp |
| Average daylight factor (Lynes) | Closed form + published worked example | exact (3.7778 %; worked example 2.4267 %) |
| Perez all-weather sky luminance | Published 1993 coefficient table, independent code | ≤ 0.25 % relative; coefficients a–e match to 4 decimals |
| Perez vs gendaylit | Radiance gendaylit sampling | ≤ 3.5 %, attributable to gendaylit's sampling implementation |
| Glare (DGP) | Wienold & Christoffersen 2006, independent evaluation | agreement ≤ 3×10⁻⁵ DGP units |
| Ocular hazard (SGHAT) | Ho et al. closed form + paper worked example | exact: Er 8.004 W/cm², burn threshold 12.69 vs paper ≈12.7; dp², τ and radiance-invariance laws verified |
| EPW ingestion | Identity-encoded synthetic 8,760-hour file | exact field-level round-trip; illuminance fields read as illuminance |
| Annual sDA/ASE vs Radiance two-phase | Radiance gendaymtx + rfluxmtx daylight-coefficient run, Denver TMY3 | reference room, R = 0: exact aggregate and point-count agreement — sDA 22.22 %, ASE 22.22 % (8/36 both) |
| Reflected-light (IRC) term vs Radiance multi-bounce | Radiance -ab 6, reference room, per-point DF | sky component exact (+0.07 % at R = 0); reflected term over-predicts +6 % at R = 0.3 and +38 % at R = 0.6 — refl = 0 by default |
DResults — BRE 209 battery
| Check | Reference | Result |
|---|---|---|
| Solar position · 24 random datetimes, ±60° lat | NREL SPA (pvlib) | max dev 0.011° |
| Per-point VSC on meshes · 3 scenes | Radiance + the production engine, same triangles | ≤ 0.20 pp vs Radiance; ≤ 0.24 pp vs engine — three independent ray-casters agree |
| No-sky-line map · 36-point room grid | Radiance per-point sky visibility | 36/36 booleans identical |
| DF grid · window room, 16 points | Radiance per-point (R = 0) | mean dev 0.8 % rel; max 0.14 pp |
| Sun visibility (APSH core) · 25 sampled hours | Radiance direct-only oracle | 0 mismatches |
| APSH plane-partition identity | Physical necessity | opposite windows sum to 100.00 % of sunny hours |
| Garden 2-hour test | Behavioural battery | open ground 100 %; obstruction response and verdicts correct |
| Input strictness | — | unknown parameters are hard errors, never silently ignored |
EMethodological notes
Radiance's stock sky blends luminance toward the ground brightness near the horizon — exactly the band a vertical window weights most. Used naively it reads VSC ≈ 39.10 % for the unobstructed case: a spurious −0.5 pp bias against any engine under test. Our reference supplies the pure CIE overcast distribution (skybr = if(Dz,(1+2·Dz)/3,0)), which agrees with the exact integral to 0.01 pp. If you validate daylight software, this footnote is yours to keep.
A "sunny hour" is an EPW hour with DNI ≥ 120 W/m² — the WMO sunshine-duration threshold. Winter is 21 September to 21 March. An hour is received when the sun is above the horizon, in front of the window plane, and the ray to the sun is unobstructed by site geometry. Every verb's output names its definitions so a report can cite them.
FContinuous checking
Both harnesses run against every engine release. If a rebuild moves any number past its threshold, the release doesn't ship. The thresholds:
| Metric | Ship threshold vs reference |
|---|---|
| VSC / sky component (analytic or Radiance) | ≤ 0.2 pp |
| Mesh ray-cast VSC, identical geometry | ≤ 0.3 pp |
| Formula metrics (ADF, DGP, SGHAT) | exact |
| Solar position vs SPA | ≤ 0.05° |
| DF grid vs Radiance (R = 0) | ≤ 5 % relative on mean |
| Annual sDA/ASE vs Radiance two-phase (reference room, R = 0) | exact — 22.22 %/22.22 %, 8/36 both |
Published and stated openly: the annual sDA/ASE cross-check against a Radiance two-phase simulation matches exactly on the reference case — aggregates and per-point counts — on Denver TMY3 at R = 0. Scope is honest: one room, one climate, R = 0. The reflected-light (IRC) term at R > 0 over-predicts (+6 % at R = 0.3, +38 % at R = 0.6 on the reference room), so refl defaults to 0 for conservative screening; over-predicting daylight is anti-conservative for adequacy claims.