Stage BG3: opt-in code-rule daylighting on BEMGen's geometry (design note)¶
Status: Done (D-233 to D-236, ADR-037) · Date: 2026-11-01 · Decided by: Cheng Xuan Li (the owner accepted issue F5 (b) of the 2026-10-31 review on 2026-11-01 with its method "all as proposed"); the controller (the realisation below where the method leaves it open) · Decisions: D-157, D-172, D-174, D-213, ADR-027 decision 4; new: D-233 to D-235 · Amends: D-174 (its "never" becomes the default) and ADR-027 decision 4
The review's issue F5 (b) asked whether BEMGen should ever write the daylighting controls that Program JSON carries (ZoneProgram.Daylighting). D-172 had written one reference point per glazed zone controlling the program's recorded fraction, and D-174 removed that writer ("no daylight dimming in IDF runs, ever"). The owner's method keeps D-174 as the default and adds an opt-in in which the program says whether and how and BEMGen's geometry says where.
1. The owner's method (F5 b)¶
- Whether and how: the program.
daylightingpresent or null; control type, setpoint, minimum input power and light output fractions, steps, availability, method (ZoneProgram.Daylighting, read as before). - Where: BEMGen's geometry. The 90.1 primary and secondary sidelit areas from each window's head height and width, and toplit areas under skylights, as openstudio-standards computes them for the prototypes. Per zone up to two
Daylighting:ReferencePoints at 0.8 m (one in the primary area, one in the secondary), each controlling its area's share of the zone;Daylighting:Controlswith SplitFlux; sun and sky from the EPW andSite:Location. - A zone without glazing gets no controls; a merged zone gets its daylit areas from its own geometry (the power-weighted fraction stays provenance only).
- The prototype fractions are a check, not an input (§5).
- Off by default; the LOD study keeps it off.
- Occupancy sensors and time switches: check whether PNNL models them as reductions in the lighting schedules or power densities (§6).
2. The code rule (D-233)¶
openstudio-standards is pinned in the atlas at c8c1b9ebb30c5f1a441231bf3eae76b18fbbe907 (its standards-controls build cache). The base methods (Standard#space_daylighted_areas, #space_add_daylighting_controls) are identical to the copy under data/raw/openstudio-standards; the edition methods are in standards/ashrae_90_1/ashrae_90_1_<edition>/ashrae_90_1_<edition>.Space.rb. BEMGen follows them as below (Lod.Core.Conversion.CodeDaylighting).
| Step | openstudio-standards | BEMGen |
|---|---|---|
| Primary sidelit area | per window: as wide as the window plus, each side, 2 ft (fixed, 90.1-2010) or half the head height (proportional, 90.1-2013, 2016, 2019); from the wall to one head height in |
the same, in the plane of the window's wall on the floor of the storey the window stands on |
| Secondary sidelit area | the same width, from one to two head heights in | the same |
| Toplit area | per rectangular skylight: grown on every side by 0.7 × its height above the floor | the same; BEMGen's skylights are rectangles |
| Net areas | united per kind; primary less toplit; secondary less toplit and primary; each on the space's floor | on the zone's floor: the union of its parts on each storey (so a merged zone takes its own geometry), the storeys added; a window belongs to the storey of the part hosting its wall (its outline under the window, its height holding the sill), a skylight to that of the part whose top is the roof and whose footprint holds it, so a part spanning another part's floor elevation keeps its own (D-236) |
| Required (2013 to 2019) | primary: ≥ 150 W of lighting in it and ≥ 20 ft² of window; secondary: ≥ 300 W in both sidelit areas and ≥ 20 ft² of window; toplit: ≥ 150 W in it | the same, with the zone's lighting power per floor area |
| Required (2010) | primary: ≥ 250 ft²; toplit: ≥ 900 ft² and skylight effective aperture ≥ 0.006; no secondary | the same; the sidelighting aperture exception applies only to buildings without a prototype type in openstudio-standards, so not here |
| Exceptions | Core_Retail: no primary, secondary flag for a second toplit point; Entry, Front_Retail, Point_of_Sale, strip malls: no sidelighting; apartments: none |
the same, by the space type in the program's space_types evidence |
| Sensors | the edition's space_daylighting_fractions_and_windows: which areas sensors 1 and 2 control and at which window or skylight; toplighting only in 90.1-2013+: one sensor in 6A, 6B, 7A, 8A, two of half the share elsewhere |
the same, with the program's climate zone; 90.1-2013 to 2019 with toplit and primary control required and secondary not have no branch in openstudio-standards' table, so no sensor: BEMGen keeps that parity, and the header says the controls are required and openstudio-standards places no sensor (D-236) |
| Office whole building | sensor 1 × psa_nongeometry_fraction, sensor 2 × ssa_nongeometry_fraction, only for Office WholeBuilding space types |
the same, from the program's standards_rule |
| Shares | rounded to three decimals; sensor 1 below 1 by 0.001, sensor 2 lowered so both stay below 1 | the same |
| Position | sensor 1 0.66 × head in from the window's centre, sensor 2 1.33 × head; under a skylight's centre; 2.5 ft above the floor | the same in plan, 0.8 m above the floor (the owner's height); a point that falls outside the zone's floor (a zone shallower than 1.33 head heights) moves to the interior point of its area, recorded in the header |
| Window order | facade (south, west, east, north), then name | facade by the wall's plan azimuth, then the building's surface order |
- The edition comes from the program's template (
source.template): 90.1-2010 has its own rule; 90.1-2013, 2016, and 2019 share one (their openstudio-standardsSpacemethods are identical). Other templates (IECC, DOE reference, 90.1-2004 and 2007, where openstudio-standards requires no controls) have no code rule: their controls are carried and never placed, with the warningDaylightingNoCodeRule. Astandards_rulewithdaylighting_appropriate: false(openstudio-standards'na) has no code rule either. - The settings are the program's: setpoint at both points, control type, minimum fractions, steps, method. Availability
all_days_except_design_daysis written blank (always), since the IDF runs no sizing periods, as D-172 did. The glare is computed at point 1, view along the zone's y axis, DGI 22; it controls nothing (no window shading control). - Merges. A merged zone takes its lead source's rule with its settings (
WithFraction, ADR-027 decision 4's rule); its areas come from its own geometry, and the power-weightedControlledLightingFractionstays provenance. Since D-236 the rule is not part ofSameSettings: two sources with the same written settings and different rules (90.1-2019 Banquet and Cafe, say) give noDaylightingSettingsDifferwarning but the infoDaylightingRuleDiffers, so the default-off path's warnings are those of before D-233.
3. Interfaces¶
IdfOptions.WriteDaylighting(false by default). Convert2IDF appends the input Daylighting (index 12,Dayl, Boolean, default false); the component's GUID is unchanged, and a Boolean input needs no new parameter type, so no new GUID.- The test-suite spec's
settings.daylighting(Boolean, default false) gives the option to every site. The LOD study's specs do not set it. - IDF header: without controls in any program nothing changes. With the option off,
Daylighting: not written (Convert2IDF's Daylighting option is off, the default; D-233); n zone(s) with controls in their programsand the infoDaylightingNotWritten. With it on,Daylighting: written by the code rule on BEMGen's geometry (D-233); k of n zone(s) …and one line per zone: its edition, areas, and points, or why none (no window or skylight; not required, with its lighting power and areas; no code rule). Provenance:DAYLIGHTING: …. - Program JSON: the preset's source gains
DaylightingRule(the rule, or why none), and its Left Out line says the controls are written only when Convert2IDF's Daylighting input is on. - EnergyPlus's warning
GetDaylightingControls: Fraction of zone or space controlled by the Daylighting reference points is < 1.0.is expected (ExpectedWarnings.PartialDaylightingControl) only for an IDF that holds aDaylighting:Controlsobject (ExpectedWarnings.ForIdf, used byeplus-checkand the batch runner);ExpectedWarnings.Defaultkeeps it unexpected. The export tests'IdfCheckskeep failing any daylighting object unless a test passesdaylighting: true. - With the option on, a zoning's lighting depends on its windows, so the evaluation metrics' pairing check (D-157) can report a site as unpaired on its internal loads; nothing else changes. This is why the LOD study keeps it off.
4. Tests (test first)¶
CodeDaylightingTests(Core, 31): rooms with one and two glazed walls, too little lighting, a skylight (by climate zone), toplit areas taken out of the sidelit ones, all three areas, no glazing, another zone's windows, a merged zone across its parts, a zone over two storeys, the office non-geometry fractions and where they do not apply, theCore_Retailexception, 90.1-2010's width, threshold, and two-window split, the 20 ft² window exception, the cap below 1, a point moved into its area, the templates with and without a rule. They failed to compile before the types existed (observed); the other new tests below were written before their code but first run after it, except the suite test, observed failing on the schema.DaylightingAndMainsAggregationTests.AMergeKeepsTheCodeRuleOfItsControls(Core).ReleaseTwoTests(ProgramJson, 4 new): the medium office's rule (90.1-2019, space type, 0.68 / 0.32, climate zone), the retail core's space type without non-geometry fractions, the IECC office without a rule, a space type where daylighting is not appropriate. The preset snapshotmedium-office-presetgains itsDaylightingRuleline (the only change).IdfCodeDaylightingTests(Export, 6): off by default with its header; on, every zone's objects equal the layout ofCodeDaylightingwith the program's settings and pass the daylighting checks; a windowless zone's header line; a program without a code rule warns; a building without controls is written byte for byte the same with the option on; an IDF with controls fails the default checks.IdfProgramJsonTeststakes the new header text.RunVerdictTests.TheDaylightingWarningIsExpectedOnlyForAnIdfWithDaylightingControls(Simulation).DoeSuiteTests.DaylightingIsWrittenOnlyWhenTheSpecAsksForIt(TestSuiteGenerator): it failed first on the schema (/settings/daylighting).CodeDaylightingEndToEndTests(Simulation, opt-inBEMGEN_ENERGYPLUS): the medium office program on the office plate, off and on, Chicago O'Hare TMY3, EnergyPlus 26.2.04bd7a1f26f: both runs completed with 0 severe and 0 fatal errors; the run with controls gave 3 warnings, allPartialDaylightingControl; interior lights 66 750.5 kWh off and 53 133.0 kWh on (20.4 % less), interior equipment 125 213.7 kWh both.- Every existing IDF snapshot is unchanged (no snapshot's programs carry controls).
5. The prototype check (D-235)¶
The DOE prototypes as BEMGen generates them (the suite generator's doe block, 90.1-2019, climate zone 5A, No Simplification and Stack, the option on), with the LOD study's pinned atlas inputs, except the medium office, whose keys all take the whole-building program (WholeBuilding - Md Office, as in the PNNL model). Against the PNNL 90.1-2019 prototype IDFs for Buffalo (5A), read with their table.htm zone summaries (zones in the floor area only):
| Prototype | Controlled floor fraction, BEMGen / PNNL | Controlled lighting fraction, BEMGen / PNNL | Zones with controls, BEMGen / PNNL |
|---|---|---|---|
| Medium office | 0.438 / 0.408 | 0.183 / 0.213 | 22 of 65 / 12 of 15 |
| Primary school | 0.748 / 0.748 | 0.408 / 0.460 | 18 of 25 / 18 of 25 |
| Stand-alone retail | 0.066 / 0.698 | 0.012 / 0.387 | 1 of 5 / 1 of 5 |
| Warehouse | 0.052 / 1.000 | 0.058 / 0.492 | 1 of 3 / 3 of 3 |
The four IDFs ran a year in EnergyPlus 26.2.0 on the Buffalo weather (eplus-check): all passed, 0 severe, the only expected warning PartialDaylightingControl.
Why they differ:
- Medium office. BEMGen's DOE medium office is the DOE reference layout of rooms (
medium-officelayout record, 65 zones) with the reference building's glazing, a window centred on each wall at 0.477 of its area (heads at about 3.1 m, against 2.33 m in the PNNL ribbon); the PNNL model has 15 perimeter and core zones with a 33 % ribbon window. The rooms with windows hold 0.438 of the floor, close to the PNNL perimeter's 0.408. The lighting share is lower, 0.183 against 0.213, because the code's power thresholds act on each zone: in BEMGen's small rooms the secondary area often carries less than 300 W (the conference rooms get one point only) and one classroom carries less than 150 W in its primary area, so they are not controlled, where the PNNL model's large perimeter zones always pass; the deeper primary areas of BEMGen's taller windows do not make up for it. - Primary school. The same 18 zones are controlled; the lighting share is lower, 0.408 against 0.460, from BEMGen's windows (one centred per wall at the reference ratio, heads at about 3.2 m) against the PNNL windows. It was not analysed zone by zone.
- Stand-alone retail and warehouse. The DOE reference records BEMGen's generators follow have no skylights in these types (
skylightRatio0), and the 2.0.0 atlas programs of the study carry no fenestration, so BEMGen's geometry has no toplit area; the 90.1-2019 PNNL models have skylights over the retail core and the warehouse's bulk and fine storage, which carry their controls. On BEMGen's geometry only the glazed front (retail, by theCore_Retailrule of its mixed program) and the office (warehouse) are daylit. This is a difference of the geometry's glazing, not of the rule; a program or spec that gives these keys the prototype's skylight ratio would give them toplit areas.
The rule is therefore checked where the geometry matches (the school's zones, the office's perimeter share), and the remaining differences are BEMGen's glazing, which the method deliberately uses.
6. Occupancy sensors and time switches (D-234)¶
Checked in the PNNL 90.1 medium office IDFs (Denver, 2004 to 2019) and the 90.1-2016 and 2019 IDFs of every type (Denver):
- In the lighting schedules. The occupied-hour values of the office lighting schedule fall from 0.9 (90.1-2004) to 0.885 × 0.9 (2010) and 0.8368 × 0.9 = 0.75314 (2013 to 2019); the atlas's 90.1-2019 medium office carries openstudio-standards'
OfficeMedium BLDG_LIGHT_SCH_2013(0.776 at weekday occupied hours), so the program already holds a schedule-based control credit. - In the power density. The 90.1-2019 IDF's parameters list
LPD_Ctrl = 0.02and its office LPD is 6.664 W/m²; the atlas program carries openstudio-standards' 6.889 W/m² (0.64 W/ft²). The difference is the atlas's to explain (its program values come from openstudio-standards, not from the PNNL IDF). - A gap: an occupancy-driven cap. The 90.1-2016 and 2019 PNNL models add an EMS program per zone in the office, restaurant, retail, strip mall, and warehouse types (2010 and 2013 have none): when the zone's occupant count is 0 and its lighting exceeds 0.02 W/ft², the lighting is set to 0.02 W/ft² (90.1's unoccupied lighting limit). Neither the atlas programs nor BEMGen carry it. Since BEMGen's occupancy is a deterministic schedule, it could be expressed as a schedule rule, but it changes the program's lighting, which is the atlas's to record (GLOBAL.md scientific rule 3: BEMGen does not change program assumptions). BEMGen adds nothing; the gap is reported to the owner for the atlas.
- Time switches appear only as the schedules above; there is no separate object.
7. Open¶
- The owner's choice for IECC programs: openstudio-standards has no IECC daylighting rule, so IECC controls are never placed (warning
DaylightingNoCodeRule). An IECC edition could take the 90.1-2019 rule by decision. Decided (D-248): they take it. - The atlas: the occupancy-driven unoccupied lighting cap of the 90.1-2016 and 2019 prototypes (§6), and the LPD difference.
- Rhino checks for the person: the smoke checklist's Convert2IDF daylighting items (
docs/development/grasshopper-smoke-test.md).