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

CO2 module and fuel module #536

Merged
merged 33 commits into from
Sep 18, 2023
Merged

CO2 module and fuel module #536

merged 33 commits into from
Sep 18, 2023

Conversation

fc4uk
Copy link
Collaborator

@fc4uk fc4uk commented Aug 24, 2023

This update provides tracking for both the consumption and cost of fuel. It covers the fuel used in power generation as well as startup fuel. Additionally, it considers CO2 emissions, including those that are emitted, captured, and sequestered. Consequently, "CO2.jl" will replace "emissions.jl."

Currently, for generators equipped with Carbon Capture and Storage (CCS), GenX designates the fuel type as "NG_CCS." This classification has a reduced CO2 content and higher fuel costs due to CO2 sequestration. However, this makes it challenging to track the mass of CO2 captured and sequestered. With the integration of the CO2.jl module, the fuel utilized by CCS-equipped plants will match the costs and CO2 content of fuels in traditional coal/gas plants. This update allows users to define the CO2_Capture_Rate and the associated costs of CO2 injection and sequestration in the "Generator_Data.csv" file. If a non-zero CO2_Capture_Rate is detected, we'll formulate expressions to account for the captured and emitted CO2. Additionally, a biomass option has been incorporated into CO2.jl, enabling us to denote zero emissions from biomass without CCS and negative emissions from biomass with CCS.

Within "Fuel.jl," we track fuel consumption and costs associated with power generation and startup events. The fuel consumption for power generation is determined by multiplying power generation by its respective heat rate. For the equations mentioned, thermal generators are projected to have consistent fuel consumption for producing 1 MWh of electricity, regardless of minimum load or full load. Nevertheless, thermal generators often experience reduced efficiency when operating at part-load, resulting in elevated fuel consumption for the same electricity output. Thus, "Fuel.jl" has been enhanced to accurately depict fuel consumption at part-load to represent this relationship.

After the CO2.jl and Fuel.jl are merged, we will be merging CO2 tax credits into the policies module to separately track the CO2 tax/credits.

Co-Authored-By: Qingyu Xu [email protected]

src/model/core/co2.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
fc4uk and others added 11 commits August 25, 2023 14:01
1.	In load_fuels_data.jl, there is no need to scale fuel_co2 as it will cause scaling issues when the parameter scale is on.
2.	In load_generator_data.jl, remove the start up fuel costs as all the costs associated with fuel consumption will be accounted in fuel.jl.
3.	In discharge.jl, remove the fuel costs as they will be separately accounted in fuel.jl
4.	In Generate_model.jl, remove emissions!(EP, inputs) as emissions.jl will be replaced by CO2.jl. include fuel.jl.
5.	Fuel.jl is a module that tracks the consumption (MMBTU or billion BTU scaled) and costs ($ or million $) of fuels used in generators (startup fuels included as well). It also includes a piecewise fuel consumption option if you want to represent the fuel consumption during different load factor.
6.	CO2.jl is an updated version of emissios.jl, and we don’t need emissions.jl when we have co2.jl. Also added BECCS options in CO2.jl, line 29 and line 39. Basically, when BECCS plants are included, “Generator_data.csv” should have a column named “BECCS”, and the values under “BECCS” column should be 1 for BECCS facilities and 0 for non-BECCS facilities. The amount of CO2 captured and stored for BECCS generators are accounted in the same way as other thermal generators, but its corresponding emissions should be negative.
7.	Modified write_costs such that fuel costs are appropriately included.
8.	Include write_co2.jl and write_fuel_consumption.jl, which give co2 emissions and fuel consumption for each generator.

Co-Authored-By: Qingyu Xu <[email protected]>
accidently deleted eEmissionsByZone... added them in this version.

Co-Authored-By: Qingyu Xu <[email protected]>
…data.jl as they will be tracked separately

The fuel (including start up fuel) costs and CO2 emissions will be separately tracked in Fuel.jl and CO2.jl. No need to determine C_Fuel_per_MWh and CO2_per_MWh, and C_Start.

Delete redundant comments.
Delete emissions.jl as emissions.jl will be replaced by co2.jl
Delete the formulations to write emissions.csv as write_emissions.jl has the same function.
Add documents for co2.jl and fuel.jl
delete redundant comments
remove CO2Capture from setting
In fuel.jl, separately tracked the fuel costs for power generation and fuel costs for start up event.
In write_costs.jl, disaggregated cVar into two components: cVar (variable OM) and cFuel (fuel costs for power generation). Similarly, disaggregated cStart into cStart (startup costs) and cStartFuel (fuel costs during startup).
add cCO2, which represent the costs or credits associated with CO2. positive values are costs while negative values are credits.
Fixed a typo.
For piecewise fuel consumption module, change the "slope" to "Incremental_Heat_Rate_Segment", change "intercept" to "Intercept_Fuel_Consumption_Segment". The updated col names should be better representation than previous names.
Also scale the "Intercept_Fuel_Consumption_Segment" when scaling is on.
1. changed "PieceWiseHeatRate" to "PiecewiseHeatRate"
2. Deleted license header
3. No need to initialize array as zeros
4. wrote df[!, col][row] as df[row,: col]
5. replaced inputs_gen["dfGen"] to gen_in
6. used  /= operator to avoid listing col names twice
7. create a function to write zeros if col names do not exist in gen_in
Copy link
Collaborator

@gmantegna gmantegna left a comment

Choose a reason for hiding this comment

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

The formulation looks good overall. I have several specific comments on the code itself and also several more general comments:

  • Please add documentation for the new Generators_data columns in the .md files in /docs.
  • How hard would it be to make the number of segments flexible instead of fixed at three? This is not necessary, just a suggestion.
  • This is not in reference to changes introduced in this module, but while we are at it with fixing up the way fuels and emissions are tracked, would it be possible to fix up the sloppy dataframe indexing in load_fuels_data.jl? In particular, the use of "2:end" is very easy to lead to silent bugs if the data frame format is different from what the programmer intended.

src/load_inputs/load_fuels_data.jl Outdated Show resolved Hide resolved
src/load_inputs/load_generators_data.jl Outdated Show resolved Hide resolved
src/load_inputs/load_generators_data.jl Show resolved Hide resolved
src/load_inputs/load_generators_data.jl Outdated Show resolved Hide resolved
src/load_inputs/load_generators_data.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Show resolved Hide resolved
src/model/generate_model.jl Outdated Show resolved Hide resolved
@gmantegna
Copy link
Collaborator

gmantegna commented Aug 28, 2023 via email

@fc4uk
Copy link
Collaborator Author

fc4uk commented Aug 28, 2023 via email

1. Changed "PiecewiseHeatRate" to "PiecewiseFuelUsage" as we are modeling the linear approximation of fuel consumption at different load. PiecewiseFuelUsage sounds more accurate since it's in fuel.jl
2. add co2.jl and fuel.jl to MD files
3. make piecewise fuel usage flexible rather than fixing at 3 segments.
4. add "CO2_Capturate_Rate_Startup" for co2 emissions during the start up events. Typically, the CO2 capture rate during the start up is less than the CO2 capture rate at steady state
5. Change "Incremental_Heat_Rate" and "Intercept_fuel_consumption" back to "Slope" and "Intercept"
6. improve the documentation
Copy link
Collaborator

@gmantegna gmantegna left a comment

Choose a reason for hiding this comment

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

Have a couple of minor comments on documentation. However I have tested and otherwise this looks good.

Example_Systems/PiecewiseFuel_CO2_Example/README.md Outdated Show resolved Hide resolved
src/load_inputs/load_generators_data.jl Outdated Show resolved Hide resolved
src/load_inputs/load_generators_data.jl Outdated Show resolved Hide resolved
src/model/core/co2.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
src/model/core/fuel.jl Outdated Show resolved Hide resolved
revise the description for biomass. some minor revision on comments for better clarity.
Copy link
Collaborator

@gmantegna gmantegna left a comment

Choose a reason for hiding this comment

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

Looks good!

CHANGELOG.md Outdated Show resolved Hide resolved
remove code related to CO2 emissions/capture per zone & per year, which will only be used when CO2 tax/credit policies module are merged
end
# for non-zero values, heat rates and load point should follow an increasing trend
if any([any(diff(filter(x->x!=0, row)) .< 0) for row in eachrow(heat_rate_mat)]) .| any([any(diff(filter(x->x!=0, row)) .< 0) for row in eachrow(load_point_mat)])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this conditional be broken into multiple lines? This is very long.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, are two vectors being compared or two single values? If two single values, use | instead of .|

Copy link
Collaborator

Choose a reason for hiding this comment

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

filter(x->x!=0, row)

I learned recently that x->x!=0 can be written simply as !=(0). Comparison operators now have functional forms.


# check if values for piecewise fuel consumption make sense. Negative heat rate or load point are not allowed
if any(heat_rate_mat .< 0) .| any(load_point_mat .< 0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use |, not .| for two single Bool

@fc4uk fc4uk merged commit df1a91b into develop Sep 18, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants