Optimizer Documentation
Technical documentation for the capacity expansion optimization engine.
← Back to Grid Planner
|
Simulation Model Docs →
Table of Contents
1. Introduction
The optimizer performs least-cost capacity expansion planning under a CO2 emissions constraint. Given a target annual CO2 level (in million metric tons), it determines the optimal mix of new generation, storage, and carbon removal technologies to add to the existing grid that minimizes total annualized system cost while meeting the emissions target and reliability constraints.
Unlike Manual Mode, where the user adjusts technology sliders by hand and observes the impact, Optimize Mode automates this process. It runs hundreds of dispatch simulations internally, evaluating different capacity combinations to find the most cost-effective portfolio that meets the CO2 target.
Key outputs: Recommended capacity additions (GW or GWh per technology), total system cost ($/year), achieved CO2 emissions, reserve margin, curtailment rate, and a detailed cost breakdown including abatement costs.
Recent Updates (February 2026)
1. Deterministic Multi-Start Optimization: The optimizer now uses a seeded PRNG (Mulberry32) for full reproducibility. By default, 3 runs with different seeds (42, 137, 2024) are executed, and the best result is selected. This addresses non-determinism caused by the multimodal solution space.
2. Supply Curves for Resource-Constrained Technologies: Geothermal (0-2 GW: 1.0×, 2-4 GW: 1.3×, 4-5 GW: 1.6×) and Biomass (0-1.5 GW: 1.0×, 1.5-3 GW: 1.4×) now have stepped cost curves reflecting resource scarcity. Marginal CAPEX guides selection; blended CAPEX calculates total cost.
3. Tightened Resource Bounds: Geothermal max reduced from 20 GW to 5 GW (hydrothermal + EGS resource limit). Biomass max reduced from 20 GW to 3 GW (sustainable feedstock constraint).
4. Updated Solar & Wind CAPEX: Solar reduced from $1,200/kW to $800/kW (2025-2026 utility-scale market prices). Wind reduced from $1,500/kW to $1,200/kW. This significantly improves VRE competitiveness (solar LCOE ~$42/MWh, wind ~$41/MWh).
5. RNG & Hydrogen Dispatch Fix: Moved from inflexible (24/7 must-run) to flexible dispatch. They now respond to net load, operating only when needed, improving system efficiency and correctly counting toward reserve margin.
6. Inter-Day Storage Carryover: Long-duration storage (24-hr) can now carry state-of-charge across days with 1% monthly self-discharge, enabling multi-day energy shifting. Short-term batteries (4-hr, 8-hr) remain day-independent.
7. Storage Dispatch by Type: Each storage type (4-hr, 8-hr, 24-hr) now dispatches independently with type-specific parameters, replacing the previous pooled dispatch model.
8. Nelder-Mead Exploration: Simplex refinement now includes "exploration points" for up to 3 inactive technologies, allowing discovery of cost-effective technologies missed by the greedy search phase.
9. Bug Fixes: Corrected storage variable O&M double-counting, fixed SoC tracking (gross vs net charge), and reordered thermal dispatch (CCGT → Coal → CT).
2. Time Resolution & Demand Model
The model uses a 288-hour representative year, consisting of 12 months × 24 hours. Each month is represented by a single "typical day" of 24 hourly time steps. This compact representation captures seasonal and diurnal variation while keeping computation fast enough for interactive use.
To convert hourly simulation values to annual totals, each hour is weighted by the number of days in its month:
where:
| Month | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Days | 31 | 28 | 31 | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 31 |
Demand is provided as a 288-element array in GW (12 months × 24 hours). For California, the system uses direct CAISO-derived monthly profiles where each of the 12 months has a complete 24-hour demand pattern with realistic diurnal variation. For other regions, four seasonal base 24-hour shapes (spring, summer, fall, winter) are scaled by per-month multipliers to generate 12 monthly profiles, preserving backward compatibility while capturing month-to-month variation.
3. Technology Cost Model
3.1 Cost Data
Each technology has four cost parameters plus a lifetime. Users can edit these values in the "Edit Cost & Performance Assumptions" panel. Default values are:
| Technology | CAPEX | Fixed O&M | Variable O&M | Lifetime | Capacity Factor |
|---|---|---|---|---|---|
| Solar PV | $800/kW | $15/kW-yr | $0/MWh | 30 yr | 25% |
| Onshore Wind | $1,200/kW | $35/kW-yr | $1/MWh | 30 yr | 35% |
| Offshore Wind | $5,000/kW | $100/kW-yr | $0/MWh | 30 yr | 50% |
| Nuclear | $7,242/kW | $140/kW-yr | $10/MWh | 60 yr | 90% |
| Geothermal | $3,329/kW* | $120/kW-yr | $5/MWh | 30 yr | 90% |
| Biomass | $3,500/kW* | $100/kW-yr | $10/MWh | 25 yr | 85% |
| RNG (Biogas) | $3,000/kW | $95/kW-yr | $50/MWh | 25 yr | 85% |
| Hydrogen | $3,500/kW | $90/kW-yr | $410/MWh | 30 yr | 20% |
| Gas CCGT | $1,300/kW | $20/kW-yr | $35–80/MWh | 30 yr | 55% |
| Coal | $4,407/kW | $40/kW-yr | $30/MWh | 40 yr | 60% |
| Battery (4-hr) | $350/kWh | $15/kW-yr | $2/MWh | 15 yr | — |
| Battery (8-hr) | $300/kWh | $15/kW-yr | $2/MWh | 15 yr | — |
| Long-Duration (24-hr) | $300/kWh | $60/kW-yr | $1/MWh | 25 yr | — |
| DAC | $1,000/ton-yr | $20/ton-yr | $400/ton | 25 yr | — |
Note: Storage CAPEX is in $/kWh of energy capacity. DAC costs are per annual ton of CO2 capture capacity.
* Geothermal and Biomass use supply curves: CAPEX increases with deployment. Base costs shown; see section 3.2 Supply Curves for details.
3.2 Supply Curves for Resource-Constrained Technologies
Some technologies face increasing costs as deployment grows, reflecting resource scarcity and site quality degradation. The model implements supply curves for geothermal and biomass, where CAPEX increases in steps as cumulative capacity grows.
Geothermal Supply Curve
| Capacity Range | Cost Multiplier | Effective CAPEX | Marginal LCOE |
|---|---|---|---|
| 0-2 GW | 1.0× | $3,329/kW | ~$49/MWh |
| 2-4 GW | 1.3× | $4,328/kW | ~$64/MWh |
| 4-5 GW | 1.6× | $5,326/kW | ~$78/MWh |
The first 2 GW represents the best hydrothermal resources (The Geysers, Salton Sea). The 2-4 GW band captures good sites requiring deeper drilling and higher reservoir development costs. Beyond 4 GW, only marginal sites and enhanced geothermal systems (EGS) remain feasible, significantly increasing costs.
Biomass Supply Curve
| Capacity Range | Cost Multiplier | Effective CAPEX | Marginal LCOE |
|---|---|---|---|
| 0-1.5 GW | 1.0× | $3,500/kW | ~$54/MWh |
| 1.5-3 GW | 1.4× | $4,900/kW | ~$75/MWh |
The first 1.5 GW uses cheapest feedstocks: waste residues, agricultural waste, and forest thinnings with minimal transport costs. Beyond 1.5 GW, dedicated energy crops are required with longer transport distances, increasing both feedstock and logistics costs.
How Supply Curves Work
The optimizer uses two CAPEX values:
- Marginal CAPEX: Used in LCOE calculations to guide technology selection. This is the cost of the next GW at the current deployment level. For example, if 3 GW of geothermal is already deployed, the marginal CAPEX for the 4th GW is $4,328/kW (1.3× multiplier).
- Blended CAPEX: Used in total system cost calculations. This is the capacity-weighted average cost across all deployment bands. For example, if 3 GW is deployed, blended CAPEX = (2 GW × $3,329 + 1 GW × $4,328) / 3 GW = $3,662/kW.
This dual approach ensures the optimizer sees accurate marginal economics (guiding incremental decisions) while calculating correct total costs (reflecting what was actually paid for all deployed capacity).
3.3 Capital Recovery Factor (CRF)
Capital costs are annualized using the Capital Recovery Factor, which converts a lump-sum investment into equal annual payments over the asset's lifetime at a given discount rate:
where d is the discount rate (default: 7% = 0.07) and n is the asset lifetime in years.
For example, a solar plant (30 years, 7% discount): CRF = 0.07 × 1.0730 / (1.0730 − 1) ≈ 0.0806, meaning ~8.06% of capital cost is paid annually.
3.4 Annualized Cost Formulas
Generation Technologies (Solar, Wind, Nuclear, etc.)
Annual Fixed O&M = Capacity (kW) × Fixed O&M ($/kW-yr)
Annual Variable O&M = Annual Generation (MWh) × Variable O&M ($/MWh)
Total Annual Cost = Annual CAPEX + Fixed O&M + Variable O&M
Annual generation is computed by summing hourly dispatch across all 288 hours, weighted by days in each month.
Storage Technologies (Battery, Long-Duration)
Storage is specified in GWh of energy capacity. Power capacity is derived from the duration:
4-hr battery: Duration = 4 hours
8-hr battery: Duration = 8 hours
Long-duration: Duration = 24 hours
Annual CAPEX = Energy (kWh) × CAPEX ($/kWh) × CRF(d, n)
Annual Fixed O&M = Power (kW) × Fixed O&M ($/kW-yr)
Annual Variable O&M = Annual Discharge (MWh) × Variable O&M ($/MWh)
Round-trip efficiency for all storage types is 85%. This means for every 1 MWh charged, only 0.85 MWh is available for discharge.
Direct Air Capture (DAC)
Annual CAPEX = Annual Capacity × CAPEX ($/ton-yr) × CRF(d, n)
Annual Fixed O&M = Annual Capacity × Fixed O&M ($/ton-yr)
Annual Variable O&M = Annual Capacity × Variable O&M ($/ton)
3.5 Incentives
Government incentives reduce technology costs:
- Production Tax Credit (PTC): Applied as $/MWh to annual generation. Reduces the annual cost of the technology by
Annual Generation (MWh) × PTC rate. Available for solar, wind, offshore wind, nuclear, geothermal, biomass, RNG, and hydrogen. - Investment Tax Credit (ITC): Applied to storage. Reduces cost by
Energy Capacity (kWh) × CAPEX × ITC rate × CRF(annualized). - DAC Incentive: Per-ton subsidy that directly reduces DAC annual cost.
- Carbon Tax: Adds cost:
(Annual CO2 in kg / 1000) × Carbon Tax ($/ton). - Export Price: Curtailed energy can be "exported" at a given price (can be negative). Revenue =
Curtailment (GWh) × 1000 × Export Price ($/MWh).
3.6 Total System Cost
∑ Generation Tech Costs (CAPEX + Fixed O&M + Var O&M − PTC)
+ ∑ Storage Costs (CAPEX + Fixed O&M + Var O&M − ITC)
+ DAC Cost (CAPEX + Fixed O&M + Var O&M − DAC Incentive)
+ Carbon Tax Cost
− Export Revenue
This cost includes both existing baseline capacity and new additions. The optimizer minimizes this total while meeting the CO2 constraint.
4. Dispatch Simulation
Every candidate solution is evaluated by running a full hourly dispatch simulation (getSimulationResult). This determines how the grid operates each hour: which plants run, how storage charges/discharges, what gets curtailed, and the resulting emissions. The dispatch follows a merit order, prioritizing low-cost and zero-carbon sources.
Dispatch Order (each hour)
- Must-run baseload: Nuclear, geothermal, and biomass run at their capacity factor regardless of demand. Hydro runs at its country-specific capacity factor.
- Variable Renewable Energy (VRE): Solar and wind generation is computed as
Capacity (GW) × CF Profile[hour]. The CF profile varies by hour and month, capturing diurnal and seasonal patterns. - Net Load calculation:
Net Load = Demand − Must-run − VRE. If net load is negative, there is excess generation. - Storage dispatch: Storage operates via economic arbitrage. Short-term batteries (4-hr, 8-hr) charge/discharge within each day. Long-duration storage (24-hr) can carry state-of-charge across days with 1% monthly self-discharge, enabling multi-day energy shifting. All storage has 85% round-trip efficiency. The algorithm sorts hours by net load, identifying arbitrage opportunities (charge during excess generation, discharge during high net load) while respecting energy and power constraints.
- Flexible clean dispatch: RNG (biogas) and Hydrogen are dispatched only when net load is positive, operating as flexible zero-carbon resources. Unlike the old inflexible dispatch (24/7 must-run), they now respond to system needs.
- Thermal dispatch: Remaining net load (after storage and flexible clean) is met by fossil fuels in merit order: Natural Gas CCGT (cheapest) → Coal → Natural Gas CT (most expensive peakers). Each plant ramps between a minimum and maximum output, with the marginal cost increasing linearly as output increases.
- Curtailment: If total generation exceeds demand after all dispatch, the excess is curtailed.
Curtailment Rate = Curtailed Energy / (Total Generation + Curtailment).
4.1 Emissions Calculation
Hourly emissions are computed by multiplying each technology's generation by its emission factor:
| Technology | Emission Factor (kg CO2/MWh) |
|---|---|
| Natural Gas (generic) | 410 |
| Natural Gas CCGT | 370 |
| Natural Gas CT | 500 |
| Coal | 920 |
| Biomass | 50 (net, after regrowth offset) |
| All other (solar, wind, nuclear, etc.) | 0 |
Annual CO2 is then computed by summing hourly emissions weighted by days per month:
5. Optimization Algorithm
The optimizer uses a multi-start deterministic search consisting of three phases: (1) a heuristic initial guess, (2) an iterative neighbor-search main loop guided by system-value adjusted LCOE, and (3) a Nelder-Mead simplex refinement. This hybrid approach balances exploration (finding good regions of the solution space) with exploitation (fine-tuning the best solution found).
Multi-Start Approach
By default, the optimizer runs 3 independent optimization runs with different random seeds (42, 137, 2024), then selects the lowest-cost feasible solution. This multi-start approach addresses the fact that capacity expansion planning has a multimodal fitness landscape—many local minima with similar costs but different technology mixes. Running multiple trajectories significantly improves the chance of finding the global optimum (or a near-optimal solution).
All randomness is controlled by a seeded pseudo-random number generator (Mulberry32), ensuring that:
- The same seed produces identical results every time (fully reproducible)
- Different seeds explore different solution trajectories
- No dependence on browser-specific
Math.random()implementation
Randomness is used in five locations: perturbation technology selection, perturbation magnitude, random exploration candidate tech, random exploration step size, and panic mode technology selection (if reserve margin fails repeatedly).
5.1 Initial Guess Heuristic
Rather than starting from zero capacity, the optimizer estimates a reasonable starting point based on the CO2 reduction needed:
CO2 Reduction Needed = max(0, Baseline CO2 − Target CO2)
Total Clean Capacity Needed (GW) = CO2 Reduction / 1.1 × 109
(Empirical rate: ~1.1 million MT CO2 reduced per GW of clean capacity)
Initial Solar = min(100, 60% of Total Clean Capacity)
Initial Wind = min(80, 40% of Total Clean Capacity)
Initial Battery = min(50, 25% of VRE Capacity) [GWh, 4-hr]
Reserve Margin Gap Check
Before starting the main loop, the optimizer checks whether the existing grid plus the initial guess has sufficient flexible capacity. If the reserve margin target (20%) is not met, it adds:
- 80% of the gap as 4-hr battery (GWh = gap × 4 × 0.8)
- 15% as RNG
- 5% as Hydrogen
Adaptive Scaling
If a previous optimization overshot the target (CO2 came in >5% below target), the initial guess is scaled down to prevent the same overshoot. The scale factor is max(0.5, 1.0 − previousGapPercent/100), capping at 50% reduction.
5.2 Main Optimization Loop
The core loop runs up to 1000 iterations (configurable). Each iteration:
-
Compute system-value adjusted LCOE for each technology using
calculateMarginalLCOEWithSystemValue. This starts from the base LCOE but adjusts based on current system conditions:- If curtailment > 10%: VRE LCOE is penalized (solar ×(1 + curtailment rate), wind ×(1 + curtailment × 0.5), offshore ×(1 + curtailment × 0.3)) since adding more VRE will further increase curtailment.
- If reserve margin < target: Flexible technology LCOEs receive a 90% discount (multiplied by 0.1), and firm baseload (nuclear, geothermal) gets a 50% discount.
- If CO2 gap exists: All zero-carbon technologies get a 10% discount. If the gap is severe (>1.5× target), DAC gets a 30% discount.
-
Generate candidate solutions: Technologies are ranked by adjusted LCOE. For each technology (in LCOE order), candidates are generated by adding or subtracting a step size. Step sizes vary by technology:
Technology Step Size Unit Solar 1.0 – 5.0 GW Wind 1.0 – 5.0 GW Offshore Wind 0.5 – 2.0 GW Nuclear 0.5 – 2.0 GW Geothermal 0.5 – 1.0 GW Biomass 0.5 – 1.0 GW RNG / Hydrogen 0.5 – 2.0 GW Battery (4-hr / 8-hr) 2.0 – 10.0 GWh Long-Duration 5.0 – 20.0 GWh DAC 100 – 500 t/hr The step size adapts based on iteration count (larger early, smaller later) and system conditions.
- Quick feasibility pre-screen: Before running a full simulation, candidates are checked with a fast reserve margin estimate. Candidates that clearly fail are skipped.
- Full evaluation: Remaining candidates are evaluated via complete dispatch simulation, computing cost, CO2, reserve margin, curtailment, and energy balance.
- Selection: The best feasible candidate is selected. Under normal operation, the lowest-cost feasible solution wins. When the current best solution is >10% below the CO2 target, a weighted objective is used: 70% cost + 30% proximity to target, to push the solution back toward the target.
- Improvement check: An improvement is "meaningful" if cost improves by >0.01% or the CO2 gap narrows by >1%. If meaningful, the no-improvement counter resets. Otherwise, it increments.
5.3 Feasibility Constraints
A solution must pass all four constraints to be considered feasible:
| Constraint | Requirement | Tolerance |
|---|---|---|
| CO2 Target | Annual CO2 ≤ Target CO2 | 2% above target allowed |
| Reserve Margin | Flexible Capacity / Peak Demand − 1 ≥ 0.20 | None |
| Curtailment Cap | Curtailment Rate ≤ 20% | Only if enabled by user |
| Energy Balance | Unmet Energy < 10 MWh/yr | None |
The quick feasibility check only tests reserve margin (fast to compute). The full feasibility check tests all four constraints after running the complete dispatch simulation.
5.4 Convergence & Early Stopping
The optimizer stops when no meaningful improvement is found for a number of consecutive iterations:
- Normal convergence: 50 iterations with no meaningful improvement.
- Below-target mode: When the best solution's CO2 is >10% below target, the threshold increases to 200 iterations to allow the optimizer more time to find solutions closer to the target.
- Near-minimum capacity: If baseload capacity < 1 GW and total non-flexible capacity < 8 GW, the threshold reverts to 50 since we've hit a physical limit.
Perturbation (Escaping Local Minima)
After 30 iterations without improvement, the current solution is randomly perturbed. Each technology's capacity is multiplied by a random factor between 0.7 and 1.3 (up to ±30% change). This helps the optimizer explore different regions of the solution space.
5.5 Nelder-Mead Local Refinement
After the main loop converges, the best solution is refined using the Nelder-Mead simplex algorithm. This derivative-free optimization method works in the space of "active" technologies (those with non-zero capacity in the best solution), plus a limited set of inactive technologies for exploration.
Simplex Initialization
For N active technologies plus up to 3 inactive "exploration" technologies, a simplex of (N+M)+1 points is created. The first point is the current best solution. The remaining points are created by:
- Active tech points: Perturb each active technology dimension by ±0.5 GW (generation) or ±2.0 GWh (storage)
- Exploration points: Introduce small positive amounts of inactive technologies (1 GW for generation, 5 GWh for storage), allowing Nelder-Mead to discover cost-effective technologies that the greedy search phase missed
This enhancement addresses a limitation of the original algorithm: Nelder-Mead could only refine technologies already in the solution, never discovering new ones. By including exploration points, the refinement phase can now find and add previously unused technologies if they improve the objective.
Simplex Operations
Each iteration sorts the simplex by cost, then attempts to replace the worst point using these transformations:
Reflection: xr = c + α(c − xworst) [α = 1.0]
Expansion: xe = c + γ(xr − c) [γ = 2.0]
Contraction: xc = c + ρ(xworst − c) [ρ = 0.5]
Shrink: xi = xbest + σ(xi − xbest) [σ = 0.5]
The algorithm first tries reflection. If the reflected point is the best so far, it tries expansion. If reflection is worse than the second-worst, it tries contraction. If all fail, it shrinks the entire simplex toward the best point.
Convergence: The refinement stops when the cost range across the simplex (worst − best) is less than 1% of the best cost, or after 150 iterations.
6. Direct Air Capture (DAC)
DAC is a technology that actively removes CO2 from the atmosphere. In the optimizer, it acts as negative emissions.
When DAC is Enabled
DAC is only added to the candidate technology list when the CO2 target is aggressive: specifically, when the target is less than 60% of the baseline emissions. For easier targets, DAC is excluded because conventional clean generation is more cost-effective. DAC can also be manually disabled by the user via a checkbox.
LCOE Adjustments for DAC
When the CO2 gap is severe (>1.5× the target), DAC receives a 30% LCOE discount to make it more competitive. This reflects that DAC becomes increasingly valuable when other options are insufficient.
7. Reserve Margin
The reserve margin measures how much flexible, dispatchable capacity exceeds peak demand. It is a proxy for grid reliability—ensuring there is enough backup capacity for unexpected demand spikes or generator outages.
Target: ≥ 0.20 (20%)
What Counts as Flexible Capacity
| Resource Type | Capacity Credit | Notes |
|---|---|---|
| Fully Flexible (100% capacity credit) | ||
| Natural Gas (all types) | 100% | Fully dispatchable |
| RNG (Biogas) | 100% | Flexible dispatch (responds to net load) |
| Hydrogen | 100% | Flexible dispatch (responds to net load) |
| Hydro | 100% | Fully dispatchable |
| Battery Storage | Power capacity (GWh ÷ duration) | 4-hr: GWh/4; 8-hr: GWh/8; 24-hr: GWh/24 |
| Not Counted (Intermittent or Inflexible) | ||
| Solar, Wind, Offshore Wind | 0% | Intermittent generation (VRE) |
| Nuclear, Geothermal, Biomass, Coal | 0% | Inflexible baseload (24/7 operation) |
Example: A 100 GWh, 4-hour battery provides 25 GW of flexible power capacity toward the reserve margin.
8. Capacity Bounds
Each technology has minimum and maximum capacity limits. These prevent unrealistic solutions and keep the optimization space manageable:
| Technology | Min | Max | Unit |
|---|---|---|---|
| Solar | 0 | 100 | GW |
| Onshore Wind | 0 | 80 | GW |
| Offshore Wind | 0 | 50 | GW |
| Nuclear | 0 | 30 | GW |
| Geothermal | 0 | 5 | GW |
| Biomass | 0 | 3 | GW |
| RNG | 0 | 20 | GW |
| Hydrogen | 0 | 20 | GW |
| Battery (4-hr) | 0 | 100 | GWh |
| Battery (8-hr) | 0 | 100 | GWh |
| Long-Duration (24-hr) | 0 | 200 | GWh |
| DAC | 0 | 10,000 | t/hr |
These bounds represent new capacity additions only, not total installed capacity. Existing baseline capacity is separate.
9. Stranded Asset Detection
After optimization, the model checks whether existing fossil fuel capacity is underutilized. If the optimized grid's peak hourly usage of natural gas or coal is less than 80% of the installed capacity, the system flags these as potentially stranded assets.
When stranded capacity is detected, the user is offered the option to re-optimize with reduced fossil baseline. The suggested new capacity is set to 110% of the peak optimized usage (a 10% buffer). Reducing fossil capacity lowers Fixed O&M costs but may require additional flexible clean resources (batteries, RNG, hydrogen) to maintain the reserve margin.
10. Configuration Parameters
Optimization Configuration
| Parameter | Value | Description |
|---|---|---|
| MAX_ITERATIONS | 1000 | Maximum iterations in main loop |
| RESERVE_MARGIN_TARGET | 0.20 | 20% flexible capacity above peak demand |
| Discount Rate | 0.07 | 7% real discount rate for CRF |
| CO2 Tolerance | 2% | Solutions up to 2% above target are feasible |
| Curtailment Cap | 20% | Max allowed curtailment (if enabled) |
| Convergence Threshold | 50 / 200 | Iterations without improvement before stopping |
| Perturbation Trigger | 30 | No-improvement iterations before random perturbation |
| Nelder-Mead Iterations | 150 | Maximum iterations for local refinement |
| Storage Efficiency | 85% | Round-trip efficiency for all storage |
| Cache Precision | 0.1 GW | Solution hashing rounds to nearest 0.1 GW |
Monthly VRE Capacity Factor Profiles
Capacity factor profiles for solar, onshore wind, and offshore wind vary by month to capture seasonal patterns. Two approaches are used:
- California: Uses direct 12-month × 24-hour profiles extracted from CAISO 2025 Summer Assessment (Figures 2.4 & 2.5). Each month has a unique diurnal pattern with realistic shapes and all capacity factors ≤ 1.0.
- Other regions: Uses a base 24-hour profile scaled by monthly multipliers. All resulting CFs are capped at 1.0 via
Math.min(1, baseCF × multiplier).
California Monthly Profiles (CAISO-derived, rescaled to peak=1.0)
| Month | Solar Peak CF | Wind Peak CF | Offshore Wind Peak CF | Pattern Notes |
|---|---|---|---|---|
| January | 0.58 | 0.30 | 0.50 | 10 sun hours, winter-boosted offshore |
| February | 0.70 | 0.39 | 0.65 | 11 sun hours, strengthening wind |
| March | 0.81 | 0.57 | 0.80 | 13 sun hours, spring transition |
| April | 0.91 | 0.79 | 1.00 | 14 sun hours, wind ramping up |
| May | 0.98 | 0.91 | 0.93 | 15 sun hours, peak solar & wind correlation |
| June | 1.00 | 1.00 | 0.89 | 16 sun hours, strongest wind, reduced offshore |
| July | 0.96 | 0.79 | 0.80 | 15 sun hours, sustained summer peak |
| August | 0.91 | 0.66 | 0.76 | 14 sun hours, beginning descent |
| September | 0.83 | 0.63 | 0.72 | 12 sun hours, fall transition |
| October | 0.70 | 0.39 | 0.50 | 11 sun hours, weakening wind |
| November | 0.56 | 0.30 | 0.46 | 10 sun hours, winter approaching |
| December | 0.48 | 0.29 | 0.44 | 9 sun hours, winter minimum |
Key California pattern: Unlike most US regions, California wind is summer-peaking due to the coastal-to-inland thermal gradient driving strong winds through mountain passes (Tehachapi, Altamont, San Gorgonio). Both solar and wind peak in May–June (positively correlated). Offshore wind uses season-dependent transformation: winter-boosted (1.3×), summer-reduced (0.7×), then smoothed to reflect steadier marine winds. All profiles have been rescaled so the peak CF across all months equals 1.0, providing accurate relative seasonal variation while allowing maximum theoretical output during optimal conditions.
Default (other regions)
| Month | Solar | Onshore Wind | Offshore Wind |
|---|---|---|---|
| January | 0.60 | 1.15 | 1.15 |
| February | 0.70 | 1.10 | 1.10 |
| March | 0.85 | 1.05 | 1.05 |
| April | 0.95 | 0.95 | 1.00 |
| May | 1.05 | 0.90 | 0.95 |
| June | 1.15 | 0.85 | 0.90 |
| July | 1.15 | 0.80 | 0.85 |
| August | 1.10 | 0.80 | 0.85 |
| September | 0.95 | 0.85 | 0.90 |
| October | 0.80 | 0.95 | 1.00 |
| November | 0.65 | 1.10 | 1.10 |
| December | 0.55 | 1.15 | 1.15 |
In the default pattern, solar is strongest in summer and weakest in winter, while wind has the opposite pattern (strongest in winter). This seasonal complementarity is typical for most US and European regions.
Monthly Demand Profiles
Demand profiles vary by month to capture seasonal load patterns. Two approaches are used:
- California: Uses direct 12-month × 24-hour demand profiles derived from CAISO operational data. Each month has a complete hourly pattern with realistic diurnal variation, including subtle midday plateau characteristics.
- Other regions: Uses seasonal base 24-hour profiles (spring, summer, fall, winter) scaled by per-month multipliers. Each month maps to its season's shape, then is scaled by a multiplier to capture month-to-month intensity variation.
California Monthly Demand Profiles (CAISO-derived)
| Month | Peak Demand (GW) | Overnight Min (GW) | Pattern Characteristics |
|---|---|---|---|
| January | 29.5 | 19.3 | Moderate winter, evening peak |
| February | 28.0 | 18.2 | Mildest month (lowest peak) |
| March | 27.0 | 16.3 | Spring transition, lowest demand season |
| April | 26.5 | 16.4 | Annual minimum, mild spring weather |
| May | 31.0 | 17.5 | Warming, early AC usage begins |
| June | 38.5 | 21.7 | Early summer, AC demand rising |
| July | 45.0 | 25.3 | Peak summer heat, AC-driven evening peak |
| August | 46.5 | 26.2 | Hottest month (highest consistent peak) |
| September | 46.0 | 26.9 | Late summer heatwaves, volatile (historical record 52 GW) |
| October | 34.5 | 20.1 | Fall transition, cooling down |
| November | 29.0 | 18.5 | Cooling down, lower demand |
| December | 30.0 | 19.1 | Winter, holiday lighting and heating |
California pattern: Profiles exhibit subtle midday plateau (1-2 GW dip below morning peak) before the evening peak, characteristic of CAISO operational data. Demand follows a clear seasonal pattern: spring (March-April) represents the annual minimum at ~26-27 GW due to mild weather and high solar output offsetting daytime load. Summer months (July-September) show the highest peaks at 45-46 GW driven by air conditioning demand, with September being particularly volatile due to late-season heatwaves (CAISO's all-time record of 52 GW occurred in September 2022). Winter and fall months range from 28-35 GW. All values based on typical CAISO operational ranges.
Default (other regions)
For non-California regions, the system uses four seasonal base 24-hour profiles (spring, summer, fall, winter) scaled by per-month multipliers ranging from 0.92 to 1.11. This preserves backward compatibility while still capturing month-to-month demand variation.
Solution Caching
To avoid redundant dispatch simulations, the optimizer caches evaluation results. Solutions are hashed by rounding each technology's capacity to the nearest 0.1 GW (or GWh for storage, t/hr for DAC). If a solution with the same hash has been evaluated before, the cached result is returned directly. The cache is cleared at the start of each optimization run.