From 550a1c69653aadb4e68202aa6134d6b0b3c6a602 Mon Sep 17 00:00:00 2001 From: Diego Alejandro Tejada Arango <12887482+datejada@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:52:32 +0200 Subject: [PATCH] Refactor group constraints to improve performance (#807) --- docs/src/formulation.md | 2 ++ docs/src/how-to-use.md | 6 ++++-- src/constraints/group.jl | 24 ++++++++++++++++++------ src/create-model.jl | 18 ++++++++++-------- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/docs/src/formulation.md b/docs/src/formulation.md index 94631326..ff1a0dad 100644 --- a/docs/src/formulation.md +++ b/docs/src/formulation.md @@ -541,6 +541,8 @@ The following constraints aggregate variables of different assets depending on t These constraints apply to assets in a group using the investment method $\mathcal{G}^{\text{ai}}$. They help impose an investment potential of a spatial area commonly shared by several assets that can be invested there. +> **Note**: These constraints are applied to the investments each year. The model does not yet have investment limits to a group's accumulated invested capacity. + ##### Minimum Investment Limit of a Group ```math diff --git a/docs/src/how-to-use.md b/docs/src/how-to-use.md index 9a36032f..29061fde 100644 --- a/docs/src/how-to-use.md +++ b/docs/src/how-to-use.md @@ -427,8 +427,10 @@ The mathematical formulation of the maximum and minimum investment limit for gro - `invest_method = true`. This parameter enables the model to use the investment group constraints. - `min_investment_limit` $\neq$ `missing` or `max_investment_limit` $\neq$ `missing`. This value represents the limits that will be imposed on the investment that belongs to the group. - > **Note:** - > A missing value in the parameters `min_investment_limit` and `max_investment_limit` means that there is no investment limit. + > **Notes:** + > + > 1. A missing value in the parameters `min_investment_limit` and `max_investment_limit` means that there is no investment limit. + > 2. These constraints are applied to the investments each year. The model does not yet have investment limits to a group's accumulated invested capacity. #### Example diff --git a/src/constraints/group.jl b/src/constraints/group.jl index c49595d1..8a25afa1 100644 --- a/src/constraints/group.jl +++ b/src/constraints/group.jl @@ -1,38 +1,50 @@ export add_group_constraints! """ - add_group_constraints!(graph, Ai, assets_investment, groups) + add_group_constraints!(model, graph, ...) Adds group constraints for assets that share a common limits or bounds """ function add_group_constraints!(model, graph, Y, Ai, assets_investment, groups) - # - Investment group constraints + # - Group constraints for investments at each year + assets_at_year_in_group = Dict( + group => ( + (a, y) for y in Y for + a in Ai[y] if !ismissing(graph[a].group) && graph[a].group == group.name + ) for group in groups + ) @expression( model, investment_group[group in groups], if group.invest_method sum( graph[a].capacity * assets_investment[y, a] for y in Y for - a in Ai[y] if !ismissing(graph[a].group) && graph[a].group == group.name + (a, y) in assets_at_year_in_group[group] ) end ) + + groups_with_max_investment_limit = + (group for group in groups if !ismissing(group.max_investment_limit)) model[:investment_group_max_limit] = [ @constraint( model, investment_group[group] ≤ group.max_investment_limit, base_name = "investment_group_max_limit[$(group.name)]" - ) for group in groups if !ismissing(group.max_investment_limit) + ) for group in groups_with_max_investment_limit ] + + groups_with_min_investment_limit = + (group for group in groups if !ismissing(group.min_investment_limit)) model[:investment_group_min_limit] = [ @constraint( model, investment_group[group] ≥ group.min_investment_limit, base_name = "investment_group_min_limit[$(group.name)]" - ) for group in groups if !ismissing(group.min_investment_limit) + ) for group in groups_with_min_investment_limit ] - # - TODO: More group constraints + # - TODO: More group constraints e.g., limits on the accumulated investments of a group end diff --git a/src/create-model.jl b/src/create-model.jl index b74fcdcc..e27e34b0 100644 --- a/src/create-model.jl +++ b/src/create-model.jl @@ -1215,14 +1215,16 @@ function create_model( flows_investment, ) - @timeit to "add_group_constraints!" add_group_constraints!( - model, - graph, - Y, - Ai, - assets_investment, - groups, - ) + if !isempty(groups) + @timeit to "add_group_constraints!" add_group_constraints!( + model, + graph, + Y, + Ai, + assets_investment, + groups, + ) + end if !isempty(dataframes[:units_on_and_outflows]) @timeit to "add_ramping_constraints!" add_ramping_constraints!(