Skip to content

Commit

Permalink
Fixed computation of cumulative minimum retirements in multistage cod…
Browse files Browse the repository at this point in the history
…e. Previously, minimum capacity retirement parameters were not added up and this resulted in the minimum retirement constraints enforcing wrong lower bounds
  • Loading branch information
filippopecci committed Feb 14, 2024
1 parent 32db8be commit 6edebb4
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix summation error when a set of hours is empty (in thermal_commit.jl).
- Fix access to eELOSSByZone expr before initialization (#541)
- Fix modeling of hydro reservoir with long duration storage (#572).
- Fix computation of cumulative minimum capacity retirements in multistage GenX (#514)

### Changed

Expand Down
2 changes: 2 additions & 0 deletions src/case_runners/case_runner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ function run_genx_case_multistage!(case::AbstractString, mysetup::Dict)
inputs_dict[t] = load_inputs(mysetup, inpath_sub)
inputs_dict[t] = configure_multi_stage_inputs(inputs_dict[t],mysetup["MultiStageSettingsDict"],mysetup["NetworkExpansion"])

compute_cumulative_min_retirements!(inputs_dict,t)

# Step 2) Generate model
model_dict[t] = generate_model(mysetup, inputs_dict[t], OPTIMIZER)
end
Expand Down
34 changes: 30 additions & 4 deletions src/multi_stage/endogenous_retirement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,32 @@ function get_retirement_stage(cur_stage::Int, lifetime::Int, stage_lens::Array{I
return Int(ret_stage)
end

function update_cumulative_min_ret!(inputs_d::Dict,t::Int,Resource_Set::String,dfGen_Name::String,RetCap::Symbol)

CumRetCap = Symbol("Cum_"*String(RetCap));

if !isempty(inputs_d[1][Resource_Set])
if t==1
inputs_d[t][dfGen_Name][!,CumRetCap] = inputs_d[t][dfGen_Name][!,RetCap];
else
inputs_d[t][dfGen_Name][!,CumRetCap] = inputs_d[t-1][dfGen_Name][!,CumRetCap] + inputs_d[t][dfGen_Name][!,RetCap];
end
end
end

function compute_cumulative_min_retirements!(inputs_d::Dict,t::Int)

mytab =[("G","dfGen",:Min_Retired_Cap_MW),
("STOR_ALL","dfGen",:Min_Retired_Energy_Cap_MW),
("STOR_ASYMMETRIC","dfGen",:Min_Retired_Charge_Cap_MW)];

for (Resource_Set,dfGen_Name,RetCap) in mytab
update_cumulative_min_ret!(inputs_d,t,Resource_Set,dfGen_Name,RetCap)
end


end

function endogenous_retirement!(EP::Model, inputs::Dict, setup::Dict)
multi_stage_settings = setup["MultiStageSettingsDict"]

Expand Down Expand Up @@ -78,9 +104,9 @@ function endogenous_retirement_discharge!(EP::Model, inputs::Dict, num_stages::I
@expression(EP, eNewCapTrack[y in RET_CAP], sum(EP[:vCAPTRACK][y,p] for p=1:get_retirement_stage(cur_stage, dfGen[!,:Lifetime][y], stage_lens)))
@expression(EP, eMinRetCapTrack[y in RET_CAP],
if y in COMMIT
sum((dfGen[!,Symbol("Min_Retired_Cap_MW")][y]/dfGen[!,:Cap_Size][y]) for p=1:cur_stage)
dfGen[y,:Cum_Min_Retired_Cap_MW]/dfGen[y,:Cap_Size]
else
sum((dfGen[!,Symbol("Min_Retired_Cap_MW")][y]) for p=1:cur_stage)
dfGen[y,:Cum_Min_Retired_Cap_MW]
end
)

Expand Down Expand Up @@ -132,7 +158,7 @@ function endogenous_retirement_charge!(EP::Model, inputs::Dict, num_stages::Int,
# Construct and add the endogenous retirement constraint expressions
@expression(EP, eRetCapTrackCharge[y in RET_CAP_CHARGE], sum(EP[:vRETCAPTRACKCHARGE][y,p] for p=1:cur_stage))
@expression(EP, eNewCapTrackCharge[y in RET_CAP_CHARGE], sum(EP[:vCAPTRACKCHARGE][y,p] for p=1:get_retirement_stage(cur_stage, dfGen[!,:Lifetime][y], stage_lens)))
@expression(EP, eMinRetCapTrackCharge[y in RET_CAP_CHARGE], sum((dfGen[!,Symbol("Min_Retired_Charge_Cap_MW")][y]) for p=1:cur_stage))
@expression(EP, eMinRetCapTrackCharge[y in RET_CAP_CHARGE], dfGen[y,:Cum_Min_Retired_Charge_Cap_MW])

### Constratints ###

Expand Down Expand Up @@ -181,7 +207,7 @@ function endogenous_retirement_energy!(EP::Model, inputs::Dict, num_stages::Int,
# Construct and add the endogenous retirement constraint expressions
@expression(EP, eRetCapTrackEnergy[y in RET_CAP_ENERGY], sum(EP[:vRETCAPTRACKENERGY][y,p] for p=1:cur_stage))
@expression(EP, eNewCapTrackEnergy[y in RET_CAP_ENERGY], sum(EP[:vCAPTRACKENERGY][y,p] for p=1:get_retirement_stage(cur_stage, dfGen[!,:Lifetime][y], stage_lens)))
@expression(EP, eMinRetCapTrackEnergy[y in RET_CAP_ENERGY], sum((dfGen[!,Symbol("Min_Retired_Energy_Cap_MW")][y]) for p=1:cur_stage))
@expression(EP, eMinRetCapTrackEnergy[y in RET_CAP_ENERGY], dfGen[y,:Cum_Min_Retired_Energy_Cap_MW])

### Constratints ###

Expand Down

0 comments on commit 6edebb4

Please sign in to comment.