Storage

E4ST.StorageType
mutable struct Storage <: Modification

Storage(;name, file, build_file="")

Storage is represented over sets of time-weighted sequential representative hours for which the following must hold true, for a given storage device:

  • Net charge over the interval must equal zero.
  • Total charge of the device cannot exceed its maximum charge, or go below zero.
  • Initial charge over an interval can be anywhere between 0 and the maximum charge, and is the same initial charge for each time interval.

Keyword Arguments:

Tables Added:

  • storage - this table consists of rows defining the built and economic status of different storage units
  • build_storage - this table specifies the storage that the model can build

Table Columns Added:

  • (:storage, :capex_obj) - the hourly capital expenditure that is used in the objective function. Because capacity expansion is not considered for existing storage units, it is set to 0 for already built capacity.
  • (:storage, :transmission_capex_obj) - the hourly transmission capacity expenditure that is used in the objective function.
  • (:storage, :pcap) - power discharge capacity of the storage device.
  • (:storage, :pcharge) - the rate of charging, in MW
  • (:storage, :pdischarge) - the rate of discharging, in MW
  • (:storage, :echarge) - energy used in the charging of the storage device (includes round-trip storage losses)
  • (:storage, :edischarge) - energy that was discharged by the storage device.
  • (:storage, :pcap_inv_sim) - the total power discharge capacity invested in the storage unit during the simulation. Represented by a single value and remains the same after retirement.
  • (:storage, :ecap_inv_sim) - the total yearly energy discharge capacity invested in the storage unit during the simulation (pcapinvsim * hours per year). Represented by a single value and remains the same after retirement.
  • (:storage, :lmp_e) - locational marginal price of electricity.
  • (:storage, :ploss) - power lost by the battery, counted as served load equal to pcharge * (1-η)
  • (:storage, :eloss) - energy lost by the battery, counted as served load.

Model Modification

  • Variables
    • pcap_stor[stor_idx, yr_idx] - The discharge power capacity, in MW, of the storage device.
    • pcharge_stor[stor_idx, yr_idx, hr_idx] - The charge power, in MW, for a given hour.
    • pdischarge_stor[stor_idx, yr_idx, hr_idx] - The discharged power, in MW, for a given hour.
    • e0_stor[stor_idx, yr_idx, int_idx] - The starting charge energy (in MWh) for each interval.
  • Expressions
    • vom_stor[yr_idx in 1:nyr] - the addition of fixed operation and maintenance costs to the objective function.
    • fom_stor[yr_idx in 1:nyr] - the addition of variable operation and maintenance costs to the objective function.
    • routine_capex_stor[yr_idx in 1:nyr] - the addition of capital expenditure costs associated with storage to the objective function.
    • pcap_stor_inv_sim[stor_idx in axes(storage,1)] - storage power discharge capacity invested in the sim.
    • capex_obj_stor[yr_idx in 1:nyr] - the objective capital expenditures of storage.
    • transmission_capex_obj_stor[yr_idx in 1:nyr] - the objective capital expenditures of storage transmission.
  • Constraints
    • cons_stor_charge_bal[stor_idx, yr_idx, int_idx] - the charge balancing equation - net charge in each interval is 0
    • cons_stor_charge_max[stor_idx, yr_idx, int_idx, _hr_idx] - constrain the stored energy in each hour of each interval to be less than the maximum (function of pcap_stor and the discharge duration column of the storage table). Note _hr_idx is the index within the interval, not the normal hr_idx
    • cons_stor_charge_min[stor_idx, yr_idx, int_idx, _hr_idx] - constrain the stored energy in each hour of each interval to be greater than zero. Note _hr_idx is the index within the interval, not the normal hr_idx
    • cons_pcap_stor_noadd[stor_idx, yr_idx; years[yr_idx] >= storage.year_on[stor_idx]] - constrain the capacity to be non-increasing after being built. (only in multi-year simulations)
    • fix the capacity to zero before being built. (should only happen in multi-year simulations)
    • fix the exogenous, unbuilt capacity to equal pcap0 for the first year >= its build year.

Results Formulas

  • Investment Subsidy
    • (:storage, :invest_subsidy) - investment subsidies sent to the producers of exogenous or endogenous investments made in the sim
    • (:storage, :invest_subsidy_permw_perhr) - investment subsidies per MW per hour
  • Power Capacity Investment
    • (:storage, :pcap_total) - total discharge power capacity (calculates the average if multiple years provided)
    • (:storage, :ecap_total) - total energy capacity in MWh, equal to the power generation capacity multiplied by the number of hours.
    • (:storage, :echarge_total) - total energy charged
    • (:storage, :edischarge_total) - total energy discharged
    • (:storage, :eloss_total) - total energy loss
    • (:storage, :ecap_inv_total) - total invested energy discharge capacity over the given time period.
  • Electricity Costs
    • (:storage, :electricity_revenue) - revenue from discharging electricity to the grid.
    • (:storage, :electricity_cost) - costs of electricity to charge the storage units.
  • Production Costs
    • (:storage, :vom_cost) - total variable O&M cost for discharging energy.
    • (:storage, :vom_per_mwh) - average variable O&M cost for discharging 1 MWh of energy (vomcost / edischargetotal).
    • (:storage, :fom_cost) - total fixed O&M cost paid, in dollars
    • (:storage, :fom_per_mwh) - average fixed O&M cost for discharging 1 MWh of energy (fomcost / edischargetotal).
    • (:storage, :routine_capex_cost) - total routine capex cost paid, in dollars.
    • (:storage, :routine_capex_per_mwh) - average routine capex cost for discharging 1 MWh of energy
    • (:storage, :capex_cost) - total annualized capital expenditures paid including endogenous and exogenous investments incurred in the sim year.
    • (:storage, :capex_per_mwh) - average capital cost of discharging 1 MWh of energy
    • (:storage, :transmission_capex_cost) - total annualized transmission capital expenditures paid. This is only for transmissions costs related to building a storage unit, beyond what is included in the capex cost of the generator.
    • (:storage, :transmission_capex_per_mwh) - average transmission capital cost of discharging 1 MWh of energy.
    • (:storage, :invest_cost) - total annualized investment costs, in dollars
    • (:storage, :invest_cost_permw_perhr) - average investment cost per MW of invested capacity per hour.
    • (:storage, :production_cost) - cost of production, includes fixed and variable costs, does not include energy costs, subsidies, and costs from investments prior to the sim.
    • (:storage, :production_cost_per_mwh) - average cost of production for a MWh of energy discharge
    • (:storage, :net_production_cost) - net cost of production, includes fixed and variable costs and investment and production subsidies, does not include energy costs
    • (:storage, :net_production_cost_per_mwh) - average net cost of discharging 1 MWh of energy
  • Variable Costs
    • (:storage, :variable_cost) - total variable costs for operation, including vom.
    • (:storage, :variable_cost_per_mwh) - average variable costs for operation, for discharging 1 MWh from storage.
    • (:storage, :ptc_subsidy) - total production subsidy for storage.
    • (:storage, :ptc_subsidy_per_mwh) - average production subsidy for discharging 1 MWh from storage.
    • (:storage, :past_invest_cost_total) - Investment costs from past investments. This only applies to storage units built prior to the simulation. This includes the full annualized investment cost times the percentage likelihood that the storage unit would still be within its the economic lifetime for the year calculated, given that endogenously built storage units can be built in a range of years.
    • (:storage, :past_invest_subsidy_total) - Investment subsidies from past investments. This only applies to storage units built prior to the simulation. This includes the full annualized investment subsidy times the percentage likelihood that the storage unit would still be within its the economic lifetime for the year calculated, given that endogenously built storage units can be built in a range of years.
    • (:storage, :net_variable_cost) - net variable cost for storage (variablecost - ptcsubsidy)
    • (:storage, :net_variable_cost_per_mwh) - average net variable costs per MWh of discharged energy
  • Fixed Costs
    • (:storage, :fixed_cost) - total fixed costs, include capex and fixed O&M costs.
    • (:storage, :fixed_cost_permw_perhr_cost) - fixed costs per MW per hour (fixedcost / ecaptotal)
    • (:storage, :net_fixed_cost) - fixed costs minus investment subsidies
    • (:storage, :net_fixed_cost_permw_perhr) - average net fixed cost per MW per hour (netfixedcost / ecap_total)
  • Policy Costs
    • (:storage, :net_pol_cost_for_storage) - costs from all policy types (investment and production subsidies)
    • (:storage, :net_pol_cost_for_storage_per_mwh) - average policy cost per MWh of discharged energy.
    • (:storage, :net_government_revenue) - net gov revenue earned from energy storage.
    • (:storage, :going_forward_cost) - total cost of production and policies.
    • (:storage, :total_cost_prelim) - Total cost of production, including goingforwardcost, and past investment cost and subsidy for investments still within their economic lifetimes, before adjusting for cost-of-service rebates.
    • (:storage, :net_total_revenue_prelim) - preliminary net total revenue, before adjusting for cost of service rebates (electricityrevenue - electricitycost - totalcostprelim)
    • (:storage, :cost_of_service_rebate) - the sum of nettotalrevenueprelim * regfactor for each generator.
    • (:storage, :total_cost) - total cost after adjusting for the cost of service.
    • (:storage, :net_total_revenue) - net total revenue after adjusting for the cost of service rebate.
    • (:storage, :net_going_forward_revenue) - (electricityrevenue - electricitycost - netvariablecost - costofservice_rebate)

Objective Terms

  • capex_obj_stor - the capital expenditures to build the storage device, only non-zero in the build year. (function of pcap_stor and capex, and year_on)
  • fom_stor - the fixed operation and maintenance costs for the storage device (function of pcap_stor and fom from the storage table)
  • vom_stor - the variable operation and maintenance costs for the storage device (function of pdischarge_stor, the vom column of the storage table, and the hour weights get_hour_weights)

Power Balancing Equation

Each storage device can either be on the "gen" side or the "load" side, as specified by the side column.

  • "gen" side:
    • pcharge_stor gets subtracted from pgen_bus
    • pdischarge_stor gets added to pgen_bus
  • "load" side:
    • pcharge_stor gets added to plserv_bus
    • pdischarge_stor gets subtracted from plserv_bus
source
E4ST.modify_model!Method
modify_model!(mod::Modification, config, data, model)

Apply mod to the model, called in setup_model

source
E4ST.modify_results!Method
modify_results!(mod::Storage, config, data)

Modify battery results. Add columns to the storage table for:

  • pcap - discharge capacity of the storage device, in MW.
  • pcharge - the charging rate, in MW
  • pdischarge - the discharging rate, in MW
  • echarge - the energy charged in each representative hour (including losses)
  • edischarge - Energy that was discharged by the storage device
  • ploss - Power that was lost by the battery, counted as served load equal to pcharge * (1-η)
  • eloss - Energy that was lost by the battery, counted as served load
  • pcap_inv_sim - power discharge capacity invested in the sim
  • ecap_inv_sim - 8760 * pcapinvsim

Also saves the updated storage table via save_updated_storage_table.

source
E4ST.summarize_tableMethod
summarize_table(::Val{:storage})
column_namedata_typeunitrequireddescription
bus_idxInt64E4ST.NAtrueThe index of the bus table that the storage device corresponds to
statusBoolE4ST.NAfalseWhether or not the storage device is in service
build_statusInlineStrings.String15E4ST.NAtrueWhether the storage device is built, 'new, or unbuilt. All storage devices marked new when the storage file is read in will be changed to built. Can also be changed to retired_exog or retired_endog after the simulation is run. See update_build_status!
build_typeAbstractStringE4ST.NAtrueWhether the storage device is 'real', 'exog' (exogenously built), or 'endog' (endogenously built)
build_idAbstractStringE4ST.NAtrueIdentifier of the build row. For pre-existing storage devices not specified in the build file, this is usually left empty
year_onE4ST.YearStringE4ST.YeartrueThe first year of operation for the storage device. (For new devices this is also the year it was built)
year_unbuiltE4ST.YearStringE4ST.YearfalseThe latest year the generator was known not to be built. Defaults to year_on - 1. Used for past capex accounting.
econ_lifeFloat64E4ST.NumYearstrueThe number of years in the economic lifetime of the storage device.
year_offE4ST.YearStringE4ST.YeartrueThe first year that the storage unit is no longer operating in the simulation, computed from the simulation. Leave as y9999 if an existing storage unit that has not been retired in the simulation yet.
year_shutdownE4ST.YearStringE4ST.YeartrueThe forced (exogenous) shutdown year for the storage unit.
pcap_invFloat64E4ST.MWCapacitytrueOriginal invested nameplate power generation capacity for the storage device. This is the original invested capacity of exogenously built storage devices (even if there have been retirements ), and the original invested capacity in year_on for endogenously built storage devices.
pcap0Float64E4ST.MWCapacitytrueStarting nameplate power discharge capacity for the storage device
pcap_minFloat64E4ST.MWCapacitytrueMinimum nameplate power discharge capacity of the storage device (normally set to zero to allow for retirement)
pcap_maxFloat64E4ST.MWCapacitytrueMaximum nameplate power discharge capacity of the storage device
vomFloat64E4ST.DollarsPerMWhGeneratedtrueVariable operation and maintenance cost per MWh of energy discharged
fomFloat64E4ST.DollarsPerMWCapacityPerHourtrueHourly fixed operation and maintenance cost for a MW of discharge capacity
capexFloat64E4ST.DollarsPerMWBuiltCapacityPerHourtrueHourly capital expenditures for a MW of discharge capacity
transmission_capexFloat64E4ST.DollarsPerMWBuiltCapacityPerHourfalseHourly capital expenditures for the transmission supporting a MW of discharge capacity
routine_capexFloat64E4ST.DollarsPerMWCapacityPerHourtrueRoutine capital expenditures for a MW of discharge capacity
past_invest_costFloat64E4ST.DollarsPerMWCapacityPerHourfalseInvestment costs per MW of initial capacity per hour, for past investments
past_invest_subsidyFloat64E4ST.DollarsPerMWCapacityPerHourfalseInvestment subsidies from govt. per MW of initial capacity per hour, for past investments
duration_dischargeFloat64E4ST.HourstrueNumber of hours to fully discharge the storage device, from full.
duration_chargeFloat64E4ST.HoursfalseNumber of hours to fully charge the empty storage device from empty. (Defaults to equal duration_discharge)
storage_efficiencyFloat64E4ST.MWhDischargedPerMWhChargedtrueThe round-trip efficiency of the battery.
sideStringE4ST.NAtrueThe side of the power balance equation to add the charging/discharging to. Can be "gen" or "load"
hour_groupbyStringE4ST.NAtrueThe column of the hours table to group by. For example day
hour_durationStringE4ST.NAtrueThe column of the hours table specifying the duration of each representatibe hour
hour_orderStringE4ST.NAtrueThe column of the hours table specifying the sequence of the hours.
reg_factorFloat64E4ST.NAtrueThe percentage of power that dispatches to a cost-of-service regulated market
source
E4ST.summarize_tableMethod
summarize_table(::Val{:build_storage})
column_namedata_typeunitrequireddescription
areaAbstractStringE4ST.NAtrueThe area with which to filter by. I.e. "state". Leave blank to not filter by area.
subareaAbstractStringE4ST.NAtrueThe subarea to include in the filter. I.e. "maryland". Leave blank to not filter by area.
statusBoolE4ST.NAfalseWhether or not the storage device is in service
build_statusInlineStrings.String15E4ST.NAtrueWhether the storage device is built, 'new, or unbuilt. All storage devices marked new when the storage file is read in will be changed to built. Can also be changed to retired_exog or retired_endog after the simulation is run. See update_build_status!
build_typeAbstractStringE4ST.NAtrueWhether the storage device is 'real', 'exog' (exogenously built), or 'endog' (endogenously built)
build_idAbstractStringE4ST.NAtrueIdentifier of the build row. Each storage device made using this build spec will inherit this build_id
year_onE4ST.YearStringE4ST.YeartrueThe first year of operation for the storage device. (For new devices this is also the year it was built)
econ_lifeFloat64E4ST.NumYearstrueThe number of years in the economic lifetime of the storage device.
age_shutdownFloat64E4ST.NumYearstrueThe age at which the storage device is no longer operating. I.e. if year_on = y2030 and age_shutdown = 20, then capacity will be 0 in y2040.
year_on_minE4ST.YearStringE4ST.YeartrueThe first year in which a storage device can be built/come online (inclusive). Storage device with no restriction and exogenously built gens will be left blank
year_on_maxE4ST.YearStringE4ST.YeartrueThe last year in which a storage device can be built/come online (inclusive). Storage devices with no restriction and exogenously built gens will be left blank
pcap0Float64E4ST.MWCapacitytrueStarting nameplate power discharge capacity for the storage device
pcap_minFloat64E4ST.MWCapacitytrueMinimum nameplate power discharge capacity of the storage device (normally set to zero to allow for retirement)
pcap_maxFloat64E4ST.MWCapacitytrueMaximum nameplate power discharge capacity of the storage device
vomFloat64E4ST.DollarsPerMWhGeneratedtrueVariable operation and maintenance cost per MWh of energy discharged
fomFloat64E4ST.DollarsPerMWCapacityPerHourtrueHourly fixed operation and maintenance cost for a MW of discharge capacity
capexFloat64E4ST.DollarsPerMWBuiltCapacityPerHourtrueHourly capital expenditures for a MW of discharge capacity
transmission_capexFloat64E4ST.DollarsPerMWBuiltCapacityPerHourtrueHourly capital expenditures for the transmission supporting a MW of discharge capacity
routine_capexFloat64E4ST.DollarsPerMWCapacityPerHourtrueRouting capital expenditures for a MW of discharge capacity
duration_dischargeFloat64E4ST.HourstrueNumber of hours to fully discharge the storage device, from full.
duration_chargeFloat64E4ST.HoursfalseNumber of hours to fully charge the empty storage device from empty. (Defaults to equal duration_discharge)
storage_efficiencyFloat64E4ST.MWhDischargedPerMWhChargedtrueThe round-trip efficiency of the device.
sideStringE4ST.NAtrueThe side of the power balance equation to add the charging/discharging to. Can be "gen" or "load"
hour_groupbyStringE4ST.NAtrueThe column of the hours table to group by. For example day
hour_durationStringE4ST.NAtrueThe column of the hours table specifying the duration of each representatibe hour
hour_orderStringE4ST.NAtrueThe column of the hours table specifying the sequence of the hours.
source