-
Notifications
You must be signed in to change notification settings - Fork 122
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
Conversation
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.
Co-Authored-By: Qingyu Xu <[email protected]>
Co-Authored-By: Qingyu Xu <[email protected]>
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
There was a problem hiding this 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.
Yes that is what I mean by only one constraint being active. The other ones
are not at equality. And what do you mean when you say we change the fuel
usage but not the heat rate? Isn’t the heat rate defined as the fuel usage
per MWh of power generation?
…On Mon, Aug 28, 2023 at 12:11 Fangwei Cheng ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/model/core/fuel.jl
<#536 (comment)>:
> +
+The fuel consumption for power generation $vFuel_{y,t}$ is determined by power generation ($vP_{y,t}$) mutiplied by the corresponding heat rate ($Hear\_Rate_y$).
+
+The fuel costs for power generation and start fuel for a plant $y$ at time $t$, denoted by $eCFuelOut_{y,t}$ and $eFuelStart$, is determined by fuel consumption ($vFuel_{y,t}$ and $eStartFuel$) multiplied by the fuel costs (\$/MMBTU)
+
+From above formulations, thermal generators are expected to have the same fuel consumption per generating 1 MWh electricity, regardless of minimum load or full load. However, thermal generators tend to have decreased efficiency when operating at part load, leading to higher fuel consumption per generating the same amount of electricity. To have more precise representation of fuel consumption at part load, the piecewise-linear fitting of heat input can be introduced.
+
+```math
+\begin{aligned}
+vFuel_{y,t} >= vP_{y,t} * h_{y,x} + U_{g,t}* f_{y,x}
+\hspace{1cm} \forall y \in G, \forall t \in T, \forall x \in X
+\end{aligned}
+```
+Where $h_{y,x}$ represents incremental heat rate of a thermal generator $y$ in segment $x$ [MMBTU/MWh] and $f_{y,x}$ represents intercept of fuel consumption of a thermal generator $y$ in segment $x$ [MMBUT], and $U_{y,t}$ represents the commit status of a thermal generator $y$ at time $t$. We include at most three segments to represent the piecewise heat consumption.
+
+Since fuel consumption has a positive value, the optimization will optimize the fuel consumption by enforcing the inequity to equal to the highest piecewise segment. When the power output is zero, the commitment variable $U_{g,t}$ will bring the intercept to be zero such that the fuel consumption is zero when thermal units are offline.
I think all the segments are activated, but only one segment determines
the fuel consumption at vP (i.e., the optimization will enforce fuel
consumption to a segment that gives the maximum fuel usage)
for example,
segment 1: vFuel >= 6
*vP + 700; segment 2: vFuel >= 8*vP + 100;
if vP = 200, vFuel in segment1 = 1900, vFuel in segment2 = 1700; then
vFuel = 1900, heat rate = 9.5
if vP = 500, vFuel in segment1 = 3700, vFuel in segment2 = 4100, then
vFuel = 4100, heat rate = 8.2
At the time of writing this, I decided to change "PiecewiseHeatRate" to
"PiecewiseFuelUsage" as we are actually linearly approximating the fuel
usage, not the heat rate.
—
Reply to this email directly, view it on GitHub
<#536 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHKPARXVBM5NWYTWZM2CULDXXTUOVANCNFSM6AAAAAA347Q4LU>
.
You are receiving this because your review was requested.Message ID:
***@***.***>
|
Hey Gabe,
Oh I see what you mean! Right, the rest of the segments are not at equality.
"And what do you mean when you say we change the fuel
usage but not the heat rate? Isn’t the heat rate defined as the fuel usage
per MWh of power generation?"
I mean I will change the name of this module from
setup["PiecewiseHeatRate"] to setup["PiecewiseFuelUsage"], I think "
PiecewiseFuelUsage" sounds more accurate based on the equations we wrote.
On Mon, Aug 28, 2023 at 3:17 PM Gabe Mantegna ***@***.***>
wrote:
… Yes that is what I mean by only one constraint being active. The other
ones
are not at equality. And what do you mean when you say we change the fuel
usage but not the heat rate? Isn’t the heat rate defined as the fuel usage
per MWh of power generation?
On Mon, Aug 28, 2023 at 12:11 Fangwei Cheng ***@***.***>
wrote:
> ***@***.**** commented on this pull request.
> ------------------------------
>
> In src/model/core/fuel.jl
> <#536 (comment)>:
>
> > +
> +The fuel consumption for power generation $vFuel_{y,t}$ is determined
by power generation ($vP_{y,t}$) mutiplied by the corresponding heat rate
($Hear\_Rate_y$).
> +
> +The fuel costs for power generation and start fuel for a plant $y$ at
time $t$, denoted by $eCFuelOut_{y,t}$ and $eFuelStart$, is determined by
fuel consumption ($vFuel_{y,t}$ and $eStartFuel$) multiplied by the fuel
costs (\$/MMBTU)
> +
> +From above formulations, thermal generators are expected to have the
same fuel consumption per generating 1 MWh electricity, regardless of
minimum load or full load. However, thermal generators tend to have
decreased efficiency when operating at part load, leading to higher fuel
consumption per generating the same amount of electricity. To have more
precise representation of fuel consumption at part load, the
piecewise-linear fitting of heat input can be introduced.
> +
> +```math
> +\begin{aligned}
> +vFuel_{y,t} >= vP_{y,t} * h_{y,x} + U_{g,t}* f_{y,x}
> +\hspace{1cm} \forall y \in G, \forall t \in T, \forall x \in X
> +\end{aligned}
> +```
> +Where $h_{y,x}$ represents incremental heat rate of a thermal generator
$y$ in segment $x$ [MMBTU/MWh] and $f_{y,x}$ represents intercept of fuel
consumption of a thermal generator $y$ in segment $x$ [MMBUT], and
$U_{y,t}$ represents the commit status of a thermal generator $y$ at time
$t$. We include at most three segments to represent the piecewise heat
consumption.
> +
> +Since fuel consumption has a positive value, the optimization will
optimize the fuel consumption by enforcing the inequity to equal to the
highest piecewise segment. When the power output is zero, the commitment
variable $U_{g,t}$ will bring the intercept to be zero such that the fuel
consumption is zero when thermal units are offline.
>
> I think all the segments are activated, but only one segment determines
> the fuel consumption at vP (i.e., the optimization will enforce fuel
> consumption to a segment that gives the maximum fuel usage)
> for example,
> segment 1: vFuel >= 6
> *vP + 700; segment 2: vFuel >= 8*vP + 100;
>
> if vP = 200, vFuel in segment1 = 1900, vFuel in segment2 = 1700; then
> vFuel = 1900, heat rate = 9.5
> if vP = 500, vFuel in segment1 = 3700, vFuel in segment2 = 4100, then
> vFuel = 4100, heat rate = 8.2
>
> At the time of writing this, I decided to change "PiecewiseHeatRate" to
> "PiecewiseFuelUsage" as we are actually linearly approximating the fuel
> usage, not the heat rate.
>
> —
> Reply to this email directly, view it on GitHub
> <#536 (comment)>,
or
> unsubscribe
> <
https://github.com/notifications/unsubscribe-auth/AHKPARXVBM5NWYTWZM2CULDXXTUOVANCNFSM6AAAAAA347Q4LU>
> .
> You are receiving this because your review was requested.Message ID:
> ***@***.***>
>
—
Reply to this email directly, view it on GitHub
<#536 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AOEE2AS6ICFVBAGTCTMEVE3XXTVFHANCNFSM6AAAAAA347Q4LU>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
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
There was a problem hiding this 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.
revise the description for biomass. some minor revision on comments for better clarity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Example_Systems/PiecewiseFuel_CO2_Example/Settings/genx_settings.yml
Outdated
Show resolved
Hide resolved
…stent with cap_size
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)]) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 .|
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
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]