Hydrogen Supply Chain Policies

Dolphyn.co2_cap_hscMethod
co2_cap_hsc(EP::Model, inputs::Dict, setup::Dict)

This policy constraints mimics the CO$_2$ emissions cap and permit trading systems, allowing for emissions trading across each zone for which the cap applies. The constraint $p \in \mathcal{P}^{CO_2}$ can be flexibly defined for mass-based or rate-based emission limits for one or more model zones, where zones can trade CO$_2$ emissions permits and earn revenue based on their CO$_2$ allowance. Note that if the model is fully linear (e.g. no unit commitment or linearized unit commitment), the dual variable of the emissions constraints can be interpreted as the marginal CO$_2$ price per tonne associated with the emissions target. Alternatively, for integer model formulations, the marginal CO$_2$ price can be obtained after solving the model with fixed integer/binary variables.

The CO$_2$ emissions limit can be defined in one of the following ways: a) a mass-based limit defined in terms of annual CO$_2$ emissions budget (in million tonnes of CO2), b) a load-side rate-based limit defined in terms of tonnes CO$_2$ per MWh of demand and c) a generation-side rate-based limit defined in terms of tonnes CO$_2$ per MWh of generation.

Mass-based emissions constraint

Mass-based emission limits are implemented in the following expression. For each constraint, $p \in \mathcal{P}^{CO_2}_{mass}$, we define a set of zones $z \in \mathcal{Z}^{CO_2}_{p,mass}$ that can trade CO$_2$ allowance. Input data for each constraint $p \in \mathcal{P}^{CO_2}_{mass}$ requires the CO$_2$ allowance/ budget for each model zone, $\epsilon^{CO_{2}}_{z,p, mass}$, to be provided in terms of million metric tonnes. For every generator $y$, the parameter $\epsilon_{y,z}^{CO_2}$ reflects the specific $CO_2$ emission intensity in tCO$_2$/MWh associated with its operation. The resulting constraint is given as:

\[\begin{aligned} \sum_{z \in \mathcal{Z}^{CO_2}_{p,mass}} \sum_{y \in \mathcal{G}} \sum_{t \in \mathcal{T}} \left(\epsilon_{y,z}^{CO_2} \times \omega_t \times \Theta_{y,z,t} \right) & \leq \sum_{z \in \mathcal{Z}^{CO_2}_{p,mass}} \epsilon^{CO_{2}}_{z,p, mass} \hspace{1 cm} \forall p \in \mathcal{P}^{CO_2}_{mass} \end{aligned}\]

In the above constraint, we include both power discharge and charge term for each resource to account for the potential for CO$_2$ emissions (or removal when considering negative emissions technologies) associated with each step. Note that if a limit is applied to each zone separately, then the set $\mathcal{Z}^{CO_2}_{p,mass}$ will contain only one zone with no possibility of trading. If a system-wide emission limit constraint is applied, then $\mathcal{Z}^{CO_2}_{p,mass}$ will be equivalent to a set of all zones.

Load-side rate-based emissions constraint

We modify the right hand side of the above mass-based constraint, $p \in \mathcal{P}^{CO_2}_{load}$, to set emissions target based on a CO$_2$ emission rate limit in tCO$_2$/MWh $\times$ the total demand served in each zone. In the following constraint, total demand served takes into account non-served energy and storage related losses. Here, $\epsilon_{z,p,load}^{maxCO_2}$ denotes the emission limit in terms on tCO$_2$/MWh.

\[\begin{aligned} \sum_{z \in \mathcal{Z}^{CO_2}_{p,load}} \sum_{y \in \mathcal{G}} \sum_{t \in \mathcal{T}} \left(\epsilon_{y,z}^{CO_2} \times \omega_t \times \Theta_{y,t,z} \right) \leq & \sum_{z \in \mathcal{Z}^{CO_2}_{p,load}} \sum_{t \in \mathcal{T}} \left(\epsilon_{z,p,load}^{CO_2} \times \omega_t \times D_{z,t} \right) \\ + & \sum_{z \in \mathcal{Z}^{CO_2}_{p,load}} \sum_{y \in \mathcal{O}} \sum_{t \in \mathcal{T}} \left(\epsilon_{z,p,load}^{CO_2} \times \omega_t \times \left(\Pi_{y,t,z} - \Theta_{y,t,z} \right) \right) \\ - & \sum_{z \in \mathcal{Z}^{CO_2}_{p,load}} \sum_{s \in \mathcal{S} } \sum_{t \in \mathcal{T}} \left(\epsilon_{z,p,load}^{CO_2} \times \omega_t \times \Lambda_{s,z,t}\right) \hspace{1 cm} \forall p \in \mathcal{P}^{CO_2}_{load} \end{aligned}\]

Generator-side emissions rate-based constraint

Similarly, a generation based emission constraint is defined by setting the emission limit based on the total generation times the carbon emission rate limit in tCO$_2$/MWh of the region. The resulting constraint is given as:

\[\begin{aligned} \sum_{z \in \mathcal{Z}^{CO_2}_{p,gen}} \sum_{y \in \mathcal{G}} \sum_{t \in \mathcal{T}} & \left(\epsilon_{y,z}^{CO_2} \times \omega_t \times \Theta_{y,t,z} \right) \\ \leq \sum_{z \in \mathcal{Z}^{CO_2}_{p,gen}} \sum_{y \in \mathcal{G}} \sum_{t \in \mathcal{T}} & \left(\epsilon_{z,p,gen}^{CO_2} \times \omega_t \times \Theta_{y,t,z} \right) \quad \forall p \in \mathcal{P}^{CO_2}_{gen} \end{aligned}\]

Note that the generator-side rate-based constraint can be used to represent a fee-rebate (``feebate'') system: the dirty generators that emit above the bar ($\epsilon_{z,p,gen}^{maxCO_2}$) have to buy emission allowances from the emission regulator in the region $z$ where they are located; in the same vein, the clean generators get rebates from the emission regulator at an emission allowance price being the dual variable of the emissions rate constraint.

Dolphyn.time_matching_requirementMethod
time_matching_requirement(EP::Model, inputs::Dict, setup::Dict)

This function establishes constraints that require electricity consumption from certain hydrogen resource groups to be matched by electricity generated using a specific set of electricity resources over a pre-specified time period. Such a time-matching requirement (TMR) mimics the contracting of clean energy resources for hydrogen production, which being contemplated to qualify for tax credits for hydrogen production. TMR contraints can be established on either an hourly-matching basis, or an annual-matching basis.

To implement these constraints, the user needs to specify TMR groups in both the hydrogen and electiricty generation resource files. This is done by adding a column H2TMR followed by the group number (e.g. H2TMR1) to the HSCgeneration.csv file and the generation.csv file. Resources that belong to the group should be marked with a "1" in the coresponding entry in the column of the group.

We define a set of TMR policy constraints $p \in \mathcal{P}^{TMR}$. For each constraint we define a subset of hydrogen production resources $g \in \mathcal{G}^{H2, TMR}_{p}$, power generation resources $g \in \mathcal{G}^{E, TMR}_{p}$, and power storage resources $s \in \mathcal{S}^{E, TMR}_{p}$. These set of resources are resources allowed to participate in the fulfilment for TMR requirment constraint, $p$. For each constraint $p \in \mathcal{P}^{TMR}$, we define a subset of zones $z \in \mathcal{Z}^{H,ESR}_{p}$, corresponding to the eligible H2 production resources and a subset of zones $z \in \mathcal{Z}^{E,ESR}_{p}$ corresponding to the set of eligible electricity sector resources.

The expression $TMR Excess Energy_{p, t}$ calculates the differences between electricity generation from resources in $set \mathcal{G}^{E, TMR}_{p}$ + net electricity storage discharge (discharge - charge) for resources in set $\mathcal{S}^{E, TMR}_{p}$ and the electricity consumption by hydrogen production resources in $set \mathcal{G}^{H2, TMR}_{p}$ (given by variable $x_{g,z,t}^{\textrm{E,H-Gen}}$).

\[\begin{equation*} {TMR Excess Energy_{p, t}} = \sum_{z in \in \mathcal{Z}^{E,ESR}_{p}} \sum_{g \in \mathcal{G}^{H2, TMR}_{p}} x_{g,z,t}^{\textrm{E,GEN}} + \sum_{z in \in \mathcal{Z}^{E,ESR}_{p}} \sum_{s \in \mathcal{S}^{E, TMR}_{p}} x_{s,z,t}^{\textrm{E,DIS}}- \sum_{z in \in \mathcal{Z}^{E,ESR}_{p}} \sum_{s \in \mathcal{S}^{E, TMR}_{p}} x_{s,z,t}^{\textrm{E,CHA}}- \sum_{z in \in \mathcal{Z}^{H,ESR}_{p}} \sum_{g \in \mathcal{G}^{H, TMR}_{p}} x_{g,z,t}^{\textrm{E,H-Gen}} \end{equation*}\]

\[\forall {p \in \mathcal{P}^{TMR}}\]

When the parameter TimeMatchingRequirement is set to 1, we implement the following constraint to simulate hourly time-matching where electricity resources are allowed to produce in excess of demand for H$_2$ production that can be sold to the grid (i.e. excess sales allowed):

\[\begin{equation*} {TMR Excess Energy_{p, t}} >= 0 \; \forall \; p^{TMR} \in P, t \in T \end{equation*}\]

When the parameter TimeMatchingRequirement is set to 2, we implement the following constraint to simulate hourly time-matching with no excess sales:

\[\begin{equation*} {TMR Excess Energy_{p, t}} = 0 \; \forall \; p^{TMR} \in P, t \in T \end{equation*}\]

When the parameter TimeMatchingRequirement is set to 3, we implement the following constraint to simulate annual time-matching:

\[\begin{equation*} \sum_{t \in T} {TMR Excess Energy_{p, t} \times \Omega_t} = 0 \; \forall \; p^{TMR} \in P \end{equation*}\]

Notice that in the annual time-matching case, the electricity sector resources can produce in excess of electricity demand for hydrogen production at each time step, so long as the annual sum of production and generation match. The $\Omega_t$ corresponds to time-weight of each time step which will be different from 1 when considering representative periods of system operation rahter than full year operation at an hourly resolution.

In addition, when EnergyShareRequirement is set to 1, excess sales from a given TMR group is added to the corresponding ESR constraint the TMR group maps to.

Hydrogen Resources Investment

Dolphyn.h2_investmentMethod
h2_investment(EP::Model, inputs::Dict, UCommit::Int, Reserves::Int)

Sets up constraints common to all hydrogen generation resources.

This function defines the expressions and constraints keeping track of total available generation capacity $y_{k}^{\textrm{H,GEN}}$ as well as constraints on capacity retirements.

This function defines the expressions and constraints keeping track of total available storage discharge capacity $y_{s}^{\textrm{\textrm{H,STO},DIS}}$ as well as constraints on capacity retirements.

The expression defined in this file named after eH2GenTotalCap covers all variables $y_{k}^{\textrm{H,THE}}, y_{s}^{\textrm{\textrm{H,STO},DIS}}$.

\[\begin{equation*} y_{g, z}^{\textrm{H,GEN}} = \begin{cases} y_{k, z}^{\textrm{H,THE}} \quad if \quad g \in \mathcal{K} \\ y_{s, z}^{\textrm{\textrm{H,STO},DIS}} \quad if \quad g \in \mathcal{S} \end{cases} \quad \forall g \in \mathcal{G}, z \in \mathcal{Z} \end{equation*}\]

This module additionally defines contributions to the objective function from variable costs of generation (variable OM plus fuel cost) from all resources over all time periods.

The total capacity of each resource (SMR, storage, electrolysis) is defined as the sum of the existing capacity plus the newly invested capacity minus any retired capacity. Note for energy storage resources in hydrogen sector, additional energy and charge capacity decisions and constraints are defined in the storage module.

\[\begin{equation*} \begin{split} y_{g, z}^{\textrm{H,GEN}} &= y_{g}^{\textrm{H,GEN,total}} \\ & = y_{g, z}^{\textrm{H,GEN,existing}} + y_{g, z}^{\textrm{H,GEN,new}} - y_{g, z}^{\textrm{H,GEN,retired}} \end{split} \quad \forall g \in \mathcal{G}, z \in \mathcal{Z} \end{equation*}\]

Cost expressions

This module additionally defines contributions to the objective function from investment costs of generation (fixed O\&M plus investment costs) from all generation resources $g \in \mathcal{G}$:

\[\begin{equation*} \textrm{C}^{\textrm{H,GEN,c}} = \sum_{g \in \mathcal{G}} \sum_{z \in \mathcal{Z}} y_{g, z}^{\textrm{H,GEN,new}}\times \textrm{c}_{g}^{\textrm{H,INV}} + \sum_{g \in \mathcal{G}} \sum_{z \in \mathcal{Z}} y_{g, z}^{\textrm{H,GEN,total}} \times \textrm{c}_{g}^{\textrm{H,FOM}} \end{equation*}\]

Constraints on generation discharge capacity

One cannot retire more capacity than existing capacity.

\[\begin{equation*} 0 \leq y_{g, z}^{\textrm{H,GEN,retired}} \leq y_{g, z}^{\textrm{H,GEN,existing}} \quad \forall g \in \mathcal{G}, z \in \mathcal{Z} \end{equation*}\]

Non-served Hydrogen

Dolphyn.h2_non_servedMethod
h2_non_served(EP::Model, inputs::Dict, setup::Dict)

This function defines the non-served hydrogen demand decision variable $x_{s,z,t}^{\textrm{H,NSD}} \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}$, representing the total amount of hydrogen demand curtailed in demand segment $s$ at time period $t$ in zone $z$. The first segment of non-served hydrogen, $s=1$, is used to denote the cost of involuntary hydrogen demand curtailment, specified as the value of $c_{1}^{\textrm{H,NSD}}$. Additional segments, $s \geq 2$ can be used to specify a segment-wise approximation of a price elastic hydrogen demand curve, or segments of price-responsive curtailable hydrogen loads. Each segment denotes a price/cost at which the segment of hydrogen demand is willing to curtail consumption, $\textrm{n}_{s}^{\textrm{H,NSD}}$, representing the marginal willingness to pay for hydrogen demand of this segment of demand (or opportunity cost incurred when demand is not served) and a maximum quantity of demand in this segment, $\textrm{n}_{s}^{\textrm{H,NSD}}$, specified as a share of hydrogen demand in each zone in each time step, $\textrm{D}_{z, t}^{\textrm{H}}$. Note that the current implementation assumes demand segments are an equal share of hourly load in all zones.

The variable defined in this file named after vH2NSE covers the variable $x_{s,z,t}^{\textrm{H,NSD}}$.

Cost expressions

This function defines contributions to the objective function from the cost of non-served hydrogen/curtailed hydrogen from all demand curtailment segments $s \in \mathcal{SEG}$ over all time periods $t \in \mathcal{T}$ and all zones $z \in \mathcal{Z}$:

\[\begin{equation*} \textrm{C}^{\textrm{H,NSD},o} = \sum_{s \in \mathcal{SEG}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} \omega_t \times \textrm{n}_{s}^{\textrm{H,NSD}} \times x_{s,z,t}^{\textrm{H,NSD}} \end{equation*}\]

Contributions to the hydrogen balance expression from non-served hydrogen/curtailed hydrogen from each demand segment $s \in \mathcal{SEG}$ are also defined as:

\[\begin{equation*} HydrogenBal_{NSE} = \sum_{s \in \mathcal{SEG}} x_{s,z,t}^{\textrm{H,NSD}} \quad \forall z \in \mathcal{Z}, t \in \mathcal{T} \end{equation*}\]

Bounds on curtailable hydrogen demand

Hydrogen demand curtailed in each segment of curtailable demands $s \in \mathcal{SEG}$ cannot exceed maximum allowable share of hydrogen demand:

\[\begin{equation*} x_{s,z,t}^{\textrm{H,NSD}} \leq \textrm{n}_{s}^{\textrm{H,NSD}} \times \textrm{D}_{z,t}^{\textrm{H}} \quad \forall s \in \mathcal{SEG}, z \in \mathcal{Z}, t \in \mathcal{T} \end{equation*}\]

Additionally, total demand curtailed in each time step cannot exceed total hydrogen demand:

\[\begin{equation*} \sum_{s \in \mathcal{SEG}} x_{s,z,t}^{\textrm{H,NSD}} \leq \textrm{D}_{z,t}^{\textrm{H}} \quad \forall z \in \mathcal{Z}, t \in \mathcal{T} \end{equation*}\]

Hydrogen Output

Dolphyn.h2_outputsMethod
h2_outputs(EP::Model, inputs::Dict, setup::Dict)

Sets up variables common to all hydrogen generation resources.

This module defines the hydrogen generation decision variable $x_{k,z,t}^{\textrm{H,GEN}} \forall k \in \mathcal{K}, z \in \mathcal{Z}, t \in \mathcal{T}$, representing hydrogen injected into the grid by hydrogen generation resource $k$ in zone $z$ at time period $t$.

This module defines the gydrogen discharge decision variable $x_{s,z,t}^{\textrm{\textrm{H,DIS}}} \forall s \in \mathcal{S}, z \in \mathcal{Z}, t \in \mathcal{T}$, representing hydrogen injected into the grid by hydrogen storage resource $s$ in zone $z$ at time period $t$.

The variable defined in this file named after vH2Gen covers all variables $x_{k,z,t}^{\textrm{H,GEN}}, x_{s,z,t}^{\textrm{\textrm{H,DIS}}}$.

\[\begin{equation*} x_{g,z,t}^{\textrm{H,GEN}} = \begin{cases} x_{k,z,t}^{\textrm{H,THE}} if g \in \mathcal{K} \\ x_{s,z,t}^{\textrm{\textrm{H,DIS}}} if g \in \mathcal{S} \end{cases} \quad \forall z \in \mathcal{Z}, t \in \mathcal{T} \end{equation*}\]

Cost expressions

This module additionally defines contributions to the objective function from variable costs of generation (variable OM plus fuel cost) from all resources over all time periods.

\[\begin{equation*} \textrm{C}^{\textrm{H,GEN,o}} = \sum_{g \in \mathcal{G}} \sum_{t \in \mathcal{T}} \omega_t \times \left(\textrm{c}_{g}^{\textrm{H,VOM}} + \textrm{c}_{g}^{\textrm{H,FUEL}}\right) \times x_{g,z,t}^{\textrm{H,GEN}} \end{equation*}\]

Emissions

Dolphyn.emissions_hscMethod
emissions_hsc(EP::Model, inputs::Dict, setup::Dict)

This function creates expression to add the CO2 emissions for hydrogen supply chain in each zone, which is subsequently added to the total emissions.

Cost expressions

\[\begin{equation*} \textrm{C}^{\textrm{H,EMI}} = \omega_t \times \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} \textrm{c}_{z}^{\textrm{H,EMI}} x_{z,t}^{\textrm{H,EMI}} \end{equation*}\]