How the model works
← Back to the chartA look under the hood of the v2 engine that drives projection-mode Sankey charts — for the US and, since mid-2026, every individual state. Everything visible in this app — the lever sliders, the projection trajectories, the per-source tooltips — is computed from primitives shown here. Pick a section to explore.
Generation sources
Nine sources the engine knows about — Solar, Nuclear, Hydro, Wind, Geothermal, Natural Gas, Coal, Biomass, Petroleum. Each carries ~25 researched values (capex, fixed O&M, LCOE, capacity factor, retirement schedule, learning rate, …) drawn from NREL ATB, EIA, EPA eGRID, and peer-reviewed literature.
Submodels
Structural sub-models that override the simple per-sector monolithic growth math for high-leverage end-uses:
- Vehicle stock (D30 LDV + D31 HDV) — Bass-style S-curve adoption with fuel-price and policy feedbacks; LDV curve recalibrated to an AEO-vs-IEA midpoint (D85).
- Storage & VRE integration (D86–D90) — storage deployed on an LCOS-vs-value crossing, driven by a duck curve keyed on VRE capacity penetration; a vintage capacity stock (real EIA-860 install-year cohorts) tracks installed solar/wind GW.
- Hydrogen (D32, opt-in) — SMR vs electrolysis production split + sector demand.
- Data centers (D37) — logistic growth ramp into Industrial grid demand.
- Building heating (D102) — residential + commercial heat-pump stock turnover; carves space/water-heating fossil out of the CES and electrifies it at heat-pump COP (1 Q fossil → ~0.31 Q grid). On by default; reduces economy-wide CO₂. Per-state climate brackets since D107 (cold-cluster COP derate MN/WI/MI, warm-cluster FL/TX ahead of the US adoption curve).
Feedback loops
The engine isn't a one-pass calculation. A handful of loops connect per-year outputs back into next-year inputs:
- Wright's-law learning (D20/D34) — cumulative deployment shrinks per-source LCOE.
- Demand elasticity (D26) — sector demand responds to retail price changes.
- Battery-cost feedback (D27) — cheaper batteries decay the VRE integration penalty.
- Duck-curve coupling (D86/D87) — VRE capacity penetration deepens the duck curve, which both deflates VRE market value and raises storage's arbitrage value (LCOS-vs-value).
- Dispatch shift (D49) — natural gas absorbs coal-retirement gaps via existing-fleet utilization.
- Fuel-price elasticity (D68) — gasoline prices advance the BEV S-curve t_mid.
One loop the engine deliberately compresses: real-world interconnection queues, permitting, and equipment supply chains are modeled as per-source build caps (D44). The uncompressed version — who actually gates each step and why — is its own explainer: Gridlock: why it's hard to plug in.
Levers & scenarios
56 user-exposed levers across four families: generation (Wright's-law rates, retirement schedules, build caps), demand (per-sector growth + elasticity), T&D (per-ISO markups), and submodels (storage, vehicle stock, data centers, hydrogen, building heating). Defaults come from research; overrides land in a "basket" the engine consumes per-projection-year.
Wondering why even aggressive lever pulls move the projection gradually? The build caps are doing that on purpose — they compress the real world's interconnection queues, siting fights, and equipment backlogs into per-source annual limits. Gridlock: why it's hard to plug in maps that friction in full, including a "Speed it up" mode whose model-runnable fixes stage these very levers.
Policy layer
A closed-enum mechanism resolver (D29) that turns time-bounded
policies — federal IRA tax credits, state RPS targets, carbon
prices — into engine input adjustments. 15 mechanisms across
carrots (production credit, consumer credit, capex offset, …),
sticks (regulatory capex, excise tax, …), quantity constraints
(mandate floors, electrification mandates), and supply-chain
deployment capacity. Jurisdiction-aware: federal policies fire in
every region; a state policy fires at full strength in its own
state and in states that formally adopted it (§177-style
adoption_states), and at a researched spillover share
in the US aggregate.
State-scale modeling
Every state has a full historical Sankey (EIA SEDS, 2018–2023) and a committed default projection to 2050 — the same engine, re-grounded per state:
- Scaling & overrides (D62/D63) — US-aggregate submodel parameters scale by each state's load share; 31 states additionally declare researched overrides (tiered coal/nuclear retirement, BEV adoption — CA buys BEVs at ~3× the US rate — data-center concentration, build caps).
- Weather & resources (D91) — solar capacity factors follow each state's irradiance, wind follows its NREL wind class, and VRE cost scales inversely (AZ solar is cheap, WY wind is strong).
- Climate-bracket heating (D107) — the heat-pump submodel runs cold-climate physics in MN/WI/MI (seasonal COP ~2.3, adoption lagging the US curve) and warm-climate in FL/TX (COP ~3.5, heat pumps long dominant). The two extremes bracket the US average, so unlisted states inherit credible defaults.
- Interstate electricity trade (D105) — each state carries its real net position from SEDS: importers like CA show ~0.39 Q flowing in through Net Electricity Imports; exporters like PA/WY/WV send their surplus out through an Electricity Exports node (previously it was misrendered as waste heat). Traded electricity is counted with its embedded generation losses — the SEDS state-accounting convention — so the energy burden follows the buyer. Projections hold each state's position at its baseline, supply-clamped; a price-responsive exchange model was built and backtested but did not beat the baseline-anchored approach on 2018–2023, so it ships lever-gated off (D106).
A "sum of 50 states" aggregation mode exists as a validation harness (each state projected independently, every flow summed) — comparing it against the direct US projection is how per-state parameters earn their keep.
Research values & quality tiers
Every quantitative model input is wrapped in a ResearchedValue
(D21) with a quality tier:
- L1 primary (EIA / NREL / EPA / IRENA).
- L2 L1-derived (computed from primary inputs).
- L3 peer-reviewed literature.
- L4 transcribed unverified — triggers the "less-verified source" callout.
One accounting convention worth knowing: every CO₂ number in the app uses the fossil-combustion basis — biomass counts zero, matching the EIA / Ember / LLNL biogenic-zero convention every published benchmark uses. The physical biomass stack CO₂ (~93 Mt per Quad burned) is never hidden: it appears as an explicit "biogenic (not counted)" line on the impact card and the biomass tooltips (D104).
Decision history
The engine's architecture grew through 100+ numbered design
decisions (D1–D107 to date) recorded in DECISIONS.md.
Each entry carries the call, the rationale, and a review-by date
so the design stays auditable — including the negative results
(mechanisms built, backtested, and deliberately kept off).