Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjusted to changes in EMB in checks #13

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release notes

## Version 0.5.5 (2024-03-21)

* Minor changes to the checks to be consistent with `EnergyModelsBase` v0.6.7.

## Version 0.5.4 (2024-03-04)

### Examples
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "EnergyModelsRenewableProducers"
uuid = "b007c34f-ba52-4995-ba37-fffe79fbde35"
authors = ["Sigmund Eggen Holm <[email protected]>, Julian Straus <[email protected]>"]
version = "0.5.4"
version = "0.5.5"

[deps]
EnergyModelsBase = "5d7e687e-f956-46f3-9045-6f5a5fd49f50"
Expand All @@ -10,7 +10,7 @@ Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
TimeStruct = "f9ed5ce0-9f41-4eaa-96da-f38ab8df101c"

[compat]
EnergyModelsBase = "^0.6.3"
EnergyModelsBase = "^0.6.7"
JuMP = "1.5"
TimeStruct = "^0.7.0"
julia = "^1.6"
50 changes: 24 additions & 26 deletions src/checks.jl
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
"""
EMB.check_node(n::NonDisRES, 𝒯, modeltype::EMB.EnergyModel)
EMB.check_node(n::NonDisRES, 𝒯, modeltype::EMB.EnergyModel, check_timeprofiles::Bool)

This method checks that the *[`NonDisRES`](@ref NonDisRES_public)* node is valid.

## Checks
- The field `cap` is required to be non-negative (similar to the `Source` check).
- The field `opex_fixed` is required to be non-negative (similar to the `Source` check).
- The values of the dictionary `output` are required to be non-negative \
(similar to the `Source` check).
- The field `profile` is required to be in the range ``[0, 1]`` for all time steps \
``t ∈ \\mathcal{T}``.
- The value of the field `fixed_opex` is required to be non-negative and
accessible through a `StrategicPeriod` as outlined in the function
`check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)`.
- The values of the dictionary `output` are required to be non-negative
(similar to the `Source` check).
- The field `profile` is required to be in the range ``[0, 1]`` for all time steps
``t ∈ \\mathcal{T}``.
"""
function EMB.check_node(n::NonDisRES, 𝒯, modeltype::EMB.EnergyModel)
function EMB.check_node(n::NonDisRES, 𝒯, modeltype::EMB.EnergyModel, check_timeprofiles::Bool)

𝒯ᴵⁿᵛ = strategic_periods(𝒯)

@assert_or_log(
sum(capacity(n, t) ≥ 0 for t ∈ 𝒯) == length(𝒯),
"The capacity must be non-negative."
)
@assert_or_log(
sum(opex_fixed(n, t_inv) ≥ 0 for t_inv ∈ 𝒯ᴵⁿᵛ) == length(𝒯ᴵⁿᵛ),
"The fixed OPEX must be non-negative."
)
EMB.check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)
@assert_or_log(
sum(outputs(n, p) ≥ 0 for p ∈ outputs(n)) == length(outputs(n)),
"The values for the Dictionary `output` must be non-negative."
Expand All @@ -38,23 +37,25 @@ function EMB.check_node(n::NonDisRES, 𝒯, modeltype::EMB.EnergyModel)
end

"""
EMB.check_node(n::HydroStorage, 𝒯, modeltype::EMB.EnergyModel)
EMB.check_node(n::HydroStorage, 𝒯, modeltype::EMB.EnergyModel, check_timeprofiles::Bool)

This method checks that the *[`HydroStorage`](@ref HydroStorage_public)* node is valid.

## Checks
- The value of the field `rate_cap` is required to be non-negative.\n
- The value of the field `stor_cap` is required to be non-negative.\n
- The value of the field `fixed_opex` is required to be non-negative.\n
- The field `output` can only include a single `Resource`.\n
- The value of the field `output` is required to be smaller or equal to 1.\n
- The value of the field `input` is required to be in the range ``[0, 1]``.\n
- The value of the field `level_init` is required to be in the range \
``[level\\_min, 1] \\cdot stor\\_cap(t)`` for all time steps ``t ∈ \\mathcal{T}``.\n
- The value of the field `level_init` is required to be in the range ``[0, 1]``.\n
- The value of the field `rate_cap` is required to be non-negative.
- The value of the field `stor_cap` is required to be non-negative.
- The value of the field `fixed_opex` is required to be non-negative and
accessible through a `StrategicPeriod` as outlined in the function
`check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)`.
- The field `output` can only include a single `Resource`.
- The value of the field `output` is required to be smaller or equal to 1.
- The value of the field `input` is required to be in the range ``[0, 1]``.
- The value of the field `level_init` is required to be in the range
``[level\\_min, 1] \\cdot stor\\_cap(t)`` for all time steps ``t ∈ \\mathcal{T}``.
- The value of the field `level_init` is required to be in the range ``[0, 1]``.
- The value of the field `level_min` is required to be in the range ``[0, 1]``.
"""
function EMB.check_node(n::HydroStorage, 𝒯, modeltype::EMB.EnergyModel)
function EMB.check_node(n::HydroStorage, 𝒯, modeltype::EMB.EnergyModel, check_timeprofiles::Bool)

𝒯ᴵⁿᵛ = strategic_periods(𝒯)
cap = capacity(n)
Expand All @@ -67,10 +68,7 @@ function EMB.check_node(n::HydroStorage, 𝒯, modeltype::EMB.EnergyModel)
sum(cap.level[t] < 0 for t ∈ 𝒯) == 0,
"The storage capacity in field `stor_cap` has to be non-negative."
)
@assert_or_log(
sum(opex_fixed(n, t_inv) >= 0 for t_inv ∈ 𝒯ᴵⁿᵛ) == length(𝒯ᴵⁿᵛ),
"The fixed OPEX must be non-negative."
)
EMB.check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)
@assert_or_log(
length(outputs(n)) == 1,
"Only one resource can be stored, so only this one can flow out."
Expand Down
2 changes: 1 addition & 1 deletion test/test_hydro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ end
case[:T] = TwoLevel(2, 1, SimpleTimes(10, 1))

# Run the model
m = EMB.run_model(case, modeltype, OPTIMIZER)
m = EMB.run_model(case, modeltype, OPTIMIZER; check_timeprofiles=false)

# Extraction of the time structure
𝒯 = case[:T]
Expand Down
Loading