Public Interface
This page lists the main user-facing types and controls added by EnergyModelsGasNetworks.
Controls
EnergyModelsGasNetworks.set_step_pressure! — Function
set_step_pressure!(step_pressure)Set the spacing of the pressures used to generate piecewise-affine Weymouth cuts for blended gases. Default is 10 (e.g., bars).
EnergyModelsGasNetworks.set_optimizer_pwa! — Function
set_optimizer_pwa!(opt)Set the optimizer used by EnergyModelsGasNetworks for PWA approximations.
EnergyModelsGasNetworks.set_clamp_pwa_intercepts! — Function
set_clamp_pwa_intercepts!(clamp::Bool)Control whether the intercept β of each PWA plane is clamped to min(0, β) after the piecewise-affine approximation is obtained (either freshly fitted or loaded from the on-disk cache).
Background
The Weymouth PWA is fitted over the physical pressure domain [POut, PIn] barg. In bidirectional networks, reverse links are represented as CapDirect links. When a reverse link is inactive (has_flow[l, t] = 0), the constraints in constraints_balance_pressure force both link_potential_in and link_potential_out to zero via big-M bounds. The PWA constraint (one inequality per plane k) then evaluates at the origin:
link_in ≤ -dot(plane.α, (0, 0, proportion_track)) - plane.βWith link_in = 0 (inactive link) and proportion_track = 0 (CH4-only network, no H2 injection), this simplifies to:
0 ≤ -plane.βIf any plane has plane.β > 0 — which can occur due to linear extrapolation outside the [POut, PIn] fitting domain — this constraint is infeasible.
What clamping does
Clamping sets β_k ← min(0, β_k) for every plane in the fitted PWA. This is mathematically safe:
- The outer (concave) approximation property is preserved. Making
β_ksmaller (more negative or zero) increases-β_k, which loosens the upper bound onlink_in. Since the original PWA already satisfiesapprox(x) ≥ f(x)on the fitting domain, a looser upper bound still satisfies this property. - The accuracy loss in the physical operating range
[POut, PIn]is negligible: the linear termsdot(α_k, (p_in, p_out, alpha))dominate at typical pressures of 30–72 barg, so a small upward shift of-β_khas minimal effect on solution quality. - Clamping eliminates the infeasibility entirely: after clamping,
0 ≤ -β_kholds for all planes by construction.
When to disable
Set clamp = false only for:
- Research or diagnostic runs to measure the raw effect of the PWA intercepts.
- Networks where all links are guaranteed to always have
has_flow = 1(no inactive reverse links), making clamping unnecessary. - Benchmarking the impact of clamping on solution quality.
When clamp = false the model may become infeasible in bidirectional Blend networks without H2 injection if any fitted plane has a positive intercept.
Default
true (clamping is enabled).
EnergyModelsGasNetworks.get_clamp_pwa_intercepts — Function
get_clamp_pwa_intercepts() -> BoolReturn whether PWA plane intercepts are clamped to β ≤ 0 after fitting or loading from cache. The default is true.
See set_clamp_pwa_intercepts! for a full explanation.
EnergyModelsGasNetworks.delete_cache — Function
delete_cache()Deletes all files in the cache directory. Use with caution, as this will remove all cached PWA approximations.
Resources and blends
EnergyModelsGasNetworks.ResourcePressure — Type
ResourcePressure{T<:Real} <: CompoundResourceResource with an associated pressure potential in addition to a flow rate.
Fields
idis the name/identifier of the resource.co2_int::Tis the CO₂ intensity (e.g. t/MWh).
EnergyModelsGasNetworks.ResourcePooling — Type
ResourcePooling{T<:Real} <: EMB.ResourceResource that represents a blend of subresources.
Note! When the subresources are ResourcePressure, the pressure formulation is also activated for the blend. Otherwise, the blend activates only the pooling constraints.
Nodes
EnergyModelsGasNetworks.SimpleCompressor — Type
SimpleCompressor <: CompressorCompressor that adds a pressure increase (potential_Δ) and pays variable cost through an energy input proportional to potential_Δ only:
Power ≥ input[PowerRes] × potential_ΔThe input dict must include both the gas resource (coefficient 1.0) and the energy resource (e.g. Power) whose coefficient is the power-per-bar parameter.
Calibrating the energy coefficient
The constraint Power ≥ c × Δp models compression power as independent of gas flow, which is only realistic when the compressor always operates near its design capacity. For variable flow, prefer FlowPressureCompressor.
Rule of thumb: for single-stage isentropic compression of gas G from pin to pout at design capacity Q_design [MSm³/d] and efficiency η:
P_design [pu] = Q_design × (γ/(γ-1)) × (R/M) × T_in × [(p_out/p_in)^((γ-1)/γ) − 1]
× ρ_std / (3.6×10⁶ × η × pu_MW×10³)where pu_MW is the model's Power-unit in MW. Then set:
c = P_design / Δp_designExample – CH₄, 140 → 167 bar, Q = 300 MSm³/d, η = 0.80:
Using γ = 1.31, R/M = 518 J/(kg·K), ρstd = 0.717 kg/Sm³, Tin = 313 K, puMW = 41.8: Pdesign ≈ 219 pu. At Δp = 27 bar → c = 219 / 27 ≈ 8.1 pu/bar.
The constraint is a lower bound; the optimiser will set Power to the minimum required, which equals c × Δp at the binding constraint.
Fields
id::Anyis the name/identifier of the link.cap::TimeProfileis the maximum flow that the compressor can handle.opex_var::TimeProfileis the variable operational expenditure of the compressor, based on inflow.opex_fixed::TimeProfileis the fixed operational expenditure of the compressor.input::Dict{<:Resource,<:Real}is the input flow into the SimpleCompressor. Include both the inflow resource and the energy resource needed for the potential increase.output::Dict{<:Resource,<:Real}is the output flow from the SimpleCompressor. Only include the outflow resource.max_incr_potential::TimeProfileis the maximum potential increase the SimpleCompressor can provide.
EnergyModelsGasNetworks.FlowPressureCompressor — Type
FlowPressureCompressor <: CompressorCompressor whose power consumption depends linearly on both the gas flow rate and the pressure increase it provides:
Power ≥ flow_weight × cap_use + pressure_weight × potential_ΔThis is physically more accurate than SimpleCompressor (which ignores flow rate) because isentropic compression work scales with mass flow and the pressure ratio.
Physical background and linearisation
The true isentropic shaft power for a single-stage compressor is:
P = Q × (γ/(γ-1)) × (R/M) × T_in × [(p_out/p_in)^((γ-1)/γ) − 1] / η × ρ_std / (3.6×10⁶ × pu_MW×10³)where Q is volumetric flow [MSm³/d], γ the heat-capacity ratio, R/M the specific gas constant [J/(kg·K)], Tin the inlet temperature [K], η the isentropic efficiency, ρstd the gas density at standard conditions [kg/Sm³], and puMW the model Power-unit in MW. This expression is bilinear in Q and a nonlinear function of pout/p_in, so it must be approximated for a linear programme.
Linearisation strategy: choose a representative operating point (Q₀, Δp₀), compute the physical design power P₀, and allocate between the two terms using a split factor s ∈ [0, 1] (fraction attributed to the flow term):
flow_weight = s × P₀ / Q₀ [Power-units / (MSm³/d)]
pressure_weight = (1 − s) × P₀ / Δp₀ [Power-units / bar]A 50/50 split (s = 0.5) is a reasonable default.
Example – H₂ compressor, 30 → 109 bar, 12 MSm³/d, η = 0.75
Using γ = 1.40, R/M = 4124 J/(kg·K), ρstd = 0.0899 kg/Sm³, Tin = 288 K, s = 0.5, P₀ ≈ 0.802 Power-units (33.5 MW), Q₀ = 12 MSm³/d, Δp₀ = 79 bar:
flow_weight = 0.5 × 0.802 / 12 ≈ 0.0334 [Power-units / (MSm³/d)]
pressure_weight = 0.5 × 0.802 / 79 ≈ 0.00507 [Power-units / bar]Physical P₀ = 0.802 Power-units = 33.5 MW.
Compare with the simpler but uncalibrated SimpleCompressor using input[(Power, 0.332)]: P = 0.332 × 79 = 26.2 Power-units = 1096 MW — 33× the physical value.
Fields
id::Anyis the name/identifier of the node.cap::TimeProfileis the maximum gas flow the compressor can handle (MSm³/d).opex_var::TimeProfileis the variable operational expenditure, based on inflow.opex_fixed::TimeProfileis the fixed operational expenditure.input::Dict{<:Resource,<:Real}— include the gas resource and the energy resource (Power).output::Dict{<:Resource,<:Real}— only the outflow gas resource.max_incr_potential::TimeProfileis the maximum pressure increase the compressor can provide (bar).flow_weight::TimeProfileis the power coefficient for gas flow (Power unit per MSm³/d).pressure_weight::TimeProfileis the power coefficient for pressure increase (Power unit per bar).data::Vector{<:ExtensionData}— optional extension data (pressure bounds, investment data, etc.).
EnergyModelsGasNetworks.PoolingNode — Type
PoolingNode <: EMB.NetworkNodeA network junction that mixes incoming gas streams and distributes the blend across two or more outgoing pipeline links, enforcing that every split carries the same blend composition.
Introduces bilinear constraints flow_component[l_out, t, p] = proportion_out[n, t, p] × link_in[l_out, t, blend] for each outgoing blend link l_out. These are the source of MINLP nonlinearity: the proportion_out variable pins the composition ratio across all outputs simultaneously.
Use PoolingNode only when there are at least two outgoing blend links that must share a common composition. For single-output junctions (even those that mix multiple upstream streams), prefer BlendingNode, which uses a fully linear formulation.
For pure pass-through junctions with no gas injection, use TransitNode.
EnergyModelsGasNetworks.DiscretizedPoolingNode — Type
DiscretizedPoolingNode <: EMB.NetworkNodeA MILP-compatible alternative to PoolingNode that replaces the bilinear flow_component = proportion_out × link_in constraint with a piecewise linear approximation using PiecewiseLinearOpt.jl.
Instead of the continuous bilinear product (which requires an MINLP solver such as SCIP), DiscretizedPoolingNode approximates f(u, v) = u × v over a grid of breakpoints for proportion_out ∈ [0, 1] and link_in ∈ [0, F_max]. The default method is :Logarithmic, which introduces ⌈log₂(K−1)⌉ binary variables per product term (K = number of breakpoints).
This allows the gas network to be solved by standard MILP solvers (HiGHS, Gurobi, CPLEX) without any MINLP machinery, at the cost of a bounded approximation error that decreases with more breakpoints.
When to use
- When you want to avoid MINLP solvers.
- When investment decisions make the overall problem a MILP anyway.
- When a moderate approximation error on blend proportions is acceptable.
Breakpoints
Attach a DiscretizationData to data to control the number of breakpoints (default: 5). The piecewise linear approximation is exact at breakpoints and linearly interpolated between them.
Fields
Identical to PoolingNode:
id::Any— node identifiercap::TimeProfile— maximum throughput capacityopex_var::TimeProfile— variable operational expenditureopex_fixed::TimeProfile— fixed operational expenditureinput::Dict{<:Resource,<:Real}— input resource dictionaryoutput::Dict{<:Resource,<:Real}— output resource dictionarydata::Vector{<:Data}— optional data (pressure bounds,DiscretizationData)
See also
PoolingNode for the bilinear (MINLP) formulation, DiscretizationData for controlling the approximation grid.
EnergyModelsGasNetworks.BlendingNode — Type
BlendingNode <: EMB.NetworkNodeA network junction that combines upstream blend streams (and optionally raw H₂/CH₄ injection) into a single outgoing blend link, using a fully linear formulation.
BlendingNode is appropriate whenever a mixing node has exactly one outgoing blend output. Unlike PoolingNode, it does not introduce proportion_out variables or bilinear constraints. The blend composition on the single output is fully determined by the component mass balance (already linear):
flow_component[l_out, t, p] == Σ_{l_in} flow_component[l_in, t, p] + raw_in[n, t, p]Quality bounds (max_h2, min_h2 from RefBlendData) are enforced as linear flow bounds on the output link:
flow_component[l_out, t, H₂] ≤ max_h2 × link_in[l_out, t, Blend]This makes BlendingNode solvable by an LP/MIP solver without any MINLP machinery.
When to use
- Gas supply entry points (single injector → single downstream pipeline).
- Pre-sink collecting nodes (multiple incoming pipelines → single sink connection).
- Any mixing junction that feeds exactly one downstream blend pipeline.
For nodes with two or more outgoing blend links that must share a common composition, use PoolingNode. For pure pass-through junctions with no gas injection, use TransitNode.
Fields
id::Anyis the name/identifier of the node.cap::TimeProfileis the maximum throughput capacity.opex_var::TimeProfileis the variable operational expenditure.opex_fixed::TimeProfileis the fixed operational expenditure.input::Dict{<:Resource,<:Real}is the dict of input resources. TypicallyDict(H2 => 1, CH4 => 1, Blend => 1).output::Dict{<:Resource,<:Real}is the dict of output resources. Must contain exactly oneResourcePoolingblend resource, e.g.Dict(Blend => 1).data::Vector{<:Data}is the vector ofData. Can include pressure bounds (MaxPressureData,MinPressureData,FixPressureData) and quality bounds (RefBlendData).
EnergyModelsGasNetworks.TransitNode — Type
TransitNode <: EMB.NetworkNodeA corridor pass-through junction with no gas injection or extraction.
TransitNode is the node analogue of a Direct link: just as a Direct link propagates pressure unchanged (no Weymouth loss), a TransitNode passes the blend on unchanged. Its component flows are balanced linearly, so inflows from several links mix exactly.
A TransitNode only tracks the share proportion_out if a Weymouth pipe with BlendLinkData reads it through the node (see blend_share_plan). It then copies the share of its upstream nodes with a linear equality proportionout[n, t, p] == proportionout[upstream, t, p] which requires simultaneously active inflows to have the same composition.
A TransitNode sends blend down at most one outgoing link per period. Nothing ties the component flows on several outgoing links to a shared composition, so with several outgoing blend links the constraint Σ has_flow[l_out, t] ≤ 1 is added. This allows bidirectional pipelines, where only one direction is active. Several outgoing links are rejected by validate_blend_topology if any of them has no has_flow binary tied to its flow (links without a pressure resource). Use PoolingNode or DiscretizedPoolingNode where the blend must split into several pipes at the same time.
When to use
- Interior network junctions with no direct H₂/CH₄ source injection.
Fields
id::Anyis the name/identifier of the node.cap::TimeProfileis the maximum throughput capacity.opex_var::TimeProfileis the variable operational expenditure.opex_fixed::TimeProfileis the fixed operational expenditure.input::Dict{<:Resource,<:Real}is the dict of input resources. TypicallyDict(H2 => 1, CH4 => 1, Blend => 1)where H2 and CH4 come from composition-trackingDirectlinks and Blend comes from the upstream pipeline.output::Dict{<:Resource,<:Real}is the dict of output resources. TypicallyDict(Blend => 1).data::Vector{<:Data}is the vector ofData. Can include pressure bounds (MaxPressureData,MinPressureData,FixPressureData).
EnergyModelsGasNetworks.DeblendNode — Type
DeblendNode <: EMB.NetworkNodeA network node that physically separates pure H₂ from an incoming blend stream (H₂ + CH₄).
The extracted H₂ is sold as a raw resource (e.g. at a premium H₂ price) while the remaining blend — with reduced H₂ content — continues downstream, typically to a UnitConversion node with CO₂/ETS pricing.
Extraction is bounded by two independent linear constraints:
- Absolute rate limit:
flow_out[H₂, t] ≤ cap_inst[t](installed extraction capacity, MSm³/d H₂; investable viaInvData) - Fraction limit:
flow_out[H₂, t] ≤ max_extract_fraction × flow_component[l_in, t, H₂](cannot extract more than a fixed fraction of arriving H₂; specified byDeblendData)
Both constraints are linear because max_extract_fraction is a fixed parameter.
Investment cost is linked to cap (H₂ extraction rate, MSm³/d) via a standard InvData entry in data. Variable opex scales with actual H₂ extracted; fixed opex scales with installed rate.
Fields
id::Anyis the name/identifier of the node.cap::TimeProfileis the maximum H₂ extraction rate (MSm³/d).opex_var::TimeProfileis variable opex per unit H₂ extracted (MEUR/MSm³).opex_fixed::TimeProfileis fixed opex per installed rate per year (MEUR/(MSm³/d)/year).input::Dict{<:Resource,<:Real}must contain exactly oneResourcePoolingblend. TypicallyDict(Blend => 1).output::Dict{<:Resource,<:Real}must contain the sameResourcePoolingblend (for the remaining reduced-H₂ blend) and one sub-resource of that blend (the extracted H₂). TypicallyDict(Blend => 1, H2 => 1).data::Vector{<:Data}must include aDeblendDataentry. Optionally includesInvDatafor investment in extraction capacity.
EnergyModelsGasNetworks.RefConversion — Type
struct RefConversion <: UnitConversionDefault UnitConversion node to convert units.
Fields
id::Anyis the name/identifier of the node.input::Dict{<:Resource,<:Real}is the input flow into the RefConversion. The conversion valueRealis not used.output::Dict{<:Resource,<:Real}is the output flow from the RefConversion. The conversion valueRealis not used.data::Vector{<:EMB.ExtensionData}is the vector ofExtensionData. This data will define the type of conversion (e.g., volumetric flow to energy).
Links
EnergyModelsGasNetworks.CapDirect — Type
struct CapDirect{T} <: LinkA direct link between two nodes with a maximum capacity and data.
Fields
idis the name/identifier of the link.from::Nodeis the node from which there is flow into the link.to::Nodeis the node to which there is flow out of the link.formulation::Formulationis the used formulation of links. If not specified, aLinearlink is assumed.cap::Tis the maximum capacity of the link.data::Vector{<:ExtensionData}is a vector of extension data associated with the link.
EnergyModelsGasNetworks.ZeroDrop — Type
struct ZeroDrop <: EMB.LinkA zero-pressure-drop pipeline link. When carrying flow, inlet and outlet pressures are equal (no Weymouth constraint needed). When carrying no flow, the pressure equality is relaxed via a big-M formulation so that the two endpoints can be at different pressure levels — appropriate for loop networks where neighbouring PWA pipes may impose different pressures on each end.
Declared as <: EMB.Link (not <: EMB.Direct) so that constraints_bidirectional_pressure still enforces mutual exclusion when two anti-parallel ZeroDrop links model a reversible pipeline. A dedicated create_link dispatch provides the flow-balance constraint without triggering EMB's deprecation warning.
This type is used in place of EMB.Direct for pipelines that are excluded from the PWA set (e.g., via pwa_top_n / pwa_dp_threshold in build_enagas_links).
Fields
idis the name/identifier of the link.from::Nodeis the node from which there is flow into the link.to::Nodeis the node to which there is flow out of the link.formulation::Formulationis the used formulation of links. If not specified, aLinearlink is assumed.
Data structures
EnergyModelsGasNetworks.PressureLinkData — Type
PressureLinkData <: AbstractLinkPressureDataData for Links necessary to model the flow-pressure behaviour.
Fields
weymouth::Realactual weymouth constant value of the line (pipe)max_potential::Realis the maximum inlet pressure of the link, used to calculate the approximations.min_potential::Realis the minimum inlet pressure of the link, used to calculate the approximations.
EnergyModelsGasNetworks.FixPressureData — Type
FixPressureDataSet a fixed pressure in nodes or links.
EnergyModelsGasNetworks.MaxPressureData — Type
MaxPressureDataSet a maximum pressure in nodes or links.
EnergyModelsGasNetworks.MinPressureData — Type
MinPressureDataSet a minimum pressure in nodes or links.
EnergyModelsGasNetworks.RefBlendData — Type
RefBlendData{T<:CompoundResource} <: BlendDataBlending data for controlling the quality of Nodes.
EnergyModelsGasNetworks.BlendLinkData — Type
BlendLinkData{T<:CompoundResource} <: BlendDataBlending data for Links.
EnergyModelsGasNetworks.DiscretizationData — Type
DiscretizationData <: DataConfiguration data for DiscretizedPoolingNode controlling how the bilinear mixing constraint is approximated.
Fields
n_points::Intis the number of discretization levels forproportion_out. Higher values give a tighter approximation at the cost of more binary variables. Default: 5.method::Symbolselects the formulation used to enforce the bilinear constraintflow_component = proportion_out × link_in. Must be one of::pwl(default) — 2D piecewise-linear approximation viaPiecewiseLinearOpt. Uses ⌈log₂(K−1)⌉ binary variables per bilinear term (:Logarithmicmethod).:bigm— standard BigM MILP formulation. ONE set of K binary variables per time step (shared across all outgoing links).proportion_outbecomes a linear expression, making downstream pressure constraints fully MILP-compatible.:bigm_log— logarithmic BigM MILP formulation. Uses ⌈log₂(n_points)⌉ binary variables per time step (rounded up to the next power of 2). Fewer binary variables than:bigmat the cost of a potentially finer grid.
max_proportion::Float64is the upper bound for the discretization range, i.e. levels span[0, max_proportion]instead of[0, 1]. Default: 1.0 (full range).Setting
max_proportionto match the node'smax_h2limit ensures all K levels fall within the feasible H₂ fraction range, maximising the granularity without adding more binary variables. Withmax_proportion = 1.0andmax_h2 = 0.10, K=10 levels span [0%, 11.1%, ...] — only level 1 (0%) is feasible, wasting 9 of 10 levels. Withmax_proportion = 0.20, K=10 levels span [0%, 2.2%, ..., 20%] — all 10 are usable.
Variable counts (per time step) for K = n_points:
| Method | Binary vars | Continuous w-vars (per outgoing link) |
|---|---|---|
:pwl | ⌈log₂(K-1)⌉ per (link,subres) | K² λ per (link,subres) |
:bigm | K | K |
:bigm_log | ⌈log₂(K)⌉ | ⌈log₂(K)⌉ |
Notes
For :bigm and :bigm_log, only 2-component blends (M = 2) are currently supported. For :bigm_log, the actual number of levels used is 2^⌈log₂(n_points)⌉, which may exceed n_points (rounded up to the nearest power of 2).
EnergyModelsGasNetworks.BlendStorageData — Type
BlendStorageData{T<:EMB.Resource} <: EMB.ExtensionDataComponent inventories for a Storage node that stores the ResourcePooling blend blend. The storage keeps one level per sub-resource of the blend, and mode decides the composition of the discharged gas:
:relaxed: the discharged amount of each component can not exceed what was charged and stored. The composition is otherwise free, so this is a bound. The problem stays linear.:prescribed: the discharge has the composition given bydischarge_composition, an extraction quality profile. The problem stays linear. As the storage is cyclic, the stored components must be charged as well, so a profile can make the model infeasible.:fully_mixed: the discharge has the average composition of the stored gas (perfect mixing). The constraints are bilinear and require a nonlinear solver.
Full mixing is a reasonable approximation for small, well-mixed storages, such as steel tanks, line pack or salt caverns. It is a poor one for a depleted natural gas reservoir, where the gas withdrawn first is closest to the gas injected last. Use :prescribed with an extraction quality profile or :relaxed for such storages.
There is no default mode. mode must be given, except when a composition profile is passed, which implies :prescribed.
The storage must have a Cyclic behaviour, and its inputs and outputs must not include the sub-resources of blend.
Fields
blend::ResourcePooling{T}is the stored blend.mode::Symbolis:relaxed,:prescribedor:fully_mixed.discharge_composition::Union{Nothing,Dict{T,TimeProfile}}is the share of each sub-resource in the discharged gas for:prescribed, andnothingotherwise.
EnergyModelsGasNetworks.DeblendData — Type
struct DeblendData <: EMB.ExtensionDataExtension data for DeblendNode, specifying the separation parameters of the PSA (pressure-swing adsorption) or membrane unit.
Fields
max_extract_fraction::Float64: Maximum H₂ extraction fraction [0, 1]. For example,0.9means up to 90 % of the arriving H₂ flow can be deblended into pure H₂ product. The remaining H₂ (and all CH₄) continues in the outgoing blend.psa_efficiency::Float64: PSA process efficiency η ∈ (0, 1]. For every unit of H₂ extracted from the blend, only η units are delivered downstream; the remaining (1−η) is consumed internally by the PSA (purge gas, re-pressurisation). Default1.0(lossless). Example:0.9means 10 % of extracted H₂ is consumed by the PSA itself.
EnergyModelsGasNetworks.FlowToEnergyData — Type
struct FlowToEnergyData <: UnitsDataData structure for converting flow units to energy units in UnitConversion nodes.
Fields
specific_energy_content::Union{Real, Dict{<:Resource,<:Real}}it contains the specific energy content of the resources involved in the conversion.
If the input into the UnitConversion node is a single resource, it is enough to provide the value as a Real. If the input into the UnitConversion node is a ResourcePooling, one must provide a Dict{<:Resource,<:Real} with the specific energy content of each resource in the blend.
EnergyModelsGasNetworks.EmissionsConversionData — Type
struct EmissionsConversionData <: UnitsDataData structure for tracking CO₂ emissions from blend combustion in a UnitConversion node.
When attached to a UnitConversion node, a deferred constraint (added after blend component variables are available) sets the CO₂_emitted output flow equal to the sum of per-subresource CO₂ intensities weighted by the blend component flows:
flow_out[n, t, co2_res] = Σ_s co2_intensity[s] × flow_component[l_in, t, s]The co2_output resource must be listed as an output of the UnitConversion node (alongside the energy output), and must be connected via a link to a dedicated CO₂ acceptance sink node whose surplus encodes the ETS cost.
Fields
co2_intensity::Dict{<:Resource, <:Real}: CO₂ intensity in tCO₂/MSm³ for each sub-resource of the blend input. TypicallyCH4 => 0.2039, H2 => 0.0.co2_output::Resource: The output resource used to carry CO₂ emissions (e.g.CO2_emitted). Must be listed in the node's output dict.
Data accessors
EnergyModelsGasNetworks.get_n_points — Function
get_n_points(d::DiscretizationData) -> IntReturn the number of discretization levels.
EnergyModelsGasNetworks.get_method — Function
get_method(d::DiscretizationData) -> SymbolReturn the discretization method (:pwl, :bigm, or :bigm_log).
EnergyModelsGasNetworks.get_max_proportion — Function
get_max_proportion(d::DiscretizationData) -> Float64Return the upper bound of the discretization range for proportion_out (default: 1.0). Levels span [0, max_proportion]; setting this to the node's max_h2 limit ensures all K levels fall within the feasible H₂ fraction range.
EnergyModelsGasNetworks.get_tracked_resource — Function
get_tracked_resource(d::DiscretizationData)Return the resource whose proportion is discretized, or nothing for a legacy DiscretizationData(n_points, method, max_proportion) value. Legacy values are resolved from adjacent RefBlendData or BlendLinkData when constraints are created.
EnergyModelsGasNetworks.get_storage_mode — Function
get_storage_mode(data::BlendStorageData) -> SymbolReturn the discharge composition mode of data.
EnergyModelsGasNetworks.discharge_composition — Function
discharge_composition(data::BlendStorageData, p, t)
discharge_composition(data::BlendStorageData, p)Return the prescribed share of sub-resource p in the discharged gas in period t, or as a TimeProfile if t is omitted. Only defined for mode :prescribed.
EnergyModelsGasNetworks.get_blendstoragedata — Function
get_blendstoragedata(n::EMB.Node)Return the BlendStorageData of node n, or nothing if it has none.
EnergyModelsGasNetworks.psa_efficiency — Function
psa_efficiency(data::DeblendData) -> Float64
psa_efficiency(n::DeblendNode) -> Float64Return the PSA process efficiency η ∈ (0, 1] from a DeblendData instance or directly from a DeblendNode. For every unit of H₂ extracted from the blend, η units are delivered downstream and (1−η) are consumed by the PSA internally.
EnergyModelsGasNetworks.max_extract_fraction — Function
max_extract_fraction(data::DeblendData) -> Float64
max_extract_fraction(n::DeblendNode) -> Float64Return the maximum H₂ extraction fraction [0, 1] from a DeblendData instance or directly from a DeblendNode.
EnergyModelsGasNetworks.get_co2_intensity — Function
get_co2_intensity(data::EmissionsConversionData, p::EMB.Resource)Return the CO₂ intensity [tCO₂/MSm³] for sub-resource p. Returns 0.0 if p is not present in the co2_intensity dict.