Originally Contributed by: Clayton Barrows
PowerSimulations.jl supports simulations that consist of sequential optimization problems where results from previous problems inform subsequent problems in a variety of ways. This example demonstrates some of these capabilities to represent electricity market clearing.
First, let's create System
s to represent the Day-Ahead and Real-Time market clearing
process with hourly, and 5-minute time series data, respectively.
using PowerSystems
using PowerSimulations
using PowerSystemCaseBuilder
using Dates
using DataFrames
using Cbc # mip solver
solver = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 1, "ratioGap" => 0.5)
using Ipopt # solver that supports duals
ipopt_solver = optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)
[ Info: Precompiling Ipopt [b6b21f68-93f8-5de0-b562-5493be1d77c9]
MathOptInterface.OptimizerWithAttributes(Ipopt.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute,Any}[MathOptInterface.RawParameter("print_level") => 0])
The five bus system data here includes hourly day-ahead data, 5-minute real-time market data, and 6-second actual data. We'll only use the hourly and 5-minute data for the example simulations below, but the 6-second data is included for future development.
sys_DA = build_system(SIIPExampleSystems, "5_bus_matpower_DA")
sys_RT = build_system(SIIPExampleSystems, "5_bus_matpower_RT")
┌ Info: Building new system 5_bus_matpower_DA from raw data └ sys_descriptor.raw_data = "/Users/cbarrows/.julia/packages/PowerSystemCaseBuilder/UaGGi/data/matpower/case5_re_uc.m" [ Info: extending matpower format with data: areas 1x3 [ Info: extending matpower format with data: gen_name 7x4 [ Info: extending matpower format by appending matrix "gen_name" in to "gen" [ Info: reversing the orientation of branch 6 (4, 3) to be consistent with other parallel branches [ Info: the voltage setpoint on generator 4 does not match the value at bus 4 [ Info: the voltage setpoint on generator 1 does not match the value at bus 1 [ Info: the voltage setpoint on generator 5 does not match the value at bus 10 [ Info: the voltage setpoint on generator 2 does not match the value at bus 1 [ Info: the voltage setpoint on generator 3 does not match the value at bus 3 [ Info: removing 1 cost terms from generator 4: [4000.0, 0.0] [ Info: removing 1 cost terms from generator 1: [1400.0, 0.0] [ Info: removing 1 cost terms from generator 5: [1000.0, 0.0] [ Info: removing 1 cost terms from generator 2: [1500.0, 0.0] [ Info: removing 3 cost terms from generator 6: Float64[] [ Info: removing 3 cost terms from generator 7: Float64[] [ Info: removing 1 cost terms from generator 3: [3000.0, 0.0] ┌ Info: Constructing System from Power Models │ data["name"] = "nesta_case5_pjm" └ data["source_type"] = "matpower" [ Info: Reading bus data [ Info: Reading generator data [ Info: Reading branch data ┌ Warning: Rate 1200.0 MW for bus2-bus3-i_4 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 200.0 MW for bus1-bus2-i_1 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 200.0 MW for bus1-bus4-i_2 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 200.0 MW for bus4-bus5-i_7 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 1000.0 MW for bus1-bus5-i_3 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 [ Info: Reading branch data [ Info: Reading DC Line data [ Info: Reading storage data ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch2 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch2 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 [ Info: Serialized time series data to /Users/cbarrows/.julia/packages/PowerSystemCaseBuilder/UaGGi/data/serialized_system/ForecastOnly/5_bus_matpower_DA_time_series_storage.h5. [ Info: Serialized System to /Users/cbarrows/.julia/packages/PowerSystemCaseBuilder/UaGGi/data/serialized_system/ForecastOnly/5_bus_matpower_DA.json ┌ Info: Building new system 5_bus_matpower_RT from raw data └ sys_descriptor.raw_data = "/Users/cbarrows/.julia/packages/PowerSystemCaseBuilder/UaGGi/data/matpower/case5_re_uc.m" [ Info: extending matpower format with data: areas 1x3 [ Info: extending matpower format with data: gen_name 7x4 [ Info: extending matpower format by appending matrix "gen_name" in to "gen" [ Info: reversing the orientation of branch 6 (4, 3) to be consistent with other parallel branches [ Info: the voltage setpoint on generator 4 does not match the value at bus 4 [ Info: the voltage setpoint on generator 1 does not match the value at bus 1 [ Info: the voltage setpoint on generator 5 does not match the value at bus 10 [ Info: the voltage setpoint on generator 2 does not match the value at bus 1 [ Info: the voltage setpoint on generator 3 does not match the value at bus 3 [ Info: removing 1 cost terms from generator 4: [4000.0, 0.0] [ Info: removing 1 cost terms from generator 1: [1400.0, 0.0] [ Info: removing 1 cost terms from generator 5: [1000.0, 0.0] [ Info: removing 1 cost terms from generator 2: [1500.0, 0.0] [ Info: removing 3 cost terms from generator 6: Float64[] [ Info: removing 3 cost terms from generator 7: Float64[] [ Info: removing 1 cost terms from generator 3: [3000.0, 0.0] ┌ Info: Constructing System from Power Models │ data["name"] = "nesta_case5_pjm" └ data["source_type"] = "matpower" [ Info: Reading bus data [ Info: Reading generator data [ Info: Reading branch data ┌ Warning: Rate 1200.0 MW for bus2-bus3-i_4 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 200.0 MW for bus1-bus2-i_1 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 200.0 MW for bus1-bus4-i_2 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 200.0 MW for bus4-bus5-i_7 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 ┌ Warning: Rate 1000.0 MW for bus1-bus5-i_3 is larger than the max expected in the range of (min = 134.0, max = 145.0). └ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148 [ Info: Reading branch data [ Info: Reading DC Line data [ Info: Reading storage data ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch2 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch1 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 ┌ Warning: no component category=Generator name=HydroDispatch3 └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/v75Hd/src/system_data.jl:448 [ Info: Serialized time series data to /Users/cbarrows/.julia/packages/PowerSystemCaseBuilder/UaGGi/data/serialized_system/ForecastOnly/5_bus_matpower_RT_time_series_storage.h5. [ Info: Serialized System to /Users/cbarrows/.julia/packages/PowerSystemCaseBuilder/UaGGi/data/serialized_system/ForecastOnly/5_bus_matpower_RT.json
Base Power: 100.0
Num components: 30
ConcreteType | SuperTypes | Count | |
---|---|---|---|
String | String | Int64 | |
1 | Arc | Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 6 |
2 | Area | AggregationTopology <: Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 1 |
3 | Bus | Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 5 |
4 | Line | ACBranch <: Branch <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 5 |
5 | LoadZone | AggregationTopology <: Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 1 |
6 | PhaseShiftingTransformer | ACBranch <: Branch <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 2 |
7 | PowerLoad | StaticLoad <: ElectricLoad <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 3 |
8 | RenewableDispatch | RenewableGen <: Generator <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 2 |
9 | ThermalStandard | ThermalGen <: Generator <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 5 |
Components with time series data: 5
Total StaticTimeSeries: 5
Total Forecasts: 5
Resolution: 60 minutes
First initial time: 2020-01-01T00:00:00
Last initial time: 2020-03-24T12:00:00
Horizon: 12
Interval: 60 minutes
Forecast window count: 2005
OperationsProblemTemplate
s¶template_uc = template_unit_commitment()
template_ed = template_economic_dispatch()
Operations Problem Specification ============================================ Transmission: CopperPlatePowerModel ============================================ Devices Models: Type: ThermalStandard Formulation: ThermalDispatch Type: HydroDispatch Formulation: HydroDispatchRunOfRiver Type: PowerLoad Formulation: StaticPowerLoad Type: RenewableFix Formulation: FixedOutput Type: RenewableDispatch Formulation: RenewableFullDispatch Type: HydroEnergyReservoir Formulation: HydroDispatchRunOfRiver Type: InterruptibleLoad Formulation: InterruptiblePowerLoad ============================================ Branches Models: Type: Line Formulation: StaticBranch Type: TapTransformer Formulation: StaticBranch Type: Transformer2W Formulation: StaticBranch Type: HVDCLine Formulation: HVDCDispatch ============================================ Services Models: Type: VariableReserve{ReserveDown} Formulation: RangeReserve Type: VariableReserve{ReserveUp} Formulation: RangeReserve ============================================
problems = SimulationProblems(
UC = OperationsProblem(
template_uc,
sys_DA,
optimizer = solver,
balance_slack_variables = true,
),
ED = OperationsProblem(
template_ed,
sys_RT,
optimizer = ipopt_solver,
constraint_duals = [:CopperPlateBalance],
),
)
feedforward_chronologies = Dict(("UC" => "ED") => Synchronize(periods = 24))
feedforward = Dict(
("ED", :devices, :ThermalStandard) => SemiContinuousFF(
binary_source_problem = ON,
affected_variables = [ACTIVE_POWER],
),
)
#cache = Dict("UC" => [TimeStatusChange(ThermalStandard, PSI.ON)])
intervals = Dict("UC" => (Hour(24), Consecutive()), "ED" => (Hour(1), Consecutive()))
DA_RT_sequence = SimulationSequence(
problems = problems,
intervals = intervals,
ini_cond_chronology = InterProblemChronology(),
feedforward_chronologies = feedforward_chronologies,
feedforward = feedforward,
)
Feed Forward Chronology ----------------------- ED: SemiContinuousFF -> ThermalStandard UC--┐ from : On | ┌----┬----┬----┬----┬----┼----┬----┬----┬----┬----┬----┐ | | | | | | | | | | | | | | | | | | | | | | | | └─ED └─ED └─ED └─ED └─ED └─ED └─ED └─ED └─ED └─ED └─ED └─ED ... (x24) to : ["P"] Initial Condition Chronology ---------------------------- 1 | | 2 --> 2 ... (x24)
Simulation
¶file_path = mkpath(joinpath(".","5-bus-simulation"))
sim = Simulation(
name = "5bus-test",
steps = 1,
problems = problems,
sequence = DA_RT_sequence,
simulation_folder = file_path,
)
Simulation()
build!(sim)
┌ Info: │ ────────────────────────────────────────────────────────────────────────────── │ Time Allocations │ ────────────────────── ─────────────────────── │ Tot / % measured: 1.87s / 100% 254MiB / 100% │ │ Section ncalls time %tot avg alloc %tot avg │ ────────────────────────────────────────────────────────────────────────────── │ Build Simulation 1 1.87s 100% 1.87s 254MiB 100% 254MiB │ Build Problems 1 1.87s 100% 1.87s 254MiB 100% 254MiB │ Problem ED 1 1.01s 53.9% 1.01s 131MiB 51.5% 131MiB │ Build pre-step 1 805ms 43.1% 805ms 100MiB 39.3% 100MiB │ PowerLoad 1 4.22ms 0.23% 4.22ms 113KiB 0.04% 113KiB │ ThermalStandard 1 2.36ms 0.13% 2.36ms 1.22MiB 0.48% 1.22MiB │ RenewableDis... 1 2.36ms 0.13% 2.36ms 250KiB 0.10% 250KiB │ Objective 1 652μs 0.03% 652μs 175KiB 0.07% 175KiB │ CopperPlateP... 1 545μs 0.03% 545μs 222KiB 0.09% 222KiB │ Services 1 124μs 0.01% 124μs 10.4KiB 0.00% 10.4KiB │ HydroDispatch 1 73.6μs 0.00% 73.6μs 4.58KiB 0.00% 4.58KiB │ RenewableFix 1 39.2μs 0.00% 39.2μs 4.58KiB 0.00% 4.58KiB │ HydroEnergyR... 1 26.7μs 0.00% 26.7μs 4.70KiB 0.00% 4.70KiB │ Interruptibl... 1 15.8μs 0.00% 15.8μs 4.63KiB 0.00% 4.63KiB │ Line 1 1.89μs 0.00% 1.89μs 64.0B 0.00% 64.0B │ TapTransformer 1 1.05μs 0.00% 1.05μs 64.0B 0.00% 64.0B │ HVDCLine 1 710ns 0.00% 710ns 64.0B 0.00% 64.0B │ Transformer2W 1 573ns 0.00% 573ns 64.0B 0.00% 64.0B │ Problem UC 1 859ms 45.9% 859ms 123MiB 48.5% 123MiB │ ThermalStandard 1 493ms 26.4% 493ms 41.2MiB 16.2% 41.2MiB │ Services 1 140ms 7.51% 140ms 16.5MiB 6.49% 16.5MiB │ Build pre-step 1 38.4ms 2.05% 38.4ms 2.55MiB 1.00% 2.55MiB │ RenewableDis... 1 3.42ms 0.18% 3.42ms 962KiB 0.37% 962KiB │ PowerLoad 1 2.98ms 0.16% 2.98ms 321KiB 0.12% 321KiB │ CopperPlateP... 1 855μs 0.05% 855μs 454KiB 0.17% 454KiB │ Objective 1 72.8μs 0.00% 72.8μs 109KiB 0.04% 109KiB │ HydroDispatch 1 68.9μs 0.00% 68.9μs 4.58KiB 0.00% 4.58KiB │ RenewableFix 1 47.5μs 0.00% 47.5μs 4.58KiB 0.00% 4.58KiB │ HydroEnergyR... 1 43.0μs 0.00% 43.0μs 4.70KiB 0.00% 4.70KiB │ Interruptibl... 1 19.5μs 0.00% 19.5μs 4.63KiB 0.00% 4.63KiB │ Line 1 2.10μs 0.00% 2.10μs 64.0B 0.00% 64.0B │ HVDCLine 1 725ns 0.00% 725ns 64.0B 0.00% 64.0B │ TapTransformer 1 650ns 0.00% 650ns 64.0B 0.00% 64.0B │ Transformer2W 1 603ns 0.00% 603ns 64.0B 0.00% 64.0B │ Initialize Simul... 1 1.06ms 0.06% 1.06ms 19.7KiB 0.01% 19.7KiB │ Serializing Simu... 1 995μs 0.05% 995μs 16.0KiB 0.01% 16.0KiB │ Check Steps 1 33.7μs 0.00% 33.7μs 4.45KiB 0.00% 4.45KiB │ Assign FeedForward 1 29.9μs 0.00% 29.9μs 3.16KiB 0.00% 3.16KiB └ ──────────────────────────────────────────────────────────────────────────────
BuildStatus.BUILT = 0
execute!(sim, enable_progress_bar = false)
****************************************************************************** This program contains Ipopt, a library for large-scale nonlinear optimization. Ipopt is released as open source code under the Eclipse Public License (EPL). For more information visit https://github.com/coin-or/Ipopt ******************************************************************************
RunStatus.SUCCESSFUL = 0
# Results
First we can load the result metadata
results = SimulationResults(sim);
uc_results = get_problem_results(results, "UC")
ed_results = get_problem_results(results, "ED");
Then we can read and examine the results of interest
prices = read_dual(ed_results, :CopperPlateBalance)
or if we want to look at the realized values
read_realized_duals(ed_results)[:CopperPlateBalance]
note that in this simulation the prices are all equal to the balance slack penalty value of $100000/MWh because there is unserved energy in the result
This notebook was generated using Literate.jl.