{ "cells": [ { "cell_type": "markdown", "source": [ "# Operations problems with [PowerSimulations.jl](https://github.com/NREL-SIIP/PowerSimulations.jl)" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "**Originally Contributed by**: Clayton Barrows" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "## Introduction" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "PowerSimulations.jl supports the construction and solution of optimal power system\n", "scheduling problems (Operations Problems). Operations problems form the fundamental\n", "building blocks for [sequential simulations](../../notebook/3_PowerSimulations_examples/sequential_simulations.ipynb).\n", "This example shows how to specify and customize a the mathematics that will be applied to the data with\n", "an `OperationsProblemTemplate`, build and execute an `OperationsProblem`, and access the results." ], "metadata": {} }, { "cell_type": "markdown", "source": [ "## Dependencies" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "using SIIPExamples" ], "metadata": {}, "execution_count": 1 }, { "cell_type": "markdown", "source": [ "### Modeling Packages" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "using PowerSystems\n", "using PowerSimulations\n", "const PSI = PowerSimulations\n", "using PowerSystemCaseBuilder" ], "metadata": {}, "execution_count": 2 }, { "cell_type": "markdown", "source": [ "### Data management packages" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "using Dates\n", "using DataFrames" ], "metadata": {}, "execution_count": 3 }, { "cell_type": "markdown", "source": [ "### Optimization packages" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "using Cbc #solver" ], "metadata": {}, "execution_count": 4 }, { "cell_type": "markdown", "source": [ "### Data\n", "This data depends upon the [RTS-GMLC](https://github.com/gridmod/rts-gmlc) dataset. Let's\n", "use [PowerSystemCaseBuilder.jl](../../notebook/2_PowerSystems_examples/10_PowerSystemCaseBuilder.ipynb) to download and build a `System`." ], "metadata": {} }, { "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ Info: Loaded time series from storage file existing=modified_RTS_GMLC_DA_sys_time_series_storage.h5 new=/var/folders/27/2jr8c7gn4j72fvrg4qt81zrw8w_711/T/jl_yaaIsO\n", "┌ Warning: Rate 500.0 MW for C31-2 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for B8 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B26 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A32-2 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for CA-1 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for A5 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B34 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B19 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B31-2 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C30 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B27 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A21 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A32-1 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B29 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A18 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for C5 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for C13-2 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C24 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C28 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A29 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for A3 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for AB1 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for AB2 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C27 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 722.0 MW for C35 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A25-1 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for B5 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for B2 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B31-1 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C20 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B23 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A28 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A19 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for C9 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for C1 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for C2 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B25-1 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for A9 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for C11 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C19 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C23 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C25-1 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C32-2 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for B20 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for B9 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C25-2 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 175.0 MW for C12-1 is larger than the max expected in the range of (min = 47.0, max = 52.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A27 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for C21 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n", "┌ Warning: Rate 500.0 MW for A34 is larger than the max expected in the range of (min = 134.0, max = 145.0).\n", "└ @ PowerSystems ~/.julia/packages/PowerSystems/4kGrw/src/utils/IO/branchdata_checks.jl:148\n" ] }, { "output_type": "execute_result", "data": { "text/plain": "System\n======\nSystem Units Base: SYSTEM_BASE\nBase Power: 100.0\nBase Frequency: 60.0\n\nComponents\n==========\nNum components: 529\n\n\u001b[1m16×3 DataFrame\u001b[0m\n\u001b[1m Row \u001b[0m│\u001b[1m ConcreteType \u001b[0m\u001b[1m SuperTypes \u001b[0m\u001b[1m Count \u001b[0m\n\u001b[1m \u001b[0m│\u001b[90m String \u001b[0m\u001b[90m String \u001b[0m\u001b[90m Int64 \u001b[0m\n─────┼────────────────────────────────────────────────────────────────────────\n 1 │ Arc Topology <: Component <: Infrast… 109\n 2 │ Area AggregationTopology <: Topology … 3\n 3 │ Bus Topology <: Component <: Infrast… 73\n 4 │ GenericBattery Storage <: StaticInjection <: De… 1\n 5 │ HVDCLine DCBranch <: Branch <: Device <: … 1\n 6 │ HydroDispatch HydroGen <: Generator <: StaticI… 1\n 7 │ HydroEnergyReservoir HydroGen <: Generator <: StaticI… 19\n 8 │ Line ACBranch <: Branch <: Device <: … 105\n 9 │ LoadZone AggregationTopology <: Topology … 21\n 10 │ PowerLoad StaticLoad <: ElectricLoad <: St… 51\n 11 │ RenewableDispatch RenewableGen <: Generator <: Sta… 30\n 12 │ RenewableFix RenewableGen <: Generator <: Sta… 31\n 13 │ TapTransformer ACBranch <: Branch <: Device <: … 15\n 14 │ ThermalStandard ThermalGen <: Generator <: Stati… 64\n 15 │ VariableReserve{ReserveDown} Reserve{ReserveDown} <: Service … 1\n 16 │ VariableReserve{ReserveUp} Reserve{ReserveUp} <: Service <:… 4\n\nTimeSeriesContainer\n===================\nComponents with time series data: 140\nTotal StaticTimeSeries: 180\nTotal Forecasts: 180\nResolution: 60 minutes\nFirst initial time: 2020-01-01T00:00:00\nLast initial time: 2020-12-30T00:00:00\nHorizon: 48\nInterval: 1440 minutes\nForecast window count: 365\n", "text/html": [ "
Base Power: 100.0
\n", "Num components: 529
\n", "ConcreteType | SuperTypes | Count | |
---|---|---|---|
String | String | Int64 | |
1 | Arc | Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 109 |
2 | Area | AggregationTopology <: Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 3 |
3 | Bus | Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 73 |
4 | GenericBattery | Storage <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 1 |
5 | HVDCLine | DCBranch <: Branch <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 1 |
6 | HydroDispatch | HydroGen <: Generator <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 1 |
7 | HydroEnergyReservoir | HydroGen <: Generator <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 19 |
8 | Line | ACBranch <: Branch <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 105 |
9 | LoadZone | AggregationTopology <: Topology <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 21 |
10 | PowerLoad | StaticLoad <: ElectricLoad <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 51 |
11 | RenewableDispatch | RenewableGen <: Generator <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 30 |
12 | RenewableFix | RenewableGen <: Generator <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 31 |
13 | TapTransformer | ACBranch <: Branch <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 15 |
14 | ThermalStandard | ThermalGen <: Generator <: StaticInjection <: Device <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 64 |
15 | VariableReserve{ReserveDown} | Reserve{ReserveDown} <: Service <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 1 |
16 | VariableReserve{ReserveUp} | Reserve{ReserveUp} <: Service <: Component <: InfrastructureSystemsComponent <: InfrastructureSystemsType <: Any | 4 |
Components with time series data: 140
\n", "Total StaticTimeSeries: 180
\n", "Total Forecasts: 180
\n", "Resolution: 60 minutes
\n", "First initial time: 2020-01-01T00:00:00
\n", "Last initial time: 2020-12-30T00:00:00
\n", "Horizon: 48
\n", "Interval: 1440 minutes
\n", "Forecast window count: 365
\n" ] }, "metadata": {}, "execution_count": 5 } ], "cell_type": "code", "source": [ "sys = build_system(PSITestSystems, \"modified_RTS_GMLC_DA_sys\")" ], "metadata": {}, "execution_count": 5 }, { "cell_type": "markdown", "source": [ "## Define a problem specification with an `OperationsProblemTemplate`\n", "You can create an empty template with:" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "\nOperations Problem Specification\n============================================\nTransmission: CopperPlatePowerModel\n============================================\nDevices Models: \n\n============================================\nBranches Models: \n\n============================================\nServices Models:\n\n============================================\n" }, "metadata": {}, "execution_count": 6 } ], "cell_type": "code", "source": [ "template_uc = OperationsProblemTemplate()" ], "metadata": {}, "execution_count": 6 }, { "cell_type": "markdown", "source": [ "Now, you can add a `DeviceModel` for each device type to create an assignment between PowerSystems device types\n", "and the subtypes of `AbstractDeviceFormulation`. PowerSimulations has a variety of different\n", "`AbstractDeviceFormulation` subtypes that can be applied to different PowerSystems device types,\n", "each dispatching to different methods for populating optimization problem objectives, variables,\n", "and constraints." ], "metadata": {} }, { "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AbstractDeviceFormulation\n", "├─ FixedOutput\n", "├─ AbstractBranchFormulation\n", "│ ├─ AbstractDCLineFormulation\n", "│ │ ├─ HVDCDispatch\n", "│ │ ├─ HVDCLossless\n", "│ │ └─ HVDCUnbounded\n", "│ ├─ StaticBranch\n", "│ ├─ StaticBranchBounds\n", "│ └─ StaticBranchUnbounded\n", "├─ AbstractHydroFormulation\n", "│ ├─ AbstractHydroDispatchFormulation\n", "│ │ ├─ HydroDispatchRunOfRiver\n", "│ │ └─ AbstractHydroReservoirFormulation\n", "│ │ ├─ HydroDispatchPumpedStorage\n", "│ │ ├─ HydroDispatchPumpedStoragewReservation\n", "│ │ ├─ HydroDispatchReservoirBudget\n", "│ │ └─ HydroDispatchReservoirStorage\n", "│ └─ AbstractHydroUnitCommitment\n", "│ ├─ HydroCommitmentReservoirBudget\n", "│ ├─ HydroCommitmentReservoirStorage\n", "│ └─ HydroCommitmentRunOfRiver\n", "├─ AbstractLoadFormulation\n", "│ ├─ AbstractControllablePowerLoadFormulation\n", "│ │ ├─ DispatchablePowerLoad\n", "│ │ └─ InterruptiblePowerLoad\n", "│ └─ StaticPowerLoad\n", "├─ AbstractRegulationFormulation\n", "│ ├─ DeviceLimitedRegulation\n", "│ └─ ReserveLimitedRegulation\n", "├─ AbstractRenewableFormulation\n", "│ └─ AbstractRenewableDispatchFormulation\n", "│ ├─ RenewableConstantPowerFactor\n", "│ └─ RenewableFullDispatch\n", "├─ AbstractStorageFormulation\n", "│ ├─ BookKeeping\n", "│ ├─ BookKeepingwReservation\n", "│ └─ AbstractEnergyManagement\n", "│ └─ EndOfPeriodEnergyTarget\n", "└─ AbstractThermalFormulation\n", " ├─ AbstractThermalDispatchFormulation\n", " │ ├─ ThermalCompactDispatch\n", " │ ├─ ThermalDispatch\n", " │ ├─ ThermalDispatchNoMin\n", " │ └─ ThermalRampLimited\n", " └─ AbstractThermalUnitCommitment\n", " ├─ AbstractCompactUnitCommitment\n", " │ ├─ ThermalCompactUnitCommitment\n", " │ └─ ThermalMultiStartUnitCommitment\n", " └─ AbstractStandardUnitCommitment\n", " ├─ ThermalBasicUnitCommitment\n", " └─ ThermalStandardUnitCommitment\n" ] } ], "cell_type": "code", "source": [ "print_tree(PSI.AbstractDeviceFormulation)" ], "metadata": {}, "execution_count": 7 }, { "cell_type": "markdown", "source": [ "### Branch Formulations\n", "Here is an example of relatively standard branch formulations. Other formulations allow\n", "for selective enforcement of transmission limits and greater control on transformer settings." ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "set_device_model!(template_uc, Line, StaticBranch)\n", "set_device_model!(template_uc, Transformer2W, StaticBranch)\n", "set_device_model!(template_uc, TapTransformer, StaticBranch)" ], "metadata": {}, "execution_count": 8 }, { "cell_type": "markdown", "source": [ "### Injection Device Formulations\n", "Here we define template entries for all devices that inject or withdraw power on the\n", "network. For each device type, we can define a distinct `AbstractDeviceFormulation`. In\n", "this case, we're defining a basic unit commitment model for thermal generators,\n", "curtailable renewable generators, and fixed dispatch (net-load reduction) formulations\n", "for `HydroDispatch` and `RenewableFix` devices." ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "set_device_model!(template_uc, ThermalStandard, ThermalStandardUnitCommitment)\n", "set_device_model!(template_uc, RenewableDispatch, RenewableFullDispatch)\n", "set_device_model!(template_uc, PowerLoad, StaticPowerLoad)\n", "set_device_model!(template_uc, HydroDispatch, FixedOutput)\n", "set_device_model!(template_uc, HydroEnergyReservoir, HydroDispatchRunOfRiver)\n", "set_device_model!(template_uc, RenewableFix, FixedOutput)" ], "metadata": {}, "execution_count": 9 }, { "cell_type": "markdown", "source": [ "### Service Formulations\n", "We have two `VariableReserve` types, parameterized by their direction. So, similar to\n", "creating `DeviceModel`s, we can create `ServiceModel`s. The primary difference being\n", "that `DeviceModel` objects define how constraints get created, while `ServiceModel` objects\n", "define how constraints get modified." ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "set_service_model!(template_uc, VariableReserve{ReserveUp}, RangeReserve)\n", "set_service_model!(template_uc, VariableReserve{ReserveDown}, RangeReserve)" ], "metadata": {}, "execution_count": 10 }, { "cell_type": "markdown", "source": [ "### Network Formulations\n", "Finally, we can define the transmission network specification that we'd like to model. For simplicity, we'll\n", "choose a copper plate formulation. But there are dozens of specifications available through\n", "an integration with [PowerModels.jl](https://github.com/lanl-ansi/powermodels.jl). *Note that\n", "many formulations will require appropriate data and may be computationally intractable*" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "set_transmission_model!(template_uc, CopperPlatePowerModel)" ], "metadata": {}, "execution_count": 11 }, { "cell_type": "markdown", "source": [ "## `OperationsProblem`\n", "Now that we have a `System` and an `OperationsProblemTemplate`, we can put the two together\n", "to create an `OperationsProblem` that we solve." ], "metadata": {} }, { "cell_type": "markdown", "source": [ "### Optimizer\n", "It's most convenient to define an optimizer instance upfront and pass it into the\n", "`OperationsProblem` constructor. For this example, we can use the free Cbc solver with a\n", "relatively relaxed MIP gap (`ratioGap`) setting to improve speed." ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "MathOptInterface.OptimizerWithAttributes(Cbc.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute,Any}[MathOptInterface.RawParameter(\"logLevel\") => 1, MathOptInterface.RawParameter(\"ratioGap\") => 0.5])" }, "metadata": {}, "execution_count": 12 } ], "cell_type": "code", "source": [ "solver = optimizer_with_attributes(Cbc.Optimizer, \"logLevel\" => 1, \"ratioGap\" => 0.5)" ], "metadata": {}, "execution_count": 12 }, { "cell_type": "markdown", "source": [ "### Build an `OperationsProblem`\n", "The construction of an `OperationsProblem` essentially applies an `OperationsProblemTemplate`\n", "to `System` data to create a JuMP model." ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "BuildStatus.BUILT = 0" }, "metadata": {}, "execution_count": 13 } ], "cell_type": "code", "source": [ "op_problem = OperationsProblem(\n", " template_uc,\n", " sys;\n", " optimizer = solver,\n", " horizon = 24,\n", ")\n", "\n", "build!(op_problem, output_dir = mktempdir())" ], "metadata": {}, "execution_count": 13 }, { "cell_type": "markdown", "source": [ "The principal component of the `OperationsProblem` is the JuMP model. For small problems,\n", "you can inspect it by simply printing it to the screen:\n", "```julia\n", "op_problem.internal.optimization_container.JuMPmodel\n", "```\n", "\n", "For anything of reasonable size, that will be unmanageable. But you can print to a file:\n", "```julia\n", "f = open(\"testmodel.txt\",\"w\"); print(f,op_problem.internal.optimization_container.JuMPmodel); close(f)\n", "```\n", "\n", "In addition to the JuMP model, an `OperationsProblem` keeps track of a bunch of metadata\n", "about the problem and some references to pretty names for constraints and variables.\n", "All of these details are contained within the `optimization_container` field." ], "metadata": {} }, { "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "mutable struct PowerSimulations.OptimizationContainer\n", " JuMPmodel::Union{Nothing, JuMP.AbstractModel}\n", " time_steps::UnitRange{Int64}\n", " resolution::TimePeriod\n", " settings::PowerSimulations.Settings\n", " settings_copy::PowerSimulations.Settings\n", " variables::Dict{Symbol,AbstractArray}\n", " constraints::Dict{Symbol,AbstractArray}\n", " cost_function::JuMP.AbstractJuMPScalar\n", " expressions::Dict{Symbol,JuMP.Containers.DenseAxisArray}\n", " parameters::Union{Nothing, Dict{Symbol,PowerSimulations.ParameterContainer}}\n", " initial_conditions::Union{Nothing, PowerSimulations.InitialConditions}\n", " pm::Union{Nothing, PowerModels.AbstractPowerModel}\n", " base_power::Float64\n", " solve_timed_log::Dict{Symbol,Any}\n", "end\n" ] } ], "cell_type": "code", "source": [ "print_struct(typeof(op_problem.internal.optimization_container))" ], "metadata": {}, "execution_count": 14 }, { "cell_type": "markdown", "source": [ "### Solve an `OperationsProblem`" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "RunStatus.SUCCESSFUL = 0" }, "metadata": {}, "execution_count": 15 } ], "cell_type": "code", "source": [ "solve!(op_problem)" ], "metadata": {}, "execution_count": 15 }, { "cell_type": "markdown", "source": [ "## Results Inspection\n", "PowerSimulations collects the `OperationsProblem` results into a struct:" ], "metadata": {} }, { "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " struct ProblemResults\n", " base_power::Float64\n", " timestamps::StepRange{DateTime,Millisecond}\n", " system::Union{Nothing, System}\n", " variable_values::Dict{Symbol,DataFrame}\n", " dual_values::Dict{Symbol,DataFrame}\n", " parameter_values::Dict{Symbol,DataFrame}\n", " optimizer_stats::PowerSimulations.OptimizerStats\n", " output_dir::String\n", "end\n" ] } ], "cell_type": "code", "source": [ "print_struct(PSI.ProblemResults)" ], "metadata": {}, "execution_count": 16 }, { "outputs": [], "cell_type": "code", "source": [ "res = ProblemResults(op_problem);" ], "metadata": {}, "execution_count": 17 }, { "cell_type": "markdown", "source": [ "### Optimizer Stats\n", "The optimizer summary is included" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "PowerSimulations.OptimizerStats(0, 0, 1.319522463200657e6, 1, 1, 0, 6.715773105621338, 7.07046608, 7.9810925e7, 0.0)" }, "metadata": {}, "execution_count": 18 } ], "cell_type": "code", "source": [ "get_optimizer_stats(res)" ], "metadata": {}, "execution_count": 18 }, { "cell_type": "markdown", "source": [ "### Objective Function Value" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "1.319522463200657e6" }, "metadata": {}, "execution_count": 19 } ], "cell_type": "code", "source": [ "get_objective_value(res)" ], "metadata": {}, "execution_count": 19 }, { "cell_type": "markdown", "source": [ "### Variable Values\n", "The solution value data frames for variables can be accessed by:" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "Dict{Symbol,DataFrame} with 11 entries:\n :P__ThermalStandard => \u001b[1m24×65 DataFrame\u001b[0m…\n :P__RenewableDispatch => \u001b[1m24×31 DataFrame\u001b[0m…\n :Reg_Down__VariableReser… => \u001b[1m24×91 DataFrame\u001b[0m…\n :P__HydroEnergyReservoir => \u001b[1m24×20 DataFrame\u001b[0m…\n :Reg_Up__VariableReserve… => \u001b[1m24×91 DataFrame\u001b[0m…\n :Spin_Up_R2__VariableRes… => \u001b[1m24×22 DataFrame\u001b[0m…\n :On__ThermalStandard => \u001b[1m24×65 DataFrame\u001b[0m…\n :start__ThermalStandard => \u001b[1m24×65 DataFrame\u001b[0m…\n :stop__ThermalStandard => \u001b[1m24×65 DataFrame\u001b[0m…\n :Spin_Up_R1__VariableRes… => \u001b[1m24×31 DataFrame\u001b[0m…\n :Spin_Up_R3__VariableRes… => \u001b[1m24×40 DataFrame\u001b[0m…" }, "metadata": {}, "execution_count": 20 } ], "cell_type": "code", "source": [ "variable_values = get_variables(res)" ], "metadata": {}, "execution_count": 20 }, { "cell_type": "markdown", "source": [ "## Plotting\n", "Take a look at the examples in [the plotting folder.](../../notebook/3_PowerSimulations_examples/Plotting)" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "---\n", "\n", "*This notebook was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*" ], "metadata": {} } ], "nbformat_minor": 3, "metadata": { "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.5.2" }, "kernelspec": { "name": "julia-1.5", "display_name": "Julia 1.5.2", "language": "julia" } }, "nbformat": 4 }