From 43b0a8096c29496345c22ca5361c70fb03b4b3fa Mon Sep 17 00:00:00 2001 From: Chris Coey Date: Wed, 28 Oct 2026 00:41:33 -0700 Subject: [PATCH] Fix energy_grid_planning's substation capacity constraint The capacity constraint bound the upgrade and approval variables in its where clause, outside its sums over the substation's upgrades and requests. For each substation and investment level it therefore compared the sum of the upgrade variables times the sum of the upgrade capacities with the sum of the approval variables times the sum of the requested MW. Each upgrade's capacity and each request's MW is now weighted by its own variable. Listing InvestmentLevel in the objective's sum makes it say what the solver already computes, one term per request and level. The optimum moves from 1,579,200,000 to 1,562,600,000. The knee stays at $300M, now with 6 data centers, 1,530 MW and $252M net value: Google Metroplex and Lambda Labs at Dallas-Fort Worth are approved from $300M, and xAI Colossus at no budget. The README and runbook state the new results. --- energy_grid_planning/README.md | 16 ++++++++-------- energy_grid_planning/energy_grid_planning.py | 17 +++++++++-------- energy_grid_planning/runbook.md | 10 +++++----- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/energy_grid_planning/README.md b/energy_grid_planning/README.md index 787ab25c..a572937a 100644 --- a/energy_grid_planning/README.md +++ b/energy_grid_planning/README.md @@ -120,10 +120,10 @@ Texas is now the fastest-growing market for AI data center development. Hypersca ```text STAGE 5: OPTIMIZE -- Joint Interconnection + Upgrade - Status: OPTIMAL | Objective: 1,579,200,000 + Status: OPTIMAL + Objective: 1,562,600,000.00 - KNEE POINT: $300M -- 5 DCs, 1,500 MW, $264M net value - xAI Colossus ($105M/yr) unlocks at $300M -- highest-revenue single request + KNEE POINT: $300M -- $300M budget, $252,450,000 net value, 6 DCs, 1,530 MW PIPELINE COMPLETE: 5 stages executed on shared Energy Grid ontology ``` @@ -225,7 +225,7 @@ Three declarative rules consume upstream outputs, then a composite flag combines An `InvestmentLevel` Scenario Concept holds 5 budget levels ($200M-$600M), each parameterizing one MIP solve into a Pareto frontier. Binary variables `x_approve` (per DC request) and `x_upgrade` (per substation upgrade) are indexed by investment level; substation-capacity constraints use `predicted_load` from Stage 1 so the optimizer sees the same forecasted headroom as the rules engine, and budget constraints are scoped `.per(InvestmentLevel)`. Revenue reflects annual interconnection capacity revenue ($145K-$210K per MW/yr), not energy revenue. -One solve produces the entire frontier. The knee point at $300M (5 DCs, 1,500 MW, $264M net value) shows the highest marginal return, unlocking xAI Colossus ($105M/yr). At $200M, 4 DCs are approved (Microsoft, CoreWeave, Crusoe, Oracle); each additional $100M adds one more DC with diminishing returns ($995K/$M at the knee vs $400K/$M at $600M). Google Metroplex DC (400 MW) and Lambda Labs DFW (200 MW) are never approved at any budget — DFW capacity is fully consumed. Per-level results (approvals, upgrades, MW) are all queried from the ontology via `model.select()` rather than parsed from solver output. +One solve produces the entire frontier. The knee point at $300M (6 DCs, 1,530 MW, $252M net value) shows the highest marginal return: both DFW upgrades fit the budget, and Google Metroplex DC and Lambda Labs DFW join. At $200M, 4 DCs are approved (Microsoft, Amazon SA, Crusoe, Oracle); beyond the knee each additional $100M adds one more DC with diminishing returns ($1,013K/$M into the knee vs $439K/$M from $400M to $500M). xAI Colossus (500 MW) is never approved at any budget — DFW headroom goes to Google and Lambda. Per-level results (approvals, upgrades, MW) are all queried from the ontology via `model.select()` rather than parsed from solver output. See `energy_grid_planning.py` for the implementation of all five stages and `runbook.md` for the skill-driven reproduction. @@ -288,11 +288,11 @@ Focus on the first changes most users will make.
-Google and Lambda Labs are never approved at any budget level +xAI Colossus is never approved at any budget level -- Both target the Dallas-Fort Worth substation, which is already the only substation predicted to breach capacity (54.6% growth). -- Even with upgrades, DFW capacity is fully consumed by higher-revenue requests (xAI Colossus at 500 MW, $105M/yr). -- The optimizer correctly prioritizes revenue-maximizing allocations at the constrained substation. +- It targets the Dallas-Fort Worth substation, the only substation predicted to breach capacity (54.6% growth). Even with both DFW upgrades, DFW has 699.8 MW of headroom. +- That fits Google Metroplex DC and Lambda Labs DFW together (600 MW, $108M/yr) or xAI alone (500 MW, $105M/yr); xAI with Lambda would need 700 MW. +- The optimizer correctly prioritizes the revenue-maximizing allocation at the constrained substation.
diff --git a/energy_grid_planning/energy_grid_planning.py b/energy_grid_planning/energy_grid_planning.py index f1edcf3c..1c57a600 100644 --- a/energy_grid_planning/energy_grid_planning.py +++ b/energy_grid_planning/energy_grid_planning.py @@ -1010,17 +1010,18 @@ def _query_flag(relationship, flag_name): x_u_c = Float.ref("xu_c") effective_load = Substation.predicted_load | Substation.current_load_mw +# Each upgrade's capacity and each request's MW is weighted by its own variable. problem.satisfy(model.where( - DataCenterRequest.x_approve(InvestmentLevel, x_a_c), - SubstationUpgrade.x_upgrade(InvestmentLevel, x_u_c), + InvestmentLevel, DataCenterRequest.substation(Substation), - SubstationUpgrade.substation(Substation), ).require( Substation.max_capacity_mw - effective_load - + sum(x_u_c * UpgRef.capacity_increase_mw).where( - UpgRef.substation == Substation).per(Substation, InvestmentLevel) - >= sum(x_a_c * DCRef.requested_mw).where( - DCRef.substation == Substation).per(Substation, InvestmentLevel) + + sum(UpgRef, x_u_c * UpgRef.capacity_increase_mw).where( + UpgRef.substation == Substation, UpgRef.x_upgrade(InvestmentLevel, x_u_c), + ).per(Substation, InvestmentLevel) + >= sum(DCRef, x_a_c * DCRef.requested_mw).where( + DCRef.substation == Substation, DCRef.x_approve(InvestmentLevel, x_a_c), + ).per(Substation, InvestmentLevel) )) # C2: Budget per investment level @@ -1032,7 +1033,7 @@ def _query_flag(relationship, flag_name): # Objective: maximize total DC revenue across all levels problem.maximize( - sum(x_a * DataCenterRequest.annual_revenue_per_mw * DataCenterRequest.requested_mw).where( + sum(InvestmentLevel, x_a * DataCenterRequest.annual_revenue_per_mw * DataCenterRequest.requested_mw).where( DataCenterRequest.x_approve(InvestmentLevel, x_a) ) ) diff --git a/energy_grid_planning/runbook.md b/energy_grid_planning/runbook.md index b9382c4c..18e67b01 100644 --- a/energy_grid_planning/runbook.md +++ b/energy_grid_planning/runbook.md @@ -8,7 +8,7 @@ ERCOT processes 10 hyperscaler interconnection requests (2,930 MW) against a 12- ERCOT has 10 hyperscaler interconnection requests totalling 2,930 MW on a 12-substation grid where DFW is the binding capacity bottleneck. The chain produces a Pareto frontier across 5 budget levels — the knee at -$300M unlocks 5 DCs (1,500 MW, $264M net value) including xAI Colossus. +$300M unlocks 6 DCs (1,530 MW, $252M net value) including Google and Lambda at DFW. ───────────────────────────────────────────────────────────────── STAGE 1 Predictive ──► Substation.predicted_load (12) @@ -37,8 +37,8 @@ $300M unlocks 5 DCs (1,500 MW, $264M net value) including xAI Colossus. STAGE 5 Prescriptive ──► DataCenterRequest.x_approve (per InvestmentLevel) SubstationUpgrade.x_upgrade (per InvestmentLevel) OPTIMAL across 5 budget levels in one solve. - Knee $300M · 5 DCs · 1,500 MW · $264M net. - Google + Lambda never approved — DFW full. + Knee $300M · 6 DCs · 1,530 MW · $252M net. + xAI never approved — DFW headroom fits Google + Lambda. ───────────────────────────────────────────────────────────────── ``` @@ -152,7 +152,7 @@ OPTIMAL MIP across 5 `InvestmentLevel` values in one solve; `x_approve` and `x_u **Response** -Pareto frontier with knee at $300M (5 DCs, 1,500 MW, $264M net); marginal $995K/$M at knee, declining to $400K/$M by $600M; Google + Lambda never approved (DFW full). +Pareto frontier with knee at $300M (6 DCs, 1,530 MW, $252M net); marginal $1,013K/$M into the knee, declining to $439K/$M by $500M; xAI Colossus never approved (DFW headroom goes to Google + Lambda). ### 10. Persist solution concepts into the ontology @@ -164,7 +164,7 @@ Pareto frontier with knee at $300M (5 DCs, 1,500 MW, $264M net); marginal $995K/ **Response** -Ontology gains an `InvestmentPortfolio(InvestmentLevel)` Concept (5 rows, one per budget) with `dc_count`, `total_mw`, `annual_revenue`, `upgrade_cost`, `net_value`, `marginal_per_m_to_next_level`, `is_knee_point`. All five frontier rows — $200M ($165M net) → $300M ($264M net, knee) → $600M ($395M net) — are queryable as ontology rather than stdout. +Ontology gains an `InvestmentPortfolio(InvestmentLevel)` Concept (5 rows, one per budget) with `dc_count`, `total_mw`, `annual_revenue`, `upgrade_cost`, `net_value`, `marginal_per_m_to_next_level`, `is_knee_point`. All five frontier rows — $200M ($151M net) → $300M ($252M net, knee) → $600M ($398M net) — are queryable as ontology rather than stdout. ## Data