Skip to content

Commit

Permalink
Separate new-buildability and ability to retire
Browse files Browse the repository at this point in the history
Previously this was one column "New_Build" which could be 0, 1, or -1.
Now, New_Build should be either 0 or 1 and
Can_Retire should be either 0 or 1.
  • Loading branch information
cfe316 committed Aug 1, 2023
1 parent 951179b commit 9accef8
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 21 deletions.
10 changes: 6 additions & 4 deletions docs/src/data_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,12 @@ This file contains cost and performance parameters for various generators and ot
|Resource | This column contains **unique** names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand/loads.|
|Zone | Integer representing zone number where the resource is located. |
|**Technology type flags**|
|New\_Build | {-1, 0, 1}, Flag for resource (storage, generation) eligibility for capacity expansion.|
||New\_Build = 1: eligible for capacity expansion and retirement. |
||New\_Build = 0: not eligible for capacity expansion, eligible for retirement.|
||New\_Build = -1: not eligible for capacity expansion or retirement.|
|New\_Build | { 0, 1}, Flag for resource (storage, generation) eligibility for capacity expansion.|
||New\_Build = 1: eligible for capacity expansion. |
||New\_Build = 0: not eligible for capacity expansion.|
|Can\_Retire | {0, 1}, Flag for resource (storage, generation) eligibility for retirement.|
||Can\_Retire = 1: eligible for retirement. |
||Can\_Retire = 0: not eligible for retirement.|
|THERM | {0, 1, 2}, Flag to indicate membership in set of thermal resources (e.g. nuclear, combined heat and power, natural gas combined cycle, coal power plant)|
||THERM = 0: Not part of set (default) |
||THERM = 1: If the power plant relies on thermal energy input and subject unit commitment constraints/decisions if `UCommit >= 1` (e.g. cycling decisions/costs/constraints). |
Expand Down
61 changes: 47 additions & 14 deletions src/load_inputs/load_generators_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ function load_generators_data!(setup::Dict, path::AbstractString, inputs_gen::Di
# Set of storage resources with symmetric charge/discharge capacity
inputs_gen["STOR_SYMMETRIC"] = gen_in[gen_in.STOR.==1,:R_ID]
# Set of storage resources with asymmetric (separte) charge/discharge capacity components
inputs_gen["STOR_ASYMMETRIC"] = gen_in[gen_in.STOR.==2,:R_ID]
STOR_ASYMMETRIC = gen_in[gen_in.STOR.==2,:R_ID]
inputs_gen["STOR_ASYMMETRIC"] = STOR_ASYMMETRIC
# Set of all storage resources
inputs_gen["STOR_ALL"] = union(inputs_gen["STOR_SYMMETRIC"],inputs_gen["STOR_ASYMMETRIC"])
STOR_ALL = union(inputs_gen["STOR_SYMMETRIC"], STOR_ASYMMETRIC)
inputs_gen["STOR_ALL"] = STOR_ALL

# Set of storage resources with long duration storage capabilitites
inputs_gen["STOR_HYDRO_LONG_DURATION"] = gen_in[(gen_in.LDS.==1) .& (gen_in.HYDRO.==1),:R_ID]
Expand Down Expand Up @@ -78,20 +80,35 @@ function load_generators_data!(setup::Dict, path::AbstractString, inputs_gen::Di
inputs_gen["RSV"] = gen_in[(gen_in[!,:Rsv_Max].>0),:R_ID]
end

NEW_BUILD = gen_in[gen_in.New_Build.==1, :R_ID]
CAN_RETIRE = get_generators_which_can_be_retired(gen_in)

# Set of all resources eligible for new capacity
inputs_gen["NEW_CAP"] = intersect(gen_in[gen_in.New_Build.==1,:R_ID], gen_in[gen_in.Max_Cap_MW.!=0,:R_ID])
inputs_gen["NEW_CAP"] = intersect(NEW_BUILD, gen_in[gen_in.Max_Cap_MW.!=0,:R_ID])
# Set of all resources eligible for capacity retirements
inputs_gen["RET_CAP"] = intersect(gen_in[gen_in.New_Build.!=-1,:R_ID], gen_in[gen_in.Existing_Cap_MW.>=0,:R_ID])

# Set of all storage resources eligible for new energy capacity
inputs_gen["NEW_CAP_ENERGY"] = intersect(gen_in[gen_in.New_Build.==1,:R_ID], gen_in[gen_in.Max_Cap_MWh.!=0,:R_ID], inputs_gen["STOR_ALL"])
# Set of all storage resources eligible for energy capacity retirements
inputs_gen["RET_CAP_ENERGY"] = intersect(gen_in[gen_in.New_Build.!=-1,:R_ID], gen_in[gen_in.Existing_Cap_MWh.>=0,:R_ID], inputs_gen["STOR_ALL"])

# Set of asymmetric charge/discharge storage resources eligible for new charge capacity
inputs_gen["NEW_CAP_CHARGE"] = intersect(gen_in[gen_in.New_Build.==1,:R_ID], gen_in[gen_in.Max_Charge_Cap_MW.!=0,:R_ID], inputs_gen["STOR_ASYMMETRIC"])
# Set of asymmetric charge/discharge storage resources eligible for charge capacity retirements
inputs_gen["RET_CAP_CHARGE"] = intersect(gen_in[gen_in.New_Build.!=-1,:R_ID], gen_in[gen_in.Existing_Charge_Cap_MW.>=0,:R_ID], inputs_gen["STOR_ASYMMETRIC"])
inputs_gen["RET_CAP"] = intersect(CAN_RETIRE, gen_in[gen_in.Existing_Cap_MW.>=0,:R_ID])

NEW_CAP_ENERGY = Set{Int64}()
RET_CAP_ENERGY = Set{Int64}()
if !isempty(STOR_ALL)
# Set of all storage resources eligible for new energy capacity
NEW_CAP_ENERGY = intersect(NEW_BUILD, gen_in[gen_in.Max_Cap_MWh.!=0,:R_ID], STOR_ALL)
# Set of all storage resources eligible for energy capacity retirements
RET_CAP_ENERGY = intersect(CAN_RETIRE, gen_in[gen_in.Existing_Cap_MWh.>=0,:R_ID], STOR_ALL)
end
inputs_gen["NEW_CAP_ENERGY"] = NEW_CAP_ENERGY
inputs_gen["RET_CAP_ENERGY"] = RET_CAP_ENERGY

NEW_CAP_CHARGE = Set{Int64}()
RET_CAP_CHARGE = Set{Int64}()
if !isempty(STOR_ASYMMETRIC)
# Set of asymmetric charge/discharge storage resources eligible for new charge capacity
NEW_CAP_CHARGE = intersect(NEW_BUILD, gen_in[gen_in.Max_Charge_Cap_MW.!=0,:R_ID], STOR_ASYMMETRIC)
# Set of asymmetric charge/discharge storage resources eligible for charge capacity retirements
RET_CAP_CHARGE = intersect(CAN_RETIRE, gen_in[gen_in.Existing_Charge_Cap_MW.>=0,:R_ID], STOR_ASYMMETRIC)
end
inputs_gen["NEW_CAP_CHARGE"] = NEW_CAP_CHARGE
inputs_gen["RET_CAP_CHARGE"] = RET_CAP_CHARGE

# Names of resources
inputs_gen["RESOURCES"] = gen_in[!,:Resource]
Expand Down Expand Up @@ -205,3 +222,19 @@ function load_generators_data!(setup::Dict, path::AbstractString, inputs_gen::Di
end
println(filename * " Successfully Read!")
end

function get_generators_which_can_be_retired(df::DataFrame)::Set{Int64}
if string(:Can_Retire) in names(df)
CAN_RETIRE = df[df.Can_Retire.==1, :R_ID]
else
# Backward compatibility.
CAN_RETIRE = df[df.New_Build.==-1, :R_ID]
if !isempty(CAN_RETIRE)
@warn "The generators input file, 'New_Build' column, has some entries
which are -1 (indicating the ability to be retired). This input format is deprecated
and may be removed in a future version. Instead, use a column 'Can_Retire',
with entries of either 0 or 1."
end
end
return Set(CAN_RETIRE)
end
8 changes: 5 additions & 3 deletions src/multi_stage/configure_multi_stage_inputs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,14 @@ function configure_multi_stage_inputs(inputs_d::Dict, settings_d::Dict, NetworkE
inputs_d["dfGen"][!,:Fixed_OM_Cost_charge_per_MWyr] = OPEXMULT.*inputs_d["dfGen"][!,:Fixed_OM_Cost_Charge_per_MWyr]
end

CAN_RETIRE = get_generators_which_can_be_retired(dfGen)

# Set of all resources eligible for capacity retirements
inputs_d["RET_CAP"] = intersect(dfGen[dfGen.New_Build.!=-1,:R_ID])
inputs_d["RET_CAP"] = CAN_RETIRE
# Set of all storage resources eligible for energy capacity retirements
inputs_d["RET_CAP_ENERGY"] = intersect(dfGen[dfGen.New_Build.!=-1,:R_ID], inputs_d["STOR_ALL"])
inputs_d["RET_CAP_ENERGY"] = intersect(CAN_RETIRE, inputs_d["STOR_ALL"])
# Set of asymmetric charge/discharge storage resources eligible for charge capacity retirements
inputs_d["RET_CAP_CHARGE"] = intersect(dfGen[dfGen.New_Build.!=-1,:R_ID], inputs_d["STOR_ASYMMETRIC"])
inputs_d["RET_CAP_CHARGE"] = intersect(CAN_RETIRE, inputs_d["STOR_ASYMMETRIC"])

# Transmission
if NetworkExpansion == 1 && inputs_d["Z"] > 1
Expand Down

0 comments on commit 9accef8

Please sign in to comment.