From d7b92dc671b6a0e84a3d51f12d762c37c74e5653 Mon Sep 17 00:00:00 2001 From: datejada Date: Wed, 8 Nov 2023 14:12:07 +0100 Subject: [PATCH 1/5] Add initial storage level --- src/input-tables.jl | 1 + src/io.jl | 3 ++ src/model.jl | 9 +++++- test/inputs/Norse/assets-data.csv | 48 +++++++++++++++---------------- test/inputs/Tiny/assets-data.csv | 16 +++++------ 5 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/input-tables.jl b/src/input-tables.jl index ae783a20..917394e2 100644 --- a/src/input-tables.jl +++ b/src/input-tables.jl @@ -9,6 +9,7 @@ struct AssetData initial_capacity::Float64 # MW peak_demand::Float64 # MW initial_storage_capacity::Float64 # MWh + initial_storage_level::Float64 # MWh energy_to_power_ratio::Float64 # Hours end diff --git a/src/io.jl b/src/io.jl index 17de676e..a5ed963b 100644 --- a/src/io.jl +++ b/src/io.jl @@ -85,10 +85,12 @@ function create_parameters_and_sets_from_file(input_folder::AbstractString) # Parameters for storage initial_storage_capacity = Dict{String,Float64}() + initial_storage_level = Dict{String,Float64}() energy_to_power_ratio = Dict{String,Float64}() for row in eachrow(assets_data_df) if row.name in assets_storage initial_storage_capacity[row.name] = row.initial_storage_capacity + initial_storage_level[row.name] = row.initial_storage_level energy_to_power_ratio[row.name] = row.energy_to_power_ratio end end @@ -134,6 +136,7 @@ function create_parameters_and_sets_from_file(input_folder::AbstractString) flows_is_transport = flows_is_transport, peak_demand = peak_demand, initial_storage_capacity = initial_storage_capacity, + initial_storage_level = initial_storage_level, energy_to_power_ratio = energy_to_power_ratio, rp_weight = rp_weight, rp_resolution = rp_resolution, diff --git a/src/model.jl b/src/model.jl index ebac4336..e2aae0a1 100644 --- a/src/model.jl +++ b/src/model.jl @@ -141,7 +141,7 @@ function create_model(graph, params, sets; verbose = false, write_lp_file = fals model, storage_balance[a ∈ As, rp ∈ RP, (k, B) ∈ enumerate(P[(a, rp)])], storage_level[a, rp, B] == - (k > 1 ? storage_level[a, rp, P[(a, rp)][k-1]] : 0.0) + + (k > 1 ? storage_level[a, rp, P[(a, rp)][k-1]] : params.initial_storage_level[a]) + incoming_flow_w_efficiency[(a, rp, B)] - outgoing_flow_w_efficiency[(a, rp, B)] ) @@ -242,6 +242,13 @@ function create_model(graph, params, sets; verbose = false, write_lp_file = fals params.initial_storage_capacity[a] + (a ∈ Ai ? energy_limit[a] : 0.0) ) + # - cycling condition for storage level + @constraint( + model, + cycling_condition_for_storage_level[a ∈ As, rp ∈ RP, T ∈ P[(a, rp)]], + storage_level[a, rp, T] ≥ params.initial_storage_level[a] + ) + if write_lp_file write_to_file(model, "model.lp") end diff --git a/test/inputs/Norse/assets-data.csv b/test/inputs/Norse/assets-data.csv index 698dd46e..c68d286b 100644 --- a/test/inputs/Norse/assets-data.csv +++ b/test/inputs/Norse/assets-data.csv @@ -1,24 +1,24 @@ -,,{producer;consumer;storage;hub;conversion},{true;false},{true;false},kEUR/MWh,kEUR/MW/year,MW,MW,MW,MW/unit,MW/unit,MW,MW,MWh,h,kEUR/MW/year,year,0 -id,name,type,active,investable,variable_cost,investment_cost,capacity,initial_capacity,peak_demand,charging_capacity,discharging_capacity,initial_charging_capacity,initial_discharging_capacity,initial_storage_capacity,energy_to_power_ratio,fixed_cost,lifetime,efficiency -1,Asgard_Battery,storage,true,true,0.003,300,10,0,0,1,1,0,0,0,100,3,10,0 -2,Asgard_Solar,producer,true,true,0.001,350,100,0,0,0,0,0,0,0,0,8,25,0 -3,Asgard_E_demand,consumer,true,false,0,0,0,0,65787.17792,0,0,0,0,0,0,0,0,0 -4,Asgard_CCGT,conversion,true,true,0.0015,650,500,0,0,0,0,0,0,0,0,10,30,0.6 -5,G_imports,producer,true,false,0.08,0,0,75000,0,0,0,0,0,0,0,0,0,0 -6,Midgard_Wind,producer,true,true,0.002,1300,3,0,0,0,0,0,0,0,0,15,25,0 -7,Midgard_Hydro,storage,true,false,0.0012,1600,0,250,0,3,3,0,0,4000,0,16,50,0 -8,Midgard_Nuclear_SMR,producer,true,true,0.015,6000,150,1000,0,0,0,0,0,0,0,101,60,0 -9,Midgard_E_imports,producer,true,false,0.02,0,0,500,0,0,0,0,0,0,0,0,0,0 -10,Midgard_CCGT,conversion,true,true,0.0015,650,500,0,0,0,0,0,0,0,0,10,30,0.6 -11,Midgard_E_demand,consumer,true,false,0,0,0,0,19604.76443,0,0,0,0,0,0,0,0,0 -12,Valhalla_H2_generator,conversion,true,true,0,479,100,0,0,0,0,0,0,0,0,10,20,0.6 -13,Valhalla_H2_storage,storage,true,true,0,0.1,500,0,0,3,3,0,0,0,10000,0.005,50,0 -14,Valhalla_H2_demand,consumer,true,false,0,0,0,0,745.735,0,0,0,0,0,0,0,0,0 -15,Valhalla_Electrolyser,conversion,true,true,0,1260,100,500,0,0,0,0,0,0,0,60,25,0.704 -16,Valhalla_E_balance,hub,true,false,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -17,Valhalla_E_exports,consumer,true,false,0.09,0,0,0,50,0,0,0,0,0,0,0,0,0 -18,Valhalla_Fuel_cell,conversion,true,true,0,800,100,0,0,0,0,0,0,0,0,40,25,0.5 -19,Valhalla_Heat_pump,conversion,true,true,0,300,100,0,0,0,0,0,0,0,0,15,20,4 -20,Valhalla_Waste_heat,producer,true,false,0.0025,1450,200,0,0,0,0,0,0,0,0,0,30,0 -21,Valhalla_Heat_demand,consumer,true,false,0,0,0,0,3548.42445,0,0,0,0,0,0,0,0,0 -22,Valhalla_GT,conversion,true,true,0.0015,400,500,0,0,0,0,0,0,0,0,3.85,30,0.6 +,,{producer;consumer;storage;hub;conversion},{true;false},{true;false},kEUR/MWh,kEUR/MW/year,MW,MW,MW,MW/unit,MW/unit,MW,MW,MWh,MWh,h,kEUR/MW/year,year,0 +id,name,type,active,investable,variable_cost,investment_cost,capacity,initial_capacity,peak_demand,charging_capacity,discharging_capacity,initial_charging_capacity,initial_discharging_capacity,initial_storage_capacity,initial_storage_level,energy_to_power_ratio,fixed_cost,lifetime,efficiency +1,Asgard_Battery,storage,true,true,0.003,300,10,0,0,1,1,0,0,0,0,100,3,10,0 +2,Asgard_Solar,producer,true,true,0.001,350,100,0,0,0,0,0,0,0,0,0,8,25,0 +3,Asgard_E_demand,consumer,true,false,0,0,0,0,65787.17792,0,0,0,0,0,0,0,0,0,0 +4,Asgard_CCGT,conversion,true,true,0.0015,650,500,0,0,0,0,0,0,0,0,0,10,30,0.6 +5,G_imports,producer,true,false,0.08,0,0,75000,0,0,0,0,0,0,0,0,0,0,0 +6,Midgard_Wind,producer,true,true,0.002,1300,3,0,0,0,0,0,0,0,0,0,15,25,0 +7,Midgard_Hydro,storage,true,false,0.0012,1600,0,250,0,3,3,0,0,4000,2000,0,16,50,0 +8,Midgard_Nuclear_SMR,producer,true,true,0.015,6000,150,1000,0,0,0,0,0,0,0,0,101,60,0 +9,Midgard_E_imports,producer,true,false,0.02,0,0,500,0,0,0,0,0,0,0,0,0,0,0 +10,Midgard_CCGT,conversion,true,true,0.0015,650,500,0,0,0,0,0,0,0,0,0,10,30,0.6 +11,Midgard_E_demand,consumer,true,false,0,0,0,0,19604.76443,0,0,0,0,0,0,0,0,0,0 +12,Valhalla_H2_generator,conversion,true,true,0,479,100,0,0,0,0,0,0,0,0,0,10,20,0.6 +13,Valhalla_H2_storage,storage,true,true,0,0.1,500,0,0,3,3,0,0,0,0,10000,0.005,50,0 +14,Valhalla_H2_demand,consumer,true,false,0,0,0,0,745.735,0,0,0,0,0,0,0,0,0,0 +15,Valhalla_Electrolyser,conversion,true,true,0,1260,100,500,0,0,0,0,0,0,0,0,60,25,0.704 +16,Valhalla_E_balance,hub,true,false,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +17,Valhalla_E_exports,consumer,true,false,0.09,0,0,0,50,0,0,0,0,0,0,0,0,0,0 +18,Valhalla_Fuel_cell,conversion,true,true,0,800,100,0,0,0,0,0,0,0,0,0,40,25,0.5 +19,Valhalla_Heat_pump,conversion,true,true,0,300,100,0,0,0,0,0,0,0,0,0,15,20,4 +20,Valhalla_Waste_heat,producer,true,false,0.0025,1450,200,0,0,0,0,0,0,0,0,0,0,30,0 +21,Valhalla_Heat_demand,consumer,true,false,0,0,0,0,3548.42445,0,0,0,0,0,0,0,0,0,0 +22,Valhalla_GT,conversion,true,true,0.0015,400,500,0,0,0,0,0,0,0,0,0,3.85,30,0.6 diff --git a/test/inputs/Tiny/assets-data.csv b/test/inputs/Tiny/assets-data.csv index b40f8a11..a411498c 100644 --- a/test/inputs/Tiny/assets-data.csv +++ b/test/inputs/Tiny/assets-data.csv @@ -1,8 +1,8 @@ -,,{producer;consumer},{true;false},{true;false},kEUR/MW/year,MW,MW,MW,MWh,h -id,name,type,active,investable,investment_cost,capacity,initial_capacity,peak_demand,initial_storage_capacity,energy_to_power_ratio -1,ocgt,producer,true,true,25,100,0,0,0,0 -2,ccgt,producer,true,true,40,400,0,0,0,0 -3,wind,producer,true,true,70,50,0,0,0,0 -4,solar,producer,true,true,50,10,0,0,0,0 -5,ens,producer,true,false,0,0,1115,0,0,0 -6,demand,consumer,true,false,0,0,0,1115,0,0 +,,{producer;consumer},{true;false},{true;false},kEUR/MW/year,MW,MW,MW,MWh,MWh,h +id,name,type,active,investable,investment_cost,capacity,initial_capacity,peak_demand,initial_storage_capacity,initial_storage_level,energy_to_power_ratio +1,ocgt,producer,true,true,25,100,0,0,0,0,0 +2,ccgt,producer,true,true,40,400,0,0,0,0,0 +3,wind,producer,true,true,70,50,0,0,0,0,0 +4,solar,producer,true,true,50,10,0,0,0,0,0 +5,ens,producer,true,false,0,0,1115,0,0,0,0 +6,demand,consumer,true,false,0,0,0,1115,0,0,0 From 3321aaefe31d0a600b85ef591620f463a449222c Mon Sep 17 00:00:00 2001 From: datejada Date: Wed, 8 Nov 2023 14:22:00 +0100 Subject: [PATCH 2/5] Fix Julia Format --- src/model.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/model.jl b/src/model.jl index e2aae0a1..cb61bdeb 100644 --- a/src/model.jl +++ b/src/model.jl @@ -245,8 +245,8 @@ function create_model(graph, params, sets; verbose = false, write_lp_file = fals # - cycling condition for storage level @constraint( model, - cycling_condition_for_storage_level[a ∈ As, rp ∈ RP, T ∈ P[(a, rp)]], - storage_level[a, rp, T] ≥ params.initial_storage_level[a] + cycling_condition_for_storage_level[a ∈ As, rp ∈ RP], + storage_level[a, rp, P[(a, rp)][end]] ≥ params.initial_storage_level[a] ) if write_lp_file From 2afd1e35dbff6b81e0579ce14a697813eb49b770 Mon Sep 17 00:00:00 2001 From: datejada Date: Wed, 8 Nov 2023 15:01:21 +0100 Subject: [PATCH 3/5] Add storage inflows to the model and to the Norse case --- src/model.jl | 24 ++-- test/inputs/Norse/assets-profiles.csv | 192 ++++++++++++++++++++++++++ test/test-case-studies.jl | 2 +- 3 files changed, 209 insertions(+), 9 deletions(-) diff --git a/src/model.jl b/src/model.jl index cb61bdeb..05dd7259 100644 --- a/src/model.jl +++ b/src/model.jl @@ -126,6 +126,21 @@ function create_model(graph, params, sets; verbose = false, write_lp_file = fals ) ) + @expression( + model, + energy_limit[a ∈ As∩Ai], + params.energy_to_power_ratio[a] * + params.assets_unit_capacity[a] * + assets_investment[a] + ) + + @expression( + model, + storage_inflows[a ∈ As, rp ∈ RP, T ∈ P[(a, rp)]], + sum(get(params.assets_profile, (a, rp, k), 0.0) for k ∈ T) * + (params.initial_storage_capacity[a] + (a ∈ Ai ? energy_limit[a] : 0.0)) + ) + # Balance equations # - consumer balance equation @constraint( @@ -136,12 +151,12 @@ function create_model(graph, params, sets; verbose = false, write_lp_file = fals ) # - storage balance equation - # TODO: Add p^{inflow} @constraint( model, storage_balance[a ∈ As, rp ∈ RP, (k, B) ∈ enumerate(P[(a, rp)])], storage_level[a, rp, B] == (k > 1 ? storage_level[a, rp, P[(a, rp)][k-1]] : params.initial_storage_level[a]) + + storage_inflows[a, rp, B] + incoming_flow_w_efficiency[(a, rp, B)] - outgoing_flow_w_efficiency[(a, rp, B)] ) @@ -228,13 +243,6 @@ function create_model(graph, params, sets; verbose = false, write_lp_file = fals # Extra constraints # - upper bound constraints for storage level - @expression( - model, - energy_limit[a ∈ As∩Ai], - params.energy_to_power_ratio[a] * - params.assets_unit_capacity[a] * - assets_investment[a] - ) @constraint( model, upper_bound_for_storage_level[a ∈ As, rp ∈ RP, B ∈ P[(a, rp)]], diff --git a/test/inputs/Norse/assets-profiles.csv b/test/inputs/Norse/assets-profiles.csv index 3459c096..f27468c7 100644 --- a/test/inputs/Norse/assets-profiles.csv +++ b/test/inputs/Norse/assets-profiles.csv @@ -504,6 +504,174 @@ id,rep_period_id,time_step,value 6,1,166,0.654 6,1,167,0.673 6,1,168,0.681 +7,1,1,0.0001 +7,1,2,0.0001 +7,1,3,0.0001 +7,1,4,0.0001 +7,1,5,0.0001 +7,1,6,0.0001 +7,1,7,0.0001 +7,1,8,0.0001 +7,1,9,0.0001 +7,1,10,0.0001 +7,1,11,0.0001 +7,1,12,0.0001 +7,1,13,0.0001 +7,1,14,0.0001 +7,1,15,0.0001 +7,1,16,0.0001 +7,1,17,0.0001 +7,1,18,0.0001 +7,1,19,0.0001 +7,1,20,0.0001 +7,1,21,0.0001 +7,1,22,0.0001 +7,1,23,0.0001 +7,1,24,0.0001 +7,1,25,0.0001 +7,1,26,0.0001 +7,1,27,0.0001 +7,1,28,0.0001 +7,1,29,0.0001 +7,1,30,0.0001 +7,1,31,0.0001 +7,1,32,0.0001 +7,1,33,0.0001 +7,1,34,0.0001 +7,1,35,0.0001 +7,1,36,0.0001 +7,1,37,0.0001 +7,1,38,0.0001 +7,1,39,0.0001 +7,1,40,0.0001 +7,1,41,0.0001 +7,1,42,0.0001 +7,1,43,0.0001 +7,1,44,0.0001 +7,1,45,0.0001 +7,1,46,0.0001 +7,1,47,0.0001 +7,1,48,0.0001 +7,1,49,0.0001 +7,1,50,0.0001 +7,1,51,0.0001 +7,1,52,0.0001 +7,1,53,0.0001 +7,1,54,0.0001 +7,1,55,0.0001 +7,1,56,0.0001 +7,1,57,0.0001 +7,1,58,0.0001 +7,1,59,0.0001 +7,1,60,0.0001 +7,1,61,0.0001 +7,1,62,0.0001 +7,1,63,0.0001 +7,1,64,0.0001 +7,1,65,0.0001 +7,1,66,0.0001 +7,1,67,0.0001 +7,1,68,0.0001 +7,1,69,0.0001 +7,1,70,0.0001 +7,1,71,0.0001 +7,1,72,0.0001 +7,1,73,0.0001 +7,1,74,0.0001 +7,1,75,0.0001 +7,1,76,0.0001 +7,1,77,0.0001 +7,1,78,0.0001 +7,1,79,0.0001 +7,1,80,0.0001 +7,1,81,0.0001 +7,1,82,0.0001 +7,1,83,0.0001 +7,1,84,0.0001 +7,1,85,0.0001 +7,1,86,0.0001 +7,1,87,0.0001 +7,1,88,0.0001 +7,1,89,0.0001 +7,1,90,0.0001 +7,1,91,0.0001 +7,1,92,0.0001 +7,1,93,0.0001 +7,1,94,0.0001 +7,1,95,0.0001 +7,1,96,0.0001 +7,1,97,0.0001 +7,1,98,0.0001 +7,1,99,0.0001 +7,1,100,0.0001 +7,1,101,0.0001 +7,1,102,0.0001 +7,1,103,0.0001 +7,1,104,0.0001 +7,1,105,0.0001 +7,1,106,0.0001 +7,1,107,0.0001 +7,1,108,0.0001 +7,1,109,0.0001 +7,1,110,0.0001 +7,1,111,0.0001 +7,1,112,0.0001 +7,1,113,0.0001 +7,1,114,0.0001 +7,1,115,0.0001 +7,1,116,0.0001 +7,1,117,0.0001 +7,1,118,0.0001 +7,1,119,0.0001 +7,1,120,0.0001 +7,1,121,0.0001 +7,1,122,0.0001 +7,1,123,0.0001 +7,1,124,0.0001 +7,1,125,0.0001 +7,1,126,0.0001 +7,1,127,0.0001 +7,1,128,0.0001 +7,1,129,0.0001 +7,1,130,0.0001 +7,1,131,0.0001 +7,1,132,0.0001 +7,1,133,0.0001 +7,1,134,0.0001 +7,1,135,0.0001 +7,1,136,0.0001 +7,1,137,0.0001 +7,1,138,0.0001 +7,1,139,0.0001 +7,1,140,0.0001 +7,1,141,0.0001 +7,1,142,0.0001 +7,1,143,0.0001 +7,1,144,0.0001 +7,1,145,0.0001 +7,1,146,0.0001 +7,1,147,0.0001 +7,1,148,0.0001 +7,1,149,0.0001 +7,1,150,0.0001 +7,1,151,0.0001 +7,1,152,0.0001 +7,1,153,0.0001 +7,1,154,0.0001 +7,1,155,0.0001 +7,1,156,0.0001 +7,1,157,0.0001 +7,1,158,0.0001 +7,1,159,0.0001 +7,1,160,0.0001 +7,1,161,0.0001 +7,1,162,0.0001 +7,1,163,0.0001 +7,1,164,0.0001 +7,1,165,0.0001 +7,1,166,0.0001 +7,1,167,0.0001 +7,1,168,0.0001 11,1,1,0.688597416 11,1,2,0.676090883 11,1,3,0.654860035 @@ -1080,6 +1248,30 @@ id,rep_period_id,time_step,value 6,2,22,0.7542 6,2,23,0.7677 6,2,24,0.7785 +7,2,1,0.00005 +7,2,2,0.00005 +7,2,3,0.00005 +7,2,4,0.00005 +7,2,5,0.00005 +7,2,6,0.00005 +7,2,7,0.00005 +7,2,8,0.00005 +7,2,9,0.00005 +7,2,10,0.00005 +7,2,11,0.00005 +7,2,12,0.00005 +7,2,13,0.00005 +7,2,14,0.00005 +7,2,15,0.00005 +7,2,16,0.00005 +7,2,17,0.00005 +7,2,18,0.00005 +7,2,19,0.00005 +7,2,20,0.00005 +7,2,21,0.00005 +7,2,22,0.00005 +7,2,23,0.00005 +7,2,24,0.00005 11,2,1,0.964036382 11,2,2,0.946527236 11,2,3,0.916804049 diff --git a/test/test-case-studies.jl b/test/test-case-studies.jl index 10f57e18..6170b396 100644 --- a/test/test-case-studies.jl +++ b/test/test-case-studies.jl @@ -4,7 +4,7 @@ graph = create_graph(joinpath(dir, "assets-data.csv"), joinpath(dir, "flows-data.csv")) model = create_model(graph, parameters, sets) solution = solve_model(model) - @test solution.objective_value ≈ 164432876.31472 atol = 1e-5 + @test solution.objective_value ≈ 164432875.02939 atol = 1e-5 save_solution_to_file( OUTPUT_FOLDER, sets.assets_investment, From e31f226bd4ea57de64243d08f35444096b9969bd Mon Sep 17 00:00:00 2001 From: datejada Date: Wed, 8 Nov 2023 15:24:54 +0100 Subject: [PATCH 4/5] Update documentation --- docs/src/mathematical-formulation.md | 39 +++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/src/mathematical-formulation.md b/docs/src/mathematical-formulation.md index 349ccb6a..4ec16337 100644 --- a/docs/src/mathematical-formulation.md +++ b/docs/src/mathematical-formulation.md @@ -28,21 +28,23 @@ NOTE: Asset types are mutually exclusive. Name|Domain|Description|Units ---|---|---|--- -$p^{investment\_cost}_{a}$ | $\mathcal{A}_i$ | Investment cost of asset units | [kEUR/MW/year] -$p^{unit\_capacity}_{a}$ | $\mathcal{A}$ | Capacity of asset units | [MW] -$p^{peak\_demand}_{a}$ | $\mathcal{A}_c$ | Peak demand | [MW] -$p^{init\_capacity}_{a}$ | $\mathcal{A}$ | Initial capacity of asset units | [MW] -$p^{investment\_cost}_{f}$ | $\mathcal{F}_i$ | Investment cost of flow connections | [kEUR/MW/year] -$p^{variable\_cost}_{f}$ | $\mathcal{F}$ | Variable cost of flow connections | [kEUR/MWh] -$p^{unit\_capacity}_{f}$ | $\mathcal{F}$ | Capacity of flow connections | [MW] -$p^{init\_capacity}_{f}$ | $\mathcal{F}$ | Initial capacity of flow connections | [MW] -$p^{export\_capacity}_{f}$ | $\mathcal{F}_t$ | Export capacity of flow connections | [MW] -$p^{import\_capacity}_{f}$ | $\mathcal{F}_t$ | Import capacity of flow connections | [MW] -$p^{rp\_weight}_{rp}$ | $\mathcal{RP}$ | Representative period weight | [h] -$p^{profile}_{a,rp,k}$ | $\mathcal{A,RP,K}$ | Asset profile | [p.u.] -$p^{profile}_{f,rp,k}$ | $\mathcal{F,RP,K}$ | Flow connections profile | [p.u.] -$p^{ene\_to\_pow\_ratio}_a$| $\mathcal{A}_s$ | Energy to power ratio | [h] -$p^{eff}_f$ | $\mathcal{F}$ | Flow efficiency | [p.u.] +$p^{investment\_cost}_{a}$ | $\mathcal{A}_i$ | Investment cost of asset units | [kEUR/MW/year] +$p^{unit\_capacity}_{a}$ | $\mathcal{A}$ | Capacity of asset units | [MW] +$p^{peak\_demand}_{a}$ | $\mathcal{A}_c$ | Peak demand | [MW] +$p^{init\_capacity}_{a}$ | $\mathcal{A}$ | Initial capacity of asset units | [MW] +$p^{investment\_cost}_{f}$ | $\mathcal{F}_i$ | Investment cost of flow connections | [kEUR/MW/year] +$p^{variable\_cost}_{f}$ | $\mathcal{F}$ | Variable cost of flow connections | [kEUR/MWh] +$p^{unit\_capacity}_{f}$ | $\mathcal{F}$ | Capacity of flow connections | [MW] +$p^{init\_capacity}_{f}$ | $\mathcal{F}$ | Initial capacity of flow connections | [MW] +$p^{export\_capacity}_{f}$ | $\mathcal{F}_t$ | Export capacity of flow connections | [MW] +$p^{import\_capacity}_{f}$ | $\mathcal{F}_t$ | Import capacity of flow connections | [MW] +$p^{rp\_weight}_{rp}$ | $\mathcal{RP}$ | Representative period weight | [h] +$p^{profile}_{a,rp,k}$ | $\mathcal{A,RP,K}$ | Asset profile | [p.u.] +$p^{profile}_{f,rp,k}$ | $\mathcal{F,RP,K}$ | Flow connections profile | [p.u.] +$p^{ene\_to\_pow\_ratio}_a$ | $\mathcal{A}_s$ | Energy to power ratio | [h] +$p^{init\_storage\_level}_{a}$ | $\mathcal{A}_s$ | Initial storage level | [MWh] +$p^{inflow}_{a}$ | $\mathcal{A}_s$ | Energy storage inflows | [MWh] +$p^{eff}_f$ | $\mathcal{F}$ | Flow efficiency | [p.u.] ## [Variables](@id math-variables) @@ -177,3 +179,10 @@ v^{flow}_{f,rp,k} \geq p^{profile}_{f,rp,k} \cdot \left(p^{init\_capacity}_{f} + 0 \leq s_{a,rp,k}^{level} \leq p^{init\_storage\_capacity}_{a} + p^{ene\_to\_pow\_ratio}_a \cdot p^{unit\_capacity}_a \cdot v^{investment}_a \quad \\ \\ \forall a \in \mathcal{A}_s, \forall rp \in \mathcal{RP},\forall k \in \mathcal{K} ``` + +#### Cycling Constraints for Storage Level + +```math +s_{a,rp,k=K}^{level} \geq p^{init\_storage\_level}_{a} \quad +\\ \\ \forall a \in \mathcal{A}_s, \forall rp \in \mathcal{RP} +``` From ae06e4998581a8d0d8710699c7f063893a3d3105 Mon Sep 17 00:00:00 2001 From: datejada Date: Wed, 8 Nov 2023 16:52:42 +0100 Subject: [PATCH 5/5] Update upper bound for cycling constraint --- src/model.jl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/model.jl b/src/model.jl index 05dd7259..6fcff9da 100644 --- a/src/model.jl +++ b/src/model.jl @@ -251,11 +251,12 @@ function create_model(graph, params, sets; verbose = false, write_lp_file = fals ) # - cycling condition for storage level - @constraint( - model, - cycling_condition_for_storage_level[a ∈ As, rp ∈ RP], - storage_level[a, rp, P[(a, rp)][end]] ≥ params.initial_storage_level[a] - ) + for a ∈ As, rp ∈ RP + set_lower_bound( + storage_level[a, rp, P[(a, rp)][end]], + params.initial_storage_level[a], + ) + end if write_lp_file write_to_file(model, "model.lp")