Sequential Simulations with PowerSimulations.jl
Originally Contributed by: Clayton Barrows
Introduction
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. This example is intended to be an extension of the OperationsProblem tutorial.
Load Packages
julia> using PowerSystemsjulia> using PowerSimulationsjulia> using HydroPowerSimulationsjulia> const PSI = PowerSimulationsPowerSimulationsjulia> using PowerSystemCaseBuilderjulia> using Datesjulia> using HiGHS #solver
Optimizer
It's most convenient to define an optimizer instance upfront and pass it into the DecisionModel constructor. For this example, we can use the free HiGHS solver with a relatively relaxed MIP gap (ratioGap) setting to improve speed.
julia> solver = optimizer_with_attributes(HiGHS.Optimizer, "mip_rel_gap" => 0.5)MathOptInterface.OptimizerWithAttributes(HiGHS.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("mip_rel_gap") => 0.5])
Hourly day-ahead system
First, we'll create a System with hourly data to represent day-ahead forecasted wind, solar, and load profiles:
julia> sys_DA = build_system(PSISystems, "modified_RTS_GMLC_DA_sys"; skip_serialization = true)[ Info: Loaded time series from storage file existing=/home/runner/.julia/packages/PowerSystemCaseBuilder/tnwpN/data/serialized_system/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/modified_RTS_GMLC_DA_sys_time_series_storage.h5 new=/tmp/jl_4wOgvW compression=CompressionSettings(false, CompressionTypes.DEFLATE = 1, 3, true) System ┌───────────────────┬─────────────┐ │ Property │ Value │ ├───────────────────┼─────────────┤ │ Name │ │ │ Description │ │ │ System Units Base │ SYSTEM_BASE │ │ Base Power │ 100.0 │ │ Base Frequency │ 60.0 │ │ Num Components │ 504 │ └───────────────────┴─────────────┘ Static Components ┌──────────────────────────────┬───────┐ │ Type │ Count │ ├──────────────────────────────┼───────┤ │ ACBus │ 73 │ │ Arc │ 109 │ │ Area │ 3 │ │ FixedAdmittance │ 3 │ │ HydroDispatch │ 1 │ │ Line │ 105 │ │ LoadZone │ 21 │ │ PowerLoad │ 51 │ │ RenewableDispatch │ 29 │ │ RenewableNonDispatch │ 31 │ │ SynchronousCondenser │ 3 │ │ TapTransformer │ 15 │ │ ThermalStandard │ 54 │ │ TwoTerminalGenericHVDCLine │ 1 │ │ VariableReserve{ReserveDown} │ 1 │ │ VariableReserve{ReserveUp} │ 4 │ └──────────────────────────────┴───────┘ StaticTimeSeries Summary ┌──────────────────────┬────────────────┬──────────────────┬──────────────────── │ owner_type │ owner_category │ name │ time_series_type ⋯ │ String │ String │ String │ String ⋯ ├──────────────────────┼────────────────┼──────────────────┼──────────────────── │ Area │ Component │ max_active_power │ SingleTimeSeries ⋯ │ FixedAdmittance │ Component │ max_active_power │ SingleTimeSeries ⋯ │ HydroDispatch │ Component │ max_active_power │ SingleTimeSeries ⋯ │ PowerLoad │ Component │ max_active_power │ SingleTimeSeries ⋯ │ RenewableDispatch │ Component │ max_active_power │ SingleTimeSeries ⋯ │ RenewableNonDispatch │ Component │ max_active_power │ SingleTimeSeries ⋯ │ VariableReserve │ Component │ requirement │ SingleTimeSeries ⋯ └──────────────────────┴────────────────┴──────────────────┴──────────────────── 4 columns omitted Forecast Summary ┌──────────────────────┬────────────────┬──────────────────┬──────────────────── │ owner_type │ owner_category │ name │ time_series_type ⋯ │ String │ String │ String │ String ⋯ ├──────────────────────┼────────────────┼──────────────────┼──────────────────── │ Area │ Component │ max_active_power │ DeterministicSing ⋯ │ FixedAdmittance │ Component │ max_active_power │ DeterministicSing ⋯ │ HydroDispatch │ Component │ max_active_power │ DeterministicSing ⋯ │ PowerLoad │ Component │ max_active_power │ DeterministicSing ⋯ │ RenewableDispatch │ Component │ max_active_power │ DeterministicSing ⋯ │ RenewableNonDispatch │ Component │ max_active_power │ DeterministicSing ⋯ │ VariableReserve │ Component │ requirement │ DeterministicSing ⋯ └──────────────────────┴────────────────┴──────────────────┴──────────────────── 7 columns omitted
5-Minute system
The RTS data also includes 5-minute resolution time series data. So, we can create another System to represent 15 minute ahead forecasted data for a "real-time" market:
julia> sys_RT = build_system(PSISystems, "modified_RTS_GMLC_RT_sys"; skip_serialization = true)┌ Info: Building new system modified_RTS_GMLC_RT_sys from raw data └ sys_descriptor.raw_data = "/home/runner/.julia/artifacts/c257b2c37b981f261fdc328b0fb9b96436a96537/RTS-GMLC-0.2.3" [ Info: Parsing csv data in branch.csv ... [ Info: Successfully parsed branch.csv [ Info: Parsing csv data in bus.csv ... [ Info: Successfully parsed bus.csv [ Info: Parsing csv data in dc_branch.csv ... [ Info: Successfully parsed dc_branch.csv [ Info: Parsing csv data in gen.csv ... [ Info: Successfully parsed gen.csv [ Info: Parsing csv data in reserves.csv ... [ Info: Successfully parsed reserves.csv [ Info: Parsing csv data in simulation_objects.csv ... [ Info: Successfully parsed simulation_objects.csv [ Info: Parsing csv data in storage.csv ... [ Info: Successfully parsed storage.csv [ Info: Parsing csv data in timeseries_pointers.csv ... [ Info: Successfully parsed timeseries_pointers.csv [ Info: Unit System changed to UnitSystem.DEVICE_BASE = 1 ┌ Warning: Missing PowerSystems.InputCategoryModule.InputCategory.LOAD = 5 data. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:300 ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: Rating calculation returned 0.0. Changing to 1.0 in the p.u. of the device. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/common.jl:120 ┌ Warning: Generator SynchronousCondenser: 114_SYNC_COND_1 has base power of zero: changing device base power to match system base power, 100.0 └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:938 ┌ Warning: Rating calculation returned 0.0. Changing to 1.0 in the p.u. of the device. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/common.jl:120 ┌ Warning: Generator SynchronousCondenser: 214_SYNC_COND_1 has base power of zero: changing device base power to match system base power, 100.0 └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:938 ┌ Warning: Rating calculation returned 0.0. Changing to 1.0 in the p.u. of the device. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/common.jl:120 ┌ Warning: Generator SynchronousCondenser: 314_SYNC_COND_1 has base power of zero: changing device base power to match system base power, 100.0 └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:938 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 ┌ Warning: Heat rate parsing not valid for RenewableGen replacing with zero cost └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1039 [ Info: Adding contributing generators for Spin_Up_R1 by category ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 [ Info: Adding contributing generators for Spin_Up_R2 by category ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 [ Info: Adding contributing generators for Spin_Up_R3 by category ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 [ Info: Adding contributing generators for Flex_Up by category ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 [ Info: Adding contributing generators for Flex_Down by category ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 [ Info: Adding contributing generators for Reg_Up by category ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 [ Info: Adding contributing generators for Reg_Down by category ┌ Warning: User-defined column name Startup Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Shutdown Ramp Rate MW/min is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Status at Start is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Time at Status is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Cold is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Warm is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Start Cost Hot is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: User-defined column name Must Run is not in dataframe. └ @ PowerSystems ~/.julia/packages/PowerSystems/VW7nY/src/parsers/power_system_table_data.jl:1778 ┌ Warning: no component category=Component name=201_HYDRO_4_RESERVOIR_head └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/vIcUz/src/system_data.jl:776 [ Info: Unit System changed to UnitSystem.SYSTEM_BASE = 0 System ┌───────────────────┬─────────────┐ │ Property │ Value │ ├───────────────────┼─────────────┤ │ Name │ │ │ Description │ │ │ System Units Base │ SYSTEM_BASE │ │ Base Power │ 100.0 │ │ Base Frequency │ 60.0 │ │ Num Components │ 502 │ └───────────────────┴─────────────┘ Static Components ┌──────────────────────────────┬───────┐ │ Type │ Count │ ├──────────────────────────────┼───────┤ │ ACBus │ 73 │ │ Arc │ 109 │ │ Area │ 1 │ │ FixedAdmittance │ 3 │ │ HydroDispatch │ 1 │ │ Line │ 105 │ │ LoadZone │ 21 │ │ PowerLoad │ 51 │ │ RenewableDispatch │ 29 │ │ RenewableNonDispatch │ 31 │ │ SynchronousCondenser │ 3 │ │ TapTransformer │ 15 │ │ ThermalStandard │ 54 │ │ TwoTerminalGenericHVDCLine │ 1 │ │ VariableReserve{ReserveDown} │ 1 │ │ VariableReserve{ReserveUp} │ 4 │ └──────────────────────────────┴───────┘ StaticTimeSeries Summary ┌──────────────────────┬────────────────┬──────────────────┬──────────────────── │ owner_type │ owner_category │ name │ time_series_type ⋯ │ String │ String │ String │ String ⋯ ├──────────────────────┼────────────────┼──────────────────┼──────────────────── │ Area │ Component │ max_active_power │ SingleTimeSeries ⋯ │ FixedAdmittance │ Component │ max_active_power │ SingleTimeSeries ⋯ │ HydroDispatch │ Component │ max_active_power │ SingleTimeSeries ⋯ │ PowerLoad │ Component │ max_active_power │ SingleTimeSeries ⋯ │ RenewableDispatch │ Component │ max_active_power │ SingleTimeSeries ⋯ │ RenewableNonDispatch │ Component │ max_active_power │ SingleTimeSeries ⋯ │ VariableReserve │ Component │ requirement │ SingleTimeSeries ⋯ └──────────────────────┴────────────────┴──────────────────┴──────────────────── 4 columns omitted Forecast Summary ┌──────────────────────┬────────────────┬──────────────────┬──────────────────── │ owner_type │ owner_category │ name │ time_series_type ⋯ │ String │ String │ String │ String ⋯ ├──────────────────────┼────────────────┼──────────────────┼──────────────────── │ Area │ Component │ max_active_power │ DeterministicSing ⋯ │ FixedAdmittance │ Component │ max_active_power │ DeterministicSing ⋯ │ HydroDispatch │ Component │ max_active_power │ DeterministicSing ⋯ │ PowerLoad │ Component │ max_active_power │ DeterministicSing ⋯ │ RenewableDispatch │ Component │ max_active_power │ DeterministicSing ⋯ │ RenewableNonDispatch │ Component │ max_active_power │ DeterministicSing ⋯ │ VariableReserve │ Component │ requirement │ DeterministicSing ⋯ └──────────────────────┴────────────────┴──────────────────┴──────────────────── 7 columns omitted
ProblemTemplates define stages
Sequential simulations in PowerSimulations are created by defining OperationsProblems that represent stages, and how information flows between executions of a stage and between different stages.
Let's start by defining a two stage simulation that might look like a typical day-Ahead and real-time electricity market clearing process.
Day-ahead unit commitment stage
First, we can define a unit commitment template for the day ahead problem. We can use the included UC template, but in this example, we'll replace the ThermalBasicUnitCommitment with the slightly more complex ThermalStandardUnitCommitment for the thermal generators.
julia> template_uc = template_unit_commitment()Network Model ┌────────────────────┬───────────────────────┐ │ Network Model │ CopperPlatePowerModel │ │ Slacks │ false │ │ PTDF │ false │ │ Duals │ None │ │ HVDC Network Model │ None │ └────────────────────┴───────────────────────┘ Device Models ┌────────────────────────┬────────────────────────────┬────────┐ │ Device Type │ Formulation │ Slacks │ ├────────────────────────┼────────────────────────────┼────────┤ │ RenewableNonDispatch │ FixedOutput │ false │ │ ThermalStandard │ ThermalBasicUnitCommitment │ false │ │ PowerLoad │ StaticPowerLoad │ false │ │ InterruptiblePowerLoad │ PowerLoadInterruption │ false │ │ RenewableDispatch │ RenewableFullDispatch │ false │ └────────────────────────┴────────────────────────────┴────────┘ Branch Models ┌────────────────────────────┬─────────────────────────┬────────┐ │ Branch Type │ Formulation │ Slacks │ ├────────────────────────────┼─────────────────────────┼────────┤ │ Line │ StaticBranch │ false │ │ TapTransformer │ StaticBranch │ false │ │ Transformer2W │ StaticBranch │ false │ │ TwoTerminalGenericHVDCLine │ HVDCTwoTerminalDispatch │ false │ └────────────────────────────┴─────────────────────────┴────────┘ Service Models ┌──────────────────────────────┬──────────────┬────────┬──────────────────┐ │ Service Type │ Formulation │ Slacks │ Aggregated Model │ ├──────────────────────────────┼──────────────┼────────┼──────────────────┤ │ VariableReserve{ReserveUp} │ RangeReserve │ false │ true │ │ VariableReserve{ReserveDown} │ RangeReserve │ false │ true │ └──────────────────────────────┴──────────────┴────────┴──────────────────┘julia> set_device_model!(template_uc, ThermalStandard, ThermalStandardUnitCommitment)┌ Warning: Overwriting ThermalStandard existing model └ @ PowerSimulations ~/work/PowerSimulations.jl/PowerSimulations.jl/src/core/device_model.jl:111julia> set_device_model!(template_uc, HydroDispatch, HydroDispatchRunOfRiver)
Define the reference model for the real-time economic dispatch
In addition to the manual specification process demonstrated in the OperationsProblem example, PSI also provides pre-specified templates for some standard problems:
julia> template_ed = template_economic_dispatch(; network = NetworkModel(PTDFPowerModel; use_slacks = true), )Network Model ┌────────────────────┬────────────────┐ │ Network Model │ PTDFPowerModel │ │ Slacks │ true │ │ PTDF │ false │ │ Duals │ None │ │ HVDC Network Model │ None │ └────────────────────┴────────────────┘ Device Models ┌────────────────────────┬───────────────────────┬────────┐ │ Device Type │ Formulation │ Slacks │ ├────────────────────────┼───────────────────────┼────────┤ │ RenewableNonDispatch │ FixedOutput │ false │ │ ThermalStandard │ ThermalBasicDispatch │ false │ │ PowerLoad │ StaticPowerLoad │ false │ │ InterruptiblePowerLoad │ PowerLoadInterruption │ false │ │ RenewableDispatch │ RenewableFullDispatch │ false │ └────────────────────────┴───────────────────────┴────────┘ Branch Models ┌────────────────────────────┬─────────────────────────┬────────┐ │ Branch Type │ Formulation │ Slacks │ ├────────────────────────────┼─────────────────────────┼────────┤ │ Line │ StaticBranch │ false │ │ TapTransformer │ StaticBranch │ false │ │ Transformer2W │ StaticBranch │ false │ │ TwoTerminalGenericHVDCLine │ HVDCTwoTerminalDispatch │ false │ └────────────────────────────┴─────────────────────────┴────────┘ Service Models ┌──────────────────────────────┬──────────────┬────────┬──────────────────┐ │ Service Type │ Formulation │ Slacks │ Aggregated Model │ ├──────────────────────────────┼──────────────┼────────┼──────────────────┤ │ VariableReserve{ReserveUp} │ RangeReserve │ false │ true │ │ VariableReserve{ReserveDown} │ RangeReserve │ false │ true │ └──────────────────────────────┴──────────────┴────────┴──────────────────┘
Define the SimulationModels
DecisionModels define the problems that are executed in the simulation. The actual problem will change as the stage gets updated to represent different time periods, but the formulations applied to the components is constant within a stage. In this case, we want to define two stages with theProblemTemplates and theSystem`s that we've already created.
julia> models = SimulationModels(; decision_models = [ DecisionModel(template_uc, sys_DA; optimizer = solver, name = "UC"), DecisionModel(template_ed, sys_RT; optimizer = solver, name = "ED"), ], )┌ Warning: Transformer2W is included in the template but no available components exist in the system └ @ PowerSimulations ~/work/PowerSimulations.jl/PowerSimulations.jl/src/operation/problem_template.jl:358 ┌ Warning: Transformer2W is included in the template but no available components exist in the system └ @ PowerSimulations ~/work/PowerSimulations.jl/PowerSimulations.jl/src/operation/problem_template.jl:358 Decision Models ┌────────────┬──────────────────┬────────┬──────────────────┐ │ Model Name │ Model Type │ Status │ Output Directory │ ├────────────┼──────────────────┼────────┼──────────────────┤ │ UC │ GenericOpProblem │ EMPTY │ nothing │ │ ED │ GenericOpProblem │ EMPTY │ nothing │ └────────────┴──────────────────┴────────┴──────────────────┘ No Emulator Model Specified
SimulationSequence
Similar to a ProblemTemplate, the SimulationSequence provides a template of how to execute a sequential set of operations problems.
Let's review some of the SimulationSequence arguments.
Chronologies
In PowerSimulations, chronologies define where information is flowing. There are two types of chronologies.
- inter-stage chronologies: Define how information flows between stages. e.g. day-ahead solutions are used to inform economic dispatch problems
- intra-stage chronologies: Define how information flows between multiple executions of a single stage. e.g. the dispatch setpoints of the first period of an economic dispatch problem are constrained by the ramping limits from setpoints in the final period of the previous problem.
FeedForward
The definition of exactly what information is passed using the defined chronologies is accomplished with FeedForward. Specifically, FeedForward is used to define what to do with information being passed with an inter-stage chronology. Let's define a FeedForward that affects the semi-continuous range constraints of thermal generators in the economic dispatch problems based on the value of the unit-commitment variables.
julia> feedforward = Dict( "ED" => [ SemiContinuousFeedforward(; component_type = ThermalStandard, source = OnVariable, affected_values = [ActivePowerVariable], ), ], )Dict{String, Vector{SemiContinuousFeedforward}} with 1 entry: "ED" => [SemiContinuousFeedforward(VariableKey{OnVariable, ThermalStandard}("…
Sequencing
The stage problem length, look-ahead, and other details surrounding the temporal Sequencing of stages are controlled using the structure of the time series data in the Systems. So, to define a typical day-ahead - real-time sequence:
- Day ahead problems should represent 48 hours, advancing 24 hours after each execution (24-hour look-ahead)
- Real time problems should represent 1 hour (12 5-minute periods), advancing 15 min after each execution (15 min look-ahead)
We can adjust the time series data to reflect this structure in each System:
transform_single_time_series!(sys_DA, Hour(48), Hour(24))transform_single_time_series!(sys_RT, Minute(60), Minute(15))
Now we can put it all together to define a SimulationSequence
julia> DA_RT_sequence = SimulationSequence(; models = models, ini_cond_chronology = InterProblemChronology(), feedforwards = feedforward, )Simulation Sequence ┌──────────────────────────┬──────────┐ │ Simulation Step Interval │ 24 hours │ │ Number of Problems │ 2 │ └──────────────────────────┴──────────┘ Simulation Problems ┌────────────┬─────────┬────────────┬─────────────────────┐ │ Model Name │ Horizon │ Interval │ Executions Per Step │ ├────────────┼─────────┼────────────┼─────────────────────┤ │ UC │ 2 days │ 1 day │ 1 │ │ ED │ 1 hour │ 15 minutes │ 96 │ └────────────┴─────────┴────────────┴─────────────────────┘ Feedforwards ┌────────────┬───────────────────────────┐ │ Model Name │ Feed Forward Type │ ├────────────┼───────────────────────────┤ │ ED │ SemiContinuousFeedforward │ └────────────┴───────────────────────────┘
Simulation
Now, we can build and execute a simulation using the SimulationSequence and Stages that we've defined.
julia> sim = Simulation(; name = "rts-test", steps = 2, models = models, sequence = DA_RT_sequence, simulation_folder = joinpath(".", "rts-store"), )Simulation ┌─────────────────┬────────────────────┐ │ Simulation Name │ rts-test │ │ Build Status │ EMPTY │ │ Run Status │ NOT_READY │ │ Initial Time │ Unset Initial Time │ │ Steps │ 2 │ └─────────────────┴────────────────────┘ Decision Models ┌────────────┬──────────────────┬────────┬──────────────────┐ │ Model Name │ Model Type │ Status │ Output Directory │ ├────────────┼──────────────────┼────────┼──────────────────┤ │ UC │ GenericOpProblem │ EMPTY │ nothing │ │ ED │ GenericOpProblem │ EMPTY │ nothing │ └────────────┴──────────────────┴────────┴──────────────────┘ No Emulator Model Specified Simulation Sequence ┌──────────────────────────┬──────────┐ │ Simulation Step Interval │ 24 hours │ │ Number of Problems │ 2 │ └──────────────────────────┴──────────┘ Simulation Problems ┌────────────┬─────────┬────────────┬─────────────────────┐ │ Model Name │ Horizon │ Interval │ Executions Per Step │ ├────────────┼─────────┼────────────┼─────────────────────┤ │ UC │ 2 days │ 1 day │ 1 │ │ ED │ 1 hour │ 15 minutes │ 96 │ └────────────┴─────────┴────────────┴─────────────────────┘ Feedforwards ┌────────────┬───────────────────────────┐ │ Model Name │ Feed Forward Type │ ├────────────┼───────────────────────────┤ │ ED │ SemiContinuousFeedforward │ └────────────┴───────────────────────────┘
Build simulation
julia> build!(sim)┌ Info: │ ───────────────────────────────────────────────────────────────────────────────────────────── │ Time Allocations │ ─────────────────────── ──────────────────────── │ Tot / % measured: 34.2s / 100.0% 2.65GiB / 100.0% │ │ Section ncalls time %tot avg alloc %tot avg │ ───────────────────────────────────────────────────────────────────────────────────────────── │ Build Simulation 1 34.2s 100.0% 34.2s 2.65GiB 100.0% 2.65GiB │ Build Decision Problems 1 21.0s 61.2% 21.0s 1.92GiB 72.7% 1.92GiB │ Problem ED 1 16.5s 48.3% 16.5s 1.47GiB 55.6% 1.47GiB │ Line 2 3.21s 9.4% 1.61s 417MiB 15.4% 208MiB │ ThermalStandard 2 3.14s 9.2% 1.57s 239MiB 8.8% 120MiB │ TapTransformer 2 1.43s 4.2% 713ms 186MiB 6.8% 92.8MiB │ TwoTerminalGenericHVDCLine 2 905ms 2.6% 452ms 49.2MiB 1.8% 24.6MiB │ PTDFPowerModel 1 531ms 1.6% 531ms 16.6MiB 0.6% 16.6MiB │ Numerical Bounds Check 1 348ms 1.0% 348ms 46.4MiB 1.7% 46.4MiB │ RenewableNonDispatch 2 289ms 0.8% 144ms 10.6MiB 0.4% 5.28MiB │ RenewableDispatch 2 224ms 0.7% 112ms 7.59MiB 0.3% 3.80MiB │ PowerLoad 2 165ms 0.5% 82.6ms 6.42MiB 0.2% 3.21MiB │ Services 2 135ms 0.4% 67.5ms 10.2MiB 0.4% 5.11MiB │ Build pre-step 1 123ms 0.4% 123ms 5.60MiB 0.2% 5.60MiB │ Model Initialization 1 307μs 0.0% 307μs 43.8KiB 0.0% 43.8KiB │ Objective 1 259μs 0.0% 259μs 500KiB 0.0% 500KiB │ InterruptiblePowerLoad 2 32.2μs 0.0% 16.1μs 448B 0.0% 224B │ Power Flow Initialization 1 19.8μs 0.0% 19.8μs 896B 0.0% 896B │ Transformer2W 2 17.1μs 0.0% 8.56μs 448B 0.0% 224B │ Problem UC 1 4.43s 12.9% 4.43s 464MiB 17.1% 464MiB │ Model Initialization 1 2.31s 6.8% 2.31s 198MiB 7.3% 198MiB │ ThermalStandard 2 657ms 1.9% 328ms 88.8MiB 3.3% 44.4MiB │ RenewableNonDispatch 2 602ms 1.8% 301ms 41.1MiB 1.5% 20.6MiB │ Services 2 180ms 0.5% 90.1ms 34.6MiB 1.3% 17.3MiB │ Numerical Bounds Check 1 158ms 0.5% 158ms 58.0MiB 2.1% 58.0MiB │ RenewableDispatch 2 106ms 0.3% 53.1ms 11.4MiB 0.4% 5.70MiB │ PowerLoad 2 98.6ms 0.3% 49.3ms 10.8MiB 0.4% 5.39MiB │ HydroDispatch 2 78.1ms 0.2% 39.0ms 2.78MiB 0.1% 1.39MiB │ InterruptiblePowerLoad 2 21.7ms 0.1% 10.9ms 434KiB 0.0% 217KiB │ Line 2 6.89ms 0.0% 3.45ms 1.19MiB 0.0% 607KiB │ TapTransformer 2 1.51ms 0.0% 756μs 251KiB 0.0% 125KiB │ Objective 1 1.26ms 0.0% 1.26ms 2.24MiB 0.1% 2.24MiB │ Build pre-step 1 1.16ms 0.0% 1.16ms 64.1KiB 0.0% 64.1KiB │ TwoTerminalGenericHVDCLine 2 571μs 0.0% 285μs 147KiB 0.0% 73.7KiB │ CopperPlatePowerModel 1 536μs 0.0% 536μs 515KiB 0.0% 515KiB │ Power Flow Initialization 1 20.7μs 0.0% 20.7μs 896B 0.0% 896B │ Transformer2W 2 10.6μs 0.0% 5.30μs 448B 0.0% 224B │ Initialize Simulation State 1 5.51s 16.1% 5.51s 282MiB 10.4% 282MiB │ Serializing Simulation Files 1 155ms 0.5% 155ms 22.9MiB 0.8% 22.9MiB │ Check Steps 1 8.54μs 0.0% 8.54μs 1.12KiB 0.0% 1.12KiB └ ───────────────────────────────────────────────────────────────────────────────────────────── InfrastructureSystems.Simulation.SimulationBuildStatusModule.SimulationBuildStatus.BUILT = 0
Execute simulation
the following command returns the status of the simulation (0: is proper execution) and stores the results in a set of HDF5 files on disk.
julia> execute!(sim; enable_progress_bar = false)InfrastructureSystems.Simulation.RunStatusModule.RunStatus.SUCCESSFULLY_FINALIZED = 0
Results
To access the results, we need to load the simulation result metadata and then make requests to the specific data of interest. This allows you to efficiently access the results of interest without overloading resources.
julia> results = SimulationResults(sim);julia> uc_results = get_decision_problem_results(results, "UC"); # UC stage result metadatajulia> ed_results = get_decision_problem_results(results, "ED"); # ED stage result metadata
We can read all the result variables
julia> read_variables(uc_results)Dict{String, SortedDict{Dates.DateTime, DataFrames.DataFrame, Base.Order.ForwardOrdering}} with 15 entries: "ActivePowerReserveVaria… => SortedDict(DateTime("2020-01-01T00:00:00")=>2448… "StopVariable__ThermalSt… => SortedDict(DateTime("2020-01-01T00:00:00")=>2592… "OnVariable__ThermalStan… => SortedDict(DateTime("2020-01-01T00:00:00")=>2592… "ActivePowerReserveVaria… => SortedDict(DateTime("2020-01-01T00:00:00")=>864×… "HVDCFlowDirectionVariab… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "ActivePowerVariable__Re… => SortedDict(DateTime("2020-01-01T00:00:00")=>1392… "ActivePowerReserveVaria… => SortedDict(DateTime("2020-01-01T00:00:00")=>816×… "ActivePowerReserveVaria… => SortedDict(DateTime("2020-01-01T00:00:00")=>2448… "ActivePowerVariable__Hy… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "FlowActivePowerToFromVa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "StartVariable__ThermalS… => SortedDict(DateTime("2020-01-01T00:00:00")=>2592… "FlowActivePowerFromToVa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "ActivePowerVariable__Th… => SortedDict(DateTime("2020-01-01T00:00:00")=>2592… "HVDCLosses__TwoTerminal… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "ActivePowerReserveVaria… => SortedDict(DateTime("2020-01-01T00:00:00")=>768×…
or all the parameters
julia> read_parameters(uc_results)Dict{String, SortedDict{Dates.DateTime, DataFrames.DataFrame, Base.Order.ForwardOrdering}} with 9 entries: "RequirementTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "ActivePowerTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>2448… "ActivePowerTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>1488… "ActivePowerTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>1392… "RequirementTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "ActivePowerTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "RequirementTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "RequirementTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3… "RequirementTimeSeriesPa… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3…
We can just list the variable names contained in uc_results:
julia> list_variable_names(uc_results)15-element Vector{String}: "FlowActivePowerFromToVariable__TwoTerminalGenericHVDCLine" "ActivePowerReserveVariable__VariableReserve__ReserveUp__Spin_Up_R1" "ActivePowerVariable__ThermalStandard" "ActivePowerVariable__RenewableDispatch" "FlowActivePowerToFromVariable__TwoTerminalGenericHVDCLine" "ActivePowerReserveVariable__VariableReserve__ReserveUp__Reg_Up" "HVDCLosses__TwoTerminalGenericHVDCLine" "ActivePowerReserveVariable__VariableReserve__ReserveUp__Spin_Up_R3" "ActivePowerReserveVariable__VariableReserve__ReserveUp__Spin_Up_R2" "ActivePowerReserveVariable__VariableReserve__ReserveDown__Reg_Down" "OnVariable__ThermalStandard" "StartVariable__ThermalStandard" "ActivePowerVariable__HydroDispatch" "StopVariable__ThermalStandard" "HVDCFlowDirectionVariable__TwoTerminalGenericHVDCLine"
and a number of parameters (this pattern also works for aux_variables, expressions, and duals)
julia> list_parameter_names(uc_results)9-element Vector{String}: "ActivePowerTimeSeriesParameter__RenewableNonDispatch" "ActivePowerTimeSeriesParameter__HydroDispatch" "RequirementTimeSeriesParameter__VariableReserve__ReserveUp__Spin_Up_R1" "ActivePowerTimeSeriesParameter__RenewableDispatch" "ActivePowerTimeSeriesParameter__PowerLoad" "RequirementTimeSeriesParameter__VariableReserve__ReserveUp__Spin_Up_R3" "RequirementTimeSeriesParameter__VariableReserve__ReserveUp__Reg_Up" "RequirementTimeSeriesParameter__VariableReserve__ReserveUp__Spin_Up_R2" "RequirementTimeSeriesParameter__VariableReserve__ReserveDown__Reg_Down"
Now we can read the specific results of interest for a specific problem, time window (optional), and set of variables, duals, or parameters (optional)
julia> Dict([ v => read_variable(uc_results, v) for v in [ "ActivePowerVariable__RenewableDispatch", "ActivePowerVariable__HydroDispatch", "StopVariable__ThermalStandard", ] ])Dict{String, SortedDict{Dates.DateTime, DataFrames.DataFrame, Base.Order.ForwardOrdering}} with 3 entries: "StopVariable__ThermalSt… => SortedDict(DateTime("2020-01-01T00:00:00")=>2592… "ActivePowerVariable__Re… => SortedDict(DateTime("2020-01-01T00:00:00")=>1392… "ActivePowerVariable__Hy… => SortedDict(DateTime("2020-01-01T00:00:00")=>48×3…
Or if we want the result of just one variable, parameter, or dual (must be defined in the problem definition), we can use:
julia> read_parameter( ed_results, "ActivePowerTimeSeriesParameter__RenewableNonDispatch"; initial_time = DateTime("2020-01-01T06:00:00"), count = 5, )SortedDict{Dates.DateTime, DataFrames.DataFrame, Base.Order.ForwardOrdering} with 5 entries: DateTime("2020-01-01T06:00:00") => 372×3 DataFrame… DateTime("2020-01-01T06:15:00") => 372×3 DataFrame… DateTime("2020-01-01T06:30:00") => 372×3 DataFrame… DateTime("2020-01-01T06:45:00") => 372×3 DataFrame… DateTime("2020-01-01T07:00:00") => 372×3 DataFrame…
note that this returns the results of each execution step in a separate dataframe If you want the realized results (without lookahead periods), you can call read_realized_*:
julia> read_realized_variables( uc_results, ["ActivePowerVariable__ThermalStandard", "ActivePowerVariable__RenewableDispatch"], )Dict{String, DataFrames.DataFrame} with 2 entries: "ActivePowerVariable__Th… => 2592×3 DataFrame… "ActivePowerVariable__Re… => 1392×3 DataFrame…
Plotting
Take a look at the plotting capabilities in PowerGraphics.jl