From bbb0172f71906a767ee89453535eda144ad843c6 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:28:57 -0800 Subject: [PATCH 01/27] update readme --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 779df6d..ac1ca4a 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,14 @@ [![Documentation Build](https://github.com/NREL-Sienna/HydroPowerSimulations.jl/actions/workflows/docs.yml/badge.svg)](https://nrel-sienna.github.io/HydroPowerSimulations.jl/dev/) [](https://join.slack.com/t/nrel-sienna/shared_invite/zt-glam9vdu-o8A9TwZTZqqNTKHa7q3BpQ) +`HydroPowerSimulations.jl` is an extension package of [`PowerSimulations.jl`](https://github.com/NREL-Sienna/PowerSimulations.jl) for modeling of hydro generation technology. + +For information on using the package, see the [stable documentation](https://nrel-sienna.github.io/HydroPowerSimulations.jl/stable/). Use the [in-development documentation](https://nrel-sienna.github.io/HydroPowerSimulations.jl/dev/) for the version of the documentation which contains the unreleased features. + ## Development -Contributions to the development and enahancement of HydroPowerSimulations is welcome. Please see [CONTRIBUTING.md](https://github.com/NREL-Sienna/HydroPowerSimulations.jl/blob/master/CONTRIBUTING.md) for code contribution guidelines. +Contributions to the development and enhancement of HydroPowerSimulations is welcome. Please see [CONTRIBUTING.md](https://github.com/NREL-Sienna/HydroPowerSimulations.jl/blob/master/CONTRIBUTING.md) for code contribution guidelines. ## License -HydroPowerSimulations is released under a BSD [license](https://github.com/NREL-Sienna/HydroPowerSimulations/blob/master/LICENSE). HydroPowerSimulations has been developed as part of the Flexible Linked Analysis of Streamflow and Hydropower (FLASH) and Reliability and Resilience of coordinated water Distribution and power Distribution (R2D2) projects at the U.S. Department of Energy's National Renewable Energy Laboratory ([NREL](https://www.nrel.gov/)) Software Record SWR-23-110 +HydroPowerSimulations is released under a BSD [license](https://github.com/NREL-Sienna/HydroPowerSimulations/blob/master/LICENSE). HydroPowerSimulations has been developed as part of the Flexible Linked Analysis of Streamflow and Hydropower (FLASH) and Reliability and Resilience of coordinated water Distribution and power Distribution (R2D2) projects at the U.S. Department of Energy's National Renewable Energy Laboratory ([NREL](https://www.nrel.gov/)) Software Record SWR-23-110. From 337e3f865611d1c00bb333a78b9051b6c5bea6ec Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:31:12 -0800 Subject: [PATCH 02/27] update packages in docs toml --- docs/Project.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/Project.toml b/docs/Project.toml index 5fbf4e8..02ac5cb 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,9 +1,14 @@ [deps] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8" +HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" HydroPowerSimulations = "fc1677e0-6ad7-4515-bf3a-bd6bf20a0b1b" +Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +PowerSimulations = "e690365d-45e2-57bb-ac84-44ba829e73c4" +PowerSystems = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd" [compat] -Documenter = "0.27" +Documenter = "1" julia = "^1.6" From 25d1d24db8f51958e8879dd0d5325e79481b2b4a Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:31:30 -0800 Subject: [PATCH 03/27] add docstrings for FF --- src/feedforwards.jl | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/feedforwards.jl b/src/feedforwards.jl index 8d42e60..aba3041 100644 --- a/src/feedforwards.jl +++ b/src/feedforwards.jl @@ -1,12 +1,23 @@ """ + ReservoirTargetFeedforward( + component_type::Type{<:PSY.Component}, + source::Type{T}, + affected_values::Vector{DataType}, + target_period::Int, + penalty_cost::Float64, + meta = CONTAINER_KEY_EMPTY_META + ) where {T} + Adds a constraint to enforce a minimum reservoir level target with a slack variable associated with a penalty term. -# Fields: +# Arguments: - optmization_container_key -> - source - From where the data comes - affected_values - + - `component_type::Type{<:PSY.Component}` : Specify the type of component on which the Feedforward will be applied + - `source::Type{T}` : Specify the VariableType, ParameterType or AuxVariableType as the source of values for the Feedforward + - `affected_values::Vector{DataType}` : Specify the variable on which the reservoir target will be applied using the source values + - `target_period::Int` : Specify the time step at which the reservoir target will be applied. + - `penalty_cost::Float64` : Specify the penalty cost for not reaching the desired reservoir target. """ struct ReservoirTargetFeedforward <: PSI.AbstractAffectFeedforward optimization_container_key::PSI.OptimizationContainerKey @@ -131,7 +142,22 @@ function PSI._add_feedforward_arguments!( end """ -Adds a constraint to limit the sum of a variable over the number of periods to the source value + ReservoirLimitFeedforward( + component_type::Type{<:PSY.Component}, + source::Type{T}, + affected_values::Vector{DataType}, + number_of_periods::Int, + meta = CONTAINER_KEY_EMPTY_META + ) where {T} + +Adds a constraint to limit the sum of a variable over the number of periods to the source value. + +# Arguments: + + - `component_type::Type{<:PSY.Component}` : Specify the type of component on which the Feedforward will be applied + - `source::Type{T}` : Specify the VariableType, ParameterType or AuxVariableType as the source of values for the Feedforward + - `affected_values::Vector{DataType}` : Specify the variable on which the reservoir limit will be applied using the source values + - `number_of_periods::Int` : Specify the total number of periods that are added on which the limits are applied. For example, in a 24-step simulation if `number_of_periods = 24`, it will add only one constraint over the sum of 24 periods on which the reservoir limit will be applied. If `number_of_periods = 12`, it will create two constraints, one for the first 12 steps and one for the 13:24 steps. It is mandatory that `number_of_periods` can divide the total number of simulation steps. """ struct ReservoirLimitFeedforward <: PSI.AbstractAffectFeedforward optimization_container_key::PSI.OptimizationContainerKey From bf3df7ce6330788dad8a28baeee087e748dbed63 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:31:54 -0800 Subject: [PATCH 04/27] update doscstrings in constructors --- src/hydrogeneration_constructor.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hydrogeneration_constructor.jl b/src/hydrogeneration_constructor.jl index 1685827..4e98cbc 100644 --- a/src/hydrogeneration_constructor.jl +++ b/src/hydrogeneration_constructor.jl @@ -1120,7 +1120,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirStorage Dispatch Formulation +Construct model for HydroGen with ReservoirStorage Commitment Formulation with only Active Power """ function PSI.construct_device!( @@ -1419,6 +1419,9 @@ function PSI.construct_device!( return end +""" +Construct model for HydroGen with HydroCommitmentRunOfRiver Formulation +""" function PSI.construct_device!( container::PSI.OptimizationContainer, sys::PSY.System, From 946f5bbbfd9dc38accab8e685ad227962e74c153 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:32:14 -0800 Subject: [PATCH 05/27] add new exports --- src/HydroPowerSimulations.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/HydroPowerSimulations.jl b/src/HydroPowerSimulations.jl index 0d20647..a1dd7ca 100644 --- a/src/HydroPowerSimulations.jl +++ b/src/HydroPowerSimulations.jl @@ -21,13 +21,19 @@ export HydroCommitmentRunOfRiver ######## Hydro Variables ######## export HydroEnergyVariableUp +export HydroEnergyVariableDown export WaterSpillageVariable export HydroEnergyShortageVariable +export HydroEnergySurplusVariable ######## Hydro Aux Variables ######## export HydroEnergyOutput ######## Hydro parameters ####### +export EnergyTargetTimeSeriesParameter +export EnergyBudgetTimeSeriesParameter +export InflowTimeSeriesParameter +export OutflowTimeSeriesParameter export ReservoirTargetParameter export ReservoirLimitParameter @@ -39,6 +45,10 @@ export InitialHydroEnergyLevelDown export ReservoirTargetFeedforward export ReservoirLimitFeedforward +######## Hydro Expressions ####### +export ReserveRangeExpressionLB +export ReserveRangeExpressionUB + ################################################################################# # Imports using PowerSystems From fae3da46ffc8cba7fe56ebc0e9c7b5af3b2bd86f Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:32:26 -0800 Subject: [PATCH 06/27] update docstrings for expressions --- src/core/expressions.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/expressions.jl b/src/core/expressions.jl index 1b52635..6200a16 100644 --- a/src/core/expressions.jl +++ b/src/core/expressions.jl @@ -1,4 +1,12 @@ +""" +Expression for HydroPumpedStorage that keep track +of active power and reserves for Lower Bound limits +""" struct ReserveRangeExpressionLB <: PSI.RangeConstraintLBExpressions end +""" +Expression for HydroPumpedStorage that keep track +of active power and reserves for Upper Bound limits +""" struct ReserveRangeExpressionUB <: PSI.RangeConstraintUBExpressions end PSI.should_write_resulting_value(::Type{ReserveRangeExpressionUB}) = true From 03d0a6a8baf7c3ed3f54e38e333821b0e9929e38 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:33:31 -0800 Subject: [PATCH 07/27] add docstring for IC params and vars --- src/core/initial_conditions.jl | 7 +++++++ src/core/parameters.jl | 8 ++++---- src/core/variables.jl | 12 +++++++----- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/core/initial_conditions.jl b/src/core/initial_conditions.jl index b1a51c1..95ff501 100644 --- a/src/core/initial_conditions.jl +++ b/src/core/initial_conditions.jl @@ -1,2 +1,9 @@ +""" +Initial condition for Upper reservoir in HydroPumpedStorage formulations +""" struct InitialHydroEnergyLevelUp <: PSI.InitialConditionType end + +""" +Initial condition for Down reservoir in HydroPumpedStorage formulations +""" struct InitialHydroEnergyLevelDown <: PSI.InitialConditionType end diff --git a/src/core/parameters.jl b/src/core/parameters.jl index 92d39b0..8f6d373 100644 --- a/src/core/parameters.jl +++ b/src/core/parameters.jl @@ -1,10 +1,10 @@ """ -Parameter to define energy storage target level time series +Parameter to define energy storage target level time series for hydro generators """ struct EnergyTargetTimeSeriesParameter <: PSI.TimeSeriesParameter end """ -Parameter to define energy budget time series +Parameter to define energy budget time series for hydro generators """ struct EnergyBudgetTimeSeriesParameter <: PSI.TimeSeriesParameter end @@ -19,11 +19,11 @@ Parameter to define energy outflow from storage or reservoir time series struct OutflowTimeSeriesParameter <: PSI.TimeSeriesParameter end """ -Parameter to define energy target +Parameter to define energy target for feedforward """ struct ReservoirTargetParameter <: PSI.VariableValueParameter end """ -Parameter to define energy limit +Parameter to define energy limit for feedforward """ struct ReservoirLimitParameter <: PSI.VariableValueParameter end diff --git a/src/core/variables.jl b/src/core/variables.jl index 9431fdf..c0ece41 100644 --- a/src/core/variables.jl +++ b/src/core/variables.jl @@ -1,35 +1,35 @@ """ Struct to dispatch the creation of energy (water) spillage variable representing energy released from a storage/reservoir not injected into the network -Docs abbreviation: ``S`` +Docs abbreviation: ``s`` """ struct WaterSpillageVariable <: PSI.VariableType end """ Struct to dispatch the creation of a variable for energy storage level (state of charge) of upper reservoir -Docs abbreviation: ``E^{up}`` +Docs abbreviation: ``e^\\text{up}`` """ struct HydroEnergyVariableUp <: PSI.VariableType end """ Struct to dispatch the creation of a variable for energy storage level (state of charge) of lower reservoir -Docs abbreviation: ``E^{down}`` +Docs abbreviation: ``e^\\text{dn}`` """ struct HydroEnergyVariableDown <: PSI.VariableType end """ Struct to dispatch the creation of a slack variable for energy storage levels < target storage levels -Docs abbreviation: ``E^{shortage}`` +Docs abbreviation: ``e^\\text{shortage}`` """ struct HydroEnergyShortageVariable <: PSI.VariableType end """ Struct to dispatch the creation of a slack variable for energy storage levels > target storage levels -Docs abbreviation: ``E^{surplus}`` +Docs abbreviation: ``e^\\text{surplus}`` """ struct HydroEnergySurplusVariable <: PSI.VariableType end @@ -37,5 +37,7 @@ struct HydroEnergySurplusVariable <: PSI.VariableType end """ Auxiliary Variable for Hydro Models that solve for total energy output + +Docs abbreviation: ``E^\\text{hy,out}`` """ struct HydroEnergyOutput <: PSI.AuxVariableType end From f7f6642d5333b4931aeaecdc26817485ab173bef Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:33:52 -0800 Subject: [PATCH 08/27] add formulation page --- docs/src/formulation.md | 525 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100644 docs/src/formulation.md diff --git a/docs/src/formulation.md b/docs/src/formulation.md new file mode 100644 index 0000000..bb4fa7a --- /dev/null +++ b/docs/src/formulation.md @@ -0,0 +1,525 @@ +# `HydroPowerSimulations` Formulations + +Hydro generation formulations define the optimization models that describe hydro units mathematical model in different operational settings, such as economic dispatch and unit commitment. + +!!! note + + The use of reactive power variables and constraints will depend on the network model used, i.e., whether it uses (or does not use) reactive power. If the network model is purely active power-based, reactive power variables and related constraints are not created. + +!!! note + + Reserve variables for services are not included in the formulation, albeit their inclusion change the variables, expressions, constraints and objective functions created. A detailed description of the implications in the optimization models is described in the [Service formulation](https://nrel-sienna.github.io/PowerSimulations.jl/latest/formulation_library/Service/) in the [PowerSimulations documentation](https://nrel-sienna.github.io/PowerSimulations.jl/latest/). + +### Table of Contents + + 1. [`HydroDispatchRunOfRiver`](#HydroDispatchRunOfRiver) + 2. [`HydroDispatchReservoirBudget`](#HydroDispatchReservoirBudget) + 3. [`HydroDispatchReservoirStorage`](#HydroDispatchReservoirStorage) + 4. [`HydroDispatchPumpedStorage`](#HydroDispatchPumpedStorage) + 5. [`HydroCommitmentRunOfRiver`](#HydroCommitmentRunOfRiver) + 6. [`HydroCommitmentReservoirBudget`](#HydroCommitmentReservoirBudget) + 7. [`HydroCommitmentReservoirStorage`](#HydroCommitmentReservoirStorage) + +## `HydroDispatchRunOfRiver` + +```@docs +HydroDispatchRunOfRiver +``` + +**Variables:** + + - `ActivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy}`` + + - `ReactivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``q^\text{hy}`` + +**Auxiliary Variables:** + + - [`HydroEnergyOutput`](@ref): + + + Symbol: ``E^\text{hy,out}`` + +The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. + +**Static Parameters:** + + - ``P^\text{hy,min}`` = `PowerSystems.get_active_power_limits(device).min` + - ``P^\text{hy,max}`` = `PowerSystems.get_active_power_limits(device).max` + - ``Q^\text{hy,min}`` = `PowerSystems.get_reactive_power_limits(device).min` + - ``Q^\text{hy,max}`` = `PowerSystems.get_reactive_power_limits(device).max` + +**Time Series Parameters:** + +Uses the `max_active_power` timeseries parameter to limit the available active power at each time-step. If the timeseries parameter is not included, the power is limited by ``P^\text{th,max}``. + +**Objective:** + +Add a cost to the objective function depending on the defined cost structure of the hydro unit by adding it to its `ProductionCostExpression`. + +**Expressions:** + +Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. + +**Constraints:** + +For each hydro unit creates the range constraints for its active and reactive power depending on its static parameters. + +```math +\begin{align*} +& P^\text{hy,min} \le p^\text{hy}_t \le \text{ActivePowerTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} \\ +& Q^\text{hy,min} \le q^\text{hy}_t \le Q^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} +\end{align*} +``` + +* * * + +## `HydroDispatchReservoirBudget` + +```@docs +HydroDispatchReservoirBudget +``` + +**Variables:** + + - `ActivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy}`` + + - `ReactivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``q^\text{hy}`` + +**Auxiliary Variables:** + + - [`HydroEnergyOutput`](@ref): + + + Symbol: ``E^\text{hy,out}`` + +The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. + +**Static Parameters:** + + - ``P^\text{hy,min}`` = `PowerSystems.get_active_power_limits(device).min` + - ``P^\text{hy,max}`` = `PowerSystems.get_active_power_limits(device).max` + - ``Q^\text{hy,min}`` = `PowerSystems.get_reactive_power_limits(device).min` + - ``Q^\text{hy,max}`` = `PowerSystems.get_reactive_power_limits(device).max` + +**Time Series Parameters:** + +Uses the `hydro_budget` timeseries parameter to limit the active power usage throughout all the time steps. + +**Objective:** + +Add a cost to the objective function depending on the defined cost structure of the hydro unit by adding it to its `ProductionCostExpression`. + +**Expressions:** + +Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. + +**Constraints:** + +For each hydro unit creates the range constraints for its active and reactive power depending on its static parameters. + +```math +\begin{align*} +& P^\text{hy,min} \le p^\text{hy}_t \le P^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& Q^\text{hy,min} \le q^\text{hy}_t \le Q^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& \sum_{t=1}^T p^\text{hy}_t \le \sum_{t=1}^T \text{EnergyBudgetTimeSeriesParameter}_t, +\end{align*} +``` + +* * * + +## `HydroDispatchReservoirStorage` + +```@docs +HydroDispatchReservoirStorage +``` + +**Variables:** + + - `ActivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy}`` + + - `ReactivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``q^\text{hy}`` + - `EnergyVariable`: + + + Bounds: ``[0.0, E^\text{max}]`` + + Symbol: ``e`` + - [`WaterSpillageVariable`](@ref): + + + Bounds: [0.0, ] + + Symbol: ``s`` + - [`HydroEnergySurplusVariable`](@ref): + + + Bounds: ``[-E^\text{max}, 0.0]`` + + Symbol: ``e^\text{surplus}`` + - [`HydroEnergyShortageVariable`](@ref): + + + Bounds: ``[0.0, E^\text{max}]`` + + Symbol: ``e^\text{shortage}`` + +**Auxiliary Variables:** + + - [`HydroEnergyOutput`](@ref): + + + Symbol: ``E^\text{hy,out}`` + +The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. + +**Static Parameters:** + + - ``P^\text{hy,min}`` = `PowerSystems.get_active_power_limits(device).min` + - ``P^\text{hy,max}`` = `PowerSystems.get_active_power_limits(device).max` + - ``Q^\text{hy,min}`` = `PowerSystems.get_reactive_power_limits(device).min` + - ``Q^\text{hy,max}`` = `PowerSystems.get_reactive_power_limits(device).max` + - ``E^\text{max}`` = `PowerSystems.get_storage_capacity(device)` + +**Initial Conditions:** + +The `PowerSimulations.InitialEnergyLevel`: ``e_0`` is used as the initial condition for the energy level of the reservoir. + +**Time Series Parameters:** + +Uses the `storage_target` timeseries parameter to set a storage target of the reservoir and the `inflow` timeseries parameter to obtain the inflow to the reservoir. + +**Objective:** + +Add a cost to the objective function depending on the defined cost structure of the hydro unit by adding it to its `ProductionCostExpression`. This model has shortage costs for the energy target that are also added to the objective function. In case of no shortage cost are specified, the model will turn-off the shortage variable to avoid infeasible/unbounded problems. + +**Expressions:** + +Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. + +**Constraints:** + +For each hydro unit creates the range constraints for its active and reactive power depending on its static parameters. + +```math +\begin{align*} +& P^\text{hy,min} \le p^\text{hy}_t \le P^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& Q^\text{hy,min} \le q^\text{hy}_t \le Q^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& e_{t} = e_{t-1} - \Delta T (p^\text{hy}_t - s_t) + \text{InflowTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} \\ +& e_t + e^\text{shortage} + e^\text{surplus} = \text{EnergyTargetTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} +\end{align*} +``` + +* * * + +## HydroDispatchPumpedStorage + +This formulation is not available with reactive power. This formulation must be used with `PowerSystems.HydroPumpedStorage` component. + +```@docs +HydroDispatchPumpedStorage +``` + +**Variables:** + + - `ActivePowerOutVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy,out}`` + + - `ActivePowerInVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy,in}`` + - [`HydroEnergyVariableUp`](@ref): + + + Bounds: ``[0.0, E^\text{max,up}]`` + + Symbol: ``e^\text{up}`` + - [`HydroEnergyVariableDown`](@ref): + + + Bounds: ``[0.0, E^\text{max,dn}]`` + + Symbol: ``e^\text{dn}`` + - [`WaterSpillageVariable`](@ref): + + + Bounds: [0.0, ] + + Symbol: ``s`` + +If the attribute `reservation` is set to true, the following variable is created: + + - `ReservationVariable`: + + + Bounds: ``\{0,1\}`` + + Symbol: ``ss^\text{hy}`` + +If `reservation` is set to false (default), then the hydro pumped storage is allowed to pump and discharge simultaneously at each time step. + +**Static Parameters:** + + - ``P^\text{out,min}`` = `PowerSystems.get_active_power_limits(device).min` + - ``P^\text{out,max}`` = `PowerSystems.get_active_power_limits(device).max` + - ``P^\text{in,min}`` = `PowerSystems.get_active_power_limits_pump(device).min` + - ``P^\text{in,max}`` = `PowerSystems.get_active_power_limits_pump(device).max` + - ``E^\text{max,up}`` = `PowerSystems.get_storage_capacity(device).up` + - ``E^\text{max,dn}`` = `PowerSystems.get_storage_capacity(device).down` + - ``\eta^\text{pump}`` = `PowerSystems.get_pump_efficiency(device)` + +**Initial Conditions:** + +The `InitialHydroEnergyLevelUp`: ``e_0^\text{up}`` is used as the initial condition for the energy level of the upper reservoir, while `InitialHydroEnergyLevelDown`: ``e_0^\text{dn}`` is used as the initial condition for the energy level of the lower reservoir. + +**Time Series Parameters:** + +Uses the `inflow` and `outflow` timeseries to obtain the inflow and outflow to the reservoir. `inflow` corresponds to the inflow into the upper (up) reservoir, while `outflow` corresponds to the outflow from the lower (down) reservoir. + +**Objective:** + +Add a cost to the objective function depending on the defined cost structure of the hydro unit by adding it to its `ProductionCostExpression`. + +**Expressions:** + +Adds ``(p^\text{hy,out} - p^\text{hy,in})`` to the `ActivePowerBalance` to be used in the supply-balance constraint depending on the network model used. + +**Constraints:** + +If `reservation = true`, the limits are given by: + +```math +\begin{align*} +& ss_t^\text{hy} P^\text{out,min} \le p^\text{hy,out}_t \le ss_t^\text{hy} P^\text{out,max}, \quad \forall t\in \{1, \dots, T\} \\ +& (1-ss_t^\text{hy}) P^\text{in,min} \le p^\text{hy,in}_t \le (1 - ss_t^\text{hy}) P^\text{in,max}, \quad \forall t\in \{1, \dots, T\} +\end{align*} +``` + +If `reservation = false`, then: + +```math +\begin{align*} +& P^\text{out,min} \le p^\text{hy,out}_t \le P^\text{out,max}, \quad \forall t\in \{1, \dots, T\} \\ +& P^\text{in,min} \le p^\text{hy,in}_t \le P^\text{in,max}, \quad \forall t\in \{1, \dots, T\} +\end{align*} +``` + +The remaining constraints are: + +```math +\begin{align*} +e_{t}^\text{up} = e_{t-1}^\text{up} + \left (p_t^\text{hy,in} - \frac{p_t^\text{hy,out} + s_t}{\eta^\text{pump}} \right) \Delta T + \text{InflowTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} \\ +e_{t}^\text{dn} = e_{t-1}^\text{dn} + \left (p_t^\text{hy,out} + s_t - \frac{p_t^\text{hy,in}}{\eta^\text{pump}} \right) \Delta T - \text{OutflowTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} +\end{align*} +``` + +* * * + +## `HydroCommitmentRunOfRiver` + +```@docs +HydroCommitmentRunOfRiver +``` + +**Variables:** + + - `ActivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy}`` + + - `ReactivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``q^\text{hy}`` + - `OnVariable`: + + + Bounds: ``\{0, 1\}`` + + Symbol: ``u^\text{hy}`` + +**Auxiliary Variables:** + + - [`HydroEnergyOutput`](@ref): + + + Symbol: ``E^\text{hy,out}`` + +The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. + +**Static Parameters:** + + - ``P^\text{hy,min}`` = `PowerSystems.get_active_power_limits(device).min` + - ``P^\text{hy,max}`` = `PowerSystems.get_active_power_limits(device).max` + - ``Q^\text{hy,min}`` = `PowerSystems.get_reactive_power_limits(device).min` + - ``Q^\text{hy,max}`` = `PowerSystems.get_reactive_power_limits(device).max` + +**Time Series Parameters:** + +Uses the `max_active_power` timeseries parameter to limit the available active power at each time-step. If the timeseries parameter is not included, the power is limited by ``P^\text{th,max}``. + +**Objective:** + +Add a cost to the objective function depending on the defined cost structure of the hydro unit by adding it to its `ProductionCostExpression`. + +**Expressions:** + +Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. + +**Constraints:** + +For each hydro unit creates the range constraints for its active and reactive power depending on its static parameters. + +```math +\begin{align*} +& u_t^\text{hy} P^\text{hy,min} \le p^\text{hy}_t \le u_t^\text{hy} \text{ActivePowerTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} \\ +& u_t^\text{hy} Q^\text{hy,min} \le q^\text{hy}_t \le u_t^\text{hy} Q^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} +\end{align*} +``` + +* * * + +## `HydroCommitmentReservoirBudget` + +```@docs +HydroCommitmentReservoirBudget +``` + +**Variables:** + + - `ActivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy}`` + + - `ReactivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``q^\text{hy}`` + - `OnVariable`: + + + Bounds: ``\{0, 1\}`` + + Symbol: ``u^\text{hy}`` + +**Auxiliary Variables:** + + - [`HydroEnergyOutput`](@ref): + + + Symbol: ``E^\text{hy,out}`` + +The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. + +**Static Parameters:** + + - ``P^\text{hy,min}`` = `PowerSystems.get_active_power_limits(device).min` + - ``P^\text{hy,max}`` = `PowerSystems.get_active_power_limits(device).max` + - ``Q^\text{hy,min}`` = `PowerSystems.get_reactive_power_limits(device).min` + - ``Q^\text{hy,max}`` = `PowerSystems.get_reactive_power_limits(device).max` + +**Time Series Parameters:** + +Uses the `hydro_budget` timeseries parameter to limit the active power usage throughout all the time steps. + +**Objective:** + +Add a cost to the objective function depending on the defined cost structure of the hydro unit by adding it to its `ProductionCostExpression`. + +**Expressions:** + +Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. + +**Constraints:** + +For each hydro unit creates the range constraints for its active and reactive power depending on its static parameters. + +```math +\begin{align*} +& u_t^\text{hy} P^\text{hy,min} \le p^\text{hy}_t \le u_t^\text{hy} P^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& u_t^\text{hy} Q^\text{hy,min} \le q^\text{hy}_t \le u_t^\text{hy} Q^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& \sum_{t=1}^T p^\text{hy}_t \le \sum_{t=1}^T \text{EnergyBudgetTimeSeriesParameter}_t, +\end{align*} +``` + +* * * + +## `HydroDispatchReservoirStorage` + +```@docs +HydroCommitmentReservoirStorage +``` + +**Variables:** + + - `ActivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``p^\text{hy}`` + + - `ReactivePowerVariable`: + + + Bounds: [0.0, ] + + Symbol: ``q^\text{hy}`` + - `OnVariable`: + + + Bounds: ``\{0, 1\}`` + + Symbol: ``u^\text{hy}`` + - `EnergyVariable`: + + + Bounds: ``[0.0, E^\text{max}]`` + + Symbol: ``e`` + - [`WaterSpillageVariable`](@ref): + + + Bounds: [0.0, ] + + Symbol: ``s`` + - [`HydroEnergySurplusVariable`](@ref): + + + Bounds: ``[-E^\text{max}, 0.0]`` + + Symbol: ``e^\text{surplus}`` + - [`HydroEnergyShortageVariable`](@ref): + + + Bounds: ``[0.0, E^\text{max}]`` + + Symbol: ``e^\text{shortage}`` + +**Auxiliary Variables:** + + - [`HydroEnergyOutput`](@ref): + + + Symbol: ``E^\text{hy,out}`` + +The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. + +**Static Parameters:** + + - ``P^\text{hy,min}`` = `PowerSystems.get_active_power_limits(device).min` + - ``P^\text{hy,max}`` = `PowerSystems.get_active_power_limits(device).max` + - ``Q^\text{hy,min}`` = `PowerSystems.get_reactive_power_limits(device).min` + - ``Q^\text{hy,max}`` = `PowerSystems.get_reactive_power_limits(device).max` + - ``E^\text{max}`` = `PowerSystems.get_storage_capacity(device)` + +**Initial Conditions:** + +The `PowerSimulations.InitialEnergyLevel`: ``e_0`` is used as the initial condition for the energy level of the reservoir. + +**Time Series Parameters:** + +Uses the `storage_target` timeseries parameter to set a storage target of the reservoir and the `inflow` timeseries parameter to obtain the inflow to the reservoir. + +**Objective:** + +Add a cost to the objective function depending on the defined cost structure of the hydro unit by adding it to its `ProductionCostExpression`. This model has shortage costs for the energy target that are also added to the objective function. In case of no shortage cost are specified, the model will turn-off the shortage variable to avoid infeasible/unbounded problems. + +**Expressions:** + +Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. + +**Constraints:** + +For each hydro unit creates the range constraints for its active and reactive power depending on its static parameters. + +```math +\begin{align*} +& u_t^\text{hy} P^\text{hy,min} \le p^\text{hy}_t \le u_t^\text{hy} P^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& u_t^\text{hy} Q^\text{hy,min} \le q^\text{hy}_t \le u_t^\text{hy} Q^\text{hy,max}, \quad \forall t\in \{1, \dots, T\} \\ +& e_{t} = e_{t-1} - \Delta T (p^\text{hy}_t - s_t) + \text{InflowTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} \\ +& e_t + e^\text{shortage} + e^\text{surplus} = \text{EnergyTargetTimeSeriesParameter}_t, \quad \forall t\in \{1, \dots, T\} +\end{align*} +``` From f693d47fa635061b7e01dbe97bc51c02e13ffdd4 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:33:59 -0800 Subject: [PATCH 09/27] add quick start guide --- docs/src/quick_start_guide.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/src/quick_start_guide.md b/docs/src/quick_start_guide.md index d5903e3..3239ffa 100644 --- a/docs/src/quick_start_guide.md +++ b/docs/src/quick_start_guide.md @@ -1,3 +1,13 @@ # Quick Start Guide -HydroPowerSimulations.jl is structured to enable stuff + - **Julia:** If this is your first time using Julia visit our [Introduction to Julia](https://nrel-Sienna.github.io/SIIP-Tutorial/fundamentals/introduction-to-julia/) and the official [Getting started with Julia](https://julialang.org/learning/). + - **Package Installation:** If you want to install packages check the [Package Manager](https://pkgdocs.julialang.org/v1/environments/) instructions, or you can refer to the [PowerSimulations installation instructions](https://nrel-sienna.github.io/PowerSimulations.jl/stable/#Installation). + - **PowerSystems:** [PowerSystems.jl](https://github.com/nrel-Sienna/PowerSystems.jl) manages the data and is a fundamental dependency of PowerSimulations.jl. Check the [PowerSystems.jl Basics Tutorial](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/basics/) and [PowerSystems.jl documentation](https://nrel-Sienna.github.io/PowerSystems.jl/stable/) to understand how the inputs to the models are organized. + - **Dataset Library:** If you don't have a data set to start using `HydroPowerSimulations.jl` check the test systems provided in [`PowerSystemCaseBuilder.jl`](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/) + - **PowerSimulations:** [PowerSimulations.jl](https://github.com/NREL-Sienna/PowerSimulations.jl/) provides the basic models for + +!!! tip + + If you need to develop a dataset for a simulation check the [PowerSystems.jl Tutorials](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/basics/) on how to parse data and attach time series + + - **Tutorial:** If you are eager to run your first simulation visit the Solve a Day Ahead Market Scheduling Problem using [`PowerSimulations.jl`](https://nrel-sienna.github.io/PowerSimulations.jl/stable/) tutorials. Visit our formulations page for the available hydro generation models. From 1d79230d996551641de45d95dd3446098c04e430 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:34:07 -0800 Subject: [PATCH 10/27] update api usage --- docs/src/api/internal.md | 1 + docs/src/api/public.md | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/docs/src/api/internal.md b/docs/src/api/internal.md index 6301a6e..5726f01 100644 --- a/docs/src/api/internal.md +++ b/docs/src/api/internal.md @@ -3,4 +3,5 @@ ```@autodocs Modules = [HydroPowerSimulations] Public = false +Private = true ``` diff --git a/docs/src/api/public.md b/docs/src/api/public.md index ce477c3..415a80a 100644 --- a/docs/src/api/public.md +++ b/docs/src/api/public.md @@ -1,6 +1,72 @@ # Public API Reference +```@contents +Pages = ["public.md"] +Depth = 2 +``` + +## Variables + +```@autodocs +Modules = [HydroPowerSimulations] +Pages = ["variables.jl", + ] +Order = [:type, :function] +Public = true +Private = false +``` + +## Parameters + +```@autodocs +Modules = [HydroPowerSimulations] +Pages = ["parameters.jl", + ] +Order = [:type, :function] +Public = true +Private = false +``` + +## Expressions + +```@autodocs +Modules = [HydroPowerSimulations] +Pages = ["expressions.jl", + ] +Order = [:type, :function] +Public = true +Private = false +``` + +## Constraints + +```@autodocs +Modules = [HydroPowerSimulations] +Pages = [ "constraints.jl", + ] +Order = [:type, :function] +Public = true +Private = false +``` + +## Initial Conditions + +```@autodocs +Modules = [HydroPowerSimulations] +Pages = ["initial_conditions.jl", + ] +Order = [:type, :function] +Public = true +Private = false +``` + +## Feedforwards + ```@autodocs Modules = [HydroPowerSimulations] +Pages = ["feedforwards.jl", + ] +Order = [:type, :function] Public = true +Private = false ``` From b6c629a387dee860c052e3cf1c0cbbbd6beb1d53 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:34:19 -0800 Subject: [PATCH 11/27] complete index page --- docs/src/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index 9506f3c..4cdd607 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -6,8 +6,8 @@ CurrentModule = HydroPowerSimulations ## Overview -`HydroPowerSimulations.jl` is a [`Julia`](http://www.julialang.org) package that provides blah blah +`HydroPowerSimulations.jl` is a [`Julia`](http://www.julialang.org) package that extends [`PowerSimulations.jl`](https://github.com/NREL-Sienna/PowerSimulations.jl) for modeling of hydro generation technology in production cost modeling simulations. * * * -HydroPowerSimulations has been developed as part of the FlexPower Project at the U.S. Department of Energy's National Renewable Energy Laboratory ([NREL](https://www.nrel.gov/)) +HydroPowerSimulations has been developed as part of the Flexible Linked Analysis of Streamflow and Hydropower (FLASH) and Reliability and Resilience of coordinated water Distribution and power Distribution (R2D2) projects at the U.S. Department of Energy's National Renewable Energy Laboratory ([NREL](https://www.nrel.gov/)) Software Record SWR-23-110. From 26f79a6c11a2cfb49bdc16eb6f917dda17ab013f Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:34:32 -0800 Subject: [PATCH 12/27] add tutorial for single step simulation --- docs/src/tutorials/single_stage_model.md | 62 ++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 docs/src/tutorials/single_stage_model.md diff --git a/docs/src/tutorials/single_stage_model.md b/docs/src/tutorials/single_stage_model.md new file mode 100644 index 0000000..ce13d28 --- /dev/null +++ b/docs/src/tutorials/single_stage_model.md @@ -0,0 +1,62 @@ +# [Operation Problem with `HydroPowerSimulations.jl`](@id op_problem) + +**Originally Contributed by:** Rodrigo Henriquez-Auba + +Load packages: + +```@repl op_problem +using PowerSystems +using PowerSimulations +using HydroPowerSimulations +using PowerSystemCaseBuilder +using HiGHS # solver +``` + +## Data + +!!! note + + `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 Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/) + +```@repl op_problem +sys = build_system(PSITestSystems, "c_sys5_hy") +``` + +With a single `HydroDispatch`: + +```@repl op_problem +hy = only(get_components(HydroDispatch, sys)) +``` + +## Decision Model + +Setting up the formulations, including hydro using `HydroDispatchRunOfRiver` + +```@repl op_problem +template = ProblemTemplate(PTDFPowerModel) +set_device_model!(template, ThermalStandard, ThermalBasicDispatch) +set_device_model!(template, PowerLoad, StaticPowerLoad) +set_device_model!(template, Line, StaticBranch) +set_device_model!(template, HydroDispatch, HydroDispatchRunOfRiver) +``` + +```@repl op_problem +model = DecisionModel(template, sys; optimizer=HiGHS.Optimizer) +build!(model, output_dir=mktempdir()) +solve!(model) +``` + +## Exploring Results + +Results can be explored using: + +```@repl op_problem +res = OptimizationProblemResults(model) +``` + +with dispatch variable for the hydro: + +```@repl op_problem +var = read_variable(res, "ActivePowerVariable__HydroDispatch") +``` From 028742b648cb965ebe78541e1a692add0b12ab43 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 23 Dec 2024 16:34:38 -0800 Subject: [PATCH 13/27] update make.jl --- docs/make.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/make.jl b/docs/make.jl index 9b0f515..daf5288 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -4,6 +4,8 @@ import DataStructures: OrderedDict pages = OrderedDict( "Welcome Page" => "index.md", "Quick Start Guide" => "quick_start_guide.md", + "Tutorials" => Any["tutorials/single_stage_model.md"], + "Formulation Library" => "formulation.md", "Public API Reference" => "api/public.md", "Internal API Reference" => "api/internal.md", ) From 0e4927dbfc95d8014bb7a701ce610d6ee13c1732 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:25:39 -0800 Subject: [PATCH 14/27] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac1ca4a..6cb6521 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Documentation Build](https://github.com/NREL-Sienna/HydroPowerSimulations.jl/actions/workflows/docs.yml/badge.svg)](https://nrel-sienna.github.io/HydroPowerSimulations.jl/dev/) [](https://join.slack.com/t/nrel-sienna/shared_invite/zt-glam9vdu-o8A9TwZTZqqNTKHa7q3BpQ) -`HydroPowerSimulations.jl` is an extension package of [`PowerSimulations.jl`](https://github.com/NREL-Sienna/PowerSimulations.jl) for modeling of hydro generation technology. +`HydroPowerSimulations.jl` is an extension package of [`PowerSimulations.jl`](https://nrel-sienna.github.io/PowerSimulations.jl/stable/) for modeling of hydro generation technology. For information on using the package, see the [stable documentation](https://nrel-sienna.github.io/HydroPowerSimulations.jl/stable/). Use the [in-development documentation](https://nrel-sienna.github.io/HydroPowerSimulations.jl/dev/) for the version of the documentation which contains the unreleased features. From d81d4744dd7dd79a810d64d0ac533f66497f36bf Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:26:01 -0800 Subject: [PATCH 15/27] add PSB and Interlinks to docs TOML --- docs/Project.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Project.toml b/docs/Project.toml index 02ac5cb..625b826 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -2,11 +2,13 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8" HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" HydroPowerSimulations = "fc1677e0-6ad7-4515-bf3a-bd6bf20a0b1b" Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" PowerSimulations = "e690365d-45e2-57bb-ac84-44ba829e73c4" +PowerSystemCaseBuilder = "f00506e0-b84f-492a-93c2-c0a9afc4364e" PowerSystems = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd" [compat] From 2d80bc3749a2a9514a64da5255b2fa35c48eb4c1 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:26:34 -0800 Subject: [PATCH 16/27] add interlinks to make.jl --- docs/make.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/make.jl b/docs/make.jl index daf5288..d18ae9b 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,5 +1,11 @@ using Documenter, HydroPowerSimulations import DataStructures: OrderedDict +using DocumenterInterLinks + +links = InterLinks( + "PowerSystems" => "https://nrel-sienna.github.io/PowerSystems.jl/stable/", + "PowerSimulations" => "https://nrel-sienna.github.io/PowerSimulations.jl/stable/", +) pages = OrderedDict( "Welcome Page" => "index.md", @@ -18,6 +24,7 @@ makedocs( ), sitename="HydroPowerSimulations.jl", pages=Any[p for p in pages], + plugins=[links], ) deploydocs( From 979e33b24e76a99434e87c46a229231e54fc6ada Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:26:47 -0800 Subject: [PATCH 17/27] export constraints --- src/HydroPowerSimulations.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/HydroPowerSimulations.jl b/src/HydroPowerSimulations.jl index a1dd7ca..6af743e 100644 --- a/src/HydroPowerSimulations.jl +++ b/src/HydroPowerSimulations.jl @@ -41,6 +41,12 @@ export ReservoirLimitParameter export InitialHydroEnergyLevelUp export InitialHydroEnergyLevelDown +######## Hydro Constraints ####### +export EnergyTargetConstraint +export EnergyCapacityDownConstraint +export EnergyCapacityUpConstraint +export EnergyBudgetConstraint + ######## Hydro feedforwards ####### export ReservoirTargetFeedforward export ReservoirLimitFeedforward From f878352be7965aa60507e9f7365b7589bd6fe06c Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:27:02 -0800 Subject: [PATCH 18/27] update constraint docstrings --- src/core/constraints.jl | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/core/constraints.jl b/src/core/constraints.jl index fb5fbd8..61b85ce 100644 --- a/src/core/constraints.jl +++ b/src/core/constraints.jl @@ -1,9 +1,52 @@ struct EnergyLimitConstraint <: PSI.ConstraintType end +""" +Struct to create the constraint that set-up the target for reservoir formulations. + +For more information check [HydroPowerSimulations Formulations](@ref HydroPowerSimulations-Formulations). + +The specified constraint is formulated as: + +```math +e_t + e^\\text{shortage} + e^\\text{surplus} = \\text{EnergyTargetTimeSeriesParameter}_t, \\quad \\forall t \\in \\{1,\\dots, T\\} +``` +""" struct EnergyTargetConstraint <: PSI.ConstraintType end struct EnergyShortageVariableLimitsConstraint <: PSI.ConstraintType end +""" +Struct to create the constraint that keeps track of the reservoir level of the lower (down) reservoir + +For more information check [HydroPowerSimulations Formulations](@ref HydroPowerSimulations-Formulations). + +The specified constraint is formulated as: + +```math +e_{t}^\\text{dn} = e_{t-1}^\\text{dn} + \\left (p_t^\\text{hy,out} + s_t - \\frac{p_t^\\text{hy,in}}{\\eta^\\text{pump}} \\right) \\Delta T - \\text{OutflowTimeSeriesParameter}_t, \\quad \\forall t \\in \\{1,\\dots, T\\} +``` +""" struct EnergyCapacityDownConstraint <: PSI.ConstraintType end +""" +Struct to create the constraint that keeps track of the reservoir level of the upper (up) reservoir + +For more information check [HydroPowerSimulations Formulations](@ref HydroPowerSimulations-Formulations). + +The specified constraint is formulated as: + +```math +e_{t}^\\text{up} = e_{t-1}^\\text{up} + \\left (p_t^\\text{hy,in} - \\frac{p_t^\\text{hy,out} + s_t}{\\eta^\\text{pump}} \\right) \\Delta T + \\text{InflowTimeSeriesParameter}_t, \\quad \\forall t \\in \\{1,\\dots, T\\} +``` +""" struct EnergyCapacityUpConstraint <: PSI.ConstraintType end +""" +Struct to create the constraint that limits the budget for reservoir formulations. + +For more information check [HydroPowerSimulations Formulations](@ref HydroPowerSimulations-Formulations). + +The specified constraint is formulated as: +```math +\\sum_{t=1}^T p^\\text{hy}_t \\le \\sum_{t=1}^T \\text{EnergyBudgetTimeSeriesParameter}_t, +``` +""" struct EnergyBudgetConstraint <: PSI.ConstraintType end struct EnergyCapacityConstraint <: PSI.ConstraintType end From 7ba59f7392ff094912b52b0fd62dac1051605606 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:27:15 -0800 Subject: [PATCH 19/27] add links --- src/core/expressions.jl | 4 ++-- src/core/formulations.jl | 14 +++++++------- src/core/initial_conditions.jl | 4 ++-- src/feedforwards.jl | 30 +++++++++++++++--------------- src/hydro_generation.jl | 22 +++++++++++----------- src/hydrogeneration_constructor.jl | 28 ++++++++++++++-------------- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/core/expressions.jl b/src/core/expressions.jl index 6200a16..a71c83c 100644 --- a/src/core/expressions.jl +++ b/src/core/expressions.jl @@ -1,10 +1,10 @@ """ -Expression for HydroPumpedStorage that keep track +Expression for [`PowerSystems.HydroPumpedStorage`](@extref) that keep track of active power and reserves for Lower Bound limits """ struct ReserveRangeExpressionLB <: PSI.RangeConstraintLBExpressions end """ -Expression for HydroPumpedStorage that keep track +Expression for [`PowerSystems.HydroPumpedStorage`](@extref) that keep track of active power and reserves for Upper Bound limits """ struct ReserveRangeExpressionUB <: PSI.RangeConstraintUBExpressions end diff --git a/src/core/formulations.jl b/src/core/formulations.jl index 3d49b79..731acb3 100644 --- a/src/core/formulations.jl +++ b/src/core/formulations.jl @@ -10,36 +10,36 @@ abstract type AbstractHydroReservoirFormulation <: AbstractHydroDispatchFormulat abstract type AbstractHydroUnitCommitment <: AbstractHydroFormulation end """ -Formulation type to add injection variables constrained by total energy production budget defined with a time series for `HydroGen` +Formulation type to add injection variables constrained by total energy production budget defined with a time series for [`PowerSystems.HydroGen`](@extref) """ struct HydroDispatchReservoirBudget <: AbstractHydroReservoirFormulation end """ -Formulation type to constrain hydropower production with a representation of the energy storage capacity and water inflow time series of a reservoir for `HydroGen` +Formulation type to constrain hydropower production with a representation of the energy storage capacity and water inflow time series of a reservoir for [`PowerSystems.HydroGen`](@extref) """ struct HydroDispatchReservoirStorage <: AbstractHydroReservoirFormulation end """ -Formulation type to constrain energy production from pumped storage with a representation of the energy storage capacity of upper and lower reservoirs and water inflow time series of upper reservoir and outflow time series of lower reservoir for `HydroPumpedStorage` +Formulation type to constrain energy production from pumped storage with a representation of the energy storage capacity of upper and lower reservoirs and water inflow time series of upper reservoir and outflow time series of lower reservoir for [`PowerSystems.HydroPumpedStorage`](@extref) """ struct HydroDispatchPumpedStorage <: AbstractHydroReservoirFormulation end """ -Formulation type to add injection variables constrained by a maximum injection time series for `HydroGen` +Formulation type to add injection variables constrained by a maximum injection time series for [`PowerSystems.HydroGen`](@extref) """ struct HydroDispatchRunOfRiver <: AbstractHydroDispatchFormulation end """ -Formulation type to add commitment and injection variables constrained by total energy production budget defined with a time series for `HydroGen` +Formulation type to add commitment and injection variables constrained by total energy production budget defined with a time series for [`PowerSystems.HydroGen`](@extref) """ struct HydroCommitmentReservoirBudget <: AbstractHydroReservoirFormulation end """ -Formulation type to constrain hydropower production with unit commitment variables and a representation of the energy storage capacity and water inflow time series of a reservoir for `HydroGen` +Formulation type to constrain hydropower production with unit commitment variables and a representation of the energy storage capacity and water inflow time series of a reservoir for [`PowerSystems.HydroGen`](@extref) """ struct HydroCommitmentReservoirStorage <: AbstractHydroReservoirFormulation end """ -Formulation type to add commitment and injection variables constrained by a maximum injection time series for `HydroGen` +Formulation type to add commitment and injection variables constrained by a maximum injection time series for [`PowerSystems.HydroGen`](@extref) """ struct HydroCommitmentRunOfRiver <: AbstractHydroUnitCommitment end diff --git a/src/core/initial_conditions.jl b/src/core/initial_conditions.jl index 95ff501..bb10a29 100644 --- a/src/core/initial_conditions.jl +++ b/src/core/initial_conditions.jl @@ -1,9 +1,9 @@ """ -Initial condition for Upper reservoir in HydroPumpedStorage formulations +Initial condition for Upper reservoir in [`PowerSystems.HydroPumpedStorage`](@extref) formulations """ struct InitialHydroEnergyLevelUp <: PSI.InitialConditionType end """ -Initial condition for Down reservoir in HydroPumpedStorage formulations +Initial condition for Down reservoir in [`PowerSystems.HydroPumpedStorage`](@extref) formulations """ struct InitialHydroEnergyLevelDown <: PSI.InitialConditionType end diff --git a/src/feedforwards.jl b/src/feedforwards.jl index aba3041..dbf6dbe 100644 --- a/src/feedforwards.jl +++ b/src/feedforwards.jl @@ -1,6 +1,6 @@ """ ReservoirTargetFeedforward( - component_type::Type{<:PSY.Component}, + component_type::Type{<:PowerSystems.Component}, source::Type{T}, affected_values::Vector{DataType}, target_period::Int, @@ -13,7 +13,7 @@ variable associated with a penalty term. # Arguments: - - `component_type::Type{<:PSY.Component}` : Specify the type of component on which the Feedforward will be applied + - `component_type::Type{<:`[`PowerSystems.Component`](@extref)`}` : Specify the type of component on which the Feedforward will be applied - `source::Type{T}` : Specify the VariableType, ParameterType or AuxVariableType as the source of values for the Feedforward - `affected_values::Vector{DataType}` : Specify the variable on which the reservoir target will be applied using the source values - `target_period::Int` : Specify the time step at which the reservoir target will be applied. @@ -74,10 +74,10 @@ Constructs a equality constraint to a fix a variable in one model using the vari `` x + slack >= param`` # Arguments -* container::PSI.OptimizationContainer : the optimization_container model built in PowerSimulations -* model::PSI.DeviceModel : the device model -* devices::IS.FlattenIteratorWrapper{T} : list of devices -* ff::ReservoirTargetFeedforward : a instance of the FixValue Feedforward +* `container::PSI.OptimizationContainer` : the optimization_container model built in PowerSimulations +* `model::`[`PowerSimulations.DeviceModel`](@extref) : the device model +* `devices::IS.FlattenIteratorWrapper{T}` : list of devices +* `ff::`[`ReservoirTargetFeedforward`](@ref) : a instance of the ReservoirTarget Feedforward """ function PSI.add_feedforward_constraints!( container::PSI.OptimizationContainer, @@ -154,7 +154,7 @@ Adds a constraint to limit the sum of a variable over the number of periods to t # Arguments: - - `component_type::Type{<:PSY.Component}` : Specify the type of component on which the Feedforward will be applied + - `component_type::Type{<:`[`PowerSystems.Component`](@extref)`}` : Specify the type of component on which the Feedforward will be applied - `source::Type{T}` : Specify the VariableType, ParameterType or AuxVariableType as the source of values for the Feedforward - `affected_values::Vector{DataType}` : Specify the variable on which the reservoir limit will be applied using the source values - `number_of_periods::Int` : Specify the total number of periods that are added on which the limits are applied. For example, in a 24-step simulation if `number_of_periods = 24`, it will add only one constraint over the sum of 24 periods on which the reservoir limit will be applied. If `number_of_periods = 12`, it will create two constraints, one for the first 12 steps and one for the 13:24 steps. It is mandatory that `number_of_periods` can divide the total number of simulation steps. @@ -194,10 +194,10 @@ PSI.get_optimization_container_key(ff) = ff.optimization_container_key get_number_of_periods(ff) = ff.number_of_periods @doc raw""" - add_feedforward_constraints(container::OptimizationContainer, - cons_name::Symbol, - param_reference, - var_key::VariableKey) + add_feedforward_constraints(container::PSI.OptimizationContainer, + model::PSI.DeviceModel, + devices, + ff::ReservoirLimitFeedforward) Constructs a parameterized integral limit constraint to implement feedforward from other models. The Parameters are initialized using the upper boundary values of the provided variables. @@ -210,10 +210,10 @@ The Parameters are initialized using the upper boundary values of the provided v `` \sum_{t} x \leq param^{max}`` # Arguments -* container::OptimizationContainer : the optimization_container model built in PowerSimulations -* model::DeviceModel : the device model -* devices::IS.FlattenIteratorWrapper{T} : list of devices -* ff::FixValueFeedforward : a instance of the FixValue Feedforward +* `container::PowerSimulations.OptimizationContainer` : the optimization_container model built in PowerSimulations +* `model::`[`PowerSimulations.DeviceModel`](@extref) : the device model +* `devices::IS.FlattenIteratorWrapper{T}` : list of devices +* `ff::`[`ReservoirLimitFeedforward`](@ref) : a instance of the Reservoir Limit Feedforward """ function PSI.add_feedforward_constraints!( container::PSI.OptimizationContainer, diff --git a/src/hydro_generation.jl b/src/hydro_generation.jl index 3efd46b..18d9b62 100644 --- a/src/hydro_generation.jl +++ b/src/hydro_generation.jl @@ -292,7 +292,7 @@ function PSI.add_constraints!( end """ -Add semicontinuous range constraints for Hydro Unit Commitment formulation +Add semicontinuous range constraints for [`HydroCommitmentRunOfRiver`](@ref) formulation """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -385,7 +385,7 @@ function PSI.get_min_max_limits( end """ -Add power variable limits constraints for hydro unit commitment formulation +Add power variable limits constraints for abstract hydro unit commitment formulations """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -400,7 +400,7 @@ function PSI.add_constraints!( end """ -Add power variable limits constraints for hydro dispatch formulation +Add power variable limits constraints for abstract hydro dispatch formulations """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -421,7 +421,7 @@ function PSI.add_constraints!( end """ -Add input power variable limits constraints for hydro dispatch formulation +Add input power variable limits constraints for abstract hydro dispatch formulations """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -446,7 +446,7 @@ function PSI.add_constraints!( end """ -Add output power variable limits constraints for hydro dispatch formulation +Add output power variable limits constraints for abstract hydro dispatch formulations """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -471,7 +471,7 @@ function PSI.add_constraints!( end """ -Min and max output active power variable limits for hydro dispatch pumped storage +Min and max output active power variable limits for [`HydroDispatchPumpedStorage`](@ref) """ function PSI.get_min_max_limits( x::PSY.HydroGen, @@ -482,7 +482,7 @@ function PSI.get_min_max_limits( end """ -Min and max input active power variable limits for hydro dispatch pumped storage +Min and max input active power variable limits for [`HydroDispatchPumpedStorage`](@ref) """ function PSI.get_min_max_limits( x::PSY.HydroGen, @@ -584,7 +584,7 @@ function _add_output_limits_with_reserves!( """ This function defines the constraints for the water level (or state of charge) -for the Hydro Reservoir. +for the [`PowerSystems.HydroEnergyReservoir`](@extref). """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -643,7 +643,7 @@ end """ This function defines the constraints for the water level (or state of charge) -for the HydroPumpedStorage. +for the [`PowerSystems.HydroPumpedStorage`](@extref). """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -712,7 +712,7 @@ function PSI.add_constraints!( end """ -Add energy capacity down constraints for hydro pumped storage +Add energy capacity down constraints for [`PowerSystems.HydroPumpedStorage`](@extref) """ function PSI.add_constraints!( container::PSI.OptimizationContainer, @@ -779,7 +779,7 @@ function PSI.add_constraints!( end """ -Add energy target constraints for hydro gen +Add energy target constraints for [`PowerSystems.HydroGen`](@extref) """ function PSI.add_constraints!( container::PSI.OptimizationContainer, diff --git a/src/hydrogeneration_constructor.jl b/src/hydrogeneration_constructor.jl index 4e98cbc..94ae3e3 100644 --- a/src/hydrogeneration_constructor.jl +++ b/src/hydrogeneration_constructor.jl @@ -1,5 +1,5 @@ """ -Construct model for HydroGen with FixedOutput Formulation +Construct model for [`PowerSystems.HydroGen``](@extref) with [`PowerSimulations.FixedOutput`](@extref) Formulation """ function PSI.construct_device!( container::PSI.OptimizationContainer, @@ -69,7 +69,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with RunOfRiver Dispatch Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroDispatchRunOfRiver`](@ref) Formulation """ function PSI.construct_device!( container::PSI.OptimizationContainer, @@ -176,7 +176,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with RunOfRiver Dispatch Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroDispatchRunOfRiver`](@ref) Formulation with only Active Power. """ function PSI.construct_device!( @@ -266,7 +266,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirBudget Dispatch Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with ReservoirBudget Dispatch Formulation """ function PSI.construct_device!( container::PSI.OptimizationContainer, @@ -382,7 +382,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirBudget Dispatch Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroDispatchReservoirBudget`](@ref) Formulation with only Active Power. """ function PSI.construct_device!( @@ -477,7 +477,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirStorage Dispatch Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroDispatchReservoirStorage`](@ref) Formulation """ function PSI.construct_device!( container::PSI.OptimizationContainer, @@ -630,7 +630,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirStorage Dispatch Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroDispatchReservoirStorage`](@ref) Formulation with only Active Power """ function PSI.construct_device!( @@ -764,7 +764,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirBudget Commitment Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroCommitmentReservoirBudget`](@ref) Formulation """ function PSI.construct_device!( container::PSI.OptimizationContainer, @@ -866,7 +866,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirBudget Commitment Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroCommitmentReservoirBudget`](@ref) Formulation with only Active Power. """ function PSI.construct_device!( @@ -960,7 +960,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirStorage Commitment Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroCommitmentReservoirStorage`](@ref) Formulation """ function PSI.construct_device!( container::PSI.OptimizationContainer, @@ -1120,7 +1120,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with ReservoirStorage Commitment Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroCommitmentReservoirStorage`](@ref) Formulation with only Active Power """ function PSI.construct_device!( @@ -1259,7 +1259,7 @@ function PSI.construct_device!( end """ -Construct model for HydroPumpedStorage with PumpedStorage Dispatch Formulation +Construct model for [`PowerSystems.HydroPumpedStorage`](@extref) with [`HydroDispatchPumpedStorage`](@ref) Formulation with only Active Power """ function PSI.construct_device!( @@ -1420,7 +1420,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with HydroCommitmentRunOfRiver Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroCommitmentRunOfRiver`](@ref) Formulation """ function PSI.construct_device!( container::PSI.OptimizationContainer, @@ -1478,7 +1478,7 @@ function PSI.construct_device!( end """ -Construct model for HydroGen with RunOfRiver Commitment Formulation +Construct model for [`PowerSystems.HydroGen`](@extref) with [`HydroCommitmentRunOfRiver`](@ref) Formulation with only Active Power. """ function PSI.construct_device!( From 35faf03a2a7e11271996b00ee7a9ff3f1747bd9d Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:27:33 -0800 Subject: [PATCH 20/27] add links and false canonical docstring in formulations --- docs/src/formulation.md | 84 ++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/docs/src/formulation.md b/docs/src/formulation.md index bb4fa7a..dc3b614 100644 --- a/docs/src/formulation.md +++ b/docs/src/formulation.md @@ -22,18 +22,18 @@ Hydro generation formulations define the optimization models that describe hydro ## `HydroDispatchRunOfRiver` -```@docs +```@docs; canonical=false HydroDispatchRunOfRiver ``` **Variables:** - - `ActivePowerVariable`: + - [`PowerSimulations.ActivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy}`` - - `ReactivePowerVariable`: + - [`PowerSimulations.ReactivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``q^\text{hy}`` @@ -44,7 +44,7 @@ HydroDispatchRunOfRiver + Symbol: ``E^\text{hy,out}`` -The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. +The [`HydroEnergyOutput`](@ref) is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. **Static Parameters:** @@ -63,7 +63,7 @@ Add a cost to the objective function depending on the defined cost structure of **Expressions:** -Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. +Adds ``p^\text{hy}`` to the `PowerSimulations.ActivePowerBalance` expression and ``q^\text{hy}`` to the `PowerSimulations.ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. **Constraints:** @@ -80,18 +80,18 @@ For each hydro unit creates the range constraints for its active and reactive po ## `HydroDispatchReservoirBudget` -```@docs +```@docs; canonical=false HydroDispatchReservoirBudget ``` **Variables:** - - `ActivePowerVariable`: + - [`PowerSimulations.ActivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy}`` - - `ReactivePowerVariable`: + - [`PowerSimulations.ReactivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``q^\text{hy}`` @@ -102,7 +102,7 @@ HydroDispatchReservoirBudget + Symbol: ``E^\text{hy,out}`` -The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. +The [`HydroEnergyOutput`](@ref) is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. **Static Parameters:** @@ -121,7 +121,7 @@ Add a cost to the objective function depending on the defined cost structure of **Expressions:** -Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. +Adds ``p^\text{hy}`` to the `PowerSimulations.ActivePowerBalance` expression and ``q^\text{hy}`` to the `PowerSimulations.ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. **Constraints:** @@ -139,22 +139,22 @@ For each hydro unit creates the range constraints for its active and reactive po ## `HydroDispatchReservoirStorage` -```@docs +```@docs; canonical=false HydroDispatchReservoirStorage ``` **Variables:** - - `ActivePowerVariable`: + - [`PowerSimulations.ActivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy}`` - - `ReactivePowerVariable`: + - [`PowerSimulations.ReactivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``q^\text{hy}`` - - `EnergyVariable`: + - [`PowerSimulations.EnergyVariable`](@extref): + Bounds: ``[0.0, E^\text{max}]`` + Symbol: ``e`` @@ -177,7 +177,7 @@ HydroDispatchReservoirStorage + Symbol: ``E^\text{hy,out}`` -The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. +The [`HydroEnergyOutput`](@ref) is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. **Static Parameters:** @@ -201,7 +201,7 @@ Add a cost to the objective function depending on the defined cost structure of **Expressions:** -Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. +Adds ``p^\text{hy}`` to the `PowerSimulations.ActivePowerBalance` expression and ``q^\text{hy}`` to the `PowerSimulations.ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. **Constraints:** @@ -220,20 +220,20 @@ For each hydro unit creates the range constraints for its active and reactive po ## HydroDispatchPumpedStorage -This formulation is not available with reactive power. This formulation must be used with `PowerSystems.HydroPumpedStorage` component. +This formulation is not available with reactive power. This formulation must be used with [`PowerSystems.HydroPumpedStorage`](@extref) component. -```@docs +```@docs; canonical=false HydroDispatchPumpedStorage ``` **Variables:** - - `ActivePowerOutVariable`: + - [`PowerSimulations.ActivePowerOutVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy,out}`` - - `ActivePowerInVariable`: + - [`PowerSimulations.ActivePowerInVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy,in}`` @@ -252,7 +252,7 @@ HydroDispatchPumpedStorage If the attribute `reservation` is set to true, the following variable is created: - - `ReservationVariable`: + - [`PowerSimulations.ReservationVariable`](@extref): + Bounds: ``\{0,1\}`` + Symbol: ``ss^\text{hy}`` @@ -271,7 +271,7 @@ If `reservation` is set to false (default), then the hydro pumped storage is all **Initial Conditions:** -The `InitialHydroEnergyLevelUp`: ``e_0^\text{up}`` is used as the initial condition for the energy level of the upper reservoir, while `InitialHydroEnergyLevelDown`: ``e_0^\text{dn}`` is used as the initial condition for the energy level of the lower reservoir. +The [`InitialHydroEnergyLevelUp`](@ref): ``e_0^\text{up}`` is used as the initial condition for the energy level of the upper reservoir, while [`InitialHydroEnergyLevelDown`](@ref): ``e_0^\text{dn}`` is used as the initial condition for the energy level of the lower reservoir. **Time Series Parameters:** @@ -283,7 +283,7 @@ Add a cost to the objective function depending on the defined cost structure of **Expressions:** -Adds ``(p^\text{hy,out} - p^\text{hy,in})`` to the `ActivePowerBalance` to be used in the supply-balance constraint depending on the network model used. +Adds ``(p^\text{hy,out} - p^\text{hy,in})`` to the `PowerSimulations.ActivePowerBalance` to be used in the supply-balance constraint depending on the network model used. **Constraints:** @@ -318,22 +318,22 @@ e_{t}^\text{dn} = e_{t-1}^\text{dn} + \left (p_t^\text{hy,out} + s_t - \frac{p_t ## `HydroCommitmentRunOfRiver` -```@docs +```@docs; canonical=false HydroCommitmentRunOfRiver ``` **Variables:** - - `ActivePowerVariable`: + - [`PowerSimulations.ActivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy}`` - - `ReactivePowerVariable`: + - [`PowerSimulations.ReactivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``q^\text{hy}`` - - `OnVariable`: + - [`PowerSimulations.OnVariable`](@extref): + Bounds: ``\{0, 1\}`` + Symbol: ``u^\text{hy}`` @@ -344,7 +344,7 @@ HydroCommitmentRunOfRiver + Symbol: ``E^\text{hy,out}`` -The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. +The [`HydroEnergyOutput`](@ref) is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. **Static Parameters:** @@ -363,7 +363,7 @@ Add a cost to the objective function depending on the defined cost structure of **Expressions:** -Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. +Adds ``p^\text{hy}`` to the `PowerSimulations.ActivePowerBalance` expression and ``q^\text{hy}`` to the `PowerSimulations.ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. **Constraints:** @@ -380,22 +380,22 @@ For each hydro unit creates the range constraints for its active and reactive po ## `HydroCommitmentReservoirBudget` -```@docs +```@docs; canonical=false HydroCommitmentReservoirBudget ``` **Variables:** - - `ActivePowerVariable`: + - [`PowerSimulations.ActivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy}`` - - `ReactivePowerVariable`: + - [`PowerSimulations.ReactivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``q^\text{hy}`` - - `OnVariable`: + - [`PowerSimulations.OnVariable`](@extref): + Bounds: ``\{0, 1\}`` + Symbol: ``u^\text{hy}`` @@ -406,7 +406,7 @@ HydroCommitmentReservoirBudget + Symbol: ``E^\text{hy,out}`` -The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. +The [`HydroEnergyOutput`](@ref) is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. **Static Parameters:** @@ -425,7 +425,7 @@ Add a cost to the objective function depending on the defined cost structure of **Expressions:** -Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. +Adds ``p^\text{hy}`` to the `PowerSimulations.ActivePowerBalance` expression and ``q^\text{hy}`` to the `PowerSimulations.ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. **Constraints:** @@ -443,26 +443,26 @@ For each hydro unit creates the range constraints for its active and reactive po ## `HydroDispatchReservoirStorage` -```@docs +```@docs; canonical=false HydroCommitmentReservoirStorage ``` **Variables:** - - `ActivePowerVariable`: + - [`PowerSimulations.ActivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``p^\text{hy}`` - - `ReactivePowerVariable`: + - [`PowerSimulations.ReactivePowerVariable`](@extref): + Bounds: [0.0, ] + Symbol: ``q^\text{hy}`` - - `OnVariable`: + - [`PowerSimulations.OnVariable`](@extref): + Bounds: ``\{0, 1\}`` + Symbol: ``u^\text{hy}`` - - `EnergyVariable`: + - [`PowerSimulations.EnergyVariable`](@extref): + Bounds: ``[0.0, E^\text{max}]`` + Symbol: ``e`` @@ -485,7 +485,7 @@ HydroCommitmentReservoirStorage + Symbol: ``E^\text{hy,out}`` -The `HydroEnergyOutput` is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. +The [`HydroEnergyOutput`](@ref) is computed as the energy used at each time step from the hydro, computed simply as ``E^\text{hy,out} \cdot \Delta T``, where ``\Delta T`` is the duration (in hours) of each time step. **Static Parameters:** @@ -509,7 +509,7 @@ Add a cost to the objective function depending on the defined cost structure of **Expressions:** -Adds ``p^\text{hy}`` to the `ActivePowerBalance` expression and ``q^\text{hy}`` to the `ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. +Adds ``p^\text{hy}`` to the `PowerSimulations.ActivePowerBalance` expression and ``q^\text{hy}`` to the `PowerSimulations.ReactivePowerBalance`, to be used in the supply-balance constraint depending on the network model used. **Constraints:** From 66f469aed2f830bfc17683c4d7ec6dd9d4bdd93f Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:27:41 -0800 Subject: [PATCH 21/27] update links --- docs/src/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/index.md b/docs/src/index.md index 4cdd607..570d8fc 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -6,7 +6,7 @@ CurrentModule = HydroPowerSimulations ## Overview -`HydroPowerSimulations.jl` is a [`Julia`](http://www.julialang.org) package that extends [`PowerSimulations.jl`](https://github.com/NREL-Sienna/PowerSimulations.jl) for modeling of hydro generation technology in production cost modeling simulations. +`HydroPowerSimulations.jl` is a [`Julia`](http://www.julialang.org) package that extends [`PowerSimulations.jl`](https://github.com/NREL-Sienna/PowerSimulations.jl) for modeling of hydro generation technology in operational simulations. * * * From 5845ab20747bc5ecc1e111ae8d1a972b2a910e1c Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:29:10 -0800 Subject: [PATCH 22/27] update tutorial docs --- docs/src/tutorials/single_stage_model.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/src/tutorials/single_stage_model.md b/docs/src/tutorials/single_stage_model.md index ce13d28..464d612 100644 --- a/docs/src/tutorials/single_stage_model.md +++ b/docs/src/tutorials/single_stage_model.md @@ -1,8 +1,10 @@ # [Operation Problem with `HydroPowerSimulations.jl`](@id op_problem) -**Originally Contributed by:** Rodrigo Henriquez-Auba +!!! note + + `HydroPowerSimulations.jl` is an extension library of [`PowerSimulations.jl`](https://nrel-sienna.github.io/PowerSimulations.jl/latest/) for modeling hydro units. Users are encouraged to review the [single-step tutorial in `PowerSimulations.jl`](https://nrel-sienna.github.io/PowerSimulations.jl/latest/tutorials/decision_problem/) before this tutorial. -Load packages: +## Load packages ```@repl op_problem using PowerSystems @@ -17,13 +19,13 @@ using HiGHS # solver !!! note `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 Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/) + For more details visit [PowerSystemCaseBuilder README](https://github.com/NREL-Sienna/PowerSystemCaseBuilder.jl/blob/main/README.md) ```@repl op_problem sys = build_system(PSITestSystems, "c_sys5_hy") ``` -With a single `HydroDispatch`: +With a single [`PowerSystems.HydroDispatch`](@extref): ```@repl op_problem hy = only(get_components(HydroDispatch, sys)) @@ -31,16 +33,23 @@ hy = only(get_components(HydroDispatch, sys)) ## Decision Model -Setting up the formulations, including hydro using `HydroDispatchRunOfRiver` +Setting up the formulations based on [`PowerSimulations.jl`](https://nrel-sienna.github.io/PowerSimulations.jl/latest/formulation_library/Introduction/): ```@repl op_problem template = ProblemTemplate(PTDFPowerModel) set_device_model!(template, ThermalStandard, ThermalBasicDispatch) set_device_model!(template, PowerLoad, StaticPowerLoad) set_device_model!(template, Line, StaticBranch) +``` + +but, now we also include the hydro using [`HydroDispatchRunOfRiver`](@ref): + +```@repl op_problem set_device_model!(template, HydroDispatch, HydroDispatchRunOfRiver) ``` +With the template properly set-up, we construct, build and solve the optimization problem: + ```@repl op_problem model = DecisionModel(template, sys; optimizer=HiGHS.Optimizer) build!(model, output_dir=mktempdir()) @@ -55,7 +64,7 @@ Results can be explored using: res = OptimizationProblemResults(model) ``` -with dispatch variable for the hydro: +with dispatch variable results for the hydro: ```@repl op_problem var = read_variable(res, "ActivePowerVariable__HydroDispatch") From 2580b81fff4c870eac7dfc22081f37dd557cdb04 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 26 Dec 2024 14:29:17 -0800 Subject: [PATCH 23/27] add formulations to API --- docs/src/api/public.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/src/api/public.md b/docs/src/api/public.md index 415a80a..b9f9a00 100644 --- a/docs/src/api/public.md +++ b/docs/src/api/public.md @@ -5,6 +5,17 @@ Pages = ["public.md"] Depth = 2 ``` +## Formulations + +```@autodocs +Modules = [HydroPowerSimulations] +Pages = ["formulations.jl", + ] +Order = [:type, :function] +Public = true +Private = false +``` + ## Variables ```@autodocs From 61e034fbf7886bae4c75857b14c9a5c7c7c0b290 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 30 Dec 2024 12:28:10 -0800 Subject: [PATCH 24/27] update PSI docs link --- docs/src/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/index.md b/docs/src/index.md index 570d8fc..9623cbd 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -6,7 +6,7 @@ CurrentModule = HydroPowerSimulations ## Overview -`HydroPowerSimulations.jl` is a [`Julia`](http://www.julialang.org) package that extends [`PowerSimulations.jl`](https://github.com/NREL-Sienna/PowerSimulations.jl) for modeling of hydro generation technology in operational simulations. +`HydroPowerSimulations.jl` is a [`Julia`](http://www.julialang.org) package that extends [`PowerSimulations.jl`](https://nrel-sienna.github.io/PowerSimulations.jl/stable/) for modeling of hydro generation technology in operational simulations. * * * From f446b6590d84e5ee547a278f6659b6b8e5d7207a Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 30 Dec 2024 14:20:20 -0800 Subject: [PATCH 25/27] update read_variable comment --- docs/make.jl | 1 + docs/src/tutorials/single_stage_model.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index d18ae9b..0c326e0 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -5,6 +5,7 @@ using DocumenterInterLinks links = InterLinks( "PowerSystems" => "https://nrel-sienna.github.io/PowerSystems.jl/stable/", "PowerSimulations" => "https://nrel-sienna.github.io/PowerSimulations.jl/stable/", + "InfrastructureSystems" => "https://nrel-sienna.github.io/InfrastructureSystems.jl/stable/", ) pages = OrderedDict( diff --git a/docs/src/tutorials/single_stage_model.md b/docs/src/tutorials/single_stage_model.md index 464d612..73d4bc1 100644 --- a/docs/src/tutorials/single_stage_model.md +++ b/docs/src/tutorials/single_stage_model.md @@ -64,7 +64,7 @@ Results can be explored using: res = OptimizationProblemResults(model) ``` -with dispatch variable results for the hydro: +Use [`read_variable`](@ref InfrastructureSystems.Optimization.read_variable) to read in the dispatch variable results for the hydro: ```@repl op_problem var = read_variable(res, "ActivePowerVariable__HydroDispatch") From 9b034f0e8aed3eff9f00c6a54807984ba7990e0c Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Tue, 31 Dec 2024 11:13:47 -0800 Subject: [PATCH 26/27] update formatter --- scripts/formatter/formatter_code.jl | 53 ++++++++++++----------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/scripts/formatter/formatter_code.jl b/scripts/formatter/formatter_code.jl index 2caa269..2a6c9d7 100644 --- a/scripts/formatter/formatter_code.jl +++ b/scripts/formatter/formatter_code.jl @@ -1,41 +1,30 @@ using Pkg Pkg.activate(@__DIR__) Pkg.instantiate() +Pkg.update() using JuliaFormatter -main_paths = [".", "./docs/src"] +main_paths = ["./src", "./test", "./docs/src"] for main_path in main_paths - format( - main_path; - whitespace_ops_in_indices=true, - remove_extra_newlines=true, - verbose=true, - always_for_in=true, - whitespace_typedefs=true, - whitespace_in_kwargs=false, - format_docstrings=true, - always_use_return=false, # removed since it has false positives. - ) -end + for (root, dir, files) in walkdir(main_path) + for f in files + @show file_path = abspath(root, f) + !((occursin(".jl", f) || occursin(".md", f))) && continue + format(file_path; + whitespace_ops_in_indices = true, + remove_extra_newlines = true, + verbose = true, + always_for_in = true, + whitespace_typedefs = true, + conditional_to_if = true, + join_lines_based_on_source = true, + separate_kwargs_with_semicolon = true, + format_markdown = true, + # Brackets in code blocks cause formatter to fail, ignore for now + ignore = ["style.md", "index.md", "tests.md"], -# Documentation Formatter -main_paths = ["./docs/src"] -for main_path in main_paths - for folder in readdir(main_path) - @show folder_path = joinpath(main_path, folder) - if isfile(folder_path) - !occursin(".md", folder_path) && continue + # always_use_return = true. # Disabled since it throws a lot of false positives + ) end - format( - folder_path; - format_markdown=true, - whitespace_ops_in_indices=true, - remove_extra_newlines=true, - verbose=true, - always_for_in=true, - whitespace_typedefs=true, - whitespace_in_kwargs=false, - # always_use_return = true # removed since it has false positives. - ) end -end +end \ No newline at end of file From 1a08f6a5502a3f79a36170892eb82eb16240763d Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Tue, 31 Dec 2024 11:13:58 -0800 Subject: [PATCH 27/27] new formatting --- docs/src/tutorials/single_stage_model.md | 4 +- src/feedforwards.jl | 10 +- src/hydro_generation.jl | 9 +- test/runtests.jl | 6 +- ...st_device_hydro_generation_constructors.jl | 163 +++++++++-------- test/test_hydro_simulations.jl | 166 ++++++++++-------- 6 files changed, 189 insertions(+), 169 deletions(-) diff --git a/docs/src/tutorials/single_stage_model.md b/docs/src/tutorials/single_stage_model.md index 73d4bc1..d91cc1c 100644 --- a/docs/src/tutorials/single_stage_model.md +++ b/docs/src/tutorials/single_stage_model.md @@ -51,8 +51,8 @@ set_device_model!(template, HydroDispatch, HydroDispatchRunOfRiver) With the template properly set-up, we construct, build and solve the optimization problem: ```@repl op_problem -model = DecisionModel(template, sys; optimizer=HiGHS.Optimizer) -build!(model, output_dir=mktempdir()) +model = DecisionModel(template, sys; optimizer = HiGHS.Optimizer) +build!(model; output_dir = mktempdir()) solve!(model) ``` diff --git a/src/feedforwards.jl b/src/feedforwards.jl index dbf6dbe..39f1218 100644 --- a/src/feedforwards.jl +++ b/src/feedforwards.jl @@ -30,7 +30,7 @@ struct ReservoirTargetFeedforward <: PSI.AbstractAffectFeedforward affected_values::Vector{DataType}, target_period::Int, penalty_cost::Float64, - meta=ISOPT.CONTAINER_KEY_EMPTY_META, + meta = ISOPT.CONTAINER_KEY_EMPTY_META, ) where {T} values_vector = Vector{PSI.VariableKey}(undef, length(affected_values)) for (ix, v) in enumerate(affected_values) @@ -104,7 +104,7 @@ function PSI.add_feedforward_constraints!( PSI.FeedforwardEnergyTargetConstraint(), T, set_name; - meta="$(var_type)target", + meta = "$(var_type)target", ) for d in devices @@ -168,7 +168,7 @@ struct ReservoirLimitFeedforward <: PSI.AbstractAffectFeedforward source::Type{T}, affected_values::Vector{DataType}, number_of_periods::Int, - meta=ISOPT.CONTAINER_KEY_EMPTY_META, + meta = ISOPT.CONTAINER_KEY_EMPTY_META, ) where {T} values_vector = Vector{PSI.VariableKey}(undef, length(affected_values)) for (ix, v) in enumerate(affected_values) @@ -245,7 +245,7 @@ function PSI.add_feedforward_constraints!( T, set_name, 1:no_trenches; - meta="$(var_type)integral", + meta = "$(var_type)integral", ) for name in set_name, i in 1:no_trenches @@ -291,7 +291,7 @@ function PSI.update_parameter_values!( max_state_index = PSI.get_num_rows(state_data) state_data_index = PSI.find_timestamp_index(state_timestamps, current_time) - sim_timestamps = range(current_time; step=resolution, length=time[end]) + sim_timestamps = range(current_time; step = resolution, length = time[end]) old_parameter_values = PSI.jump_value.(parameter_array) # The current method uses older parameter values because when passing the energy output from one stage # to the next, the aux variable values gets over-written by the lower level model after its solve. diff --git a/src/hydro_generation.jl b/src/hydro_generation.jl index 18d9b62..d4435e4 100644 --- a/src/hydro_generation.jl +++ b/src/hydro_generation.jl @@ -370,7 +370,7 @@ function PSI.get_min_max_limits( ::Type{<:PSI.ActivePowerVariableLimitsConstraint}, ::Type{<:HydroDispatchRunOfRiver}, ) - return (min=0.0, max=PSY.get_max_active_power(x)) + return (min = 0.0, max = PSY.get_max_active_power(x)) end """ @@ -871,7 +871,8 @@ function PSI.add_constraints!( param = PSI.get_parameter_column_values(param_container, name) constraint[name] = JuMP.@constraint( container.JuMPmodel, - sum([variable_out[name, t] for t in time_steps]) <= sum([multiplier[name, t] * param[t] for t in time_steps]) + sum([variable_out[name, t] for t in time_steps]) <= + sum([multiplier[name, t] * param[t] for t in time_steps]) ) end return @@ -934,8 +935,8 @@ function PSI.update_decision_state!( state_data_index = 1 state_data.timestamps[:] .= range( simulation_time; - step=state_resolution, - length=PSI.get_num_rows(state_data), + step = state_resolution, + length = PSI.get_num_rows(state_data), ) else state_data_index = PSI.find_timestamp_index(state_timestamps, simulation_time) diff --git a/test/runtests.jl b/test/runtests.jl index a7a10b3..cdb000d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -107,9 +107,9 @@ function run_tests() config = IS.LoggingConfiguration(logging_config_filename) else config = IS.LoggingConfiguration(; - filename=LOG_FILE, - file_level=Logging.Info, - console_level=Logging.Error, + filename = LOG_FILE, + file_level = Logging.Info, + console_level = Logging.Error, ) end console_logger = ConsoleLogger(config.console_stream, config.console_level) diff --git a/test/test_device_hydro_generation_constructors.jl b/test/test_device_hydro_generation_constructors.jl index 33e9f5c..cb00a17 100644 --- a/test/test_device_hydro_generation_constructors.jl +++ b/test/test_device_hydro_generation_constructors.jl @@ -32,7 +32,7 @@ end device_model = PSI.DeviceModel( HydroPumpedStorage, HydroDispatchPumpedStorage; - attributes=Dict{String, Any}("reservation" => false), + attributes = Dict{String, Any}("reservation" => false), ) c_sys5_phes_ed = PSB.build_system(PSITestSystems, "c_sys5_phes_ed") @@ -146,9 +146,9 @@ end EconomicDispatchProblem, template, sys; - optimizer=ipopt_optimizer, + optimizer = ipopt_optimizer, ) - @test build!(ED; output_dir=mktempdir(; cleanup=true)) == + @test build!(ED; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT psi_checksolve_test( ED, @@ -168,8 +168,10 @@ end set_device_model!(template, HydroDispatch, HydroCommitmentRunOfRiver) @testset "HydroRoR ED model $(net)" begin - ED = DecisionModel(UnitCommitmentProblem, template, sys; optimizer=HiGHS_optimizer) - @test build!(ED; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + ED = + DecisionModel(UnitCommitmentProblem, template, sys; optimizer = HiGHS_optimizer) + @test build!(ED; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT psi_checksolve_test(ED, [MOI.OPTIMAL, MOI.LOCALLY_SOLVED], 175521.0, 1000) end end @@ -197,9 +199,9 @@ end EconomicDispatchProblem, template, sys; - optimizer=ipopt_optimizer, + optimizer = ipopt_optimizer, ) - @test build!(ED; output_dir=mktempdir(; cleanup=true)) == + @test build!(ED; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT psi_checksolve_test( ED, @@ -232,9 +234,9 @@ end UnitCommitmentProblem, template, sys; - optimizer=HiGHS_optimizer, + optimizer = HiGHS_optimizer, ) - @test build!(ED; output_dir=mktempdir(; cleanup=true)) == + @test build!(ED; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT psi_checksolve_test( ED, @@ -256,9 +258,10 @@ end EconomicDispatchProblem, template, c_sys5_hyd; - optimizer=HiGHS_optimizer, + optimizer = HiGHS_optimizer, ) - @test build!(model; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + @test build!(model; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT moi_tests(model, 15, 0, 3, 3, 9, false) # The value of this test needs to be revised # psi_checksolve_test(model, [MOI.OPTIMAL], 5621.0, 10.0) @@ -274,9 +277,10 @@ end EconomicDispatchProblem, template, c_sys5_hyd; - optimizer=HiGHS_optimizer, + optimizer = HiGHS_optimizer, ) - @test build!(model; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + @test build!(model; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT moi_tests(model, 15, 0, 3, 3, 9, false) # The value of this test needs to be revised # psi_checksolve_test(model, [MOI.OPTIMAL], 21.0) @@ -292,9 +296,10 @@ end EconomicDispatchProblem, template, c_sys5_hyd; - optimizer=HiGHS_optimizer, + optimizer = HiGHS_optimizer, ) - @test build!(model; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + @test build!(model; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT moi_tests(model, 15, 0, 3, 3, 9, false) # The value of this test needs to be revised # psi_checksolve_test(model, [MOI.OPTIMAL], -5429.0, 10.0) @@ -310,9 +315,10 @@ end EconomicDispatchProblem, template, c_sys5_hyd; - optimizer=HiGHS_optimizer, + optimizer = HiGHS_optimizer, ) - @test build!(model; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + @test build!(model; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT moi_tests(model, 15, 0, 3, 3, 9, false) psi_checksolve_test(model, [MOI.OPTIMAL], 21.0, 10.0) end @@ -327,9 +333,10 @@ end EconomicDispatchProblem, template, c_sys5_hyd; - optimizer=HiGHS_optimizer, + optimizer = HiGHS_optimizer, ) - @test build!(model; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + @test build!(model; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT moi_tests(model, 15, 0, 3, 3, 9, false) # The value of this test needs to be revised # psi_checksolve_test(model, [MOI.OPTIMAL], -17179.0) @@ -340,43 +347,43 @@ end @testset "Test SemiContinuousFeedforward to HydroDispatch with HydroDispatchRunOfRiver model" begin device_model = PSI.DeviceModel(HydroDispatch, HydroDispatchRunOfRiver) ff_sc = SemiContinuousFeedforward(; - component_type=HydroDispatch, - source=PSI.OnVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = HydroDispatch, + source = PSI.OnVariable, + affected_values = [PSI.ActivePowerVariable], ) PSI.attach_feedforward!(device_model, ff_sc) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hy") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 72, 0, 48, 24, 0, false) end @testset "Test UpperBoundFeedforward to HydroDispatch with HydroCommitmentRunOfRiver model" begin device_model = PSI.DeviceModel(HydroDispatch, HydroCommitmentRunOfRiver) ff_ub = UpperBoundFeedforward(; - component_type=HydroDispatch, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = HydroDispatch, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], ) PSI.attach_feedforward!(device_model, ff_ub) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hy") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 96, 0, 72, 24, 0, true) end @testset "Test LowerBoundFeedforward to HydroDispatch with HydroCommitmentRunOfRiver model" begin device_model = PSI.DeviceModel(HydroDispatch, HydroCommitmentRunOfRiver) ff_ub = LowerBoundFeedforward(; - component_type=HydroDispatch, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = HydroDispatch, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], ) PSI.attach_feedforward!(device_model, ff_ub) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hy") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 96, 0, 48, 48, 0, true) end @@ -384,15 +391,15 @@ end device_model = PSI.DeviceModel(HydroDispatch, HydroDispatchRunOfRiver) ff_ub = UpperBoundFeedforward(; - component_type=HydroDispatch, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = HydroDispatch, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], ) PSI.attach_feedforward!(device_model, ff_ub) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hy") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 72, 0, 72, 24, 0, false) end @@ -400,91 +407,91 @@ end device_model = PSI.DeviceModel(HydroDispatch, HydroDispatchRunOfRiver) ff_ub = LowerBoundFeedforward(; - component_type=HydroDispatch, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = HydroDispatch, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], ) PSI.attach_feedforward!(device_model, ff_ub) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hy") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 72, 0, 48, 48, 0, false) end @testset "Test ReservoirLimitFeedforward to HydroEnergyReservoir with HydroDispatchReservoirBudget model" begin device_model = PSI.DeviceModel(HydroEnergyReservoir, HydroDispatchReservoirBudget) ff_il = ReservoirLimitFeedforward(; - component_type=HydroEnergyReservoir, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], - number_of_periods=12, + component_type = HydroEnergyReservoir, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], + number_of_periods = 12, ) PSI.attach_feedforward!(device_model, ff_il) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hyd") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 72, 0, 27, 24, 0, false) end @testset "Test ReservoirLimitFeedforward to HydroEnergyReservoir with HydroDispatchReservoirStorage model" begin device_model = PSI.DeviceModel(HydroEnergyReservoir, HydroDispatchReservoirStorage) ff_il = ReservoirLimitFeedforward(; - component_type=HydroEnergyReservoir, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], - number_of_periods=12, + component_type = HydroEnergyReservoir, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], + number_of_periods = 12, ) PSI.attach_feedforward!(device_model, ff_il) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hyd_ems") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 193, 0, 26, 24, 48, false) end @testset "Test LowerBoundFeedforward to HydroEnergyReservoir with HydroDispatchReservoirStorage model" begin device_model = PSI.DeviceModel(HydroEnergyReservoir, HydroDispatchReservoirStorage) ff_il = LowerBoundFeedforward(; - component_type=HydroEnergyReservoir, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = HydroEnergyReservoir, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], ) PSI.attach_feedforward!(device_model, ff_il) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hyd_ems") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 193, 0, 24, 48, 48, false) end @testset "Test ReservoirLimitFeedforward to HydroEnergyReservoir with HydroCommitmentReservoirStorage model" begin device_model = PSI.DeviceModel(HydroEnergyReservoir, HydroCommitmentReservoirStorage) ff_il = ReservoirLimitFeedforward(; - component_type=HydroEnergyReservoir, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], - number_of_periods=12, + component_type = HydroEnergyReservoir, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], + number_of_periods = 12, ) PSI.attach_feedforward!(device_model, ff_il) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hyd_ems") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 217, 0, 26, 24, 48, true) end @testset "Test SemiContinuousFeedforward to HydroEnergyReservoir with HydroDispatchReservoirStorage model" begin device_model = PSI.DeviceModel(HydroEnergyReservoir, HydroDispatchReservoirStorage) ff_sc = SemiContinuousFeedforward(; - component_type=HydroEnergyReservoir, - source=PSI.OnVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = HydroEnergyReservoir, + source = PSI.OnVariable, + affected_values = [PSI.ActivePowerVariable], ) PSI.attach_feedforward!(device_model, ff_sc) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_hyd_ems") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 193, 0, 24, 24, 48, false) end @@ -492,16 +499,16 @@ end device_model = PSI.DeviceModel(HydroPumpedStorage, HydroDispatchPumpedStorage) ff_il = ReservoirLimitFeedforward(; - component_type=HydroPumpedStorage, - source=PSI.ActivePowerOutVariable, - affected_values=[PSI.ActivePowerOutVariable], - number_of_periods=12, + component_type = HydroPumpedStorage, + source = PSI.ActivePowerOutVariable, + affected_values = [PSI.ActivePowerOutVariable], + number_of_periods = 12, ) PSI.attach_feedforward!(device_model, ff_il) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_phes_ed") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 110, 0, 25, 24, 24, true) end @@ -509,17 +516,17 @@ end device_model = PSI.DeviceModel(HydroPumpedStorage, HydroDispatchPumpedStorage) ff_up = ReservoirTargetFeedforward(; - component_type=HydroPumpedStorage, - source=HydroEnergyVariableUp, - affected_values=[HydroEnergyVariableUp], - target_period=12, - penalty_cost=1e4, + component_type = HydroPumpedStorage, + source = HydroEnergyVariableUp, + affected_values = [HydroEnergyVariableUp], + target_period = 12, + penalty_cost = 1e4, ) PSI.attach_feedforward!(device_model, ff_up) c_sys5_hy = PSB.build_system(PSITestSystems, "c_sys5_phes_ed") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_hy) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 122, 0, 24, 25, 24, true) end @@ -540,9 +547,10 @@ end ServiceModel(ReserveDemandCurve{ReserveUp}, StepwiseCostReserve, "ORDC1"), ) - c_sys5_hyd = PSB.build_system(PSITestSystems, "c_sys5_hyd"; add_reserves=true) + c_sys5_hyd = PSB.build_system(PSITestSystems, "c_sys5_hyd"; add_reserves = true) model = DecisionModel(template, c_sys5_hyd) - @test build!(model; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + @test build!(model; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT # The value of this test needs to be revised # moi_tests(model, 240, 0, 48, 96, 72, false) end @@ -560,7 +568,8 @@ end ServiceModel(VariableReserve{ReserveDown}, RangeReserve, "Reserve8"), ) - c_sys5_phes_ed = PSB.build_system(PSITestSystems, "c_sys5_phes_ed", add_reserves=true) + c_sys5_phes_ed = PSB.build_system(PSITestSystems, "c_sys5_phes_ed"; add_reserves = true) model = DecisionModel(template, c_sys5_phes_ed) - @test build!(model; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + @test build!(model; output_dir = mktempdir(; cleanup = true)) == + PSI.ModelBuildStatus.BUILT end diff --git a/test/test_hydro_simulations.jl b/test/test_hydro_simulations.jl index c1c3590..75270b6 100644 --- a/test/test_hydro_simulations.jl +++ b/test/test_hydro_simulations.jl @@ -1,5 +1,5 @@ @testset "Single-stage Hydro Pumped Simulation" begin - output_dir = mktempdir(; cleanup=true) + output_dir = mktempdir(; cleanup = true) sys_ed = PSB.build_system(PSITestSystems, "c_sys5_phes_ed") template_ed = ProblemTemplate(CopperPlatePowerModel) @@ -9,15 +9,15 @@ model = DecisionModel( template_ed, - sys_ed, - name="ED", - optimizer=HiGHS_optimizer, - optimizer_solve_log_print=true, - store_variable_names=true, + sys_ed; + name = "ED", + optimizer = HiGHS_optimizer, + optimizer_solve_log_print = true, + store_variable_names = true, ) - @test build!(model, output_dir=output_dir) == PSI.ModelBuildStatus.BUILT - @test solve!(model; optimizer=HiGHS_optimizer, output_dir=output_dir) == + @test build!(model; output_dir = output_dir) == PSI.ModelBuildStatus.BUILT + @test solve!(model; optimizer = HiGHS_optimizer, output_dir = output_dir) == IS.Simulation.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) @@ -27,7 +27,7 @@ # the last simulation step. reservoir_up_level = "HydroEnergyVariableUp__HydroPumpedStorage" last_value = last(variables[reservoir_up_level])["HydroPumpedStorage"] - @test isapprox(last_value, 0, atol=1e-5) + @test isapprox(last_value, 0, atol = 1e-5) end @testset "Multi-Stage Hydro Simulation Build" begin @@ -58,62 +58,62 @@ end DecisionModel( template, sys_md; - name="MD", - initialize_model=false, - system_to_file=false, - optimizer=HiGHS_optimizer, + name = "MD", + initialize_model = false, + system_to_file = false, + optimizer = HiGHS_optimizer, ), DecisionModel( template_uc, sys_uc; - name="UC", - initialize_model=false, - system_to_file=false, - optimizer=HiGHS_optimizer, + name = "UC", + initialize_model = false, + system_to_file = false, + optimizer = HiGHS_optimizer, ), DecisionModel( template_ed, sys_ed; - name="ED", - initialize_model=false, - system_to_file=false, - optimizer=HiGHS_optimizer, + name = "ED", + initialize_model = false, + system_to_file = false, + optimizer = HiGHS_optimizer, ), ]) feedforwards = Dict( "UC" => [ ReservoirLimitFeedforward(; - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], - component_type=HydroEnergyReservoir, - number_of_periods=24, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], + component_type = HydroEnergyReservoir, + number_of_periods = 24, ), ], "ED" => [ ReservoirLimitFeedforward(; - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], - component_type=HydroEnergyReservoir, - number_of_periods=12, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], + component_type = HydroEnergyReservoir, + number_of_periods = 12, ), ], ) test_sequence = SimulationSequence(; - models=models, - ini_cond_chronology=InterProblemChronology(), - feedforwards=feedforwards, + models = models, + ini_cond_chronology = InterProblemChronology(), + feedforwards = feedforwards, ) sim = Simulation(; - name="test_md", - steps=2, - models=models, - sequence=test_sequence, - simulation_folder=mktempdir(; cleanup=true), + name = "test_md", + steps = 2, + models = models, + sequence = test_sequence, + simulation_folder = mktempdir(; cleanup = true), ) - @test build!(sim; serialize=false) == PSI.SimulationBuildStatus.BUILT + @test build!(sim; serialize = false) == PSI.SimulationBuildStatus.BUILT end function test_2_stage_decision_models_with_feedforwards(in_memory) @@ -130,49 +130,59 @@ function test_2_stage_decision_models_with_feedforwards(in_memory) template_ed, PSI.NetworkModel( CopperPlatePowerModel; - duals=[CopperPlateBalanceConstraint], - use_slacks=true, + duals = [CopperPlateBalanceConstraint], + use_slacks = true, ), ) c_sys5_hy_uc = PSB.build_system(PSITestSystems, "c_sys5_hy_uc") c_sys5_hy_ed = PSB.build_system(PSITestSystems, "c_sys5_hy_ed") models = SimulationModels(; - decision_models=[ - DecisionModel(template_uc, c_sys5_hy_uc; name="UC", optimizer=HiGHS_optimizer), - DecisionModel(template_ed, c_sys5_hy_ed; name="ED", optimizer=ipopt_optimizer), + decision_models = [ + DecisionModel( + template_uc, + c_sys5_hy_uc; + name = "UC", + optimizer = HiGHS_optimizer, + ), + DecisionModel( + template_ed, + c_sys5_hy_ed; + name = "ED", + optimizer = ipopt_optimizer, + ), ], ) sequence = SimulationSequence(; - models=models, - feedforwards=Dict( + models = models, + feedforwards = Dict( "ED" => [ SemiContinuousFeedforward(; - component_type=ThermalStandard, - source=PSI.OnVariable, - affected_values=[PSI.ActivePowerVariable], + component_type = ThermalStandard, + source = PSI.OnVariable, + affected_values = [PSI.ActivePowerVariable], ), ReservoirLimitFeedforward(; - component_type=HydroEnergyReservoir, - source=PSI.ActivePowerVariable, - affected_values=[PSI.ActivePowerVariable], - number_of_periods=12, + component_type = HydroEnergyReservoir, + source = PSI.ActivePowerVariable, + affected_values = [PSI.ActivePowerVariable], + number_of_periods = 12, ), ], ), - ini_cond_chronology=InterProblemChronology(), + ini_cond_chronology = InterProblemChronology(), ) sim = Simulation(; - name="no_cache", - steps=2, - models=models, - sequence=sequence, - simulation_folder=mktempdir(; cleanup=true), + name = "no_cache", + steps = 2, + models = models, + sequence = sequence, + simulation_folder = mktempdir(; cleanup = true), ) - build_out = build!(sim; console_level=Logging.Error) + build_out = build!(sim; console_level = Logging.Error) @test build_out == PSI.SimulationBuildStatus.BUILT - execute_out = execute!(sim; in_memory=in_memory) + execute_out = execute!(sim; in_memory = in_memory) @test execute_out == PSI.RunStatus.SUCCESSFULLY_FINALIZED end @@ -183,8 +193,8 @@ end end @testset "HydroPumpedStorage simulation with Reserves" begin - output_dir = mktempdir(; cleanup=true) - sys = PSB.build_system(PSITestSystems, "c_sys5_phes_ed"; add_reserves=true) + output_dir = mktempdir(; cleanup = true) + sys = PSB.build_system(PSITestSystems, "c_sys5_phes_ed"; add_reserves = true) res5 = only(get_components(VariableReserve{ReserveUp}, sys)) set_requirement!(res5, 0.1) @@ -197,7 +207,7 @@ end DeviceModel( HydroPumpedStorage, HydroDispatchPumpedStorage; - attributes=Dict{String, Any}("reservation" => false), + attributes = Dict{String, Any}("reservation" => false), ), ) set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) @@ -206,14 +216,14 @@ end model = DecisionModel( template, - sys, - name="ED", - optimizer=HiGHS_optimizer, - optimizer_solve_log_print=true, - store_variable_names=true, + sys; + name = "ED", + optimizer = HiGHS_optimizer, + optimizer_solve_log_print = true, + store_variable_names = true, ) - @test build!(model, output_dir=output_dir) == PSI.ModelBuildStatus.BUILT - @test solve!(model; optimizer=HiGHS_optimizer, output_dir=output_dir) == + @test build!(model; output_dir = output_dir) == PSI.ModelBuildStatus.BUILT + @test solve!(model; optimizer = HiGHS_optimizer, output_dir = output_dir) == IS.Simulation.RunStatus.SUCCESSFULLY_FINALIZED set_device_model!( @@ -221,19 +231,19 @@ end DeviceModel( HydroPumpedStorage, HydroDispatchPumpedStorage; - attributes=Dict{String, Any}("reservation" => true), + attributes = Dict{String, Any}("reservation" => true), ), ) model = DecisionModel( template, - sys, - name="ED", - optimizer=HiGHS_optimizer, - optimizer_solve_log_print=true, - store_variable_names=true, + sys; + name = "ED", + optimizer = HiGHS_optimizer, + optimizer_solve_log_print = true, + store_variable_names = true, ) - @test build!(model, output_dir=output_dir) == PSI.ModelBuildStatus.BUILT - @test solve!(model; optimizer=HiGHS_optimizer, output_dir=output_dir) == + @test build!(model; output_dir = output_dir) == PSI.ModelBuildStatus.BUILT + @test solve!(model; optimizer = HiGHS_optimizer, output_dir = output_dir) == IS.Simulation.RunStatus.SUCCESSFULLY_FINALIZED end