Energy Storage
Data Fields & Method Definitions
New
- class StorageResource
Resource with storage capacity.
Adds state-of-charge tracking.
It feels like BatteryResource could be composed of a GenericResource + Asset (that represents the storage costs), but need to think about this more before implementing.
- Fields:
allow_inter_period_sharing (Annotated[bool, Metadata(category=FieldCategory.OPERATIONS)])
annualized_storage_fixed_om_cost (new_modeling_toolkit.core.temporal.timeseries.NumericTimeseries)
asset_groups (Annotated[dict[str, linkage.AssetToAssetGroup], Metadata(linkage_order='to')])
build_year (Annotated[pd.Timestamp, Metadata(category=FieldCategory.BUILD)])
can_build_new (Annotated[bool, Metadata(category=FieldCategory.BUILD)])
can_retire (Annotated[bool, Metadata(category=FieldCategory.BUILD)])
charging_efficiency (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries)
charging_efficiency__type (new_modeling_toolkit.core.temporal.timeseries.TimeseriesType | None)
discharging_efficiency (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries)
discharging_efficiency__type (new_modeling_toolkit.core.temporal.timeseries.TimeseriesType | None)
elcc_surfaces (Annotated[dict[str, linkage.AssetToELCC], Metadata(linkage_order='to')])
erm_policies (Annotated[dict[str, linkage.ERMContribution], Metadata(linkage_order='to')])
include (Annotated[bool, Metadata(category=FieldCategory.BUILD)])
min_operational_capacity (Annotated[ts.NumericTimeseries | None, Metadata(units=units.MW)])
outage_profile__type (Annotated[TimeseriesType | None, Metadata(category=FieldCategory.OPERATIONS)])
physical_lifetime (Annotated[int, Metadata(category=FieldCategory.BUILD, units=units.year)])
potential (Annotated[float | None, Metadata(category=FieldCategory.BUILD, units=units.megawatt)])
power_input_max (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries)
power_input_max__type (new_modeling_toolkit.core.temporal.timeseries.TimeseriesType | None)
power_input_min (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries)
power_input_min__type (new_modeling_toolkit.core.temporal.timeseries.TimeseriesType | None)
prm_policies (Annotated[dict[str, linkage.ReliabilityContribution], Metadata(linkage_order='to')])
ptc_term (Annotated[int | None, Metadata(units=units.years, excel_short_title='PTC Term')])
random_seed (Annotated[int | None, Metadata(category=FieldCategory.RELIABILITY)])
retired_storage_capacity (new_modeling_toolkit.core.temporal.timeseries.NumericTimeseries | None)
stochastic_outage_rate (Annotated[float | None, Metadata(category=FieldCategory.RELIABILITY)])
variable_cost_power_input (new_modeling_toolkit.core.temporal.timeseries.NumericTimeseries)
- field allow_inter_period_sharing: Annotated[bool, Metadata(category=FieldCategory.OPERATIONS)] = False
For resources & fuel storage resources that have chronological energy storage capability, enable inter-period energy/state-of-charge tracking. For resources with ramp rates, enable inter-period tracking of ramp constraints.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field annual_energy_policies: Annotated[dict[str, linkage.AnnualEnergyStandardContribution], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field annualized_capital_cost: Annotated[float, Metadata(category=FieldCategory.BUILD, units=units.dollar / units.kW_year, excel_short_title='Capital Cost', warning_bounds=(0, 1000))] = 0
- Constraints:
category = FieldCategory.BUILD
units = dollar / kiloW_year
excel_short_title = Capital Cost
warning_bounds = (0, 1000)
show_year_headers = True
default_exclude = False
- field annualized_fixed_om_cost: Annotated[ts.NumericTimeseries, Metadata(category=FieldCategory.BUILD, units=units.dollar / units.kW_year, excel_short_title='Fixed O&M', warning_bounds=(0, 100))] [Optional]
- Constraints:
category = FieldCategory.BUILD
units = dollar / kiloW_year
excel_short_title = Fixed O&M
warning_bounds = (0, 100)
show_year_headers = True
default_exclude = False
- field annualized_storage_capital_cost: float = 0.0 (alias 'new_storage_annual_fixed_cost_dollars_per_kwh_yr_by_vintage')
$/kWh-yr. For new storage capacity, the annualized fixed cost of investment. This is an annualized version of an overnight cost that could include financing costs ($/kWh-year).
- Constraints:
units = dollar / kiloWh_year
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field annualized_storage_fixed_om_cost: NumericTimeseries [Optional] (alias 'new_storage_capacity_fixed_om_by_vintage')
$/kWh-yr. For the planned portion of the resource’s storage capacity, the ongoing fixed O&M cost
- Constraints:
units = dollar / kiloWh_year
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field asset_groups: Annotated[dict[str, linkage.AssetToAssetGroup], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field attr_path: str | pathlib.Path | None = PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/e3-resolve/checkouts/latest/docs/source')
the path to the attributes file
- field build_year: Annotated[pd.Timestamp, Metadata(category=FieldCategory.BUILD)] = Timestamp('2000-01-01 00:00:00') (alias 'commission_date')
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field caiso_tx_constraints: Annotated[dict[str, linkage.AssetToCaisoTxConstraint], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field can_build_new: Annotated[bool, Metadata(category=FieldCategory.BUILD)] = False
Whether resource can be expanded (for now only linear capacity expansion).
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field can_retire: Annotated[bool, Metadata(category=FieldCategory.BUILD)] = False
Whether resource can be retired. By default, resources cannot be retired.
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field charging_efficiency: FractionalTimeseries [Optional]
[RESOLVE, RECAP]. % of Charging MW. Efficiency losses associated with charging (increasing load), typically expressed as a % of nameplate unless charging power specified to increase storage “state of charge”.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field charging_efficiency__type: TimeseriesType | None = None
Whether the charging_efficiency profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field class_name: str | None = None
- field cumulative_retired_capacity: ts.NumericTimeseries | None = None
- field cumulative_retired_storage_capacity: NumericTimeseries | None = None
- field custom_constraints: Annotated[dict[str, CustomConstraintLinkage], Metadata(linkage_order=3, default_exclude=True)] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = 3
default_exclude = True
- field discharging_efficiency: FractionalTimeseries [Optional]
[RESOLVE, RECAP]. % of Discharging MW, Efficiency losses associated with discharging (providing power), typically expressed as a % of nameplate unless charging power specified, taking energy out of storage “state of charge”.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field discharging_efficiency__type: TimeseriesType | None = None
Whether the discharging_efficiency profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field duration: float [Required] (alias 'storage_duration')
[RESOLVE, RECAP]. Hours of operational time the battery can operate at a specified power level before it runs out of energy. Required when resource is an operational group or does not belong to one.
- Constraints:
ge = 0
category = FieldCategory.OPERATIONS
units = hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = False
default_exclude = False
- field duration_constraint: StorageDurationConstraint = StorageDurationConstraint.FIXED
These three attributes are outputs, not inputs. They are initialized to None and are updated to their chosen optimal values after the RESOLVE model is solved. The attributes are used to give build and retirement decisions to a model run in production simulation mode.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field elcc_surfaces: Annotated[dict[str, linkage.AssetToELCC], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field emissions_policies: Annotated[dict[str, linkage.EmissionsContribution], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field energy_budget_annual: Annotated[ts.FractionalTimeseries | None, Metadata(category=FieldCategory.OPERATIONS, units=1 / units.year, excel_short_title='Annual')] = None
Annual fraction of energy capacity allowed for annual dispatch.
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / year
excel_short_title = Annual
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field energy_budget_daily: Annotated[ts.FractionalTimeseries | None, Metadata(category=FieldCategory.OPERATIONS, units=1 / units.day, excel_short_title='Daily')] = None
Daily fraction of energy capacity allowed for daily dispatch.
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / day
excel_short_title = Daily
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field energy_budget_monthly: Annotated[ts.FractionalTimeseries | None, Metadata(category=FieldCategory.OPERATIONS, units=1 / units.month, excel_short_title='Monthly')] = None
Monthly fraction of energy capacity allowed for monthly dispatch]
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / month
excel_short_title = Monthly
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field erm_policies: Annotated[dict[str, linkage.ERMContribution], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field hourly_energy_policies: Annotated[dict[str, linkage.HourlyEnergyStandardContribution], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field include: Annotated[bool, Metadata(category=FieldCategory.BUILD)] = True
Include component in system.
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field integer_build_increment: Annotated[float | None, Metadata(category=FieldCategory.BUILD, units=units.megawatt)] = None
If not None, consider integer (rather than linear) build decisions. If set equal to potential, this will force an all or nothing choice. Otherwise, this can be used to build certain increments of assets
- Constraints:
ge = 0
category = FieldCategory.BUILD
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field mean_time_to_repair: Annotated[float | None, Metadata(category=FieldCategory.RELIABILITY, units=units.hour)] = None
Mean time to repair
- Constraints:
category = FieldCategory.RELIABILITY
units = hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field min_operational_capacity: Annotated[ts.NumericTimeseries | None, Metadata(units=units.MW)] = None
These three attributes are outputs, not inputs. They are initialized to None and are updated to their chosen optimal values after the RESOLVE model is solved. The attributes are used to give build and retirement decisions to a model run in production simulation mode.
Minimum required operational capacity (planned+selected) by model year for this asset
- Constraints:
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field name: str | tuple [Required]
- field operational_capacity: ts.NumericTimeseries | None = None
- field operational_storage_capacity: NumericTimeseries | None = None
- field outage_distributions: Annotated[dict[str, linkage.ResourceToOutageDistribution], Metadata(linkage_order='to')] [Optional]
This input links resources to a specific OutageDistribution component. When a random or planned outage occurs, the outage distribution dictates what the possible outage state are for each resource. For example, if a unit is either on or offline, then it’s outage distribution is 0,1.
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field outage_profile: Annotated[ts.FractionalTimeseries, Metadata(category=FieldCategory.OPERATIONS, units=units.unitless, excel_short_title='Outage', default_exclude=True)] [Optional]
Fixed profile of simulated outages, where a value of 1.0 represents availability of full nameplate capacity and a value less than 1.0 represents a partial outage.
- Constraints:
category = FieldCategory.OPERATIONS
units = unitless
excel_short_title = Outage
warning_bounds = (None, None)
show_year_headers = True
default_exclude = True
- field outage_profile__type: Annotated[TimeseriesType | None, Metadata(category=FieldCategory.OPERATIONS)] = None
Whether the outage_profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field parasitic_loss: float = 0
[Storage] Hourly state of charge losses.
- Constraints:
ge = 0
le = 1
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field physical_lifetime: Annotated[int, Metadata(category=FieldCategory.BUILD, units=units.year)] = 100
Number of years after commission date that asset is operational.
- Constraints:
ge = 0
category = FieldCategory.BUILD
units = year
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field planned_capacity: Annotated[ts.NumericTimeseries, Metadata(category=FieldCategory.BUILD, units=units.megawatt)] [Optional]
- Constraints:
category = FieldCategory.BUILD
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field potential: Annotated[float | None, Metadata(category=FieldCategory.BUILD, units=units.megawatt)] = inf
- Constraints:
ge = 0
category = FieldCategory.BUILD
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_input_max: FractionalTimeseries [Optional] (alias 'increase_load_potential_profile')
Fixed shape of resource’s potential power draw (e.g. flat shape for storage resources). Used in conjunction with
new_modeling_toolkit.common.resource.Resource.curtailable
.- Constraints:
category = FieldCategory.OPERATIONS
units = unitless
excel_short_title = Max Input Profile
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_input_max__type: TimeseriesType | None = None
Whether the power_input_max profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_input_min: FractionalTimeseries [Optional]
Fixed shape of resource’s potential power draw (e.g. flat shape for storage resources). Used in conjunction with
new_modeling_toolkit.common.resource.Resource.curtailable
.- Constraints:
category = FieldCategory.OPERATIONS
units = unitless
excel_short_title = Min Input Profile
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_input_min__type: TimeseriesType | None = None
Whether the power_input_min profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_max: Annotated[ts.FractionalTimeseries, Metadata(category=FieldCategory.OPERATIONS, excel_short_title='Max Output Profile')] [Optional] (alias 'provide_power_potential_profile')
Fixed shape of resource’s potential power output (e.g., solar or wind shape or flat shapefor firm resources or storage resources). Used in conjunction with
new_modeling_toolkit.common.resource.Resource.curtailable
.- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title = Max Output Profile
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_max__type: Annotated[TimeseriesType | None, Metadata(category=FieldCategory.OPERATIONS)] = None
Whether the power_output_max profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_min: Annotated[ts.FractionalTimeseries, Metadata(category=FieldCategory.OPERATIONS, excel_short_title='Min Output Profile')] [Optional] (alias 'provide_power_min_profile')
Fixed shape of resource’s potential power output (e.g., solar or wind shape or flat shapefor firm resources or storage resources). Used in conjunction with
new_modeling_toolkit.common.resource.Resource.curtailable
.- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title = Min Output Profile
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_min__type: Annotated[TimeseriesType | None, Metadata(category=FieldCategory.OPERATIONS)] = None
Whether the power_output_min profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field prm_policies: Annotated[dict[str, linkage.ReliabilityContribution], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field production_tax_credit: Annotated[float | None, Metadata(units=units.dollar / units.MWh, excel_short_title='PTC')] = None
- Constraints:
units = dollar / megawatt_hour
excel_short_title = PTC
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ptc_term: Annotated[int | None, Metadata(units=units.years, excel_short_title='PTC Term')] = None
- Constraints:
units = year
excel_short_title = PTC Term
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_1_hour: Annotated[float | None, Metadata(category=FieldCategory.OPERATIONS, units=1 / units.hour)] = None
Single-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_2_hour: Annotated[float | None, Metadata(category=FieldCategory.OPERATIONS, units=1 / units.hour / 2)] = None
Two-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 0.5 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_3_hour: Annotated[float | None, Metadata(category=FieldCategory.OPERATIONS, units=1 / units.hour / 3)] = None
Three-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 0.3333333333333333 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_4_hour: Annotated[float | None, Metadata(category=FieldCategory.OPERATIONS, units=1 / units.hour / 4)] = None
Four-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 0.25 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field random_seed: Annotated[int | None, Metadata(category=FieldCategory.RELIABILITY)] = None
Random seed
- Constraints:
category = FieldCategory.RELIABILITY
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field reserves: Annotated[dict[str, linkage.ResourceToReserve], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] [Optional]
This input links the resource to a specific reserve type that it can contribute to. For example, Storage can provide both regulation up and down, but might not provide non-spin reserves.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field resource_groups: Annotated[dict[str, linkage.ResourceToResourceGroup], Metadata(linkage_order='to')] [Optional]
This gives each resource a group for RECAP. Depending on the Resource class, the upsampling method could change. For example, with Solar and Wind, these will be upsampled using a day draw methodology.
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field retired_capacity: ts.NumericTimeseries | None = None
- field retired_storage_capacity: NumericTimeseries | None = None
- field selected_capacity: float | None = None
- field selected_storage_capacity: float | None = None
- field state_of_charge_min: float = 0
[Storage] Minimum state-of-charge at any given time.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field stochastic_outage_rate: Annotated[float | None, Metadata(category=FieldCategory.RELIABILITY)] = None
Stochastic forced outage rate
- Constraints:
category = FieldCategory.RELIABILITY
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field variable_cost_power_input: NumericTimeseries [Optional] (alias 'variable_cost_increase_load')
Variable O&M cost per MWh generated.
- Constraints:
category = FieldCategory.OPERATIONS
units = dollar / megawatt_hour
excel_short_title = VO&M In
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field variable_cost_power_output: Annotated[ts.NumericTimeseries, Metadata(category=FieldCategory.OPERATIONS, units=units.dollar / units.MWh, excel_short_title='VO&M Out')] [Optional] (alias 'variable_cost_provide_power')
Variable O&M cost per MWh charged.
- Constraints:
category = FieldCategory.OPERATIONS
units = dollar / megawatt_hour
excel_short_title = VO&M Out
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field vintage_parent_group: str | None = None
- field zones: Annotated[dict[str, linkage.ResourceToZone], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- apply_parasitic_loss(state_of_charge, period_hrs)
- check_if_operationally_equal(other)
Check is this Asset is “operationally equivalent” to another Asset.
This check is used when automatically grouping resources together in RESOLVE for the construction of operational constraints. See AssetGroup for more information.
Operational equivalence is defined by two categories. First, all the “operational attributes” of the Assets (which are defined in a class variable) must be equal. Any attribute whose value may impact the optimal operational decisions for the assets have to be equal. For example, they must have equal power_output_max profiles, among other things. Second, they must have equivalent “operational linkages” - see check_operational_linkages_are_equal for more information.
- Parameters:
other – the Resource to compare to
check_linkages – whether linkages should be considered in determining operational equality
fields_to_check – an optional list of a subset of fields to check
- Returns:
whether the two Resources are operationally equal
- Return type:
bool
- clear_calculated_properties()
Clear the property cache so scaled profiles are recalculated after rescaling
- revalidate()
Abstract method to run additional validations after Linkage.announce_linkage_to_instances.
- save_capacity_expansion_results()
- save_cumulative_retired_storage_capacity()
Save the resulting retired storage capacity after the RESOLVE model has been solved.
- save_operational_storage_capacity()
Save the resulting operational storage capacity after the RESOLVE model has been solved.
- save_retired_storage_capacity()
Save the resulting retired storage capacity after the RESOLVE model has been solved.
- save_selected_storage_capacity()
Save the resulting selected storage capacity after the RESOLVE model has been solved.
- SAVE_PATH: ClassVar[str] = 'resources/storage'
- property imax_profile: Series
- property imin_profile: Series
- property planned_storage_capacity: Series
This property is for storage only now.
- property scaled_SOC_max_profile: Dict[int, Series]
This property is for storage only now.
- property scaled_imax_profile: Dict[int, Series]
- property scaled_imin_profile: Dict[int, Series]
Inherited
- class GenericResource
- Fields:
asset_groups (Annotated[dict[str, linkage.AssetToAssetGroup], Metadata(linkage_order='to')])
build_year (Annotated[pd.Timestamp, Metadata(category=FieldCategory.BUILD)])
can_build_new (Annotated[bool, Metadata(category=FieldCategory.BUILD)])
can_retire (Annotated[bool, Metadata(category=FieldCategory.BUILD)])
elcc_surfaces (Annotated[dict[str, linkage.AssetToELCC], Metadata(linkage_order='to')])
energy_budget_annual (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries | None)
energy_budget_daily (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries | None)
energy_budget_monthly (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries | None)
erm_policies (Annotated[dict[str, linkage.ERMContribution], Metadata(linkage_order='to')])
include (Annotated[bool, Metadata(category=FieldCategory.BUILD)])
min_operational_capacity (Annotated[ts.NumericTimeseries | None, Metadata(units=units.MW)])
outage_distributions (dict[str, new_modeling_toolkit.core.linkage.ResourceToOutageDistribution])
outage_profile (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries)
outage_profile__type (new_modeling_toolkit.core.temporal.timeseries.TimeseriesType | None)
physical_lifetime (Annotated[int, Metadata(category=FieldCategory.BUILD, units=units.year)])
potential (Annotated[float | None, Metadata(category=FieldCategory.BUILD, units=units.megawatt)])
power_output_max (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries)
power_output_max__type (new_modeling_toolkit.core.temporal.timeseries.TimeseriesType | None)
power_output_min (new_modeling_toolkit.core.temporal.timeseries.FractionalTimeseries)
power_output_min__type (new_modeling_toolkit.core.temporal.timeseries.TimeseriesType | None)
prm_policies (Annotated[dict[str, linkage.ReliabilityContribution], Metadata(linkage_order='to')])
random_seed (Annotated[int | None, Metadata(category=FieldCategory.RELIABILITY)])
reserves (dict[str, new_modeling_toolkit.core.linkage.ResourceToReserve])
resource_groups (dict[str, new_modeling_toolkit.core.linkage.ResourceToResourceGroup])
stochastic_outage_rate (Annotated[float | None, Metadata(category=FieldCategory.RELIABILITY)])
variable_cost_power_output (new_modeling_toolkit.core.temporal.timeseries.NumericTimeseries)
zones (dict[str, new_modeling_toolkit.core.linkage.ResourceToZone])
- field allow_inter_period_sharing: bool = False
For resources & fuel storage resources that have chronological energy storage capability, enable inter-period energy/state-of-charge tracking. For resources with ramp rates, enable inter-period tracking of ramp constraints.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field annual_energy_policies: Annotated[dict[str, linkage.AnnualEnergyStandardContribution], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field annualized_capital_cost: Annotated[float, Metadata(category=FieldCategory.BUILD, units=units.dollar / units.kW_year, excel_short_title='Capital Cost', warning_bounds=(0, 1000))] = 0
- Constraints:
category = FieldCategory.BUILD
units = dollar / kiloW_year
excel_short_title = Capital Cost
warning_bounds = (0, 1000)
show_year_headers = True
default_exclude = False
- field annualized_fixed_om_cost: Annotated[ts.NumericTimeseries, Metadata(category=FieldCategory.BUILD, units=units.dollar / units.kW_year, excel_short_title='Fixed O&M', warning_bounds=(0, 100))] [Optional]
- Constraints:
category = FieldCategory.BUILD
units = dollar / kiloW_year
excel_short_title = Fixed O&M
warning_bounds = (0, 100)
show_year_headers = True
default_exclude = False
- field asset_groups: Annotated[dict[str, linkage.AssetToAssetGroup], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field attr_path: str | pathlib.Path | None = PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/e3-resolve/checkouts/latest/docs/source')
the path to the attributes file
- field build_year: Annotated[pd.Timestamp, Metadata(category=FieldCategory.BUILD)] = Timestamp('2000-01-01 00:00:00') (alias 'commission_date')
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field caiso_tx_constraints: Annotated[dict[str, linkage.AssetToCaisoTxConstraint], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field can_build_new: Annotated[bool, Metadata(category=FieldCategory.BUILD)] = False
Whether resource can be expanded (for now only linear capacity expansion).
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field can_retire: Annotated[bool, Metadata(category=FieldCategory.BUILD)] = False
Whether resource can be retired. By default, resources cannot be retired.
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field class_name: str | None = None
- field cumulative_retired_capacity: ts.NumericTimeseries | None = None
- field custom_constraints: Annotated[dict[str, CustomConstraintLinkage], Metadata(linkage_order=3, default_exclude=True)] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = 3
default_exclude = True
- field elcc_surfaces: Annotated[dict[str, linkage.AssetToELCC], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field emissions_policies: Annotated[dict[str, linkage.EmissionsContribution], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field energy_budget_annual: FractionalTimeseries | None = None
Annual fraction of energy capacity allowed for annual dispatch.
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / year
excel_short_title = Annual
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field energy_budget_daily: FractionalTimeseries | None = None
Daily fraction of energy capacity allowed for daily dispatch.
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / day
excel_short_title = Daily
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field energy_budget_monthly: FractionalTimeseries | None = None
Monthly fraction of energy capacity allowed for monthly dispatch]
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / month
excel_short_title = Monthly
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field erm_policies: Annotated[dict[str, linkage.ERMContribution], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field hourly_energy_policies: Annotated[dict[str, linkage.HourlyEnergyStandardContribution], Metadata(linkage_order='to', category=FieldCategory.OPERATIONS)] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field include: Annotated[bool, Metadata(category=FieldCategory.BUILD)] = True
Include component in system.
- Constraints:
category = FieldCategory.BUILD
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field integer_build_increment: Annotated[float | None, Metadata(category=FieldCategory.BUILD, units=units.megawatt)] = None
If not None, consider integer (rather than linear) build decisions. If set equal to potential, this will force an all or nothing choice. Otherwise, this can be used to build certain increments of assets
- Constraints:
ge = 0
category = FieldCategory.BUILD
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field mean_time_to_repair: Annotated[float | None, Metadata(category=FieldCategory.RELIABILITY, units=units.hour)] = None
Mean time to repair
- Constraints:
category = FieldCategory.RELIABILITY
units = hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field min_operational_capacity: Annotated[ts.NumericTimeseries | None, Metadata(units=units.MW)] = None
These three attributes are outputs, not inputs. They are initialized to None and are updated to their chosen optimal values after the RESOLVE model is solved. The attributes are used to give build and retirement decisions to a model run in production simulation mode.
Minimum required operational capacity (planned+selected) by model year for this asset
- Constraints:
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field name: str | tuple [Required]
- field operational_capacity: ts.NumericTimeseries | None = None
- field outage_distributions: dict[str, ResourceToOutageDistribution] [Optional]
This input links resources to a specific OutageDistribution component. When a random or planned outage occurs, the outage distribution dictates what the possible outage state are for each resource. For example, if a unit is either on or offline, then it’s outage distribution is 0,1.
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field outage_profile: FractionalTimeseries [Optional]
Fixed profile of simulated outages, where a value of 1.0 represents availability of full nameplate capacity and a value less than 1.0 represents a partial outage.
- Constraints:
category = FieldCategory.OPERATIONS
units = unitless
excel_short_title = Outage
warning_bounds = (None, None)
show_year_headers = True
default_exclude = True
- field outage_profile__type: TimeseriesType | None = None
Whether the outage_profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field physical_lifetime: Annotated[int, Metadata(category=FieldCategory.BUILD, units=units.year)] = 100
Number of years after commission date that asset is operational.
- Constraints:
ge = 0
category = FieldCategory.BUILD
units = year
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field planned_capacity: Annotated[ts.NumericTimeseries, Metadata(category=FieldCategory.BUILD, units=units.megawatt)] [Optional]
- Constraints:
category = FieldCategory.BUILD
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field potential: Annotated[float | None, Metadata(category=FieldCategory.BUILD, units=units.megawatt)] = inf
- Constraints:
ge = 0
category = FieldCategory.BUILD
units = megawatt
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_max: FractionalTimeseries [Optional] (alias 'provide_power_potential_profile')
Fixed shape of resource’s potential power output (e.g., solar or wind shape or flat shapefor firm resources or storage resources). Used in conjunction with
new_modeling_toolkit.common.resource.Resource.curtailable
.- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title = Max Output Profile
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_max__type: TimeseriesType | None = None
Whether the power_output_max profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_min: FractionalTimeseries [Optional] (alias 'provide_power_min_profile')
Fixed shape of resource’s potential power output (e.g., solar or wind shape or flat shapefor firm resources or storage resources). Used in conjunction with
new_modeling_toolkit.common.resource.Resource.curtailable
.- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title = Min Output Profile
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field power_output_min__type: TimeseriesType | None = None
Whether the power_output_min profile data is of type ‘weather year’, ‘modeled year’, ‘month-hour’, ‘season-hour’, or ‘monthly’
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field prm_policies: Annotated[dict[str, linkage.ReliabilityContribution], Metadata(linkage_order='to')] = {}
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field production_tax_credit: float | None = None
- Constraints:
units = dollar / megawatt_hour
excel_short_title = PTC
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ptc_term: int | None = None
- Constraints:
units = year
excel_short_title = PTC Term
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_1_hour: float | None = None
Single-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 1 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_2_hour: float | None = None
Two-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 0.5 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_3_hour: float | None = None
Three-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 0.3333333333333333 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field ramp_rate_4_hour: float | None = None
Four-hour ramp rate. When used in conjunction with the other ramp rate limits (1-4 hour), a resource’s dispatch will be constrained by all applicable ramp rate limits on a rolling basis.
- Constraints:
category = FieldCategory.OPERATIONS
units = 0.25 / hour
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field random_seed: Annotated[int | None, Metadata(category=FieldCategory.RELIABILITY)] = None
Random seed
- Constraints:
category = FieldCategory.RELIABILITY
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field reserves: dict[str, ResourceToReserve] [Optional]
This input links the resource to a specific reserve type that it can contribute to. For example, Storage can provide both regulation up and down, but might not provide non-spin reserves.
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field resource_groups: dict[str, ResourceToResourceGroup] [Optional]
This gives each resource a group for RECAP. Depending on the Resource class, the upsampling method could change. For example, with Solar and Wind, these will be upsampled using a day draw methodology.
- Constraints:
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- field retired_capacity: ts.NumericTimeseries | None = None
- field selected_capacity: float | None = None
- field stochastic_outage_rate: Annotated[float | None, Metadata(category=FieldCategory.RELIABILITY)] = None
Stochastic forced outage rate
- Constraints:
category = FieldCategory.RELIABILITY
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field variable_cost_power_output: NumericTimeseries [Optional] (alias 'variable_cost_provide_power')
Variable O&M cost per MWh charged.
- Constraints:
category = FieldCategory.OPERATIONS
units = dollar / megawatt_hour
excel_short_title = VO&M Out
warning_bounds = (None, None)
show_year_headers = True
default_exclude = False
- field vintage_parent_group: str | None = None
- field zones: dict[str, ResourceToZone] = {}
- Constraints:
category = FieldCategory.OPERATIONS
units =
excel_short_title =
warning_bounds = (None, None)
show_year_headers = True
linkage_order = to
default_exclude = False
- clear_calculated_properties()
Clear the property cache so scaled profiles are recalculated after rescaling
- get_ramp_MW(modeled_year: Timestamp, timepoint_1: Tuple[Timestamp, Timestamp], timepoint_2: Tuple[Timestamp, Timestamp])
Change in output MW between two timepoints
- revalidate()
Abstract method to run additional validations after Linkage.announce_linkage_to_instances.
- SAVE_PATH: ClassVar[str] = 'resources/generic'
- property annual_results_column_order
This property defines the ordering of columns in the Asset annual results summary out of Resolve.
- property has_energy_budget: bool
- property outage_distribution: OutageDistribution | None
- property pmax_profile: Series
- property pmin_profile: Series
- property production_tax_credit_ts: NumericTimeseries
- property resource_group: ResourceGroup | None
- property results_reporting_category
- property results_reporting_folder
- property scaled_annual_energy_budget
- property scaled_daily_energy_budget
- property scaled_monthly_energy_budget
- property scaled_pmax_profile: Dict[int, Series]
- property scaled_pmin_profile
The StorageResources and HybridStorageResource class represent resources that both provide power and take power and energy capacity. These resources are typically described as “energy-limited resources” or ELRs.
The keystone feature in rebuilding resolve
in kit
in 2021 was to migrate to a more flexible formulation for storage
energy tracking based on [1].
Recap
What are considered Energy-limited Resources?
Batteries are the most obvious technology that fits into this category, but as more ELRs emerge, this class can flexibly
take on resources of different durations, round-trip efficiencies (RTE) and performance characteristics
Where do the data inputs go?
Resource Attributes will be specified in the UI
Custom attributes below can be specified as a timeseries, placed in
data > profiles
Pmin Rating
Pmax Rating
Max Charging Rating (CSV file)
Daily Energy Budget
Annual Energy Budget
Important considerations when modeling storage:
Symmetric or Asymmetric round-trip efficiency (RTE)
Total energy capacity / duration relative to RTE
is the 4-hr duration inclusive of RTE losses?
Forced outage rate assumption
During the Summer of Sept 2022 when CAISO avoided a near black-out, the 2GW storage fleet experienced unplanned outages of ~10% of the total nameplate
In Recap, StorageResource
are considered energy-limited resources, a special class of resources in Recap that has two
types of dispatch: Heuristic or Optimized dispatch.