diff --git a/src/model/core/co2.jl b/src/model/core/co2.jl index fb277004e9..2ace2fe9d3 100644 --- a/src/model/core/co2.jl +++ b/src/model/core/co2.jl @@ -60,6 +60,9 @@ function co2!(EP::Model, inputs::Dict) Z = inputs["Z"] # Number of zones MULTI_FUELS = inputs["MULTI_FUELS"] SINGLE_FUEL = inputs["SINGLE_FUEL"] + CCS = inputs["CCS"] + println(CCS) + println(length(G), length(CCS)) fuel_CO2 = inputs["fuel_CO2"] # CO2 content of fuel (t CO2/MMBTU or ktCO2/Billion BTU) omega = inputs["omega"] if !isempty(MULTI_FUELS) @@ -71,7 +74,7 @@ function co2!(EP::Model, inputs::Dict) # CO2 emissions from power plants in "Generators_data.csv" # If all the CO2 capture fractions from Generators_data are zeros, the CO2 emissions from thermal generators are determined by fuel consumption times CO2 content per MMBTU - if all(dfGen.CO2_Capture_Fraction .==0) + if isempty(CCS) @expression(EP, eEmissionsByPlant[y=1:G, t=1:T], if y in SINGLE_FUEL ((1-dfGen[y, :Biomass]) *(EP[:vFuel][y, t] + EP[:vStartFuel][y, t]) * fuel_CO2[dfGen[y,:Fuel]]) @@ -82,8 +85,8 @@ function co2!(EP::Model, inputs::Dict) @info "Using the CO2 module to determine the CO2 emissions of CCS-equipped plants" # CO2_Capture_Fraction refers to the CO2 capture rate of CCS equiped power plants at a steady state # CO2_Capture_Fraction_Startup refers to the CO2 capture rate of CCS equiped power plants during startup events - + @expression(EP, eEmissionsByPlant[y=1:G, t=1:T], if y in SINGLE_FUEL (1-dfGen[y, :Biomass] - dfGen[y, :CO2_Capture_Fraction]) * EP[:vFuel][y, t] * fuel_CO2[dfGen[y,:Fuel]]+ @@ -94,7 +97,7 @@ function co2!(EP::Model, inputs::Dict) end) # CO2 captured from power plants in "Generators_data.csv" - @expression(EP, eEmissionsCaptureByPlant[y=1:G, t=1:T], + @expression(EP, eEmissionsCaptureByPlant[y in CCS, t=1:T], if y in SINGLE_FUEL dfGen[y, :CO2_Capture_Fraction] * EP[:vFuel][y, t] * fuel_CO2[dfGen[y,:Fuel]]+ dfGen[y, :CO2_Capture_Fraction_Startup] * EP[:eStartFuel][y, t] * fuel_CO2[dfGen[y,:Fuel]] @@ -102,19 +105,21 @@ function co2!(EP::Model, inputs::Dict) sum(dfGen[y, :CO2_Capture_Fraction] * EP[:vMulFuels][y, i, t] * fuel_CO2[dfGen[y, fuel_cols[i]]] for i = 1:max_fuels)+ sum(dfGen[y, :CO2_Capture_Fraction_Startup] * EP[:vMulStartFuels][y, i, t] * fuel_CO2[dfGen[y, fuel_cols[i]]] for i = 1:max_fuels) end) + + println(length(eEmissionsCaptureByPlant)) - @expression(EP, eEmissionsCaptureByPlantYear[y=1:G], + @expression(EP, eEmissionsCaptureByPlantYear[y in CCS], sum(omega[t] * eEmissionsCaptureByPlant[y, t] for t in 1:T)) # add CO2 sequestration cost to objective function # when scale factor is on tCO2/MWh = > kt CO2/GWh - @expression(EP, ePlantCCO2Sequestration[y=1:G], + @expression(EP, ePlantCCO2Sequestration[y in CCS], sum(omega[t] * eEmissionsCaptureByPlant[y, t] * dfGen[y, :CCS_Disposal_Cost_per_Metric_Ton] for t in 1:T)) @expression(EP, eZonalCCO2Sequestration[z=1:Z], sum(ePlantCCO2Sequestration[y] - for y in dfGen[(dfGen[!, :Zone].==z), :R_ID])) + for y in intersect(dfGen[(dfGen[!, :Zone].==z), :R_ID], CCS))) @expression(EP, eTotaleCCO2Sequestration, sum(eZonalCCO2Sequestration[z] for z in 1:Z)) diff --git a/src/model/core/fuel.jl b/src/model/core/fuel.jl index cdc55954d7..65d874f176 100644 --- a/src/model/core/fuel.jl +++ b/src/model/core/fuel.jl @@ -111,6 +111,11 @@ function fuel!(EP::Model, inputs::Dict, setup::Dict) max_cofire = inputs["MAX_COFIRE"] min_cofire_start =inputs["MIN_COFIRE_START"] max_cofire_start =inputs["MAX_COFIRE_START"] + COFIRE_MAX = [dfGen[dfGen[!, Symbol(string("Fuel",i, "_Max_Cofire_Level"))].< 1, :][!, :R_ID] for i in 1:max_fuels] + COFIRE_MAX_START = [dfGen[dfGen[!, Symbol(string("Fuel",i, "_Max_Cofire_Level_Start"))].< 1, :][!, :R_ID] for i in 1:max_fuels] + COFIRE_MIN = [dfGen[dfGen[!, Symbol(string("Fuel",i, "_Min_Cofire_Level"))].> 0, :][!, :R_ID] for i in 1:max_fuels] + COFIRE_MIN_START = [dfGen[dfGen[!, Symbol(string("Fuel",i, "_Min_Cofire_Level_Start"))].> 0, :][!, :R_ID] for i in 1:max_fuels] + @variable(EP, vMulFuels[y in MULTI_FUELS, i = 1:max_fuels, t = 1:T] >= 0) @variable(EP, vMulStartFuels[y in MULTI_FUELS, i = 1:max_fuels, t = 1:T] >= 0) end @@ -295,21 +300,23 @@ function fuel!(EP::Model, inputs::Dict, setup::Dict) # fuel2/heat rate >= min_cofire_level * total power # fuel2/heat rate <= max_cofire_level * total power without retrofit if !isempty(MULTI_FUELS) - # during power generation - @constraint(EP, cMinCofire[y in MULTI_FUELS, i in 1:max_fuels, t = 1:T], - EP[:vMulFuels][y, i, t] >= min_cofire[i][y] * EP[:ePlantFuel_generation][y,t] - ) - @constraint(EP, cMaxCofire[y in MULTI_FUELS, i in 1:max_fuels, t = 1:T], - EP[:vMulFuels][y, i, t] <= max_cofire[i][y] * EP[:ePlantFuel_generation][y,t] - ) - # startup - @constraint(EP, cMinCofireStart[y in MULTI_FUELS, i in 1:max_fuels, t = 1:T], - EP[:vMulStartFuels][y, i, t] >= min_cofire_start[i][y] * EP[:ePlantFuel_start][y,t] - ) - @constraint(EP, cMaxCofireStart[y in MULTI_FUELS, i in 1:max_fuels, t = 1:T], - EP[:vMulStartFuels][y, i, t] <= max_cofire_start[i][y] * EP[:ePlantFuel_start][y,t] - ) - + for i in 1:max_fuels + # during power generation + # cofire constraints without the name due to the loop + @constraint(EP, [y in intersect(MULTI_FUELS, COFIRE_MIN[i]), t = 1:T], + EP[:vMulFuels][y, i, t] >= min_cofire[i][y] * EP[:ePlantFuel_generation][y,t] + ) + @constraint(EP, [y in intersect(MULTI_FUELS, COFIRE_MAX[i]), t = 1:T], + EP[:vMulFuels][y, i, t] <= max_cofire[i][y] * EP[:ePlantFuel_generation][y,t] + ) + # startup + @constraint(EP, [y in intersect(MULTI_FUELS, COFIRE_MIN_START[i]), t = 1:T], + EP[:vMulStartFuels][y, i, t] >= min_cofire_start[i][y] * EP[:ePlantFuel_start][y,t] + ) + @constraint(EP, [y in intersect(MULTI_FUELS, COFIRE_MAX_START[i]), t = 1:T], + EP[:vMulStartFuels][y, i, t] <= max_cofire_start[i][y] * EP[:ePlantFuel_start][y,t] + ) + end end return EP