Internal API
PRASCore.Simulations.DispatchProblem
— TypeDispatchProblem(sys::SystemModel)
Create a min-cost flow problem for the multi-region max power delivery problem with generation and storage discharging in decreasing order of priority, and storage charging with excess capacity. Storage and GeneratorStorage devices within a region are represented individually on the network.
This involves injections/withdrawals at one node (regional capacity surplus/shortfall) for each modelled region, as well as two/three nodes associated with each Storage/GeneratorStorage device, and a supplementary "slack" node in the network that can absorb undispatched power or pass unserved energy or unused charging capability through to satisfy power balance constraints.
Flows from the generation nodes are free, while flows to charging and from discharging nodes are costed or rewarded according to the time-to-discharge of the storage device, ensuring efficient coordination across units, while enforcing that storage is only discharged once generation capacity is exhausted (implying an operational strategy that prioritizes resource adequacy over economic arbitrage). This is based on the storage dispatch strategy of Evans, Tindemans, and Angeli, as outlined in "Minimizing Unserved Energy Using Heterogenous Storage Units" (IEEE Transactions on Power Systems, 2019).
Flows to the charging node have an attenuated negative cost (reward), incentivizing immediate storage charging if generation and transmission allows it, while avoiding charging by discharging other storage (since that would incur an overall positive cost).
Flows to the slack node (representing unused generation or storage discharge capacity) are free, but flows from the slack node to serve load incur the lost load penalty of 9999. Flows from the slack node in lieu of storage charging or discharging are free.
Flows on transmission interfaces assume a hurdle rate of 1 to keep unserved energy close to the source of the shortage and eliminate loop flows. This has the side-effect of disincentivising wheeling power across multiple regions for charging purposes, however.
Nodes in the problem are ordered as:
- Regions generation surplus/shortfall (Regions order)
- Storage discharge capacity (Storage order)
- Storage charge capacity (Storage order)
- GenerationStorage inflow capacity (GeneratorStorage order)
- GenerationStorage discharge capacity (GeneratorStorage order)
- GenerationStorage grid injection (GeneratorStorage order)
- GenerationStorage charge capacity (GeneratorStorage order)
- Slack node
Edges are ordered as:
- Regions demand unserved (Regions order)
- Regions generation unused (Regions order)
- Interfaces forward flow (Interfaces order)
- Interfaces reverse flow (Interfaces order)
- Storage discharge to grid (Storage order)
- Storage discharge unused (Storage order)
- Storage charge from grid (Storage order)
- Storage charge unused (Storage order)
- GenerationStorage discharge to grid (GeneratorStorage order)
- GenerationStorage discharge unused (GeneratorStorage order)
- GenerationStorage inflow to grid (GenerationStorage order)
- GenerationStorage total to grid (GeneratorStorage order)
- GenerationStorage charge from grid (GeneratorStorage order)
- GenerationStorage charge from inflow (GeneratorStorage order)
- GenerationStorage charge unused (GeneratorStorage order)
- GenerationStorage inflow unused (GeneratorStorage order)
PRASCore.Results.StorageAvailability
— TypeStorageAvailability
The StorageAvailability
result specification reports the sample-level discrete availability of Storages
, producing a StorageAvailabilityResult
.
A StorageAvailabilityResult
can be indexed by storage device name and a timestamp to retrieve a vector of sample-level availability states for the unit in the given timestep. States are provided as a boolean with true
indicating that the unit is available and false
indicating that it's unavailable.
Example:
storavail, =
assess(sys, SequentialMonteCarlo(samples=10), StorageAvailability())
samples = storavail["MyStorage123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")]
@assert samples isa Vector{Bool}
@assert length(samples) == 10
SiennaPRASInterface.HVDCLineTypes
— TypeSupported DC branch Types
SiennaPRASInterface.OUTAGE_INFO_FILE
— ConstantDEFAULT outage data which is used when outage_flag is set to FALSE
Based on ERCOT historical data
SiennaPRASInterface.TransformerTypes
— ConstantFiltered Transformer Types
These transformers are not modeled as lines in PRAS.
SiennaPRASInterface.AbstractRAFormulation
— TypeAbstractRAFormulation
Abstract type for translating a Sienna object in PRAS. Multiple objects can use the same formulation.
Formulations are also intended to contain information about their configuration such as time series names.
PRAS formulation subtypes for specific PRAS types
GeneratorPRAS
StoragePRAS
(abstract type)GeneratorStoragePRAS
(abstract type)
SiennaPRASInterface.InterfacePRAS
— TypeInterfacePRAS <: AbstractRAFormulation
InterfacePRAS produces interface entries in PRAS.
If not supplied, then interfaces will be generated by Lines
Subtypes must provide add_to_interface!
function.
SiennaPRASInterface.LoadPRAS
— TypeLoadPRAS <: AbstractRAFormulation
See add_to_load_matrix
for how the formulation is used to add load to regions.
SiennaPRASInterface.S2P_metadata
— TypeS2P_metadata
Struct to store metadata for the Sienna to PRAS conversion
SiennaPRASInterface.SPIOutageResult
— TypeSPIOutageResult(; shortfall_samples, gen_availability, stor_availability, gen_stor_availability)
Arguments
shortfall_samples::PRASCore.Results.ShortfallSamplesResult
: Shortfall Sample Resultgen_availability::PRASCore.Results.GeneratorAvailabilityResult
: Generator Availability Resultstor_availability::PRASCore.Results.StorageAvailabilityResult
: Storage Availability Resultgen_stor_availability::PRASCore.Results.GeneratorStorageAvailabilityResult
: GeneratorStorage Availability Result
SPIOutageResult is used to parse Tuple{Vararg{PRAS.PRASCore.Results.Result}} and add structure to it.
SiennaPRASInterface.outage_data
— Typeoutage_data
Struct to store the outage information for a component.
SiennaPRASInterface.add_asset_status!
— Methodadd_asset_status!(
sys::PowerSystems.System,
results::SiennaPRASInterface.SPIOutageResult,
template::RATemplate
)
Add the asset status from the worst sample to PSY.TimeSeriesForcedOutage of the component.
Arguments
sys::PSY.System
: PowerSystems.jl system modelresults::T
: SPIOutageResulttemplate::RATemplate
: PRAS problem template
Returns
- PSY System with PSY.TimeSeriesForcedOutage for all components for which asset status is available
SiennaPRASInterface.add_default_data!
— FunctionAdd default data to a system from OUTAGE_INFO_FILE
(ERCOT data).
SiennaPRASInterface.add_to_interface!
— Methodadd_to_interface!(
_::AreaInterchangeLimit,
interface,
s2p_meta,
forward_row,
backward_row
) -> Any
Add flow limits of an Sienna interface to an existing PRAS interface
SiennaPRASInterface.appliestodevice
— MethodCheck whether a DeviceRAModel applies to a given type
SiennaPRASInterface.assign_to_gen_stor_matrices!
— Methodassign_to_gen_stor_matrices!(
formulation::HybridSystemPRAS,
g_s::PowerSystems.Device,
s2p_meta::SiennaPRASInterface.S2P_metadata,
charge_cap_array,
discharge_cap_array,
inflow_array,
energy_cap_array,
gridinj_cap_array
) -> Any
Apply HybridSystem Formulation to fill in a row of a PRAS Matrix. Views should be passed in for all arrays.
SiennaPRASInterface.assign_to_gen_stor_matrices!
— Methodassign_to_gen_stor_matrices!(
formulation::HydroEnergyReservoirPRAS,
g_s::PowerSystems.Device,
s2p_meta::SiennaPRASInterface.S2P_metadata,
charge_cap_array,
discharge_cap_array,
inflow_array,
energy_cap_array,
gridinj_cap_array
) -> Any
Apply HydroEnergyReservoir Formulation to fill in a row of a PRAS Matrix. Views should be passed in for all arrays.
SiennaPRASInterface.assign_to_line_matrices!
— Methodassign_to_line_matrices!(
_::LinePRAS,
line::PowerSystems.Branch,
s2p_meta::SiennaPRASInterface.S2P_metadata,
forward_cap,
backward_cap
) -> Any
Apply LinePRAS to create PRAS matrices for lines. Views should be passed in.
SiennaPRASInterface.build_component_to_formulation
— Methodbuild_component_to_formulation(_, sys, device_models)
Constructs a dictionary from Sienna Devices to formulation objects
SiennaPRASInterface.build_interfaces_from_lines
— Methodbuild_interfaces_from_lines(
line_forward_cap::Matrix{Int64},
line_backward_cap::Matrix{Int64},
interface_reg_idxs::Vector{Tuple{Int64, Int64}},
interface_line_idxs::Vector{UnitRange{Int64}},
s2p_meta::SiennaPRASInterface.S2P_metadata
) -> Interfaces{_A, MW} where _A
Create PRAS interfaces from PRAS Lines
SiennaPRASInterface.check_file
— Methodcheck_file(loc::String)
Check if the file exists and is openable.
SiennaPRASInterface.filter_component_to_formulation
— Methodfilter_component_to_formulation(gens_to_formula)
Filter the dictionary from Sienna Devices to GeneratorPRAS formulation objects for Lumped vs. NonLumped
SiennaPRASInterface.get_aggregation_function
— Methodget_aggregation_function(::PSY.Area)
Get getter function based on PSY.AggregationTopology
SiennaPRASInterface.get_available_components
— MethodUses a PRAS device model to find all components matching it in a system.
SiennaPRASInterface.get_available_components_in_aggregation_topology
— Methodget_available_components_in_aggregation_topology(
type::Type{<:PSY.StaticInjection},
sys::PSY.System,
region::PSY.AggregationTopology,
)
Get available components in the AggregationTopology region of the given type.
SiennaPRASInterface.get_device_ramodel
— MethodGet DeviceRAModel for PRAS AbstractAvailabilityResult
SiennaPRASInterface.get_device_ramodel
— MethodGet DeviceRAModel for PRAS AbstractAvailabilityResult
SiennaPRASInterface.get_device_ramodel
— MethodGet DeviceRAModel for PRAS AbstractAvailabilityResult
SiennaPRASInterface.get_formulation
— MethodGet formulation from a DeviceRAModel
SiennaPRASInterface.get_gen_storage_region_indices
— Methodget_gen_storage_region_indices(
sys::PowerSystems.System,
regions,
component_to_formulation::Dict{PowerSystems.Device, GeneratorStoragePRAS}
) -> Tuple{Any, Any}
Extract components with a generator storage formulation.
SiennaPRASInterface.get_generator_category
— Methodget_generator_category(gen::StaticInjection)
Get the category of the generator.
Arguments
gen::StaticInjection
: Generator
Returns
String
: Category of the generator
SiennaPRASInterface.get_generator_region_indices
— Methodget_generator_region_indices(
sys::PowerSystems.System,
s2p_meta::SiennaPRASInterface.S2P_metadata,
regions,
component_to_formulation::Dict{PowerSystems.Device, GeneratorPRAS}
) -> Tuple{Any, Any, Dict{String, Vector{PowerSystems.Device}}}
Extraction of generators using formulation dictionary to create a list of generators and appropriate indices for PRAS. Note that objects with 0 max active power are excluded.
SiennaPRASInterface.get_inflow
— MethodGet inflow time series name
SiennaPRASInterface.get_lump_renewable_generation
— MethodGet whether renewable generation is lumped to regions
SiennaPRASInterface.get_max_active_power
— MethodGet max active power time series name
SiennaPRASInterface.get_max_active_power
— MethodGet max active power time series name
SiennaPRASInterface.get_max_active_power
— MethodGet max active power time series name
SiennaPRASInterface.get_pras_array_from_timeseries
— MethodTurn a time series into an Array of floored ints
SiennaPRASInterface.get_region_loads
— Methodget_region_loads(
s2p_meta::SiennaPRASInterface.S2P_metadata,
regions,
loads_to_formulations::Dict{PowerSystems.Device, SiennaPRASInterface.LoadPRAS}
) -> Matrix{Int64}
Extract region load as a matrix of Int64 values.
SiennaPRASInterface.get_sorted_lines
— Methodget_sorted_lines(lines::Vector{PSY.Branch}, region_names::Vector{String})
Get sorted lines, interface region indices, and interface line indices.
Arguments
lines::Vector{PSY.Branch}
: Linesregion_names::Vector{String}
: Region names
Returns
sorted_lines::Vector{PSY.Branch}
: Sorted linesinterface_reg_idxs::Vector{Tuple{Int, Int}}
: Interface region indicesinterface_line_idxs::Vector{UnitRange{Int}}
: Interface line indices
SiennaPRASInterface.get_sorted_region_tuples
— Methodget_sorted_region_tuples(lines::Vector{PSY.Branch}, region_names::Vector{String})
Get sorted (regfrom, regto) tuples of inter-regional lines.
SiennaPRASInterface.get_storage_capacity
— MethodGet storage capacity time series name
SiennaPRASInterface.get_storage_region_indices
— Methodget_storage_region_indices(
sys::PowerSystems.System,
s2p_meta::SiennaPRASInterface.S2P_metadata,
regions,
component_to_formulation::Dict{PowerSystems.Device, StoragePRAS}
) -> Tuple{Any, Any}
Extraction of storage devices using formulation dictionary to create a list of storage devices and appropriate indices for PRAS.
SiennaPRASInterface.get_timestamps
— Methodget_timestamps(initial_time, resolution, steps, horizon)
Return a vector of timestamps starting from initial_time
with resolution
and steps
for horizon
steps
SiennaPRASInterface.initialize_availability!
— Methodinitializeavailability!(rng, availability, nexttransition, devices, tlast)
Arguments
rng::Random.AbstractRNG
: Random number generatoravailability::Vector{Bool}
: Vector of availability statusnexttransition::Vector{Int}
: Vector of next transition timedevices::Vector{PSY.Generator}
: Vector of devices with outage SupplementalAttributest_last::Int
: Last time step
Returns
Modifies input arguments and rereturns
availability::Vector{Bool}
: Vector of availability statusnexttransition::Vector{Int}
: Vector of next transition time
SiennaPRASInterface.line_rating
— Methodline_rating(line::Branch)
Get the line rating.
Arguments
line::Branch
: Line
Returns
Tuple{forward_capacity::Float64, backward_capacity::Float64}
: Line rating
SiennaPRASInterface.line_type
— Methodline_type(line::Branch)
Get the line type.
Arguments
line::Branch
: Line
Returns
String
: Line type
SiennaPRASInterface.process_generators
— Methodprocess_generators(
gen::Array{PowerSystems.Device},
s2p_meta::SiennaPRASInterface.S2P_metadata,
component_to_formulation::Dict{PowerSystems.Device, GeneratorPRAS},
lumped_mapping::Dict{String, Vector{PowerSystems.Device}}
) -> Generators{_A, _B, T, MW} where {_A, _B, T<:Period}
Apply GeneratorPRAS to process all generators objects into rows in PRAS matrices:
- Capacity, λ, μ
Negative max active power will translate into zeros for time series data.
SiennaPRASInterface.process_genstorage
— Methodprocess_genstorage(
gen_stor::Array{PowerSystems.Device},
s2p_meta::SiennaPRASInterface.S2P_metadata,
component_to_formulation::Dict{PowerSystems.Device, GeneratorStoragePRAS}
) -> GeneratorStorages{_A, _B, T, MW, MWh} where {_A, _B, T<:Period}
Apply GeneratorStoragePRAS to create PRAS matrices for generator storage
SiennaPRASInterface.process_interfaces
— Methodprocess_interfaces(
interface_reg_idxs::Vector{Tuple{Int64, Int64}},
regions,
s2p_meta::SiennaPRASInterface.S2P_metadata,
interfaces_to_formulation::Dict{PowerSystems.Device, SiennaPRASInterface.InterfacePRAS}
) -> Interfaces{_A, MW} where _A
Process interfaces using a formulation dictionary to create PRAS matrices.
SiennaPRASInterface.process_lines
— Methodprocess_lines(
sorted_lines::Vector{PowerSystems.Branch},
s2p_meta::SiennaPRASInterface.S2P_metadata,
lines_to_formulation::Dict{PowerSystems.Device, LinePRAS}
) -> Lines{_A, _B, T, MW} where {_A, _B, T<:Period}
Create PRAS from sorted lines and formulations.
SiennaPRASInterface.process_storage
— Methodprocess_storage(
stor::Array{PowerSystems.Device},
s2p_meta::SiennaPRASInterface.S2P_metadata,
component_to_formulation::Dict{PowerSystems.Device, StoragePRAS}
) -> Storages{_A, _B, T, MW, MWh} where {_A, _B, T<:Period}
Apply StoragePRAS to process all storage objects
SiennaPRASInterface.rate_to_probability
— Methodrate_to_probability(for_gen::Float64, mttr::Int64)
Converts the forced outage rate and mean time to repair to the λ and μ parameters
Arguments
for_gen::Float64
: Forced outage rate [1/T]mttr::Int64
: Mean time to repair [T]
Returns
λ::Float64
: Transition probability from online to offline [1/T]μ::Float64
: Transition rate from offline to online [1/T]
Reference
https://core.ac.uk/download/pdf/13643059.pdf
SiennaPRASInterface.runchecks
— Methodrunchecks(sys_location::String)
Check if the System JSON file is serialized as well as other files required.
SiennaPRASInterface.update_availability!
— Methodupdate_availability!(rng, availability, nexttransition, devices, t_now, t_last)
Return availability and next transition with new randomness