Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a feature to enable thermal power plants to burn multiple fuels #586

Merged
merged 61 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
10c5d76
include fuel.jl co2.jl from Qingyu's CO2 module
fc4uk May 16, 2023
f44eeb8
Update co2.jl
fc4uk May 17, 2023
3c9a23a
Add a second fuel
qluo0320github May 22, 2023
4983584
Edit dual fuel
qluo0320github May 23, 2023
fbc6395
Remove variables P1 and P2
qluo0320github May 24, 2023
e0e34d2
Cleaned up unused input data and added some comments
filippopecci May 25, 2023
4c3b11c
no change made to example systems
filippopecci May 25, 2023
ae47121
Added option for two different heat rates, and modified generator dat…
filippopecci May 31, 2023
84b0f5f
Add EPA new rules constraints
qluo0320github Aug 11, 2023
7e32e58
epa separation commit
qluo0320github Aug 14, 2023
9fa2a31
Add max cofire level for resources without retro
qluo0320github Aug 21, 2023
8fb2e2b
Add max co-fire variable to input file
qluo0320github Aug 21, 2023
70333d6
Enable resources in GenX to use multi fuel
qluo0320github Aug 23, 2023
f06db58
changes when writing outputs
qluo0320github Aug 23, 2023
d3e14cc
Add documentation about multi fuel in fuel.jl
qluo0320github Aug 25, 2023
56ddfec
Update Generators_data.csv
qluo0320github Aug 25, 2023
896e942
Remove outdated HiGHS setting `simplex_dualise_strategy`
qluo0320github Aug 30, 2023
23a33aa
Merge remote-tracking branch 'origin/develop' into multi_fuels
qluo0320github Aug 30, 2023
e2e0df3
Add blending level constraints during startup processes
qluo0320github Aug 30, 2023
1537f63
remove start fuel costs when writing costs
qluo0320github Aug 31, 2023
0de8a13
Merge branch 'multi_fuels' into epa_ghg
qluo0320github Sep 11, 2023
7e5b829
apply CF constraints to certain resources
qluo0320github Sep 14, 2023
9aecca8
fix bugs related to multi fuels and unit-level emission constraints
qluo0320github Sep 19, 2023
f998ec4
Merge remote-tracking branch 'origin/develop' into epa_ghg
qluo0320github Sep 22, 2023
b0d2ec2
fix bugs after merge
qluo0320github Sep 25, 2023
1660932
Only keep constraints about multi-fuels
qluo0320github Nov 8, 2023
79162ea
Remove unneeded check when loading fuel data (#545)
cfe316 Oct 3, 2023
13ec11d
Maintenance formulation (for thermal generators) (#556)
cfe316 Oct 4, 2023
27d06db
Separate new build and retirement eligibility (#392)
cfe316 Oct 24, 2023
6e5d76c
Endogenous retirements bugfix
filippopecci Oct 24, 2023
82e5cd4
[Fix] eELOSSByZone expr: access before initialization (#568)
lbonaldo Oct 27, 2023
e43e3b0
Removed unused capacity factor setting
qluo0320github Nov 8, 2023
eaeafa2
Merge remote-tracking branch 'origin/develop' into multi_fuels
qluo0320github Nov 27, 2023
7c80cc7
Clean GenX.jl after merge
qluo0320github Nov 27, 2023
39faec5
Update the example case for multi-fuels
qluo0320github Nov 27, 2023
48945f1
Removed unused files
qluo0320github Nov 28, 2023
3d7df51
Update Demand_data.csv
qluo0320github Nov 28, 2023
34a9d62
Update data_documentation.md
qluo0320github Nov 28, 2023
eb157d1
Removed unused space, variables, and comments
qluo0320github Nov 28, 2023
15ba005
undo changes to some files
qluo0320github Nov 28, 2023
c0c89b8
Add a function to read data related to multi fuels in Generators_dat…
qluo0320github Nov 28, 2023
2a1616e
Assign variables at the beginning functions
qluo0320github Dec 1, 2023
8dd4aff
Define variables for MULTI_FUELS only when MULTI_FUELS exists
qluo0320github Dec 1, 2023
77afe78
Move if statement before fun call in load_generators_data
lbonaldo Dec 5, 2023
8f48fa4
Add multi_fuels test
lbonaldo Dec 5, 2023
5b983be
1. check the compatibility between multi-fuels and piesewise heat rat…
qluo0320github Jan 4, 2024
4ac5a63
Merge remote-tracking branch 'origin/develop' into multi_fuels
qluo0320github Jan 4, 2024
4805818
define THERM_COMMIT_PWFU in function load_multi_fuels_data
qluo0320github Jan 4, 2024
d518d99
use process_piecewisefuelusage so that THERM_COMMIT_PWFU can be used …
qluo0320github Jan 4, 2024
ab22570
check compatibility between piese wise heat rates and multi-fuels onl…
qluo0320github Jan 4, 2024
92ad0cf
check compatibility between piese wise heat rates and multi-fuels onl…
qluo0320github Jan 4, 2024
6bc4c5b
use variable "fuel_cols" when multi-fuel exists
qluo0320github Jan 16, 2024
8ec89b0
reduce # of constraints to reduce memory use
qluo0320github Jan 19, 2024
e8fc0cb
remove used println()
qluo0320github Jan 19, 2024
488d849
define CCS when loading input
qluo0320github Jan 19, 2024
289558b
Modify write outputs scripts for CCS
qluo0320github Jan 24, 2024
a0f4a70
Merge remote-tracking branch 'origin/develop' into multi_fuels
qluo0320github Feb 19, 2024
c06660b
Add units to fuel outputs; fix bugs in fuel.jl
qluo0320github Feb 19, 2024
0f54cc5
Add tests and fix HAS_FUEL flag
lbonaldo Feb 20, 2024
1b25178
Fix resources filename
lbonaldo Feb 20, 2024
3ca43a4
Update CHANGELOG.md
lbonaldo Feb 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
except for a few places such as the common term "value of lost load" which refers to non-served demand (#397).
- `New_Build = -1` in `Generators_data.csv`: instead, use `New_Build = 0` and `Can_Retire = 0`.


## [0.3.6] - 2023-08-01

### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
,Network_zones,CO_2_Cap_Zone_1,CO_2_Max_tons_MWh_1,CO_2_Max_Mtons_1
NE,z1,1,0.05,0.018
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
,Network_zones,CapRes_1
NE,z1,0.156
25 changes: 25 additions & 0 deletions Example_Systems/SmallNewEngland/OneZone_MultiFuels/Demand_data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Voll,Demand_Segment,Cost_of_Demand_Curtailment_per_MW,Max_Demand_Curtailment,Rep_Periods,Timesteps_per_Rep_Period,Sub_Weights,Time_Index,Demand_MW_z1
50000,1,1,1,1,24,8760,1,11162
,,,,,,,2,10556
,,,,,,,3,10105
,,,,,,,4,9878
,,,,,,,5,9843
,,,,,,,6,10017
,,,,,,,7,10390
,,,,,,,8,10727
,,,,,,,9,11298
,,,,,,,10,11859
,,,,,,,11,12196
,,,,,,,12,12321
,,,,,,,13,12381
,,,,,,,14,12270
,,,,,,,15,12149
,,,,,,,16,12219
,,,,,,,17,13410
,,,,,,,18,14539
,,,,,,,19,14454
,,,,,,,20,14012
,,,,,,,21,13494
,,,,,,,22,12772
,,,,,,,23,11877
,,,,,,,24,10874
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
,Network_zones,ESR_1,ESR_2
NE,z1,0.259,0.348
26 changes: 26 additions & 0 deletions Example_Systems/SmallNewEngland/OneZone_MultiFuels/Fuels_data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Time_Index,NG,None,H2
0,0.05306,0,0
1,5.28,0,16
2,5.28,0,16
3,5.28,0,16
4,5.28,0,16
5,5.28,0,16
6,5.28,0,16
7,5.28,0,16
8,5.28,0,16
9,5.28,0,16
10,5.28,0,16
11,5.28,0,16
12,5.28,0,16
13,5.28,0,16
14,5.28,0,16
15,5.28,0,16
16,5.28,0,16
17,5.28,0,16
18,5.28,0,16
19,5.28,0,16
20,5.28,0,16
21,5.28,0,16
22,5.28,0,16
23,5.28,0,16
24,5.28,0,16
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Resource,Zone,THERM,MUST_RUN,STOR,FLEX,HYDRO,VRE,LDS,Num_VRE_Bins,MULTI_FUELS,New_Build,Can_Retire,Existing_Cap_MW,Existing_Cap_MWh,Existing_Charge_Cap_MW,Max_Cap_MW,Max_Cap_MWh,Max_Charge_Cap_MW,Min_Cap_MW,Min_Cap_MWh,Min_Charge_Cap_MW,Inv_Cost_per_MWyr,Inv_Cost_per_MWhyr,Inv_Cost_Charge_per_MWyr,Fixed_OM_Cost_per_MWyr,Fixed_OM_Cost_per_MWhyr,Fixed_OM_Cost_Charge_per_MWyr,Var_OM_Cost_per_MWh,Var_OM_Cost_per_MWh_In,Heat_Rate_MMBTU_per_MWh,Fuel,Cap_Size,Start_Cost_per_MW,Start_Fuel_MMBTU_per_MW,Up_Time,Down_Time,Ramp_Up_Percentage,Ramp_Dn_Percentage,Hydro_Energy_to_Power_Ratio,Min_Power,Self_Disch,Eff_Up,Eff_Down,Min_Duration,Max_Duration,Max_Flexible_Demand_Advance,Max_Flexible_Demand_Delay,Flexible_Demand_Energy_Eff,Reg_Max,Rsv_Max,Reg_Cost,Rsv_Cost,MaxCapTag_1,MaxCapTag_2,MaxCapTag_3,MinCapTag_1,MinCapTag_2,MinCapTag_3,MGA,Resource_Type,CapRes_1,ESR_1,ESR_2,region,cluster,Num_Fuels,Fuel1,Heat_Rate1_MMBTU_per_MWh,Fuel1_Min_Cofire_Level,Fuel1_Max_Cofire_Level,Fuel1_Min_Cofire_Level_Start,Fuel1_Max_Cofire_Level_Start,Fuel2,Heat_Rate2_MMBTU_per_MWh,Fuel2_Min_Cofire_Level,Fuel2_Max_Cofire_Level,Fuel2_Min_Cofire_Level_Start,Fuel2_Max_Cofire_Level_Start
natural_gas_combined_cycle,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,-1,-1,-1,0,0,0,65400,0,0,10287,0,0,3.55,0,7.43,NG,250,91,2,6,6,0.64,0.64,0,0.468,0,1,1,0,0,0,0,1,0.25,0.5,0,0,0,0,0,0,0,0,1,natural_gas_fired_combined_cycle,0.93,0,0,NE,1,2,NG,7.43,0,1,0,1,H2,7.43,0.05,1,0.05,1
solar_pv,1,0,0,0,0,0,1,0,1,0,1,0,0,0,0,-1,-1,-1,0,0,0,85300,0,0,18760,0,0,0,0,9.13,None,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,solar_photovoltaic,0.8,1,1,NE,1,1,None,0,0,0,0,0,None,0,0,0,0,1
onshore_wind,1,0,0,0,0,0,1,0,1,0,1,0,0,0,0,-1,-1,-1,0,0,0,97200,0,0,43205,0,0,0.1,0,9.12,None,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,1,onshore_wind_turbine,0.8,1,1,NE,1,1,None,0,0,0,0,1,None,0,0,0,0,1
battery,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,-1,-1,-1,0,0,0,19584,22494,0,4895,5622,0,0.15,0.15,0,None,0,0,0,0,0,1,1,0,0,0,0.92,0.92,1,10,0,0,1,0,0,0,0,0,0,1,0,0,1,0,battery_mid,0.95,0,0,NE,0,1,None,0,0,0,0,0,None,0,0,0,0,1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Time_Index,natural_gas_combined_cycle,solar_pv,onshore_wind,battery
1,1,0,0.889717042,1
2,1,0,0.877715468,1
3,1,0,0.903424203,1
4,1,0,0.895153165,1
5,1,0,0.757258117,1
6,1,0,0.630928695,1
7,1,0,0.557177782,1
8,1,0,0.6072492,1
9,1,0.1779,0.423417866,1
10,1,0.429,0.007470775,1
11,1,0.5748,0.002535942,1
12,1,0.6484,0.002153709,1
13,1,0.6208,0.00445132,1
14,1,0.596,0.007711587,1
15,1,0.5013,0.100848213,1
16,1,0.3311,0.201802149,1
17,1,0.0642,0.141933054,1
18,1,0,0.567022562,1
19,1,0,0.946024895,1
20,1,0,0.923394203,1
21,1,0,0.953386247,1
22,1,0,0.929205418,1
23,1,0,0.849528909,1
24,1,0,0.665570974,1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MaxCapReqConstraint,ConstraintDescription,Max_MW
1,PV,50000
2,Wind,100000
3,Batteries,60000
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MinCapReqConstraint,ConstraintDescription,Min_MW
1,PV,5000
2,Wind,10000
3,Batteries,6000
15 changes: 15 additions & 0 deletions Example_Systems/SmallNewEngland/OneZone_MultiFuels/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Small New England: One Zone with resources that can use multiple fuels

**SmallNewEngland** is set of a simplified versions of the more detailed example system RealSystemExample. It is condensed for easy comprehension and quick testing of different components of the GenX. **SmallNewEngland/OneZone_MultiFules** is one of our most basic models, a 24-hour example with hourly resolution containing only one zone representing New England. The model includes only natural gas (cofiring with H2), solar PV, wind, and lithium-ion battery storage with no initial capacity.

To run the model, first navigate to the example directory at `GenX/Example_Systems/SmallNewEngland/OneZone_MultiFuels`:

`cd("Example_Systems/SmallNewEngland/OneZone_MultiFuels")`

Next, ensure that your settings in `GenX_settings.yml` are correct. The default settings use the solver HiGHS (`Solver: HiGHS`). Other optional policies include minimum capacity requirements, a capacity reserve margin, and more.

Once the settings are confirmed, run the model with the `Run.jl` script in the example directory:

`include("Run.jl")`

Once the model has completed, results will write to the `Results` directory.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reg_Req_Percent_Demand,Reg_Req_Percent_VRE,Rsv_Req_Percent_Demand,Rsv_Req_Percent_VRE,Unmet_Rsv_Penalty_Dollar_per_MW,Dynamic_Contingency,Static_Contingency_MW
0.01,0.0032,0.033,0.0795,1000,0,0
3 changes: 3 additions & 0 deletions Example_Systems/SmallNewEngland/OneZone_MultiFuels/Run.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using GenX

run_genx_case!(dirname(@__FILE__))
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# CPLEX Solver Parameters
Feasib_Tol: 1.0e-05 # Constraint (primal) feasibility tolerances.
Optimal_Tol: 1e-5 # Dual feasibility tolerances.
Pre_Solve: 1 # Controls presolve level.
TimeLimit: 110000 # Limits total time solver.
MIPGap: 1e-3 # Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise).
Method: 2 # Algorithm used to solve continuous models (including MIP root relaxation).
BarConvTol: 1.0e-08 # Barrier convergence tolerance (determines when barrier terminates).
NumericFocus: 0 # Numerical precision emphasis.
SolutionType: 2 # Solution type for LP or QP.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
OverwriteResults: 0 # Overwrite existing results in output folder or create a new one; 0 = create new folder; 1 = overwrite existing results
PrintModel: 0 # Write the model formulation as an output; 0 = active; 1 = not active
NetworkExpansion: 0 # Transmission network expansionl; 0 = not active; 1 = active systemwide
Trans_Loss_Segments: 1 # Number of segments used in piecewise linear approximation of transmission losses; 1 = linear, >2 = piecewise quadratic
Reserves: 0 # Regulation (primary) and operating (secondary) reserves; 0 = not active, 1 = active systemwide
EnergyShareRequirement: 1 # Minimum qualifying renewables penetration; 0 = not active; 1 = active systemwide
CapacityReserveMargin: 1 # Number of capacity reserve margin constraints; 0 = not active; 1 = active systemwide
CO2Cap: 0 # CO2 emissions cap; 0 = not active (no CO2 emission limit); 1 = mass-based emission limit constraint; 2 = demand + rate-based emission limit constraint; 3 = generation + rate-based emission limit constraint
StorageLosses: 1 # Energy Share Requirement and CO2 constraints account for energy lost; 0 = not active (DO NOT account for energy lost); 1 = active systemwide (DO account for energy lost)
MinCapReq: 1 # Activate minimum technology carveout constraints; 0 = not active; 1 = active
MaxCapReq: 1 # Activate maximum technology carveout constraints; 0 = not active; 1 = active
ParameterScale: 1 # Turn on parameter scaling wherein load, capacity and power variables are defined in GW rather than MW. 0 = not active; 1 = active systemwide
WriteShadowPrices: 1 # Write shadow prices of LP or relaxed MILP; 0 = not active; 1 = active
UCommit: 2 # Unit committment of thermal power plants; 0 = not active; 1 = active using integer clestering; 2 = active using linearized clustering
TimeDomainReductionFolder: "TDR_Results" # Directory name where results from time domain reduction will be saved. If results already exist here, these will be used without running time domain reduction script again.
TimeDomainReduction: 0 # Time domain reduce (i.e. cluster) inputs based on Demand_data.csv, Generators_variability.csv, and Fuels_data.csv; 0 = not active (use input data as provided); 0 = active (cluster input data, or use data that has already been clustered)
ModelingToGenerateAlternatives: 0 # Modeling to generate alternatives; 0 = not active; 1 = active. Note: produces a single solution as output
ModelingtoGenerateAlternativeSlack: 0.1 # Slack value as a fraction of least-cost objective in budget constraint used for evaluating alternative model solutions; positive float value
ModelingToGenerateAlternativeIterations: 3 # Number of MGA iterations with maximization and minimization objective
MethodofMorris: 0 #Flag for turning on the Method of Morris analysis
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Gurobi Solver Parameters
# Common solver settings
Feasib_Tol: 1.0e-05 # Constraint (primal) feasibility tolerances.
Optimal_Tol: 1e-5 # Dual feasibility tolerances.
TimeLimit: 110000 # Limits total time solver.
Pre_Solve: 1 # Controls presolve level.
Method: 2 # Algorithm used to solve continuous models (including MIP root relaxation).

#Gurobi-specific solver settings
MIPGap: 1e-3 # Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise).
BarConvTol: 1.0e-08 # Barrier convergence tolerance (determines when barrier terminates).
NumericFocus: 0 # Numerical precision emphasis.
Crossover: 0 # Barrier crossver strategy.
PreDual: 0 # Decides whether presolve should pass the primal or dual linear programming problem to the LP optimization algorithm.
AggFill: 10 # Allowed fill during presolve aggregation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# HiGHS Solver Parameters
# Common solver settings
Feasib_Tol: 1.0e-05 # Primal feasibility tolerance # [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
Optimal_Tol: 1.0e-05 # Dual feasibility tolerance # [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
TimeLimit: 1.0e23 # Time limit # [type: double, advanced: false, range: [0, inf], default: inf]
Pre_Solve: choose # Presolve option: "off", "choose" or "on" # [type: string, advanced: false, default: "choose"]
Method: choose #HiGHS-specific solver settings # Solver option: "simplex", "choose" or "ipm" # [type: string, advanced: false, default: "choose"]

#highs-specific solver settings

# run the crossover routine for ipx
# [type: string, advanced: "on", range: {"off", "on"}, default: "off"]
run_crossover: "on"
26 changes: 26 additions & 0 deletions docs/src/data_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,32 @@ This file contains the time-series of capacity factors / availability of the win

• Second column onwards: Resources are listed from the second column onward with headers matching each resource name in the `Generators_data.csv` and `Vre_and_stor_data.csv` files in any order. The availability for each resource at each time step is defined as a fraction of installed capacity and should be between 0 and 1. Note that for this reason, resource names specified in `Generators_data.csv` and `Vre_and_stor_data.csv` must be unique.

#### 2.2.12 Settings-specific columns in the Generators\_data.csv to use multi fuels

This file contains additional setting and performance parameters for specifically thermal resources that use multiple fuels.
These variables must be explicitly listed in the `Generators_data.csv`.

###### Table 17: Settings-specific columns in the Generators\_data.csv file to use multi fuels
|**Column Name** | **Description**|
| :------------ | :-----------|
|**Technology type flags**|
|MULTI_FUELS | {0, 1}, Flag to indicate membership in set of thermal resources that can burn multiple fuels at the same time (e.g., natural gas combined cycle cofiring with hydrogen, coal power plant cofiring with natural gas.|
||MULTI_FUELS = 0: Not part of set (default) |
||MULTI_FUELS = 1: Resources that can use fuel blending. |
|**Technical performance parameters**|
|Num\_Fuels |Number of fuels that a multi-fuel generator (MULTI_FUELS = 1) can use at the same time. The length of ['Fuel1', 'Fuel2', ...] should be equal to 'Num\_Fuels'. Each fuel will requires its corresponding heat rate, min cofire level, and max cofire level. |
|Fuel1 |Frist fuel needed for a mulit-fuel generator (MULTI_FUELS = 1). The names should match with the ones in the `Fuels_data.csv`. |
|Fuel2 |Second fuel needed for a mulit-fuel generator (MULTI_FUELS = 1). The names should match with the ones in the `Fuels_data.csv`. |
|Heat1\_Rate\_MMBTU\_per\_MWh |Heat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel1. |
|Heat2\_Rate\_MMBTU\_per\_MWh |Heat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel2. |
|Fuel1\_Min\_Cofire\_Level |The minimum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process. |
|Fuel1\_Min\_Cofire_Level\_Start |The minimum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process. |
|Fuel1\_Max\_Cofire\_Level |The maximum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process. |
|Fuel1\_Max\_Cofire_Level\_Start |The maximum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process. |
|Fuel2\_Min\_Cofire\_Level |The minimum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process. |
|Fuel2\_Min\_Cofire_Level\_Start |The minimum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process. |
|Fuel2\_Max\_Cofire\_Level |The maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process. |
|Fuel2\_Max\_Cofire_Level\_Start |The maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process. |

## 3 Outputs

Expand Down
59 changes: 54 additions & 5 deletions src/load_inputs/load_generators_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

# Add Resource IDs after reading to prevent user errors
gen_in[!,:R_ID] = 1:G

scale_factor = setup["ParameterScale"] == 1 ? ModelScalingFactor : 1
## Defining sets of generation and storage resources

Expand Down Expand Up @@ -66,13 +66,18 @@
if !("RETRO" in names(gen_in))
gen_in[!, "RETRO"] = zero(gen_in[!, "R_ID"])
end

inputs_gen["RETRO"] = gen_in[gen_in.RETRO.==1,:R_ID]
# Disable Retrofit while it's under development
if !(isempty(inputs_gen["RETRO"]))
error("The Retrofits feature, which is activated by nonzero data in a 'RETRO' column in Generators_data.csv, is under development and is not ready for public use. Disable this message to enable this *experimental* feature.")
end

# Set of multi-fuel resources
if "MULTI_FUELS" ∉ names(gen_in)
gen_in[!, "MULTI_FUELS"] = zero(gen_in[!, "R_ID"])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use zeros(G) to create a vector of zero elements of length G (it should be faster because it doesn't read the data frame)

Suggested change
gen_in[!, "MULTI_FUELS"] = zero(gen_in[!, "R_ID"])
gen_in[!, "MULTI_FUELS"] = zeros(G)

end

# Set of thermal generator resources
if setup["UCommit"]>=1
# Set of thermal resources eligible for unit committment
Expand Down Expand Up @@ -158,7 +163,6 @@

inputs_gen["RETROFIT_INV_CAP_COSTS"] = [ [ inv_cap[i][y] for i in 1:max_retro_sources if inv_cap[i][y] >= 0 ] for y in 1:G ] # The set of investment costs (capacity $/MWyr) of each retrofit by source
end

# See documentation for descriptions of each column
# Generally, these scalings converts energy and power units from MW to GW
# and $/MW to $M/GW. Both are done by dividing the values by 1000.
Expand Down Expand Up @@ -219,7 +223,7 @@
end

load_vre_stor_data!(inputs_gen, setup, path)

load_multi_fuels_data!(inputs_gen, setup, path)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest defining here the two entries inputs_gen["SINGLE_FUEL"] and inputs_gen["MULTI_FUELS"] instead of inside the load_multi_fuels_data!, and adding the function call inside a if !isempty(inputs_gen["MULTI_FUELS"]) end block. Something like:

# Single-fuel resources
inputs_gen["SINGLE_FUEL"] = gen_in[gen_in.MULTI_FUELS.!=1,:R_ID]
# Multi-fuel resources
inputs_gen["MULTI_FUELS"] = gen_in[gen_in.MULTI_FUELS.==1,:R_ID]
if !isempty(inputs_gen["MULTI_FUELS"]) # If there are any resources using multi fuels, read relevant data
    load_multi_fuels_data!(inputs_gen, setup, path)
end


# write zeros if col names are not in the gen_in dataframe
required_cols_for_co2 = ["Biomass", "CO2_Capture_Fraction", "CO2_Capture_Fraction_Startup", "CCS_Disposal_Cost_per_Metric_Ton"]
Expand All @@ -241,6 +245,51 @@
println(filename * " Successfully Read!")
end

@doc raw"""
load_multi_fuels_data!(inputs_gen::Dict, setup::Dict, path::AbstractString)

Function for reading input parameters related to multi fuels
"""
function load_multi_fuels_data!(inputs_gen::Dict, setup::Dict, path::AbstractString)
gen_in = inputs_gen["dfGen"]
inputs_gen["MULTI_FUELS"] = gen_in[gen_in.MULTI_FUELS.==1,:R_ID]
inputs_gen["SINGLE_FUEL"] = gen_in[gen_in.MULTI_FUELS.!=1,:R_ID]

if !isempty(inputs_gen["MULTI_FUELS"]) # If there are any resources using multi fuels, read relevant data
inputs_gen["NUM_FUELS"] = gen_in[!,:Num_Fuels] # Number of fuels that this resource can use
max_fuels = maximum(inputs_gen["NUM_FUELS"])
fuel_cols = [ Symbol(string("Fuel",i)) for i in 1:max_fuels ]
heat_rate_cols = [ Symbol(string("Heat_Rate",i, "_MMBTU_per_MWh")) for i in 1:max_fuels ]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for f in 1:max_fuels might be more readable than for i in 1:max_fuels

max_cofire_cols = [ Symbol(string("Fuel",i, "_Max_Cofire_Level")) for i in 1:max_fuels ]
min_cofire_cols = [ Symbol(string("Fuel",i, "_Min_Cofire_Level")) for i in 1:max_fuels ]
max_cofire_start_cols = [ Symbol(string("Fuel",i, "_Max_Cofire_Level_Start")) for i in 1:max_fuels ]
min_cofire_start_cols = [ Symbol(string("Fuel",i, "_Min_Cofire_Level_Start")) for i in 1:max_fuels ]
fuel_types = [ gen_in[!,f] for f in fuel_cols ]
heat_rates = [ gen_in[!,f] for f in heat_rate_cols ]
max_cofire = [ gen_in[!,f] for f in max_cofire_cols ]
min_cofire = [ gen_in[!,f] for f in min_cofire_cols ]
max_cofire_start = [ gen_in[!,f] for f in max_cofire_start_cols ]
min_cofire_start = [ gen_in[!,f] for f in min_cofire_start_cols ]
inputs_gen["HEAT_RATES"] = heat_rates
inputs_gen["MAX_COFIRE"] = max_cofire
inputs_gen["MIN_COFIRE"] = min_cofire
inputs_gen["MAX_COFIRE_START"] = max_cofire_start
inputs_gen["MIN_COFIRE_START"] = min_cofire_start
inputs_gen["FUEL_TYPES"] = fuel_types
inputs_gen["FUEL_COLS"] = fuel_cols
inputs_gen["MAX_NUM_FUELS"] = max_fuels

Check warning on line 280 in src/load_inputs/load_generators_data.jl

View check run for this annotation

Codecov / codecov/patch

src/load_inputs/load_generators_data.jl#L259-L280

Added lines #L259 - L280 were not covered by tests

# check whether non-zero heat rates are used for resources that only use a single fuel
for i in 1:max_fuels
for hr in heat_rates[i][inputs_gen["SINGLE_FUEL"]]
if hr > 0

Check warning on line 285 in src/load_inputs/load_generators_data.jl

View check run for this annotation

Codecov / codecov/patch

src/load_inputs/load_generators_data.jl#L283-L285

Added lines #L283 - L285 were not covered by tests
error("Heat rates for multi fuels must be zero when only one fuel is used")
end
end

Check warning on line 288 in src/load_inputs/load_generators_data.jl

View check run for this annotation

Codecov / codecov/patch

src/load_inputs/load_generators_data.jl#L288

Added line #L288 was not covered by tests
end
end
end


@doc raw"""
check_vre_stor_validity(df::DataFrame, setup::Dict)
Expand Down Expand Up @@ -369,7 +418,7 @@
Function for reading input parameters related to co-located VRE-storage resources
"""
function load_vre_stor_data!(inputs_gen::Dict, setup::Dict, path::AbstractString)

error_strings = String[]
dfGen = inputs_gen["dfGen"]
inputs_gen["VRE_STOR"] = "VRE_STOR" in names(dfGen) ? dfGen[dfGen.VRE_STOR.==1,:R_ID] : Int[]
Expand Down
Loading