diff --git a/NEWS.md b/NEWS.md index d485c4e..1ff87f7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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 diff --git a/Project.toml b/Project.toml index b030add..bc37985 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "EnergyModelsRenewableProducers" uuid = "b007c34f-ba52-4995-ba37-fffe79fbde35" authors = ["Sigmund Eggen Holm , Julian Straus "] -version = "0.5.4" +version = "0.5.5" [deps] EnergyModelsBase = "5d7e687e-f956-46f3-9045-6f5a5fd49f50" @@ -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" diff --git a/src/checks.jl b/src/checks.jl index eb1095a..0028cf3 100644 --- a/src/checks.jl +++ b/src/checks.jl @@ -1,17 +1,19 @@ """ - 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(𝒯) @@ -19,10 +21,7 @@ function EMB.check_node(n::NonDisRES, 𝒯, modeltype::EMB.EnergyModel) 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." @@ -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) @@ -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." diff --git a/test/test_hydro.jl b/test/test_hydro.jl index d616702..7b64bb7 100644 --- a/test/test_hydro.jl +++ b/test/test_hydro.jl @@ -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]