Skip to content

Commit

Permalink
Merge a6cb30b into 2334364
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigomha committed Apr 23, 2024
2 parents 2334364 + a6cb30b commit 2c812c1
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 10 deletions.
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ pages = OrderedDict(
"Troubleshooting" => "code_base_developer_guide/troubleshooting.md",
],
"Formulation Library" => Any[
"Introduction" => "formulation_library/Introduction.md",
"General" => "formulation_library/General.md",
"Network" => "formulation_library/Network.md",
"Thermal Generation" => "formulation_library/ThermalGen.md",
"Renewable Generation" => "formulation_library/RenewableGen.md",
"Load" => "formulation_library/Load.md",
"Network" => "formulation_library/Network.md",
"Branch" => "formulation_library/Branch.md",
],
"API Reference" => "api/PowerSimulations.md",
Expand Down
67 changes: 67 additions & 0 deletions docs/src/formulation_library/Introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Formulations Introduction

PowerSimulations.jl enables modularity in its formulations by assigning a `DeviceModel` to each `PowerSystems.jl` component type existing in a defined system.

`PowerSimulations.jl` has a multiple `AbstractDeviceFormulation` subtypes that can be applied to different `PowerSystems.jl` device types, each dispatching to different methods for populating the optimization problem **variables**, **objective function**, **expressions** and **constraints**.

## Example Formulation

For example a typical optimization problem in a `DecisionModel` in `PowerSimulations.jl` with three `DeviceModel` has the abstract form of:

```math
\begin{align*}
&\min_{\boldsymbol{x}}~ \text{Objective\_DeviceModelA} + \text{Objective\_DeviceModelB} + \text{Objective\_DeviceModelC} \\
& ~~\text{s.t.} \\
& \hspace{0.9cm} \text{Constraints\_NetworkModel} \\
& \hspace{0.9cm} \text{Constraints\_DeviceModelA} \\
& \hspace{0.9cm} \text{Constraints\_DeviceModelB} \\
& \hspace{0.9cm} \text{Constraints\_DeviceModelC}
\end{align*}
```

Suppose this is a system with the following characteristics:
- Horizon: 48 hours
- Interval: 24 hours
- Resolution: 1 hour
- Three Buses: 1, 2 and 3
- One `ThermalStandard` (device A) unit at bus 1
- One `RenewableDispatch` (device B) unit at bus 2
- One `PowerLoad` (device C) at bus 3
- Three `Line` that connects all the buses

Now, we assign the following `DeviceModel` to each `PowerSystems.jl` with:

| Type | Formulation |
| ----------- | ----------- |
| Network | `CopperPlatePowerModel` |
| `ThermalStandard` | `ThermalDispatchNoMin` |
| `RenewableDispatch` | `RenewableFullDispatch` |
| `PowerLoad` | `StaticPowerLoad` |

Note that we did not assigned any `DeviceModel` to `Line` since the `CopperPlatePowerModel` used for the network assumes that everything is lumped in the same node (like a copper plate with infinite capacity), and hence there are no flows between buses that branches can limit.

Each `DeviceModel` formulation is described in specific in their respective page, but the overall optimization problem will end-up as:

```math
\begin{align*}
&\min_{\boldsymbol{p}^\text{th}, \boldsymbol{p}^\text{re}}~ \sum_{t=1}^{48} C^\text{th} p_t^\text{th} - C^\text{re} p_t^\text{re} \\
& ~~\text{s.t.} \\
& \hspace{0.9cm} p_t^\text{th} + p_t^\text{re} = P_t^\text{load}, \quad \forall t \in {1,\dots, 48} \\
& \hspace{0.9cm} 0 \le p_t^\text{th} \le P^\text{th,max} \\
& \hspace{0.9cm} 0 \le p_t^\text{re} \le \text{ActivePowerTimeSeriesParameter}_t
\end{align*}
```

Note that the `StaticPowerLoad` does not impose any cost to the objective function or any constraint, but add its power demand to the supply-balance demand of the `CopperPlatePowerModel` used. Since we are using the `ThermalDispatchNoMin` formulation for the thermal generation, the lower bound for the power is 0, instead of ``P^\text{th,min}``. In addition, we are assuming a linear cost ``c^\text{th}``. Finally, the `RenewableFullDispatch` formulation allows the dispatch of the renewable unit to be between 0 and its maximum injection time series ``p_t^\text{re,param}``.

# Nomenclature

In the formulations described in the other pages, the nomenclature is as follows:
- Lowercase letters are used for variables, e.g., ``p`` for power.
- Uppercase letters are used for parameters, e.g., ``C`` for costs.
- Subscripts are used for indexing, e.g., ``(\cdot)_t`` for indexing at time ``t``.
- Superscripts are used for descriptions, e.g., ``(\cdot)^\text{th}`` to describe a thermal (th) variable/parameter.
- Bold letters are used for vectors, e.g., ``\boldsymbol{p} = \{p\}_{1,\dots,24}``.



125 changes: 124 additions & 1 deletion docs/src/formulation_library/Network.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,126 @@
# [Network Formulations](@id network_formulations)

TODO
Network formulations are used to describe how the network and buses are handled when constructing constraints. The most common constraint decided by the network formulation is the supply-demand balance constraint. Available Network Models are:

| Formulation | Description |
| ----- | ---- |
| `CopperPlatePowerModel` | Copper plate connection between all components, i.e. infinite transmission capacity |
| `AreaBalancePowerModel` | Network model approximation to represent inter-area flow with each area represented as a single node |
| `PTDFPowerModel` | Uses the PTDF factor matrix to compute the fraction of power transferred in the network across the branches |

[`PowerModels.jl`](https://github.com/lanl-ansi/PowerModels.jl) available formulations:
- Exact non-convex models: `ACPPowerModel`, `ACRPowerModel`, `ACTPowerModel`.
- Linear approximations: `DCPPowerModel`, `NFAPowerModel`.
- Quadratic approximations: `DCPLLPowerModel`, `LPACCPowerModel`
- Quadratic relaxations: `SOCWRPowerModel`, `SOCWRConicPowerModel`, `SOCBFPowerModel`, `SOCBFConicPowerModel`, `QCRMPowerModel`, `QCLSPowerModel`.
- SDP relaxations: `SDPWRMPowerModel`, `SparseSDPWRMPowerModel`.

All of these formulations are described in the [PowerModels.jl documentation](https://lanl-ansi.github.io/PowerModels.jl/stable/formulation-details/) and will not be described here.


## `CopperPlatePowerModel`

```@docs
CopperPlatePowerModel
```

**Variables:**

If Slack variables are enabled:
- [`SystemBalanceSlackUp`](@ref):
- Bounds: [0.0, ]
- Default initial value: 0.0
- Default proportional cost: 1e6
- Symbol: ``p^\text{sl,up}``
- [`SystemBalanceSlackDown`](@ref):
- Bounds: [0.0, ]
- Default initial value: 0.0
- Default proportional cost: 1e6
- Symbol: ``p^\text{sl,dn}``

**Objective:**

Add a large proportional cost to the objective function if slack variables are used ``+ (p^\text{sl,up} + p^\text{sl,dn}) \cdot 10^6``

**Expressions:**

Adds ``p^\text{sl,up}`` and ``p^\text{sl,dn}`` terms to the respective active power balance expressions `ActivePowerBalance` created by this `CopperPlatePowerModel` network formulation.

**Constraints:**

Adds the `CopperPlateBalanceConstraint` to balance the active power of all components available in the system

```math
\begin{align}
& \sum_{c \in \text{components}} p_t^c = 0, \quad \forall t \in \{1, \dots, T\}
\end{align}
```

## `AreaBalancePowerModel`

```@docs
AreaBalancePowerModel
```

**Variables:**

Slack variables are not supported for `AreaBalancePowerModel`

**Objective:**

No changes to the objective function.

**Expressions:**

Creates `ActivePowerBalance` expressions for each bus that then are used to balance active power for all buses within a single area.

**Constraints:**

Adds the `AreaDispatchBalanceConstraint` to balance the active power of all components available in an area.

```math
\begin{align}
& \sum_{c \in \text{components}_a} p_t^c = 0, \quad \forall a\in \{1,\dots, A\}, t \in \{1, \dots, T\}
\end{align}
```

## `PTDFPowerModel`

```@docs
PTDFPowerModel
```

**Variables:**

If Slack variables are enabled:
- [`SystemBalanceSlackUp`](@ref):
- Bounds: [0.0, ]
- Default initial value: 0.0
- Default proportional cost: 1e6
- Symbol: ``p^\text{sl,up}``
- [`SystemBalanceSlackDown`](@ref):
- Bounds: [0.0, ]
- Default initial value: 0.0
- Default proportional cost: 1e6
- Symbol: ``p^\text{sl,dn}``

**Objective:**

Add a large proportional cost to the objective function if slack variables are used ``+ (p^\text{sl,up} + p^\text{sl,dn}) \cdot 10^6``

**Expressions:**

Adds ``p^\text{sl,up}`` and ``p^\text{sl,dn}`` terms to the respective active power balance expressions `ActivePowerBalance` created by this `CopperPlatePowerModel` network formulation.

**Constraints:**

Adds the `CopperPlateBalanceConstraint` to balance the active power of all components available in the system

```math
\begin{align}
& \sum_{c \in \text{components}} p_t^c = 0, \quad \forall t \in \{1, \dots, T\}
\end{align}
```

In addition creates `NodalBalanceActiveConstraint` for HVDC buses balance, if DC components are connected to an HVDC network.

4 changes: 2 additions & 2 deletions src/core/formulations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ struct LossLessLine <: AbstractBranchFormulation end

abstract type AbstractPTDFModel <: PM.AbstractDCPModel end
"""
Linear active power approximation using the power transfer distribution factor ((PTDF)[https://nrel-sienna.github.io/PowerNetworkMatrices.jl/stable/tutorials/tutorial_PTDF_matrix/]) matrix.
Linear active power approximation using the power transfer distribution factor [PTDF](https://nrel-sienna.github.io/PowerNetworkMatrices.jl/stable/tutorials/tutorial_PTDF_matrix/) matrix.
"""
struct PTDFPowerModel <: AbstractPTDFModel end
"""
Infinate capacity approximation of network flow to represent entire system with a single node.
Infinite capacity approximation of network flow to represent entire system with a single node.
"""
struct CopperPlatePowerModel <: PM.AbstractActivePowerModel end
"""
Expand Down
22 changes: 16 additions & 6 deletions src/core/variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,28 @@ get_component_type(
"""
Struct to dispatch the creation of Active Power Variables
Docs abbreviation: ``Pg``
Docs abbreviation: ``p``
"""
struct ActivePowerVariable <: VariableType end

"""
Struct to dispatch the creation of Active Power Variables above minimum power for Thermal Compact formulations
Docs abbreviation: ``\\hat{Pg}``
Docs abbreviation: ``\\hat{p}``
"""
struct PowerAboveMinimumVariable <: VariableType end

"""
Struct to dispatch the creation of Active Power Input Variables for 2-directional devices. For instance storage or pump-hydro
Docs abbreviation: ``Pg^{in}``
Docs abbreviation: ``P^\text{in}``
"""
struct ActivePowerInVariable <: VariableType end

"""
Struct to dispatch the creation of Active Power Output Variables for 2-directional devices. For instance storage or pump-hydro
Docs abbreviation: ``Pg^{out}``
Docs abbreviation: ``P^\text{out}``
"""
struct ActivePowerOutVariable <: VariableType end

Expand Down Expand Up @@ -83,7 +83,7 @@ struct ColdStartVariable <: VariableType end
"""
Struct to dispatch the creation of a variable for energy storage level (state of charge)
Docs abbreviation: ``E``
Docs abbreviation: ``e``
"""
struct EnergyVariable <: VariableType end

Expand All @@ -99,7 +99,7 @@ struct OnVariable <: VariableType end
"""
Struct to dispatch the creation of Reactive Power Variables
Docs abbreviation: ``Qg``
Docs abbreviation: ``q``
"""
struct ReactivePowerVariable <: VariableType end

Expand Down Expand Up @@ -147,8 +147,18 @@ struct AdditionalDeltaActivePowerDownVariable <: VariableType end

struct SmoothACE <: VariableType end

"""
Struct to dispatch the creation of System-wide slack up variables. Used when there is not enough generation.
Docs abbreviation: ``p^\text{sl,up}``
"""
struct SystemBalanceSlackUp <: VariableType end

"""
Struct to dispatch the creation of System-wide slack down variables. Used when there is not enough load curtailment.
Docs abbreviation: ``p^\text{sl,dn}``
"""
struct SystemBalanceSlackDown <: VariableType end

struct ReserveRequirementSlack <: VariableType end
Expand Down

0 comments on commit 2c812c1

Please sign in to comment.