diff --git a/NEWS.md b/NEWS.md index f7663139..9768720b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,11 @@ # Release notes +## Version 0.8.7 (2026-04-15) + +### Bug fixes + +* Fixed a bug in the function `check_scenario_profile` resulting in an error, if utilized. + ## Version 0.8.6 (2025-11-26) ### Bugfixes diff --git a/Project.toml b/Project.toml index 3cf39729..5d15d49b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "EnergyModelsBase" uuid = "5d7e687e-f956-46f3-9045-6f5a5fd49f50" authors = ["Lars Hellemo , Julian Straus "] -version = "0.8.6" +version = "0.8.7" [deps] JuMP = "4076af6c-e467-56ae-b986-b466b2749572" diff --git a/docs/src/how-to/utilize-timestruct.md b/docs/src/how-to/utilize-timestruct.md index 85c5dc50..79c253da 100644 --- a/docs/src/how-to/utilize-timestruct.md +++ b/docs/src/how-to/utilize-timestruct.md @@ -39,7 +39,7 @@ op_number = length(op_duration) operational_periods = SimpleTimes(op_number, op_duration) # output -SimpleTimes{Int64}(11, [4, 2, 1, 1, 2, 4, 2, 1, 1, 2, 4]) +SimpleTimes{Int64}(11, [4, 2, 1, 1, 2, 4, 2, 1, 1, 2, 4], 24) ``` In this case, we model the day not with hourly resolution, but only have hourly resolution in the morning and afternoon. @@ -60,7 +60,7 @@ Instead, one can also write operational_periods = SimpleTimes(op_duration) # output -SimpleTimes{Int64}(11, [4, 2, 1, 1, 2, 4, 2, 1, 1, 2, 4]) +SimpleTimes{Int64}(11, [4, 2, 1, 1, 2, 4, 2, 1, 1, 2, 4], 24) ``` and a constructor will automatically deduce that there have to be 11 operational periods. diff --git a/src/checks.jl b/src/checks.jl index ceabd2c1..fb41ce5a 100644 --- a/src/checks.jl +++ b/src/checks.jl @@ -493,28 +493,28 @@ scenario indexing. """ function check_scenario_profile(time_profile::TimeProfile, message::String) # Check on the highest level - bool_osc = check_osc_sub_profile(time_profile, message, true) + bool_scp = check_osc_sub_profile(time_profile, message, true) # Iterate through the strategic profiles, if existing if isa(time_profile, StrategicProfile) for l1_profile ∈ time_profile.vals sub_msg = "in strategic profiles " * message - bool_osc = check_osc_sub_profile(l1_profile, sub_msg, bool_osc) + bool_scp = check_osc_sub_profile(l1_profile, sub_msg, bool_scp) if isa(l1_profile, RepresentativeProfile) for l2_profile ∈ l1_profile.vals sub_msg = "in representative profiles in strategic profiles " * message - bool_osc = check_osc_sub_profile(l2_profile, sub_msg, bool_osc) + bool_scp = check_osc_sub_profile(l2_profile, sub_msg, bool_scp) if isa(l2_profile, ScenarioProfile) for l3_profile ∈ l2_profile.vals sub_msg = "in scenario profiles in representative profiles in strategic profiles " * message - bool_osc = check_osc_sub_profile(l3_profile, sub_msg, bool_osc) + bool_scp = check_osc_sub_profile(l3_profile, sub_msg, bool_scp) end end end elseif isa(l1_profile, ScenarioProfile) for l2_profile ∈ l1_profile.vals sub_msg = "in scenario profiles in strategic profiles " * message - bool_osc = check_osc_sub_profile(l2_profile, sub_msg, bool_osc) + bool_scp = check_osc_sub_profile(l2_profile, sub_msg, bool_scp) end end end @@ -524,11 +524,11 @@ function check_scenario_profile(time_profile::TimeProfile, message::String) if isa(time_profile, RepresentativeProfile) for l1_profile ∈ time_profile.vals sub_msg = "in representative profiles " * message - bool_osc = check_osc_sub_profile(l1_profile, sub_msg, bool_osc) + bool_scp = check_osc_sub_profile(l1_profile, sub_msg, bool_scp) if isa(l1_profile, ScenarioProfile) for l2_profile ∈ l1_profile.vals sub_msg = "in scenario profiles in representative profiles " * message - bool_osc = check_osc_sub_profile(l2_profile, sub_msg, bool_osc) + bool_scp = check_osc_sub_profile(l2_profile, sub_msg, bool_scp) end end end @@ -538,7 +538,7 @@ function check_scenario_profile(time_profile::TimeProfile, message::String) if isa(time_profile, ScenarioProfile) for l1_profile ∈ time_profile.vals sub_msg = "in scenario profiles " * message - bool_osc = check_osc_sub_profile(l1_profile, sub_msg, bool_osc) + bool_scp = check_osc_sub_profile(l1_profile, sub_msg, bool_scp) end end return bool_scp diff --git a/src/constraint_functions.jl b/src/constraint_functions.jl index db728e51..a2c09f68 100644 --- a/src/constraint_functions.jl +++ b/src/constraint_functions.jl @@ -639,7 +639,7 @@ function constraints_opex_fixed(m, n::Sink, 𝒯ᴵⁿᵛ, modeltype::EnergyMode # Fix the fixed OPEX for t_inv ∈ 𝒯ᴵⁿᵛ - fix(m[:opex_fixed][n, t_inv], 0, ; force = true) + fix(m[:opex_fixed][n, t_inv], 0; force = true) end end diff --git a/src/data_functions.jl b/src/data_functions.jl index 21ab1dc7..9cd841c4 100644 --- a/src/data_functions.jl +++ b/src/data_functions.jl @@ -33,7 +33,7 @@ function constraints_data(m, n::Node, 𝒯, 𝒫, modeltype::EnergyModel, data:: # Fix the other emissions to 0 to avoid problems with unconstrained variables for t ∈ 𝒯, p_em ∈ 𝒫ᵉᵐ - fix(m[:emissions_node][n, t, p_em], 0, ; force = true) + fix(m[:emissions_node][n, t, p_em], 0; force = true) end end function constraints_data(m, n::Node, 𝒯, 𝒫, modeltype::EnergyModel, data::EmissionsProcess) diff --git a/src/structures/data.jl b/src/structures/data.jl index 7370bc01..f41c62ee 100644 --- a/src/structures/data.jl +++ b/src/structures/data.jl @@ -215,18 +215,18 @@ When multiple inputs are provided, a constructor directly creates the correspond [`StartInvData`](@extref EnergyModelsInvestments.StartInvData) type for the investment data. - **`inv_mode::Investment`** is the chosen investment mode for the technology. The following investment modes are currently available: - [`BinaryInvestment`](@extref EnergyModelsInvestments), - [`DiscreteInvestment`](@extref EnergyModelsInvestments), - [`ContinuousInvestment`](@extref EnergyModelsInvestments), - [`SemiContinuousInvestment`](@extref EnergyModelsInvestments), or - [`FixedInvestment`](@extref EnergyModelsInvestments). + [`BinaryInvestment`](@extref EnergyModelsInvestments.BinaryInvestment), + [`DiscreteInvestment`](@extref EnergyModelsInvestments.DiscreteInvestment), + [`ContinuousInvestment`](@extref EnergyModelsInvestments.ContinuousInvestment), + [`SemiContinuousInvestment`](@extref EnergyModelsInvestments.SemiContinuousInvestment), or + [`FixedInvestment`](@extref EnergyModelsInvestments.FixedInvestment). - **`life_mode::LifetimeMode`** is type of handling the lifetime. Several different alternatives can be used: - [`UnlimitedLife`](@extref EnergyModelsInvestments), - [`StudyLife`](@extref EnergyModelsInvestments), - [`PeriodLife`](@extref EnergyModelsInvestments), or - [`RollingLife`](@extref EnergyModelsInvestments). If `life_mode` is not specified, the - model assumes an [`UnlimitedLife`](@extref EnergyModelsInvestments). + [`UnlimitedLife`](@extref EnergyModelsInvestments.UnlimitedLife), + [`StudyLife`](@extref EnergyModelsInvestments.StudyLife), + [`PeriodLife`](@extref EnergyModelsInvestments.PeriodLife), or + [`RollingLife`](@extref EnergyModelsInvestments.RollingLife). If `life_mode` is not specified, the + model assumes an [`UnlimitedLife`](@extref EnergyModelsInvestments.UnlimitedLife). """ abstract type SingleInvData <: InvestmentData end diff --git a/test/test_checks.jl b/test/test_checks.jl index 7e38bafe..efe05f97 100644 --- a/test/test_checks.jl +++ b/test/test_checks.jl @@ -368,6 +368,17 @@ end @test_throws AssertionError EMB.check_scenario_profile(tp, "") end + # Check that valid profiles pass check_scenario_profile without error + valid_profiles = [ + FixedProfile(5), + StrategicProfile([FixedProfile(5)]), + StrategicProfile([RepresentativeProfile([FixedProfile(5)])]), + RepresentativeProfile([ScenarioProfile([FixedProfile(5)])]), + ] + for tp ∈ valid_profiles + @test EMB.check_scenario_profile(tp, "") + end + # Reactivate logging EMB.ASSERTS_AS_LOG = true end