The electricity model is formulated as a least-cost optimization problem to meet electricity demand with generation from multiple technology options. It includes both electricity dispatch and the option for capacity expansion. Users can also specify various power sector operations they would like to represent, for example, capabilities for representing capacity reserves, operating reserves, and ramping constraints, as well as others that will be described in more detail below.
The model has both temporal and spatial flexibility, which can be specified by the user depending on the purpose of a study. The temporal flexibility includes the ability to specify both the years and the time segments within a year, with the finest granularity available being 8760 hours annually. The 8760 hours within a year can be aggregated up by hours within a day as well as days within a season. If a user is running the model for more than one year, the user can choose how non-modeled intervals between years are aggregated. In terms of spatial flexibility, users can specify which regions they want to run and if regions have the capability to trade with one another.
The model uses linear optimization by default, but if running the model with capacity expansion, a user has the option of representing cost reductions using a nonlinear technology learning function. This function can be modeled endogenously, by either turning the problem into a nonlinear program, or by running successive iterations of linear programs over a fixed nonlinear learning function. Users can also specify which technology options are allowed to expand or retire.
After completing a run, the module will return datasets in the output directory for the variables, parameters, sets, and constraints. These datasets will be stored in the output directory at the top level. The viewer within the output directory includes options for reviewing electricity model variable results. If running the model in standalone mode, the model will also produce a graphic showing the distribution of electricity prices within the output directory.
The data needed for the electricity model is stored within the input directory in the capacity expansion model e.g., cem_input subdirectory. The inputs include regionally indexed and technology indexed input assumptions data for items like transmission and technology costs and operations. In addition, there is supply curve price and quantity data that provides the fuel cost assumptions for each power technology.
The data is prepared within the preprocessor.py file within the scripts directory. The preprocessor script creates an initial sets class for the model, based on the setting data provided by the integrator code. Sets are organized into regional sets, temporal sets, and technology-based sets. Next the preprocessor reads in all of the input data within the cem_inputs directory and processes it into the format needed for the PowerModel based on the spatial and temporal settings specified. When the preprocessor is finished, it passes a dictionary of input data as well as the sets class to the PowerModel for further processing.
There are several files where features can be switched (sw) on/off and different crosswalks (cw) can be selected. All of these options exist in run_config.toml file the integrator directory.
The run_config.toml file contains the main switches through which features for the electricity module can be toggled. The setup column names various constraint settings:
Switch | Description | Values | Notes |
---|---|---|---|
sw_trade | Interregional trade | 0 = Off 1 = On |
|
sw_expansion | Capacity expansion/retirement | 0 = Off 1 = On |
Note the file cem_inputs/AllowBuilds.csv also contains settings of which technologies are available to expand. cem_inputs/AllowRet.csv contains which technologies have the option to economically retire. |
sw_agg_year | Aggregate years | 0 = Only runs sw_year 1 = Aggregates all unselected years into subsequent selected year |
Switch to aggregate years based on the selected years in sw_year.csv |
sw_rm | Reserve margin requirement | 0 = Off 1 = On |
|
sw_ramp | Maximum ramping constaint | 0 = Off 1 = On |
|
sw_reserves | Operating reserve requirement | 0 = Off 1 = On |
|
sw_learning | Technology cost learning | 0 = Exogenous learning 1 = Iterative linear learning 2 = Nonlinear learning |
The method of which technology costs decrease as more capacity is built. Note this switch does nothing unless sw_expansion=1 |
The model contains 14 power technologies (pt) in its initial layout. Users could change the technology assignments and add more technology types or remove technology types, but any changes to the code would require updates to the cooresponding input data. The technologies represented include:
1.) Coal Steam
2.) Oil Steam
3.) Natural Gas Single-Cycle Combustion Turbine
4.) Natural Gas Combined-Cycle
5.) Hydrogen Turbine
6.) Nuclear
7.) Biomass
8.) Geothermal
9.) Municipal-Solid-Waste
10.) Hydroelectric Generation
11.) Pumped Hydroelectric Storage
12.) Battery Energy Storage
13.) Wind, Offshore
14.) Wind, Onshore
15.) Solar (step 1 = utility-scale; step 2 = end-use)
The power technologies (pt) are also combined into group based on the applicability of different constraints. These groups are defined in pt_subsets.csv within the electricity/input directory and includes:
- ptc: conventional
- ptr: renewable
- pth: hydroelectric
- pts: storage
- pti: intermittent
- ptw: wind
- ptsol: solar
- pth2: hydrogen
- ptd: dispatchable
- ptg: generating
When the capacity expansion switch is turned on, a user can select which technologies they want to have expansion and retirement capabilities. Turning these switches on allows for builds and/or retirements of a given technology and supply curve step. These files are located in the electricity/input directory.
Switch | Description | Values | Notes |
---|---|---|---|
sw_ptbuilds | Contains switches for technologies and supply curve steps where capacity is allowed to build | 0 = Not Allowed to Build 1 = Allowed to Build |
Switches contained in Sw_ptbuilds.csv |
sw_ptretires | Contains switches for technologies and supply curve steps where capacity is allowed to retire | 0 = Not Allowed to Retire 1 = Allowed to Retire |
Switches contained in Sw_ptbuilds.csv |
Set | Code | Data Type | Short Description |
---|---|---|---|
hr | Set | All representative hours | |
y | Sparse set | All selected model years | |
s | Set | All seasons | |
day | Set | All representative days | |
r | Set | All selected model domestic regions | |
r | Set | All selected model international regions | |
demand_balance_index | Sparse set | All load sparse set | |
generation_total_index | Sparse set | All non-storage generation sparse set | |
H2GenSet | Sparse set | All hydrogen generation sparse set | |
StorageSet | Sparse set | All storage set | |
unmet_load_index | Sparse Set | All unmet load set | |
capacity_total_index | Sparse Set | Existing capacity set | |
generation_dispatchable_ub_index | Sparse Set | Dispatchable technology generation upper bound set | |
generation_vre_ub_index | Sparse Set | Intermittent technology generation upper bound set | |
generation_hydro_ub_index | Sparse Set | Hydroelectric generation upper bound set | |
capacity_hydro_ub_index | Sparse Set | Hydroelectric generation seasonal upper bound set | |
capacity_retirements_index | Sparse Set | Retirable capacity set | |
BuildSet | Sparse Set | Buildable capacity set | |
capacity_builds_index | Sparse Set | Set of capacity costs | |
CapCostInitial_index | Sparse Set | Set of initial year's capacity costs | |
storage_first_hour_balance_index | Sparse set | First hour storage balance set | |
storage_most_hours_balance_index | Sparse set | (non-first hour) storage balance set | |
reserves_procurement_index | Sparse set | Set for procurement of operating reserves | |
generation_ramp_index | Sparse set | Set for ramping | |
ramp_first_hour_balance_index | Sparse set | Set for ramping in first hour of each representative day | |
ramp_most_hours_balance_index | Sparse set | Set for ramping in non-first hour of each representative day | |
trade_interregional_index | Sparse set | Domestic interregional trade set | |
trade_interational_index | Sparse set | International interregional trade set | |
TranLimitInt_index | Sparse set | International interregional trade limit set | |
TranLimit_index | Sparse set | Domestic interregional trade limit set | |
TranLineLimitInt_index | Sparse set | International interregional trade line limit set |
These sets are re-indexed for specific constraints. They are all sub-sets accessed by certain indicies to return the remaining indicies.
Set | Code | Data Type | Short Description |
---|---|---|---|
H2GenSetByHour | Sparse subset | Set for H2 generation indexed by hour | |
GenSetByHour | Sparse subset | Set for generation indexed by hour | |
StorageSetByHour | Sparse subset | Set for storage indexed by hour | |
GenSetDemandBalance | Sparse subset | Set for generation indexed by y,r,h | |
StorageSetDemandBalance | Sparse subset | Set for storage indexed by y,r,h | |
TradeSetDemandBalance | Sparse subset | Set for trade indexed by y,r,h | |
TradeCanSetDemandBalance | Sparse subset | Set for international trade indexed by y,r,h | |
WindSetReserves | Sparse subset | Set for wind generaton for operational reserves indexed by y,r,h | |
SolarSetReserves | Sparse subset | Set for solar capacity for operational reserves indexed by y,r,h | |
ProcurementSetReserves | Sparse subset | Set for procurement of operating reserves for operational reserves indexed by y,r,h | |
SupplyCurveRM | Sparse subset | Set for supply curve for reserve margin indexed by y,r,seas | |
HourSHydro | Sparse subset | Set for hours indexed by season |
Note: the existing code shows cost units in MW/MWh instead of GW/GWh; we are aware and just haven't updated the code yet.
Parameter | Code | Domain | Short Description | Units |
---|---|---|---|---|
y0 | First year of model | unitless | ||
num_hr_day | Number of representative hours in a representative day | unitless | ||
Load | Electricity demand | instantaneous GW | ||
SupplyCurve | Existing capacity (prescribed or initial) | GW | ||
SupplyPrice | Fuel + variable O&M price | $/GWh | ||
SolWindCapFactor | Intermittent technology maximum capacity factor | fraction | ||
HydroCapFactor | Hydroelectric technology maximum capacity factor | fraction | ||
StorageLevelCost | Cost to hold storage (mimics losses) | $/GWh | ||
StorageEfficiency | Roundtrip efficiency of storage | fraction | ||
HourstoBuy | Storage duration | hours | ||
UnmetLoadPenalty | Unmet load penalty | $/GWh | ||
year_weights | number of years represented by a representative year (weight) | years/representative years | ||
Hr_weights | number of hours represented by a representative hours(weight) | hours/representative hours | ||
Idaytq | number of days representated by a representative day (weight) | days/representative day | ||
Map_hr_d | map representative hour to representative day | unitless | ||
WeightSeason | number of hours (per year) in a season (weight) | unitless | ||
Map_hr_s | map representative hour to season | unitless | ||
FOMCost | Fixed O&M cost | $/GW-year | ||
CapacityCredit | Capacity credit | fraction | ||
ReserveMargin | Reserve margin requirement | fraction | ||
RampUpCost | Ramp up cost | $/GW | ||
RampDownCost | Ramp down cost | $/GW | ||
RampRate | Max ramp rate | GW | ||
TranLimit | Domestic interregional trade line limit | GW | ||
TranLimitGenInt | International interregional trade limit | GW | ||
TranLimitCapInt | International interregional trade line limit | GW | ||
TranCost | Transmission hurdle rate (cost) | $/GWh | ||
TranCostInt | International transmission hurdle rate (cost) | $/GWh | ||
TransLoss | Transmission line losses from 1 region to another | fraction | ||
RegReservesCost | Cost of operating reserve procurement (TODO: update this in code so it contains all optypes) | $/GWh | ||
ResTechUpperBound | Maximum amount of capacity which can be used to procure operating reserves | fraction | ||
H2_heatrate | Hydrogen heatrate | kg/GWh | ||
H2Price | Hydrogen fuel price. Mutable parameter. | $/kg | ||
CapCostLearning | Cost of capacity based on technology learning. Mutable parameter. | $/GW | ||
CapCostInitial | Initial year's capacity cost to build | $/GW | ||
LearningRate | Learning rate factor | unitless | ||
SupplyCurveLearning | Learning rate factor | unitless |
Variable | Code | Domain | Short Description | Units | Switch notes |
---|---|---|---|---|---|
storage_inflow | Storage inflow | GW | |||
storage_outflow | Storage outflow | GW | |||
storage_level | Storage level (state-of-charge) | GWh | |||
generation_total | Instantaneous generation | GW | |||
unmet_load | Unmet load | GW | |||
capacity_total | Total capacity | GW | |||
capacity_builds | New capacity built | GW | Only created if sw_expansion=1 | ||
capacity_retirements | Retirement capacity | GW | Only created if sw_expansion=1 | ||
trade_interregional | Interregional trade from region |
GW | Only created if sw_trade=1 | ||
trade_interational | International interregional trade from region |
GW | Only created if sw_trade=1 | ||
generation_ramp_up | Ramp up (increase in generation for dispatchable cap) | GW | Only created if sw_ramp=1 | ||
generation_ramp_down | Ramp down (decrease in generation for dispatchable cap) | GW | Only created if sw_ramp=1 | ||
reserves_procurement | Operating reserves procurement amount | GW | Only created if sw_reserves=1 | ||
storage_avail_cap | Available storage capacity to meet the reserve margin | GW | Only created if sw_rm=1 |
Objective is to minimize costs to the electric power system. Costs include dispatch cost (e.g., variable O&M cost), fixed operation and maintenance (FOM) cost, capacity expansion cost component (nonlinear and linear options available), interregional trade cost, ramping cost, operating reserve cost and unmet load cost (note: unmet load cost should equal zero).
Minimize total cost ($)
where:
Dispatch cost:
Unmet load cost:
Capacity expansion cost:
Fixed O&M cost:
Interregional trade cost:
Ramping cost:
Operating reserve cost:
Balance constraints exist for generation as well as energy storage. For demand, this means that generation must equal to or exceed demand for electricity.
For energy storage technologies, the balance constraints ensure that the storage level in the current time segment is equal to the storage level in the previous time-segment plus any storage charge and/or discharge (while also accounting for round-trip efficiency losses).
Demand balance constraint:
First hour storage balance constraint:
Storage balance (not first hour) constraint:
Generation upper bound constraints limit generation from generating technologies, accounting for reserve requirements, operating capacity, and capacity factors where:
This is the same constraint for dispatchable, hydroelectric, and intermittent technologies. For intermittent technologies, the capacity factors are exogenously specified in the input data. In addition, hydroelectric generation has an additional seasonal constraint, where hydroelectric capacity is seasonally limited based on assumed availability of water resources seasonally, as specified in the input data. Storage upper bound constraints need to account for the upper bounds on both the charge and discharge of the technology, as well as the operating level in any given time segment.
Hydroelectric generation seasonal upper bound:
Dispatchable technology generation upper bound:
Hydroelectric technology generation upper bound:
Intermittent technology upper bound:
Storage technology inflow upper bound:
Storage technology outflow upper bound:
Storage technology level upper bound:
The model can build new generating technologies each year (when the expansion switch is turned on). The expansion constraint ensures that operating capacity is based on the capacity in the previous year, plus any additions and minus any retirements. The retirement constraint ensures that retirements never exceed the capacity available on the system.
Total capacity balance:
Capacity retirement upper bound:
Electricity trade constraints ensure that trade within any given time segment cannot exceed the capabilities of the transmission lines between the regions trading. In addition, there are supply quantity/price constraints for international trade, where supply from international regions cannot exceed the availability from the region.
International interregional trade line capacity upper bound:
International interregional trade resource capacity upper bound:
Domestic interregional trade line capacity upper bound:
Reserve margin constraints ensure that there is additional quantity of capacity available beyond load requirements in each time segment. Available capacity that can contribute to the reserve margin is also potentially decremented based on capacity credit assumptions. Storage technologies have additional reserve margin constraints accounts for both the power capacity and the energy capacity availability towards contributing to reserve margin requirements.
Reserve margin requirement constraint:
Constraint to ensure available storage capacity to meet RM <= power cap, upper bound:
Constraint to ensure available storage capacity to meet RM <= existing storage level, upper bound:
Ramping constraints ensure that generating technologies are limited in the rate in which they can increase or decrease their generation from one time segment to the next. Ramping capabilities are balanced within each day.
First hour ramping balance constraint:
Ramping balance (not first hour) constraint:
Ramp up upper bound:
Ramp down upper bound:
The model allows for three different types of operating reserves to be represented within the model, either spinning reserves, regulation reserves, or flexibility reserve requirements. These operating reserves reflect the need to additional capacity to be held in reserve to meet and short-term needs for generation based on un-expected changes in things like electricity demand or variable renewable generation output.
Spinning reserve requirement constraint. 3% of load required:
Regulation reserve requirement constraint. 1% of load + 0.5% of wind generation + 0.3% of solar capacity required:
Flexibility reserve requirement constraint. 10% of wind generation + 4% of solar capacity required:
Operating reserve procurement upper bound: