Internal API
PRASCore.Simulations.DispatchProblem — Type
DispatchProblem(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, storage charging with excess capacity and demand response devices enabling load shed and shift functionality. Storage, GeneratorStorage, and Demand Response 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. Demand Response devices are represented in a structurally similar manner as storage charging and discharging.
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). Demand Response devices will borrow energy in devices with the longest payback window first, and vice versa for payback energy. Demand Response devices are utilized only after discharging all storage/genstor and paid back before storage/genstor charging.
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)
- DemandResponse payback capacity (DemandResponse order)
- DemandResponse borrowing capacity (DemandResponse 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)
- DemandResponse payback to grid (DemandResponse order)
- DemandResponse payback unused (DemandResponse order)
- DemandResponse borrowing from grid (DemandResponse order)
- DemandResponse borrowing unused (DemandResponse order)
PRASCore.Results.StorageAvailability — Type
StorageAvailabilityThe 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) == 10SiennaPRASInterface.OUTAGE_INFO_FILE — Constant
DEFAULT outage data which is used when outage_flag is set to FALSEBased on ERCOT historical data
SiennaPRASInterface.TransformerTypes — Constant
Filtered Transformer TypesThese transformers are not modeled as lines in PRAS.
SiennaPRASInterface.λ_default — Constant
Default GeometricDistributionForcedOutage SupplementalAttributes
This will be added to the component for which no outage data is provided.
SiennaPRASInterface.AbstractRAFormulation — Type
AbstractRAFormulationAbstract 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
GeneratorPRASStoragePRAS(abstract type)GeneratorStoragePRAS(abstract type)
SiennaPRASInterface.InterfacePRAS — Type
InterfacePRAS <: AbstractRAFormulationInterfacePRAS produces interface entries in PRAS.
If not supplied, then interfaces will be generated by Lines
Subtypes must provide add_to_interface! function.
SiennaPRASInterface.LoadPRAS — Type
LoadPRAS <: AbstractRAFormulationSee add_to_load_matrix for how the formulation is used to add load to regions.
SiennaPRASInterface.S2P_metadata — Type
S2P_metadataStruct to store metadata for the Sienna to PRAS conversion
SiennaPRASInterface.SPIOutageResult — Type
SPIOutageResult(; 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 — Type
outage_dataStruct to store the outage information for a component.
SiennaPRASInterface.add_asset_status! — Method
add_asset_status!(
sys::PowerSystems.System,
results::SiennaPRASInterface.SPIOutageResult,
template::RATemplate
)
Add the asset status from the worst sample to GeometricDistributionForcedOutage of the component.
Arguments
sys::PSY.System: PowerSystems.jl system modelresults::T: SPIOutageResulttemplate::RATemplate: PRAS problem template
Returns
- PSY System with asset availability times series added to PSY.GeometricDistributionForcedOutage for all components for which asset status is availableSiennaPRASInterface.add_default_data! — Function
Add default data to a system from OUTAGE_INFO_FILE (ERCOT data).
SiennaPRASInterface.add_to_interface! — Method
add_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 — Method
Check whether a DeviceRAModel applies to a given type
SiennaPRASInterface.assign_to_gen_stor_matrices! — Method
assign_to_gen_stor_matrices!(
formulation::HybridSystemPRAS,
g_s::PowerSystems.Device,
s2p_meta::SiennaPRASInterface.S2P_metadata,
turbine_to_reservoir_mapping::Dict{PowerSystems.HydroUnit, PowerSystems.HydroReservoir},
charge_cap_array,
discharge_cap_array,
inflow_array,
energy_cap_array,
gridinj_cap_array,
gridwdr_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_line_matrices! — Method
assign_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 — Method
build_component_to_formulation(_, sys, device_models)
Constructs a dictionary from Sienna Devices to formulation objects
SiennaPRASInterface.build_interfaces_from_lines — Method
build_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 — Method
check_file(loc::String)Check if the file exists and is openable.
SiennaPRASInterface.filter_component_to_formulation — Method
filter_component_to_formulation(gens_to_formula)
Filter the dictionary from Sienna Devices to GeneratorPRAS formulation objects for Lumped vs. NonLumped
SiennaPRASInterface.get_add_default_transition_probabilities — Method
Get whether default forced outages needed to be added to generators
SiennaPRASInterface.get_add_default_transition_probabilities — Method
Get whether default forced outages needed to be added to generatorstorages
SiennaPRASInterface.get_add_default_transition_probabilities — Method
Get whether default forced outages needed to be added to generatorstorages
SiennaPRASInterface.get_aggregation_function — Method
get_aggregation_function(::PSY.Area)Get getter function based on PSY.AggregationTopology
SiennaPRASInterface.get_available_components — Method
Uses a PRAS device model to find all components matching it in a system.
SiennaPRASInterface.get_available_components_in_aggregation_topology — Method
get_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 — Method
Get DeviceRAModel for PRAS AbstractAvailabilityResult
SiennaPRASInterface.get_device_ramodel — Method
Get DeviceRAModel for PRAS AbstractAvailabilityResult
SiennaPRASInterface.get_device_ramodel — Method
Get DeviceRAModel for PRAS AbstractAvailabilityResult
SiennaPRASInterface.get_formulation — Method
Get formulation from a DeviceRAModel
SiennaPRASInterface.get_gen_storage_region_indices — Method
get_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 — Method
get_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 — Method
get_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 — Method
Get inflow time series name
SiennaPRASInterface.get_lump_renewable_generation — Method
Get whether renewable generation is lumped to regions
SiennaPRASInterface.get_max_active_power — Method
Get max active power time series name
SiennaPRASInterface.get_max_active_power — Method
Get max active power time series name
SiennaPRASInterface.get_outage_probability — Method
Get outage_probability time series name
SiennaPRASInterface.get_outage_probability — Method
Get outage_probability time series name
SiennaPRASInterface.get_outage_probability — Method
Get outage_probability time series name
SiennaPRASInterface.get_pras_array_from_timeseries — Method
Turn a time series into an Array of floored ints
SiennaPRASInterface.get_recovery_probability — Method
Get recovery_probability time series name
SiennaPRASInterface.get_recovery_probability — Method
Get recovery_probability time series name
SiennaPRASInterface.get_recovery_probability — Method
Get recovery_probability time series name
SiennaPRASInterface.get_region_loads — Method
get_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 — Method
get_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 — Method
get_sorted_region_tuples(lines::Vector{PSY.Branch}, region_names::Vector{String})Get sorted (regfrom, regto) tuples of inter-regional lines.
SiennaPRASInterface.get_storage_capacity — Method
Get storage capacity time series name
SiennaPRASInterface.get_storage_region_indices — Method
get_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 — Method
get_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! — Method
initializeavailability!(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 — Method
line_rating(line::Branch)Get the line rating.
Arguments
line::Branch: Line
Returns
Tuple{forward_capacity::Float64, backward_capacity::Float64}: Line rating
SiennaPRASInterface.line_type — Method
line_type(line::Branch)Get the line type.
Arguments
line::Branch: Line
Returns
String: Line type
SiennaPRASInterface.process_generators — Method
process_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 — Method
process_genstorage(
gen_stor::Array{PowerSystems.Device},
s2p_meta::SiennaPRASInterface.S2P_metadata,
component_to_formulation::Dict{PowerSystems.Device, GeneratorStoragePRAS};
turbine_to_reservoir_mapping
)
Apply GeneratorStoragePRAS to create PRAS matrices for generator storage
SiennaPRASInterface.process_interfaces — Method
process_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 — Method
process_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 — Method
process_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 — Method
rate_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 — Method
runchecks(sys_location::String)Check if the System JSON file is serialized as well as other files required.
SiennaPRASInterface.update_availability! — Method
update_availability!(rng, availability, nexttransition, devices, t_now, t_last)Return availability and next transition with new randomness