Skip to content

Commit

Permalink
Improvement of function calls (#21)
Browse files Browse the repository at this point in the history
* Adjusted the model for changes in EMI and TS

* Prepared EMG for EMI reimplementation
  • Loading branch information
JulStraus authored May 24, 2024
1 parent 6b76fbd commit 4d401ac
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 74 deletions.
11 changes: 11 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Release notes

## Version 0.9.0 (2024-05-24)

### Update on function calls for dispatching on `modeltype`

* Introduced `modeltype` as argument for all create and constraint functions.
* Moved constraint on installed capacity to function `constraints_capacity_installed` to replicate the dispatch behaviour from `EnergyModelsBase`.

## Version 0.8.5 (2024-05-24)

* Update of dependencies and adjustment to changes in `EnergyModelsBase` v0.7.

## Version 0.8.4 (2024-05-09)

* Provided a contribution section in the documentation.
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "EnergyModelsGeography"
uuid = "3f775d88-a4da-46c4-a2cc-aa9f16db6708"
authors = ["Espen Flo Bødal <[email protected]>"]
version = "0.8.5"
version = "0.9.0"

[deps]
EnergyModelsBase = "5d7e687e-f956-46f3-9045-6f5a5fd49f50"
Expand Down
3 changes: 3 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Pages = [
"manual/transmission-mode.md",
"manual/simple-example.md"
]
Depth = 1
```

## How to guides
Expand All @@ -27,6 +28,7 @@ Pages = [
Pages = [
"how-to/contribute.md",
]
Depth = 1
```

## Library outline
Expand All @@ -36,4 +38,5 @@ Pages = [
"library/public.md",
"library/internals/reference.md",
]
Depth = 1
```
31 changes: 26 additions & 5 deletions docs/src/manual/constraint-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ In later implementation, it is planned to also use dispatch for this analysis as
## Capacity constraints

```julia
constraints_capacity(m, tm::TransmissionMode, 𝒯::TimeStructure)
constraints_capacity(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)
```

correponds to the constraints on the capacity usage of a transmission mode ``tm``.
Expand All @@ -17,10 +17,31 @@ The key difference between the former two is related that `PipeMode` does not al
`PipeLinepackSimple` includes in addition the maximum storage capacity for a pipeline when considering linepacking.
The implementation is still preliminary and based on a simplified potential for energy storage in a pipeline.

Within this function, the function

```julia
constraints_capacity_installed(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)
```

is called to limit the variable ``\texttt{trans\_cap\_inst}`` of transmission mode ``tm``.
This functions is also used to subsequently dispatch on model type for the introduction of investments.

!!! warning
As the function `constraints_capacity_installed` is used for including investments for tranmission modes, it is important that it is also called when creating a new mode.
It is not possible to only add a function for
```julia
constraints_capacity_installed(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)
```
without adding a function for
```julia
constraints_capacity_installed(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EMI.AbstractInvestmentModel)
```
as this can lead to a method ambiguity error.

## Transmission loss functions

```julia
constraints_trans_loss(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
constraints_trans_loss(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
```

correponds to the constraints on the energy balance of a transmission mode ``tm``.
Expand All @@ -31,7 +52,7 @@ The loss is calculated for the provided `TransmissionMode`s as relative loss of
## Balance functions

```julia
constraints_trans_balance(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
constraints_trans_balance(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
```

correponds to the constraints on the energy balance of a transmission mode ``tm``.
Expand All @@ -48,15 +69,15 @@ The standard approach only relies on the conservation of mass/energy, while stor
## Operational expenditure constraints

```julia
constraints_opex_fixed(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
constraints_opex_fixed(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
```

corresponds to the constraints calculating the fixed operational costs of a transmission mode `tm`.
There is currently only a single implemented version.
It can however be extended, if desirable.

```julia
constraints_opex_var(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
constraints_opex_var(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
```

corresponds to the constraints calculating the variable operational costs of a transmission mode `tm`.
Expand Down
14 changes: 8 additions & 6 deletions examples/network.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ function get_sub_system_data(
NG, Coal, Power, CO2 = products

# Use of standard demand if not provided differently
d_standard = OperationalProfile([10, 10, 10, 10, 35, 40, 45, 45, 50, 50, 60, 60, 50, 45, 45, 40, 35, 40, 45, 40, 35, 30, 30, 30])
d_standard = OperationalProfile([20, 20, 20, 20, 25, 30, 35, 35, 40, 40, 40, 40, 40, 35, 35, 30, 25, 30, 35, 30, 25, 20, 20, 20])
if demand == false
demand = [d_standard; d_standard; d_standard; d_standard]
demand *= d_scale
Expand Down Expand Up @@ -225,12 +225,14 @@ function get_sub_system_data(
Dict(Power => 1), # Output from the node with output ratio
[EmissionsEnergy()], # Additonal data for emissions
),
RefStorage(
RefStorage{AccumulatingEmissions}(
j+6, # Node id
FixedProfile(20), # Rate capacity in t/h
FixedProfile(600), # Storage capacity in t
FixedProfile(9.1), # Storage variable OPEX for the rate in EUR/t
FixedProfile(0), # Storage fixed OPEX for the rate in EUR/(t/h 24h)
StorCapOpex(
FixedProfile(20), # Charge capacity in t/h
FixedProfile(9.1), # Storage variable OPEX for the charging in EUR/t
FixedProfile(0), # Storage fixed OPEX for the charging in EUR/(t/h 8h)
),
StorCap(FixedProfile(600)), # Storage capacity in t
CO2, # Stored resource
Dict(CO2 => 1, Power => 0.02), # Input resource with input ratio
# Line above: This implies that storing CO2 requires Power
Expand Down
74 changes: 52 additions & 22 deletions src/constraint_functions.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""
constraints_capacity(m, tm::TransmissionMode, 𝒯::TimeStructure)
constraints_capacity(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the maximum capacity of a generic `TransmissionMode`.
This function serves as fallback option if no other function is specified for a `TransmissionMode`.
"""
function constraints_capacity(m, tm::TransmissionMode, 𝒯::TimeStructure)
function constraints_capacity(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)

# Upper limit defined by installed capacity
@constraint(m, [t 𝒯],
Expand All @@ -17,36 +17,48 @@ function constraints_capacity(m, tm::TransmissionMode, 𝒯::TimeStructure)
m[:trans_in][tm, t] >= -1 * m[:trans_cap][tm, t]
)
else
@constraint(m, [t 𝒯], m[:trans_out][tm, t] >= 0)
for t 𝒯
set_lower_bound(m[:trans_in][tm, t], 0)
set_lower_bound(m[:trans_out][tm, t], 0)
end
end

# Add constraints for the installed capacity
constraints_capacity_installed(m, tm, 𝒯, modeltype)
end

"""
constraints_capacity(m, tm::PipeMode, 𝒯::TimeStructure)
constraints_capacity(m, tm::PipeMode, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the maximum capacity of a generic `PipeMode`.
"""
function constraints_capacity(m, tm::PipeMode, 𝒯::TimeStructure)
function constraints_capacity(m, tm::PipeMode, 𝒯::TimeStructure, modeltype::EnergyModel)

# Upper and lower limit defined by installed capacity
@constraint(m, [t 𝒯],
m[:trans_out][tm, t] <= m[:trans_cap][tm, t]
)
@constraint(m, [t 𝒯], m[:trans_out][tm, t] >= 0)
for t 𝒯
set_lower_bound(m[:trans_out][tm, t], 0)
set_lower_bound(m[:trans_in][tm, t], 0)
end

# Bi-directional not allowed for PipeMode
if is_bidirectional(tm)
@warn "Only uni-directional tranmission is allowed for TransmissionMode of type
$(typeof(tm)), uni-directional constraints for capacity is implemented for $tm."
end

# Add constraints for the installed capacity
constraints_capacity_installed(m, tm, 𝒯, modeltype)
end

"""
constraints_capacity(m, tm::PipeLinepackSimple, 𝒯::TimeStructure)
constraints_capacity(m, tm::PipeLinepackSimple, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the maximum capacity of a `PipeLinepackSimple`.
"""
function constraints_capacity(m, tm::PipeLinepackSimple, 𝒯::TimeStructure)
function constraints_capacity(m, tm::PipeLinepackSimple, 𝒯::TimeStructure, modeltype::EnergyModel)

# Upper and lower transmission limit defined by installed capacity
@constraint(m, [t 𝒯],
Expand All @@ -55,8 +67,10 @@ function constraints_capacity(m, tm::PipeLinepackSimple, 𝒯::TimeStructure)
@constraint(m, [t 𝒯],
m[:trans_in][tm, t] - m[:trans_loss][tm, t] <= m[:trans_cap][tm, t]
)
@constraint(m, [t 𝒯], m[:trans_out][tm, t] >= 0)
@constraint(m, [t 𝒯], m[:trans_in][tm, t] >= 0)
for t 𝒯
set_lower_bound(m[:trans_out][tm, t], 0)
set_lower_bound(m[:trans_in][tm, t], 0)
end

# Linepack storage upper limit
@constraint(m, [t 𝒯],
Expand All @@ -67,16 +81,32 @@ function constraints_capacity(m, tm::PipeLinepackSimple, 𝒯::TimeStructure)
@warn "Only uni-directional tranmission is allowed for TransmissionMode of type
$(typeof(tm)), uni-directional constraints for capacity is implemented for $tm."
end

# Add constraints for the installed capacity
constraints_capacity_installed(m, tm, 𝒯, modeltype)
end

"""
constraints_capacity_installed(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the installed capacity of a `TransmissionMode`.
"""
function constraints_capacity_installed(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)

# Fix the installed capacity to the upper bound
for t 𝒯
fix(m[:trans_cap][tm, t], capacity(tm, t); force=true)
end
end


"""
constraints_trans_loss(m, tm::TransmissionMode, 𝒯::TimeStructure)
constraints_trans_loss(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the transmission loss of a generic `TransmissionMode`.
This function serves as fallback option if no other function is specified for a `TransmissionMode`.
"""
function constraints_trans_loss(m, tm::TransmissionMode, 𝒯::TimeStructure)
function constraints_trans_loss(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)

if is_bidirectional(tm)
# The total loss equals the sum of negative and positive loss (absolute loss)
Expand All @@ -100,11 +130,11 @@ function constraints_trans_loss(m, tm::TransmissionMode, 𝒯::TimeStructure)
end

"""
constraints_trans_loss(m, tm::PipeMode, 𝒯::TimeStructure)
constraints_trans_loss(m, tm::PipeMode, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the transmission loss of a generic `PipeMode`.
"""
function constraints_trans_loss(m, tm::PipeMode, 𝒯::TimeStructure)
function constraints_trans_loss(m, tm::PipeMode, 𝒯::TimeStructure, modeltype::EnergyModel)


@constraint(m, [t 𝒯],
Expand All @@ -119,24 +149,24 @@ end


"""
constraints_trans_balance(m, tm::TransmissionMode, 𝒯::TimeStructure)
constraints_trans_balance(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the transmission balance for a generic `TransmissionMode`.
This function serves as fallback option if no other function is specified for a `TransmissionMode`.
"""
function constraints_trans_balance(m, tm::TransmissionMode, 𝒯::TimeStructure)
function constraints_trans_balance(m, tm::TransmissionMode, 𝒯::TimeStructure, modeltype::EnergyModel)

@constraint(m, [t 𝒯],
m[:trans_out][tm, t] == m[:trans_in][tm, t] - m[:trans_loss][tm, t])

end

"""
constraints_trans_balance(m, tm::PipeLinepackSimple, 𝒯::TimeStructure)
constraints_trans_balance(m, tm::PipeLinepackSimple, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the transmission balance for a`PipeLinepackSimple`.
"""
function constraints_trans_balance(m, tm::PipeLinepackSimple, 𝒯::TimeStructure)
function constraints_trans_balance(m, tm::PipeLinepackSimple, 𝒯::TimeStructure, modeltype::EnergyModel)

𝒯ᴵⁿᵛ = strategic_periods(𝒯)
for t_inv 𝒯ᴵⁿᵛ, (t_prev, t) withprev(t_inv)
Expand Down Expand Up @@ -165,12 +195,12 @@ end


"""
constraints_opex_fixed(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
constraints_opex_fixed(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
Function for creating the constraint on the fixed OPEX of a generic `TransmissionMode`.
This function serves as fallback option if no other function is specified for a `TransmissionMode`.
"""
function constraints_opex_fixed(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
function constraints_opex_fixed(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)

@constraint(m, [t_inv 𝒯ᴵⁿᵛ],
m[:trans_opex_fixed][tm, t_inv] ==
Expand All @@ -180,12 +210,12 @@ end


"""
constraints_opex_var(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
constraints_opex_var(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
Function for creating the constraint on the variable OPEX of a generic `TransmissionMode`.
This function serves as fallback option if no other function is specified for a `TransmissionMode`.
"""
function constraints_opex_var(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ)
function constraints_opex_var(m, tm::TransmissionMode, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)

if is_bidirectional(tm)
@constraint(m, [t_inv 𝒯ᴵⁿᵛ],
Expand Down
Loading

2 comments on commit 4d401ac

@JulStraus
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/107564

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.9.0 -m "<description of version>" 4d401ac1adfd2c6ce38b70f6be6ebebfae06c3d7
git push origin v0.9.0

Please sign in to comment.