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 PowerSystemsjulia> using PowerSimulationsjulia> using HydroPowerSimulationsjulia> using PowerSystemCaseBuilderjulia> 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/edcb5940e84a802a86ad4f2223214d33121ac044/PowerSystemsTestData-4.0.2/psy_data/data_5bus_pu.jl" [ Info: Serialized time series data to /home/runner/.julia/packages/PowerSystemCaseBuilder/zW01F/data/serialized_system/4e67b70ea6977dbe21c7731d72cdc1494adf072a7f3f08d921db740cf264ce79/c_sys5_hy_time_series_storage.h5. [ Info: Serialized System to /home/runner/.julia/packages/PowerSystemCaseBuilder/zW01F/data/serialized_system/4e67b70ea6977dbe21c7731d72cdc1494adf072a7f3f08d921db740cf264ce79/c_sys5_hy.json [ Info: Serialized System metadata to /home/runner/.julia/packages/PowerSystemCaseBuilder/zW01F/data/serialized_system/4e67b70ea6977dbe21c7731d72cdc1494adf072a7f3f08d921db740cf264ce79/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 │ name │ time_series_type │ initi ⋯ │ String │ String │ String │ String │ Strin ⋯ ├───────────────┼────────────────┼──────────────────┼──────────────────┼──────── │ HydroDispatch │ Component │ max_active_power │ Deterministic │ 2024- ⋯ │ PowerLoad │ Component │ max_active_power │ Deterministic │ 2024- ⋯ └───────────────┴────────────────┴──────────────────┴──────────────────┴──────── 6 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 status: false time_at_status: 10000.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 │ │ HVDC Network Model │ 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 │ │ HVDC Network Model │ 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 = 0julia> 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 ┌───────────────────────────────────────────┐ │ PTDFBranchFlow__Line │ │ ActivePowerBalance__ACBus │ │ ProductionCostExpression__ThermalStandard │ │ ActivePowerBalance__System │ │ ProductionCostExpression__HydroDispatch │ └───────────────────────────────────────────┘ PowerSimulations Problem Parameters Results ┌───────────────────────────────────────────────┐ │ ActivePowerTimeSeriesParameter__HydroDispatch │ │ ActivePowerTimeSeriesParameter__PowerLoad │ └───────────────────────────────────────────────┘ PowerSimulations Problem Variables Results ┌──────────────────────────────────────┐ │ ActivePowerVariable__ThermalStandard │ │ ActivePowerVariable__HydroDispatch │ └──────────────────────────────────────┘
Use read_variable to read in the dispatch variable results for the hydro:
julia> var = read_variable(res, "ActivePowerVariable__HydroDispatch")24×3 DataFrame Row │ DateTime name value │ DateTime String Float64 ─────┼────────────────────────────────────────────── 1 │ 2024-01-01T00:00:00 HydroDispatch 188.58 2 │ 2024-01-01T01:00:00 HydroDispatch 232.01 3 │ 2024-01-01T02:00:00 HydroDispatch 137.149 4 │ 2024-01-01T03:00:00 HydroDispatch 136.006 5 │ 2024-01-01T04:00:00 HydroDispatch 133.72 6 │ 2024-01-01T05:00:00 HydroDispatch 77.718 7 │ 2024-01-01T06:00:00 HydroDispatch 86.8608 8 │ 2024-01-01T07:00:00 HydroDispatch 219.439 ⋮ │ ⋮ ⋮ ⋮ 18 │ 2024-01-01T17:00:00 HydroDispatch 269.726 19 │ 2024-01-01T18:00:00 HydroDispatch 378.303 20 │ 2024-01-01T19:00:00 HydroDispatch 438.877 21 │ 2024-01-01T20:00:00 HydroDispatch 466.307 22 │ 2024-01-01T21:00:00 HydroDispatch 427.448 23 │ 2024-01-01T22:00:00 HydroDispatch 468.593 24 │ 2024-01-01T23:00:00 HydroDispatch 114.291 9 rows omitted