From e15ea2724b77c532621239da96fa7233734b35f3 Mon Sep 17 00:00:00 2001 From: Julian Straus Date: Wed, 8 Apr 2026 14:09:18 +0200 Subject: [PATCH 1/4] Adjusted to EMI v0.9 --- Project.toml | 4 ++-- ext/EMIExt/constraints.jl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index 1f2b997f..dbc83d7a 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.9.5" +version = "0.10.0" [deps] JuMP = "4076af6c-e467-56ae-b986-b466b2749572" @@ -15,7 +15,7 @@ EnergyModelsInvestments = "fca3f8eb-b383-437d-8e7b-aac76bb2004f" EMIExt = "EnergyModelsInvestments" [compat] -EnergyModelsInvestments = "0.8" +EnergyModelsInvestments = "0.9" JuMP = "1" SparseVariables = "0.7.3" TimeStruct = "0.9" diff --git a/ext/EMIExt/constraints.jl b/ext/EMIExt/constraints.jl index 7f718048..ba414869 100644 --- a/ext/EMIExt/constraints.jl +++ b/ext/EMIExt/constraints.jl @@ -27,7 +27,7 @@ function EMB.constraints_capacity_installed( 𝒯ᴵⁿᵛ = strategic_periods(𝒯) # Add the investment constraints - EMI.add_investment_constraints(m, n, inv_data, :cap, :cap, 𝒯ᴵⁿᵛ, disc_rate) + EMI.add_investment_constraints(m, n, inv_data, :cap, :cap, 𝒯, disc_rate) else for t ∈ 𝒯 fix(m[:cap_inst][n, t], EMB.capacity(n, t); force = true) @@ -58,7 +58,7 @@ function EMB.constraints_capacity_installed( inv_data = investment_data(n, cap) # Add the investment constraints - EMI.add_investment_constraints(m, n, inv_data, cap, prefix, 𝒯ᴵⁿᵛ, disc_rate) + EMI.add_investment_constraints(m, n, inv_data, cap, prefix, 𝒯, disc_rate) elseif isa(stor_par, EMB.UnionCapacity) for t ∈ 𝒯 @@ -80,7 +80,7 @@ function EMB.constraints_capacity_installed( 𝒯ᴵⁿᵛ = strategic_periods(𝒯) # Add the investment constraints - EMI.add_investment_constraints(m, l, inv_data, :cap, :link_cap, 𝒯ᴵⁿᵛ, disc_rate) + EMI.add_investment_constraints(m, l, inv_data, :cap, :link_cap, 𝒯, disc_rate) else for t ∈ 𝒯 fix(m[:link_cap_inst][l, t], EMB.capacity(l, t); force = true) From 7d2d84e0e8a77db80662da5f029816a5e849fc26 Mon Sep 17 00:00:00 2001 From: Julian Straus Date: Wed, 8 Apr 2026 14:57:10 +0200 Subject: [PATCH 2/4] Updated value in testset --- NEWS.md | 12 ++++++++++-- test/test_investments.jl | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index bab01f1b..48039131 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,14 @@ ## Unversioned +### Breaking changes + +* Adjusted to the changes introduced in [`EnergyModelsInvestments` 0.9](https://github.com/EnergyModelsX/EnergyModelsInvestments.jl/releases/tag/v0.9.0): + * Breaking change required as early retirement is now allowed. + * Changed the function call arguments for [`add_investment_constraints`](https://github.com/EnergyModelsX/EnergyModelsInvestments.jl/blob/0c84eb4fabdf6f3c188812a3555b40f2681e916b/src/model.jl#L1). + +### Minor updates + * Introduced support in checks for `TwoLevelTree` and `StrategicStochasticProfile`. ## Version 0.9.5 (2026-03-25) @@ -59,10 +67,10 @@ ### Rework of data * Renamed extension data related functions and types: - * `Data` is now called `ExtraData`. + * `Data` is now called `ExtensionData`. * `create_data` is now called `create_ext_data`. * The old version is still accessible, but will be removed in release 0.10. -* Allow for variable creation for `ExtraData` types and implemented the approach for `InvestmentData` for both `Node`s and `Link`s. +* Allow for variable creation for `ExtensionData` types and implemented the approach for `InvestmentData` for both `Node`s and `Link`s. ### Minor updates diff --git a/test/test_investments.jl b/test/test_investments.jl index 39b02593..27698ee6 100644 --- a/test/test_investments.jl +++ b/test/test_investments.jl @@ -227,7 +227,8 @@ using EnergyModelsInvestments # Test results # (-724 compared to 0.5.x as RefStorage as emission source does not require a charge # capacity any longer in 0.7.x) - @test round(objective_value(m)) ≈ -302624 + # (-10736 compared to 0.9.x due to the potential of early retirment) + @test round(objective_value(m)) ≈ -313360.0 # Test that investments are happening 𝒯ᴵⁿᵛ = strategic_periods(get_time_struct(case)) From e6a887cd15ae18fba37c77e10939aa694e4506d9 Mon Sep 17 00:00:00 2001 From: Julian Straus Date: Wed, 8 Apr 2026 15:34:56 +0200 Subject: [PATCH 3/4] Fixed problems in documentation * Uncertain why the inventories require this now * To be considered to be removed in a later stage --- ext/EMIExt/constraints.jl | 3 --- src/structures/data.jl | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/ext/EMIExt/constraints.jl b/ext/EMIExt/constraints.jl index ba414869..db8bc726 100644 --- a/ext/EMIExt/constraints.jl +++ b/ext/EMIExt/constraints.jl @@ -24,7 +24,6 @@ function EMB.constraints_capacity_installed( # Extract the investment data, the discount rate, and the strategic periods disc_rate = discount_rate(modeltype) inv_data = investment_data(n, :cap) - 𝒯ᴵⁿᵛ = strategic_periods(𝒯) # Add the investment constraints EMI.add_investment_constraints(m, n, inv_data, :cap, :cap, 𝒯, disc_rate) @@ -42,7 +41,6 @@ function EMB.constraints_capacity_installed( ) # Extract the he discount rate and the strategic periods disc_rate = discount_rate(modeltype) - 𝒯ᴵⁿᵛ = strategic_periods(𝒯) cap_map = Dict(:charge => charge, :level => level, :discharge => discharge) @@ -77,7 +75,6 @@ function EMB.constraints_capacity_installed( # Extract the investment data, the discount rate, and the strategic periods disc_rate = discount_rate(modeltype) inv_data = investment_data(l, :cap) - 𝒯ᴵⁿᵛ = strategic_periods(𝒯) # Add the investment constraints EMI.add_investment_constraints(m, l, inv_data, :cap, :link_cap, 𝒯, disc_rate) diff --git a/src/structures/data.jl b/src/structures/data.jl index 3d1450c3..bdafa776 100644 --- a/src/structures/data.jl +++ b/src/structures/data.jl @@ -229,18 +229,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 From 9fdf5a2689a4fdd82502be6ff2ab9c48377c7bfa Mon Sep 17 00:00:00 2001 From: Julian Straus Date: Wed, 8 Apr 2026 16:14:40 +0200 Subject: [PATCH 4/4] Increased robustness of test --- test/test_investments.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/test_investments.jl b/test/test_investments.jl index 27698ee6..174c4f0a 100644 --- a/test/test_investments.jl +++ b/test/test_investments.jl @@ -260,10 +260,9 @@ end id::Any from::EMB.Node to::EMB.Node - formulation::EMB.Formulation data::Vector{<:ExtensionData} end - function EMB.create_link(m, 𝒯, 𝒫, l::InvDirect, modeltype::EnergyModel, formulation::EMB.Formulation) + function EMB.create_link(m, l::InvDirect, 𝒯, 𝒫, modeltype::EnergyModel) # Generic link in which each output corresponds to the input @constraint(m, [t ∈ 𝒯, p ∈ EMB.link_res(l)], @@ -318,7 +317,7 @@ end nodes = [source_1, source_2, sink] links = Link[ OpexDirect("OpexDirect", source_1, sink, Linear()), - InvDirect("InvDirect", source_2, sink, Linear(), data_link), + InvDirect("InvDirect", source_2, sink, data_link), ] # Creation of the time structure and global data @@ -360,7 +359,7 @@ end ) # Test that investments are happening - @test value.(m[:link_cap_add])[ℒ[2],𝒯ᴵⁿᵛ[3]] == 3 + @test sum(value.(m[:link_cap_add])[ℒ[2], t_inv] for t_inv ∈ 𝒯ᴵⁿᵛ) == 3 # Test that the variables are `link_cap_capex`, `link_cap_current`, `link_cap_add` and # `link_cap_rem` are created for the corresponding links while `link_cap_invest_b` and @@ -680,7 +679,7 @@ EMB.TEST_ENV = true Dict(Power => 1), ) nodes = [source, sink] - links = [InvDirect("scr-sink", nodes[1], nodes[2], Linear(), inv_data)] + links = [InvDirect("scr-sink", nodes[1], nodes[2], inv_data)] T = TwoLevel(4, 10, SimpleTimes(4, 1)) case = Case(T, products, [nodes, links], [[get_nodes, get_links]])