CO₂ capture retrofit
A specific CO₂ source node is required as the default implementation of a RefSource
does not allow for the CO₂ instance to be an output, as declared in the function constraints_flow_out
. This is due to the implementation using CaptureData
in which the CO₂ oulet flow is calculated through the implementation of the capture rate.
Hence, it is necessary to implement a CO₂ source node if one wants to model only a CO₂ source.
Introduced type and its field
CO₂ capture retrofit requires the implementation of two additional node types, RefNetworkNodeRetrofit
and CCSRetroFit
both nodes are quite similar to a RefNetworkNode
although their application differs:
RefNetworkNodeRetrofit
can be best seen as an existing technology to which CO₂ capture should be fitted.CCSRetroFit
is the CO₂ capture unit.
It is necessary to include both RefNetworkNodeRetrofit
and CCSRetroFit
if one wants to implement the additional installation of CO₂ capture. It is not possible to only use one of them.
If you want to include several retrofit options, it is of absolute importance that you:
- directly couple the
RefNetworkNodeRetrofit
andCCSRetroFit
nodes through aLink
and - do not include the CO₂ proxy resource (see below) as a product in the
Availability
node.
It would be otherwise possible to use a single CO₂ capture unit for all process with the option for retrofit, neglecting potential peak capacity requirements and economies of scale.
Standard fields
Both introduced nodes use the same fields, although their meaning may potentially differ. The standard fields are given as:
id
:
The fieldid
is only used for providing a name to the node. This is similar to the approach utilized inEnergyModelsBase
.cap::TimeProfile
:
The installed capacity corresponds to the potential usage of the node.
If the node should contain investments through the application ofEnergyModelsInvestments
, it is important to note that you can only useFixedProfile
orStrategicProfile
for the capacity, but notRepresentativeProfile
orOperationalProfile
. In addition, all values have to be non-negative.Meaning in boths nodes RefNetworkNodeRetrofit
:
The capacity corresponds to the production capacity of a process.CCSRetroFit
:
The capacity corresponds to the CO₂ flow rate handling capacity, not the CO₂ capture capacity
opex_var::TimeProfile
:
The variable operational expenses are based on the capacity utilization through the variable:cap_use
. Hence, it is directly related to the specifiedoutput
ratios. The variable operating expenses can be provided asOperationalProfile
as well.opex_fixed::TimeProfile
:
The fixed operating expenses are relative to the installed capacity (through the fieldcap
) and the chosen duration of a strategic period as outlined on UtilizeTimeStruct
.
It is important to note that you can only useFixedProfile
orStrategicProfile
for the fixed OPEX, but notRepresentativeProfile
orOperationalProfile
. In addition, all values have to be non-negative.Meaning in boths nodes RefNetworkNodeRetrofit
:
The variable OPEX is relative to the production of the main product.CCSRetroFit
:
The variable OPEX is relative to the amount of flue gas handled, that is not the amount of CO₂ captured.
input::Dict{<:Resource, <:Real}
andoutput::Dict{<:Resource, <:Real}
:
Both fields describe theinput
andoutput
Resource
s with their corresponding conversion factors as dictionaries.
All values have to be non-negative.Meaning in boths nodes RefNetworkNodeRetrofit
:
No special meaning. The CO₂ proxy resource is automatically included in theoutput
dictionary through providing additional methods toEMB.outputs
.CCSRetroFit
:
The CO₂ proxy resource is automatically included in theinput
dictionary through providing additional methods toEMB.inputs
. Requires the incorporation of the CO₂ resource in theoutput
dictionary, although the exact value is not relevant. It is furthermore possible to specify additional reenergy required for capturing CO₂ using a conversion factor (e.g., MWh/t CO₂).
data::Vector{Data}
:
An entry for providing additional data to the model. Thedata
vector must includeCaptureData
for bothRefNetworkNodeRetrofit
andCCSRetroFit
. It can include additional investment data whenEnergyModelsInvestments
is used.Meaning of the capture rate in both nodes RefNetworkNodeRetrofit
:
The capture rate corresponds to the fraction of the flue gas which is sent to theCCSRetroFit
node. Hence, if the value is below 1, only a fraction of the flue gas can be captured.CCSRetroFit
:
The capture rate corresponds to- the fraction captured from the flue gas (
CaptureFlueGas
), - the fraction captured from the flue gas and the energy input to the unit (
CaptureEnergyEmissions
), - the fraction captured from the flue gas and the process emissions (
CaptureProcessEmissions
), or - the fraction captured from the flue gas, the energy input to the unit, and the process emissions (
CaptureProcessEnergyEmissions
)
- the fraction captured from the flue gas (
Additional fields
Both introduced nodes have one additional field:
co2_proxy::Resource
:
The CO₂ proxy resource is introduced to simplify the analyses and seperate all streams corresponding to CO₂ from the CO₂ streams considered in CO₂ capture retrofit. It should be specified asResourceCarrier
with a CO₂ intensity of 0.
Mathematical description
In the following mathematical equations, we use the name for variables and functions used in the model. Variables are in general represented as
$\texttt{var\_example}[index_1, index_2]$
with square brackets, while functions are represented as
$func\_example(index_1, index_2)$
with paranthesis.
Variables
Standard variables
Both introduced nodes utilize all standard variables from the RefNetworkNode
, as described on the page Optimization variables. The variables include:
- $\texttt{opex\_var}$
- $\texttt{opex\_fixed}$
- $\texttt{cap\_use}$
- $\texttt{cap\_inst}$
- $\texttt{flow\_in}$
- $\texttt{flow\_out}$
- $\texttt{emissions\_node}$
Additional variables
Both introduced nodes do not add additional variables.
Constraints
The following sections omit the direct inclusion of the vector of any node. Instead, it is implicitly assumed that the constraints are valid $\forall n ∈ N$ for all RefNetworkNodeRetrofit
or CCSRetroFit
types if not stated differently. In addition, all constraints are valid $\forall t \in T$ (that is in all operational periods) or $\forall t_{inv} \in T^{Inv}$ (that is in all strategic periods).
Standard constraints
Both introduced nodes utilize in general the standard constraints described on Constraint functions. These standard constraints are:
constraints_capacity
:\[\texttt{cap\_use}[n, t] \leq \texttt{cap\_inst}[n, t]\]
constraints_capacity_installed
:\[\texttt{cap\_inst}[n, t] = capacity(n, t)\]
Using investments The function
constraints_capacity_installed
is also used inEnergyModelsInvestments
to incorporate the potential for investment. Nodes with investments are then no longer constrained by the parameter capacity.constraints_flow_in
:\[\texttt{flow\_in}[n, t, p] = inputs(n, p) \times \texttt{cap\_use}[n, t] \qquad \forall p \in inputs(n)\]
This standard constraint is only included for `RefNetworkNodeRetrofit`. constraints_flow_out
:\[\texttt{flow\_out}[n, t, p] = outputs(n, p) \times \texttt{cap\_use}[n, t] \qquad \forall p \in outputs(n) \setminus \{\text{CO}_2\}\]
This standard constraint is only included for `CCSRetroFit`. constraints_opex_fixed
:\[\texttt{opex\_fixed}[n, t_{inv}] = opex\_fixed(n, t_{inv}) \times \texttt{cap\_inst}[n, first(t_{inv})]\]
Why do we use `first()` The variable $\texttt{cap\_inst}$ is declared over all operational periods (see the section on Capacity variables for further explanations). Hence, we use the function $first(t_{inv})$ to retrieve the installed capacity in the first operational period of a given strategic period $t_{inv}$ in the function
constraints_opex_fixed
.constraints_opex_var
:\[\texttt{opex\_var}[n, t_{inv}] = \sum_{t \in t_{inv}} opex_var(n, t) \times \texttt{cap\_use}[n, t] \times scale\_op\_sp(t_{inv}, t)\]
The function `scale_op_sp` The function $scale\_op\_sp(t_{inv}, t)$ calculates the scaling factor between operational and strategic periods. It also takes into account potential operational scenarios and their probability as well as representative periods.
constraints_data
:
This function is only called for specified data of the nodes, see above. This function is extended with multiple methods for bothCCSRetroFit
andRefNetworkNodeRetrofit
. The individual methods are explained below.
The outlet flow constraint for a RefNetworkNodeRetrofit
node is requires introducing new methods for the function constraints_flow_out
as the outlet flow of the CO₂ proxy is calculated in the function constraints_data
as outlined in Standard constraints. This constraint is given by:
\[\texttt{flow\_out}[n, t, p] = outputs(n, p) \times \texttt{cap\_use}[n, t] \qquad \forall p \in outputs(n) \setminus \{co2\_proxy(n)\}\]
The introduction of the CO₂ capture unit as retrofit option requires introducing new methods for the function constraints_data
for all CaptureData
as described on Data functions. In all methods, the process emissions of the other ResourceEmit
s, that is all emissions resources except for CO₂, are calculated as
\[\begin{aligned} \texttt{emissions\_node}&[n, t, p_{em}] = \\ & \texttt{cap\_use}[n, t] \times process\_emissions(data, p_{em}, t) \qquad \forall p_{em} \in P^{em} \setminus \{\text{CO}_2\} \end{aligned}\]
RefNetworkNodeRetrofit
introduces methods for CaptureProcessEmissions
, CaptureEnergyEmissions
, and CaptureProcessEnergyEmissions
.
The total produced CO₂ is calculated through an auxiliary expression as
\[ CO2\_tot[n, t] = \texttt{cap\_use}[n, t] \times process\_emissions(data, \text{CO}_2, t)\]
This auxiliary variable is subsequently used to calculate the CO₂ emissions of the node as
\[\begin{aligned} \texttt{emissions\_node}&[n, t, \text{CO}_2] = \\ & (1-co2\_capture(data)) \times CO2\_tot[n, t] + \\ & \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}] \end{aligned}\]
The total produced CO₂ is calculated through an auxiliary expression as
\[ CO2\_tot[n, t] = \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}]\]
This auxiliary variable is subsequently used to calculate the CO₂ emissions of the node as
\[\begin{aligned} \texttt{emissions\_node}&[n, t, \text{CO}_2] = \\ & (1-co2\_capture(data)) \times CO2\_tot[n, t] + \\ & \texttt{cap\_use}[n, t] \times process\_emissions(data, \text{CO}_2, t) \end{aligned}\]
The total produced CO₂ is calculated through an auxiliary expression as
\[\begin{aligned} CO2\_tot&[n, t] = \\ & \texttt{cap\_use}[n, t] \times process\_emissions(data, \text{CO}_2, t) + \\ & \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}] \end{aligned}\]
This auxiliary variable is subsequently used to calculate the CO₂ emissions of the node as
\[\begin{aligned} \texttt{emissions\_node}&[n, t, \text{CO}_2] = \\ & (1-co2\_capture(data)) \times CO2\_tot[n, t] + \\ & \end{aligned}\]
These constraints are the same as it is the case for other nodes. The only difference is the calculation of the the outlet flow of the CO₂ proxy resource. It is for all CaptureData
calculated as
\[ \texttt{flow\_out}[n, t, co2\_proxy(n)] = CO2\_tot[n, t] * co2\_capture(data)\]
CCSRetroFit
introduces methods for CaptureFlueGas
, CaptureProcessEmissions
, CaptureEnergyEmissions
, and CaptureProcessEnergyEmissions
.
All types utilize similar functions although there is a variation in the individual calculations. The model introduces two auxiliaty expressiones, $CO2\_tot_[n, t]$ and $CO2\_captured[n, t]$. $CO2\_tot_[n, t]$ representes the total produced CO₂ (flue gas from the RefNetworkNodeRetrofit
and potentially energy usage related emissions and/or process emissions) in the capture unit. Hence, its calculation differes depending on the CaptureData
. $CO2\_captured[n, t]$ is calculated as:
\[ CO2\_captured[n, t] = co2\_capture(data) \times CO2\_tot[n, t]\]
The CO₂ emissions are calculated for all types using the auxiliary variable $CO2\_captured[n, t]$ as
\[\begin{aligned} \texttt{emissions\_node}&[n, t, \text{CO}_2] = \\ & \texttt{flow\_in}[n, t, co2\_proxy(n)] + \\ & \texttt{cap\_use}[n, t] \times process\_emissions(data, \text{CO}_2, t) + \\ & \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}] - \\ & CO2\_captured[n, t] \end{aligned}\]
while the CO₂ outlet flow is given as:
\[ \texttt{flow\_out}[n, t, \text{CO}_2] = CO2\_captured[n, t]\]
The total produced CO₂ is calculated as
\[ CO2\_tot[n, t] = \texttt{cap\_use}[n, t]\]
In addition, we have to provide an upper limit on the outlet CO₂ flow to avoid achieving a higher capture rate than specified when the capture unit is dimensioned for a larger CO₂ proxy inlet flow rate:
\[\begin{aligned} \texttt{flow\_out}&[n, t, \text{CO}_2] \leq \\ & co2\_capture(data) \times \\ & \texttt{flow\_in}[n, t, co2\_proxy(n)] \end{aligned}\]
The total produced CO₂ is calculated as
\[\begin{aligned} CO2\_tot&[n, t] = \\ & \texttt{cap\_use}[n, t] \times (1 + process\_emissions(data, \text{CO}_2, t)) \end{aligned}\]
In addition, we have to provide an upper limit on the outlet CO₂ flow to avoid achieving a higher capture rate than specified when the capture unit is dimensioned for a larger CO₂ proxy inlet flow rate:
\[\begin{aligned} \texttt{flow\_out}&[n, t, \text{CO}_2] \leq \\ & co2\_capture(data) \times \\ & (\texttt{flow\_in}[n, t, co2\_proxy(n)] + \\ & \texttt{cap\_use}[n, t] \times process\_emissions(data, \text{CO}_2, t)) \end{aligned}\]
The total produced CO₂ is calculated as
\[\begin{aligned} CO2\_tot&[n, t] = \\ & \texttt{cap\_use}[n, t] + \\ & \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}] \end{aligned}\]
In addition, we have to provide an upper limit on the outlet CO₂ flow to avoid achieving a higher capture rate than specified when the capture unit is dimensioned for a larger CO₂ proxy inlet flow rate:
\[\begin{aligned} \texttt{flow\_out}&[n, t, \text{CO}_2] \leq \\ & co2\_capture(data) \times \\ & (\texttt{flow\_in}[n, t, co2\_proxy(n)] + \\ & \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}]) \end{aligned}\]
The total produced CO₂ is calculated through an auxiliary expression as
\[\begin{aligned} CO2\_tot&[n, t] = \\ & \texttt{cap\_use}[n, t] \times (1 + process\_emissions(data, \text{CO}_2, t)) + \\ & \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}] \end{aligned}\]
This auxiliary variable is subsequently used to calculate the CO₂ emissions of the node as
\[\begin{aligned} \texttt{flow\_out}&[n, t, \text{CO}_2] \leq \\ & co2\_capture(data) \times \\ & (\texttt{flow\_in}[n, t, co2\_proxy(n)] + \\ & \texttt{cap\_use}[n, t] \times process\_emissions(data, \text{CO}_2, t) + \\ & \sum_{p_{in} \in P^{in}} co2\_int(p_{in}) \times \texttt{flow\_in}[n, t, p_{in}]) \end{aligned}\]
Additional constraints
Constraints calculated in create_node
The inlet flow constraint for a CCSRetroFit
node is calculated separately as the inlet flow of the CO₂ proxy is calculated in the function constraints_data
as outlined in Standard constraints. This constraint is given by:
\[\texttt{flow\_in}[n, t, p] = inputs(n, p) \times \texttt{cap\_use}[n, t] \qquad \forall p \in inputs(n) \setminus \{co2\_proxy(n)\}\]
Constraints through separate functions
Neither RefNetworkNodeRetrofit
nor CCSRetroFit
nodes introduce new functions.