Skip to content

Commit

Permalink
Remove data from graph object in src/constraints/group.jl (#985)
Browse files Browse the repository at this point in the history
  • Loading branch information
datejada authored Dec 19, 2024
1 parent 27e346c commit 59d9e96
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 56 deletions.
40 changes: 23 additions & 17 deletions src/constraints/group.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
export add_group_constraints!

"""
add_group_constraints!(model, graph, ...)
add_group_constraints!(connection, model, ...)
Adds group constraints for assets that share a common limits or bounds
"""
function add_group_constraints!(model, variables, constraints, graph, sets, groups)
# unpack from sets
Ai = sets[:Ai]
Y = sets[:Y]

assets_investment = variables[:assets_investment].lookup

# - Group constraints for investments at each year
assets_at_year_in_group = Dict(
group.name => (
(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
)
function add_group_constraints!(connection, model, variables, constraints)
assets_investment = variables[:assets_investment].container

for table_name in [:group_max_investment_limit, :group_min_investment_limit]
cons = constraints[table_name]
Expand All @@ -29,8 +17,8 @@ function add_group_constraints!(model, variables, constraints, graph, sets, grou
@expression(
model,
sum(
graph[a].capacity * assets_investment[y, a] for y in Y for
(a, y) in assets_at_year_in_group[row.name]
asset_row.capacity * assets_investment[asset_row.index] for
asset_row in _get_assets_in_group(connection, row.name)
)
) for row in eachrow(cons.indices)
],
Expand Down Expand Up @@ -73,3 +61,21 @@ function add_group_constraints!(model, variables, constraints, graph, sets, grou

return
end

function _get_assets_in_group(connection, group)
return DuckDB.query(
connection,
"SELECT
var.index,
asset.group,
asset.capacity,
FROM var_assets_investment AS var
JOIN asset
ON var.asset = asset.asset
JOIN group_asset
ON asset.group = group_asset.name
WHERE asset.group IS NOT NULL
AND asset.group = '$group'
",
)
end
22 changes: 8 additions & 14 deletions src/create-model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ function create_model!(energy_problem; kwargs...)
energy_problem.representative_periods,
energy_problem.years,
energy_problem.timeframe,
energy_problem.groups,
energy_problem.model_parameters;
kwargs...,
)
Expand All @@ -29,9 +28,9 @@ function create_model!(energy_problem; kwargs...)
end

"""
model = create_model(connection, graph, representative_periods, dataframes, timeframe, groups; write_lp_file = false, enable_names = true)
model = create_model(connection, graph, representative_periods, dataframes, timeframe; write_lp_file = false, enable_names = true)
Create the energy model given the `graph`, `representative_periods`, dictionary of `dataframes` (created by [`construct_dataframes`](@ref)), timeframe, and groups.
Create the energy model given the `graph`, `representative_periods`, dictionary of `dataframes` (created by [`construct_dataframes`](@ref)), and timeframe.
"""
function create_model(
connection,
Expand All @@ -43,7 +42,6 @@ function create_model(
representative_periods,
years,
timeframe,
groups,
model_parameters;
write_lp_file = false,
enable_names = true,
Expand Down Expand Up @@ -150,16 +148,12 @@ function create_model(
profiles,
)

if !isempty(groups)
@timeit to "add_group_constraints!" add_group_constraints!(
model,
variables,
constraints,
graph,
sets,
groups,
)
end
@timeit to "add_group_constraints!" add_group_constraints!(
connection,
model,
variables,
constraints,
)

if !isempty(constraints[:ramping_with_unit_commitment].indices)
@timeit to "add_ramping_constraints!" add_ramping_constraints!(
Expand Down
4 changes: 1 addition & 3 deletions src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ function create_internal_structures(connection)

timeframe = Timeframe(num_periods.period, TulipaIO.get_table(connection, "rep_periods_mapping"))

groups = [Group(row...) for row in TulipaIO.get_table(Val(:raw), connection, "group_asset")]

_query_data_per_year(table_name, col, year_col; where_pairs...) = begin
# Make sure valid year columns are used
@assert year_col in ("milestone_year", "commission_year")
Expand Down Expand Up @@ -296,7 +294,7 @@ function create_internal_structures(connection)
end
end

return graph, representative_periods, timeframe, groups, years
return graph, representative_periods, timeframe, years
end

function get_schema(tablename)
Expand Down
21 changes: 1 addition & 20 deletions src/structures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export GraphAssetData,
PeriodsBlock,
TimestepsBlock,
Timeframe,
Group,
Year

const TimestepsBlock = UnitRange{Int}
Expand Down Expand Up @@ -321,21 +320,6 @@ function GraphFlowData(args...)
)
end

"""
Structure to hold the group data
"""
struct Group
name::String
year::Int
invest_method::Bool
min_investment_limit::Union{Missing,Float64}
max_investment_limit::Union{Missing,Float64}

function Group(name, year, invest_method, min_investment_limit, max_investment_limit)
return new(name, year, invest_method, min_investment_limit, max_investment_limit)
end
end

mutable struct Solution
assets_investment::Dict{Tuple{Int,String},Float64}
assets_investment_energy::Dict{Tuple{Int,String},Float64} # for storage assets with energy method
Expand Down Expand Up @@ -369,7 +353,6 @@ It hides the complexity behind the energy problem, making the usage more friendl
- `constraints_partitions`: Dictionaries that connect pairs of asset and representative periods to [time partitions (vectors of time blocks)](@ref Partition)
- `timeframe`: The number of periods of the `representative_periods`.
- `dataframes`: The data frames used to linearize the variables and constraints. These are used internally in the model only.
- `groups`: The input data of the groups to create constraints that are common to a set of assets in the model.
- `model_parameters`: The model parameters.
- `model`: A JuMP.Model object representing the optimization model.
- `solved`: A boolean indicating whether the `model` has been solved or not.
Expand Down Expand Up @@ -398,7 +381,6 @@ mutable struct EnergyProblem
profiles::ProfileLookup
representative_periods::Dict{Int,Vector{RepresentativePeriod}}
timeframe::Timeframe
groups::Vector{Group}
years::Vector{Year}
model_parameters::ModelParameters
model::Union{JuMP.Model,Nothing}
Expand All @@ -416,7 +398,7 @@ mutable struct EnergyProblem
function EnergyProblem(connection; model_parameters_file = "")
model = JuMP.Model()

graph, representative_periods, timeframe, groups, years =
graph, representative_periods, timeframe, years =
@timeit to "create_internal_structure" create_internal_structures(connection)

variables = @timeit to "compute_variables_indices" compute_variables_indices(connection)
Expand All @@ -434,7 +416,6 @@ mutable struct EnergyProblem
profiles,
representative_periods,
timeframe,
groups,
years,
ModelParameters(connection, model_parameters_file),
nothing,
Expand Down
7 changes: 7 additions & 0 deletions src/variables/create.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ function _create_variables_tables(connection)
"CREATE OR REPLACE TEMP SEQUENCE id START 1;
CREATE OR REPLACE TABLE var_flows_investment AS
SELECT
nextval('id') as index,
flow.from_asset,
flow.to_asset,
flow_milestone.milestone_year,
Expand All @@ -150,6 +151,7 @@ function _create_variables_tables(connection)
"CREATE OR REPLACE TEMP SEQUENCE id START 1;
CREATE OR REPLACE TABLE var_assets_investment AS
SELECT
nextval('id') as index,
asset.asset,
asset_milestone.milestone_year,
asset.investment_integer,
Expand All @@ -170,6 +172,7 @@ function _create_variables_tables(connection)
"CREATE OR REPLACE TEMP SEQUENCE id START 1;
CREATE OR REPLACE TABLE var_assets_decommission_simple_method AS
SELECT
nextval('id') as index,
asset.asset,
asset_milestone.milestone_year,
asset.investment_integer,
Expand All @@ -185,6 +188,7 @@ function _create_variables_tables(connection)
"CREATE OR REPLACE TEMP SEQUENCE id START 1;
CREATE OR REPLACE TABLE var_assets_decommission_compact_method AS
SELECT
nextval('id') as index,
asset_both.asset,
asset_both.milestone_year,
asset_both.commission_year,
Expand All @@ -204,6 +208,7 @@ function _create_variables_tables(connection)
"CREATE OR REPLACE TEMP SEQUENCE id START 1;
CREATE OR REPLACE TABLE var_flows_decommission_using_simple_method AS
SELECT
nextval('id') as index,
flow.from_asset,
flow.to_asset,
flow_milestone.milestone_year
Expand All @@ -221,6 +226,7 @@ function _create_variables_tables(connection)
"CREATE OR REPLACE TEMP SEQUENCE id START 1;
CREATE OR REPLACE TABLE var_assets_investment_energy AS
SELECT
nextval('id') as index,
asset.asset,
asset_milestone.milestone_year,
asset.investment_integer_storage_energy,
Expand All @@ -245,6 +251,7 @@ function _create_variables_tables(connection)
"CREATE OR REPLACE TEMP SEQUENCE id START 1;
CREATE OR REPLACE TABLE var_assets_decommission_energy_simple_method AS
SELECT
nextval('id') as index,
asset.asset,
asset_milestone.milestone_year,
asset.investment_integer_storage_energy,
Expand Down
3 changes: 1 addition & 2 deletions test/test-pipeline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end
_read_csv_folder(connection, dir)

# Internal data and structures pre-model
graph, representative_periods, timeframe, groups, years = create_internal_structures(connection)
graph, representative_periods, timeframe, years = create_internal_structures(connection)
model_parameters = ModelParameters(connection)
sets = create_sets(graph, years)
variables = compute_variables_indices(connection)
Expand All @@ -39,7 +39,6 @@ end
representative_periods,
years,
timeframe,
groups,
model_parameters,
)

Expand Down

0 comments on commit 59d9e96

Please sign in to comment.