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:
- RefNetworkNodeRetrofitcan be best seen as an existing technology to which CO₂ capture should be fitted.
- CCSRetroFitis 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 RefNetworkNodeRetrofitandCCSRetroFitnodes through aLinkand
- do not include the CO₂ proxy resource (see below) as a product in the Availabilitynode.
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 field- idis only used for providing a name to the node. This is similar to the approach utilized in- EnergyModelsBase.
- cap::TimeProfile:
 The installed capacity corresponds to the potential usage of the node.
 If the node should contain investments through the application of- EnergyModelsInvestments, it is important to note that you can only use- FixedProfileor- StrategicProfilefor the capacity, but not- RepresentativeProfileor- OperationalProfile. 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 specified- outputratios. The variable operating expenses can be provided as- OperationalProfileas well.
- opex_fixed::TimeProfile:
 The fixed operating expenses are relative to the installed capacity (through the field- cap) and the chosen duration of a strategic period as outlined on Utilize- TimeStruct.
 It is important to note that you can only use- FixedProfileor- StrategicProfilefor the fixed OPEX, but not- RepresentativeProfileor- OperationalProfile. 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}and- output::Dict{<:Resource, <:Real}:
 Both fields describe the- inputand- output- Resources 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 the- outputdictionary through providing additional methods to- EMB.outputs.
- CCSRetroFit:
 The CO₂ proxy resource is automatically included in the- inputdictionary through providing additional methods to- EMB.inputs. Requires the incorporation of the CO₂ resource in the- outputdictionary, 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. The- datavector must include- CaptureDatafor both- RefNetworkNodeRetrofitand- CCSRetroFit. It can include additional investment data when- EnergyModelsInvestmentsis 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 the- CCSRetroFitnode. 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 as- ResourceCarrierwith 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_installedis also used in- EnergyModelsInvestmentsto 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 both- CCSRetroFitand- RefNetworkNodeRetrofit. 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 ResourceEmits, 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.