Operation Problem with HydroPowerSimulations.jl
HydroPowerSimulations.jl
is an extension library of PowerSimulations.jl
for modeling hydro units. Users are encouraged to review the single-step tutorial in PowerSimulations.jl
before this tutorial.
Load packages
julia> using PowerSystems
julia> using PowerSimulations
julia> using HydroPowerSimulations
julia> using PowerSystemCaseBuilder
julia> using HiGHS # solver
Data
PowerSystemCaseBuilder.jl
is a helper library that makes it easier to reproduce examples in the documentation and tutorials. Normally you would pass your local files to create the system data instead of calling the function build_system
. For more details visit PowerSystemCaseBuilder README
julia> sys = build_system(PSITestSystems, "c_sys5_hy")
┌ Info: Building new system c_sys5_hy from raw data └ sys_descriptor.raw_data = "/home/runner/.julia/artifacts/45fbc4fe058ae508e0d03c697ca276c3484a9c5e/PowerSystemsTestData-3.2/psy_data/data_5bus_pu.jl" [ Info: Serialized time series data to /home/runner/.julia/packages/PowerSystemCaseBuilder/dJGb8/data/serialized_system/614e094ea985a55912fc1321256a49b755f9fc451c0f264f24d6d04af20e84d7/c_sys5_hy_time_series_storage.h5. [ Info: Serialized System to /home/runner/.julia/packages/PowerSystemCaseBuilder/dJGb8/data/serialized_system/614e094ea985a55912fc1321256a49b755f9fc451c0f264f24d6d04af20e84d7/c_sys5_hy.json [ Info: Serialized System metadata to /home/runner/.julia/packages/PowerSystemCaseBuilder/dJGb8/data/serialized_system/614e094ea985a55912fc1321256a49b755f9fc451c0f264f24d6d04af20e84d7/c_sys5_hy_metadata.json System ┌───────────────────┬─────────────┐ │ Property │ Value │ ├───────────────────┼─────────────┤ │ Name │ │ │ Description │ │ │ System Units Base │ SYSTEM_BASE │ │ Base Power │ 100.0 │ │ Base Frequency │ 60.0 │ │ Num Components │ 26 │ └───────────────────┴─────────────┘ Static Components ┌─────────────────┬───────┐ │ Type │ Count │ ├─────────────────┼───────┤ │ ACBus │ 5 │ │ Arc │ 6 │ │ HydroDispatch │ 1 │ │ Line │ 6 │ │ PowerLoad │ 3 │ │ ThermalStandard │ 5 │ └─────────────────┴───────┘ Forecast Summary ┌───────────────┬────────────────┬──────────────────┬─────────────────────┬───── │ owner_type │ owner_category │ time_series_type │ initial_timestamp │ re ⋯ │ String │ String │ String │ String │ Da ⋯ ├───────────────┼────────────────┼──────────────────┼─────────────────────┼───── │ HydroDispatch │ Component │ Deterministic │ 2024-01-01T00:00:00 │ 1 ⋯ │ PowerLoad │ Component │ Deterministic │ 2024-01-01T00:00:00 │ 1 ⋯ └───────────────┴────────────────┴──────────────────┴─────────────────────┴───── 5 columns omitted
With a single PowerSystems.HydroDispatch
:
julia> hy = only(get_components(HydroDispatch, sys))
HydroDispatch: HydroDispatch: name: HydroDispatch available: true bus: ACBus: nodeB active_power: 0.0 reactive_power: 0.0 rating: 6.0 prime_mover_type: PowerSystems.PrimeMoversModule.PrimeMovers.HY = 16 active_power_limits: (min = 0.0, max = 6.0) reactive_power_limits: (min = 0.0, max = 6.0) ramp_limits: nothing time_limits: nothing base_power: 100.0 operation_cost: PowerSystems.HydroGenerationCost composed of variable: InfrastructureSystems.CostCurve{InfrastructureSystems.LinearCurve} services: 0-element Vector{PowerSystems.Service} dynamic_injector: nothing ext: Dict{String, Any}() InfrastructureSystems.SystemUnitsSettings: base_value: 100.0 unit_system: InfrastructureSystems.UnitSystemModule.UnitSystem.SYSTEM_BASE = 0 has_supplemental_attributes: false has_time_series: true
Decision Model
Setting up the formulations based on PowerSimulations.jl
:
julia> template = ProblemTemplate(PTDFPowerModel)
Network Model ┌───────────────┬─────────────────────────────────┐ │ Network Model │ PowerSimulations.PTDFPowerModel │ │ Slacks │ false │ │ PTDF │ false │ │ Duals │ None │ └───────────────┴─────────────────────────────────┘ Device Models ┌─────────────┬─────────────┬────────┐ │ Device Type │ Formulation │ Slacks │ └─────────────┴─────────────┴────────┘
julia> set_device_model!(template, ThermalStandard, ThermalBasicDispatch)
julia> set_device_model!(template, PowerLoad, StaticPowerLoad)
julia> set_device_model!(template, Line, StaticBranch)
but, now we also include the hydro using HydroDispatchRunOfRiver
:
julia> set_device_model!(template, HydroDispatch, HydroDispatchRunOfRiver)
With the template properly set-up, we construct, build and solve the optimization problem:
julia> model = DecisionModel(template, sys; optimizer = HiGHS.Optimizer)
[ Info: Overriding time_series_cache_size because time series is stored in memory Network Model ┌───────────────┬─────────────────────────────────┐ │ Network Model │ PowerSimulations.PTDFPowerModel │ │ Slacks │ false │ │ PTDF │ false │ │ Duals │ None │ └───────────────┴─────────────────────────────────┘ Device Models ┌──────────────────────────────┬───────────────────────────────────────┬──────── │ Device Type │ Formulation │ Slack ⋯ ├──────────────────────────────┼───────────────────────────────────────┼──────── │ PowerSystems.ThermalStandard │ PowerSimulations.ThermalBasicDispatch │ false ⋯ │ PowerSystems.PowerLoad │ PowerSimulations.StaticPowerLoad │ false ⋯ │ PowerSystems.HydroDispatch │ HydroDispatchRunOfRiver │ false ⋯ └──────────────────────────────┴───────────────────────────────────────┴──────── 1 column omitted Branch Models ┌───────────────────┬───────────────────────────────┬────────┐ │ Branch Type │ Formulation │ Slacks │ ├───────────────────┼───────────────────────────────┼────────┤ │ PowerSystems.Line │ PowerSimulations.StaticBranch │ false │ └───────────────────┴───────────────────────────────┴────────┘
julia> build!(model; output_dir = mktempdir())
InfrastructureSystems.Optimization.ModelBuildStatusModule.ModelBuildStatus.BUILT = 0
julia> solve!(model)
InfrastructureSystems.Simulation.RunStatusModule.RunStatus.SUCCESSFULLY_FINALIZED = 0
Exploring Results
Results can be explored using:
julia> res = OptimizationProblemResults(model)
Start: 2024-01-01T00:00:00 End: 2024-01-01T23:00:00 Resolution: 60 minutes PowerSimulations Problem Auxiliary variables Results ┌──────────────────────────────────┐ │ HydroEnergyOutput__HydroDispatch │ └──────────────────────────────────┘ PowerSimulations Problem Expressions Results ┌───────────────────────────────────────────┐ │ ProductionCostExpression__HydroDispatch │ │ ProductionCostExpression__ThermalStandard │ │ ActivePowerBalance__ACBus │ │ ActivePowerBalance__System │ └───────────────────────────────────────────┘ PowerSimulations Problem Parameters Results ┌───────────────────────────────────────────────┐ │ ActivePowerTimeSeriesParameter__PowerLoad │ │ ActivePowerTimeSeriesParameter__HydroDispatch │ └───────────────────────────────────────────────┘ PowerSimulations Problem Variables Results ┌──────────────────────────────────────┐ │ ActivePowerVariable__HydroDispatch │ │ FlowActivePowerVariable__Line │ │ ActivePowerVariable__ThermalStandard │ └──────────────────────────────────────┘
Use read_variable
to read in the dispatch variable results for the hydro:
julia> var = read_variable(res, "ActivePowerVariable__HydroDispatch")
24×2 DataFrame Row │ DateTime HydroDispatch │ DateTime Float64 ─────┼──────────────────────────────────── 1 │ 2024-01-01T00:00:00 188.58 2 │ 2024-01-01T01:00:00 232.01 3 │ 2024-01-01T02:00:00 137.149 4 │ 2024-01-01T03:00:00 136.006 5 │ 2024-01-01T04:00:00 133.72 6 │ 2024-01-01T05:00:00 77.718 7 │ 2024-01-01T06:00:00 86.8608 8 │ 2024-01-01T07:00:00 219.439 ⋮ │ ⋮ ⋮ 18 │ 2024-01-01T17:00:00 269.726 19 │ 2024-01-01T18:00:00 378.303 20 │ 2024-01-01T19:00:00 438.877 21 │ 2024-01-01T20:00:00 466.307 22 │ 2024-01-01T21:00:00 427.448 23 │ 2024-01-01T22:00:00 468.593 24 │ 2024-01-01T23:00:00 114.291 9 rows omitted