Internal functions
Index
EnergyModelsBase.constraints_capacityEnergyModelsBase.constraints_couple_resourceEnergyModelsBase.constraints_ext_dataEnergyModelsBase.constraints_flow_inEnergyModelsBase.constraints_flow_outEnergyModelsBase.constraints_opex_fixedEnergyModelsBase.constraints_opex_varEnergyModelsBase.constraints_resourceEnergyModelsBase.create_linkEnergyModelsBase.link_dataEnergyModelsBase.variables_flow_resourceEnergyModelsBase.variables_nodeEnergyModelsGasNetworks._get_optimizerEnergyModelsGasNetworks.calculate_flow_to_approximateEnergyModelsGasNetworks.constraints_balance_pressureEnergyModelsGasNetworks.constraints_bidirectional_pressureEnergyModelsGasNetworks.constraints_energy_potentialEnergyModelsGasNetworks.constraints_flow_capacityEnergyModelsGasNetworks.constraints_flow_pressureEnergyModelsGasNetworks.constraints_pressure_boundsEnergyModelsGasNetworks.constraints_pressure_bounds_elementEnergyModelsGasNetworks.constraints_pressure_coupleEnergyModelsGasNetworks.constraints_proportionEnergyModelsGasNetworks.constraints_proportion_sourceEnergyModelsGasNetworks.constraints_pwaEnergyModelsGasNetworks.constraints_qualityEnergyModelsGasNetworks.constraints_trackingEnergyModelsGasNetworks.define_points_curveEnergyModelsGasNetworks.get_input_fnEnergyModelsGasNetworks.get_links_to_node_blendEnergyModelsGasNetworks.get_pwaEnergyModelsGasNetworks.get_specific_energy_contentEnergyModelsGasNetworks.get_step_pressureEnergyModelsGasNetworks.nodes_upstream_ofEnergyModelsGasNetworks.normalised_weymouthEnergyModelsGasNetworks.read_from_jsonEnergyModelsGasNetworks.res_typesEnergyModelsGasNetworks.res_types_segEnergyModelsGasNetworks.resource_lhvEnergyModelsGasNetworks.sources_upstream_ofEnergyModelsGasNetworks.write_to_json
Variable creation functions
Most of the variable creation functions in EnergyModelsGasNetworks is built on the existing methods in EnergyModelsBase.
EnergyModelsBase.variables_node — Function
EMB.variables_node(m, 𝒩ᶜ::Vector{<:Compressor}, 𝒯, modeltype::EMB.EnergyModel)When the node vector is a Vector{<:Compressor} the potential increase (potential_Δ) variables are created for each compressor and timestep.
EnergyModelsBase.variables_flow_resource — Function
EMB.variables_flow_resource(m, 𝒩::Vector{<:EMB.Node}, 𝒫::Vector{<:ResourcePressure}, 𝒯, modeltype::EMB.EnergyModel)
EMB.variables_flow_resource(m, 𝒩::Vector{<:EMB.Node}, 𝒫::Vector{<:ResourcePooling}, 𝒯, modeltype::EMB.EnergyModel)Define additional potential and blending variables for nodes depending on the resources in the system. If exists 𝒫::Vector{<:ResourcePressure} then we create potential variables If exists 𝒫::Vector{<:ResourcePooling{Any}} then we create blending proportion variables
EMB.variables_flow_resource(m, ℒ::Vector{<:EMB.Link}, 𝒫::Vector{:ResourcePressure}, 𝒯, modeltype::EnergyModel)Define additional pressure-related variables for links if there are ResourcePressure in the system. Note! There is no blending variables associated to links.
Constraint functions
The functions used to dispatch on the type of Resource and element (i.e., Link and Node) are defined by extending the EnergyModelsBase package.
EnergyModelsBase.constraints_resource — Function
EMB.constraints_resource(m, n::EMB.Node, 𝒯, 𝒫::Vector{:ResourcePressure}, modeltype::EMB.EnergyModel)
EMB.constraints_resource(m, n::EMB.Node, 𝒯, 𝒫::Vector{:ResourcePooling{Any}}, modeltype::EMB.EnergyModel)
EMB.constraints_resource(m, n::EMB.Node, 𝒯, 𝒫::Vector{:ResourcePooling{ResourcePressure}}, modeltype::EMB.EnergyModel)Add blending and/or pressure related constraints to node n based on specific resource types.
- If 𝒫::Vector{<:ResourcePressure} then it adds only pressure related constraints
- If 𝒫::Vector{<:ResourcePooling{Any}} then it adds only blending related constraints
- If 𝒫::Vector{<:ResourcePooling{ResourcePressure}} then it adds both pressure and blending related constraints
Note! The blending constraints for nodes require ℒ:Vector{<:EMB.Link} to be passed as argument. Thus, all of them are defined in constraints_couple_resource() functions.
EMB.constraints_resource(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:ResourcePressure}, modeltype::EMB.EnergyModel)
EMB.constraints_resource(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:ResourcePooling{Any}}, modeltype::EMB.EnergyModel)
EMB.constraints_resource(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:ResourcePooling{ResourcePressure}}, modeltype::EMB.EnergyModel)Add blending and/or pressure related constraints to node l based on specific resource types transported through l`.
- If 𝒫::Vector{<:ResourcePressure} then it adds only pressure related constraints
- If 𝒫::Vector{<:ResourcePooling{Any}} then it adds only blending related constraints
- If 𝒫::Vector{<:ResourcePooling{ResourcePressure}} then it adds both pressure and blending related constraints
Note! The blending constraints for nodes require ℒ:Vector{<:EMB.Link} to be passed as argument. Thus, all of them are defined in constraints_couple_resource() functions.
EnergyModelsBase.constraints_couple_resource — Function
EMB.constraints_couple_resource(m, 𝒩::Vector{<:EMB.Node}, ℒ::Vector{<:EMB.Link}, 𝒫::Vector{<:ResourcePressure}, 𝒯, modeltype::EMB.EnergyModel)
EMB.constraints_couple_resource(m, 𝒩::Vector{<:EMB.Node}, ℒ::Vector{<:EMB.Link}, 𝒫::Vector{<:ResourcePooling{Any}}, 𝒯, modeltype::EMB.EnergyModel)
EMB.constraints_couple_resource(m, 𝒩::Vector{<:EMB.Node}, ℒ::Vector{<:EMB.Link}, 𝒫::Vector{<:ResourcePooling{ResourcePressure}}, 𝒯, modeltype::EMB.EnergyModel)Add blending and/or pressure related coupling constraints between nodes and links based on specific resource types.
EnergyModelsBase.create_link — Function
EMB.create_link(m, l::CapDirect, 𝒯, 𝒫::Vector{<:CompoundResource}, modeltype::EMB.EnergyModel)Dispatched function for setting the constraints for a link of type CapDirect.
EnergyModelsBase.constraints_capacity — Function
EMB.constraints_capacity(m, l::CapDirect, 𝒯, modeltype::EMB.EnergyModel)Function for creating the constraints on the maximum capacity of a link CapDirect.
EMB.constraints_capacity(m, n::UnitConversion, 𝒯, modeltype::EMB.EnergyModel)Remove the capacity constraints for UnitConversion nodes. These nodes do not have :cap_use.
EnergyModelsBase.constraints_opex_var — Function
EMB.constraints_opex_var(m, n::UnitConversion, 𝒯, modeltype::EMB.EnergyModel)Remove the opex variable constraints for UnitConversion nodes.
EnergyModelsBase.constraints_opex_fixed — Function
EMB.constraints_opex_fixed(m, n::UnitConversion, 𝒯, modeltype::EMB.EnergyModel)Remove the opex fixed constraints for UnitConversion nodes.
EnergyModelsBase.constraints_flow_in — Function
EMB.constraints_flow_in(m, n::PoolingNode, 𝒯::TimeStructure, modeltype::EMB.EnergyModel)Function for creating the constraint on the inlet flow of a PoolingNode. The sum of the flows from all input links must be equal to the used capacity of the node. It differs from generic nodes in that it is not defined as a proportion of the :input and :output fields.
EMB.constraints_flow_in(m, n::UnitConversion, 𝒯::TimeStructure, modeltype::EMB.EnergyModel)Remove the flowin constraints for UnitConversion nodes. These nodes do not use :capuse, instead flows are calculated based on their data extension in EMB.constraintsextdata.
EnergyModelsBase.constraints_flow_out — Function
EMB.constraints_flow_out(m, n::UnitConversion, 𝒯::TimeStructure, modeltype::EMB.EnergyModel)Remove the flowout constraints for UnitConversion nodes. These nodes do not use :capuse, instead flows are calculated based on their data extension in EMB.constraintsextdata.
Then, specific functions in EnergyModelsGasNetworks are defined for the generation of the flow-pressure and pooling constraints.
Those for flow-pressure relationships are:
EnergyModelsGasNetworks.constraints_balance_pressure — Function
constraints_balance_pressure(m, n::EMB.Node, 𝒯, 𝒫::Vector)
constraints_balance_pressure(m, n::EMB.NetworkNode, 𝒯, 𝒫::Vector{<:CompoundResource})
constraints_balance_pressure(m, n::SimpleCompressor, 𝒯, 𝒫::Vector{<:CompoundResource})
constraints_balance_pressure(m, n::PoolingNode, 𝒯, 𝒫::Vector{<:ResourcePressure})
constraints_balance_pressure(m, n::PoolingNode, 𝒯, 𝒫::Vector{<:ResourcePooling{ResourcePressure}})
constraints_balance_pressure(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:CompoundResource})Set internal balance pressures between potential_in and potential_out in Nodes n and Links l`. The balance will depend on type of nodes:
- For
NetworkNodenodes, the inlet and outlet potentials are equal. - For
SimpleCompressornodes, the inlet potential is lower than or equal to the outlet potential. - For
PoolingNodenodes, the inlet potential of all input resources is equal to the outlet potential of all output resources. - For Links, the inlet potential is higher than or equal to the outlet potential. if there is no flow through
l, both potentials are set to zero.
Note: Sinks and Source nodes do not have internal pressure balances, as their potentials are only defined at inlet or outlet respectively.
EnergyModelsGasNetworks.constraints_pressure_bounds_element — Function
constraints_pressure_bounds_element(m, x, 𝒯, 𝒫::Vector{<:CompoundResource})This function calls subfunctions to set the pressure bounds for each AbstractPressureData assigned to element x.
EnergyModelsGasNetworks.constraints_pressure_bounds — Function
constraints_pressure_bounds(m, n::Node, data::T, 𝒯, 𝒫::Vector{<:CompoundResource}) where {T<:PressureData}
constraints_pressure_bounds(m, n::Sink, data::T, 𝒯, 𝒫::Vector{<:CompoundResource}) where {T<:PressureData}
constraints_pressure_bounds(m, l::Link, data::T, 𝒯, 𝒫::Vector{<:CompoundResource}) where {T<:PressureData}Set the pressure limits according to the PressureData data assigned to Node n and Link l. If n is a Sink, the limits are applied to the inlet potential. Otherwise, the limits are applied to the outlet potential. For Links, the limits are applied to the outlet potential only if the link has flow.
The data can be of type:
- MaxPressureData, which will set a maximum pressure bound.
- MinPressureData, which will set a minimum pressure bound.
- FixPressureData, which will set an equality pressure bound.
EnergyModelsGasNetworks.constraints_pressure_couple — Function
constraints_pressure_couple(m, n::EMB.Source, ℒ, 𝒯, 𝒫::Vector{<:CompoundResource})
constraints_pressure_couple(m, n::EMB.Availability, ℒ, 𝒯, 𝒫::Vector{<:CompoundResource})
constraints_pressure_couple(m, n::SimpleCompressor, ℒ, 𝒯, 𝒫::Vector{<:CompoundResource})
constraints_pressure_couple(m, n::PoolingNode, ℒ, 𝒯, 𝒫::Vector{<:CompoundResource})
constraints_pressure_couple(m, n::EMB.Sink, ℒ, 𝒯, 𝒫::Vector{<:CompoundResource})Constraints setting the pressure balance between nodes and links.
Availability nodes do not allow increase in potential, while SimpleCompressor nodes allow it.
EnergyModelsGasNetworks.constraints_flow_capacity — Function
constraints_flow_capacity(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:CompoundResource})Constraints setting the maximum flow through link l at time t whether it has flow or not.
EnergyModelsGasNetworks.constraints_flow_pressure — Function
constraints_flow_pressure(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:ResourcePressure})
constraints_flow_pressure(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:ResourcePooling{<:ResourcePressure}})
constraints_flow_pressure(m, l::EMB.Link, 𝒯, 𝒫::Vector{<:Resource})
constraints_flow_pressure(m, l::EMB.Direct, 𝒯, 𝒫::Vector)Setting Weymouth constraints in link l. This calculates the flow through l based on the pressure difference between inlet and outlet. The Weymouth equation will be approximated using the first-order Taylor expansion when the Resource is a ResourcePressure. For ResourceComponentPotential, a Piecewise Affine Approximation (PWA) will be used.`
EnergyModelsGasNetworks.constraints_pwa — Function
constraints_pwa(m, l::Link, p_blend::ResourcePooling, p_track::ResourcePressure, 𝒯, plane, pwa::PWAFunc)EnergyModelsGasNetworks.constraints_energy_potential — Function
constraints_energy_potential(m, n::SimpleCompressor, 𝒯, 𝒫, modeltype::EMB.EnergyModel)
constraints_energy_potential(m, n::EMB.Node, 𝒯, 𝒫, modeltype::EMB.EnergyModel)Sets the relationship between energy needs and pressure increase, or any other parameter in Compressor n that determines its energy consumption. Skip if the node is not a type Compressor.
If n is a SimpleCompressor, the energy consumption will be calculated as the product of the flow through the compressor, and the energy input required per unit of flow. This is defined with the default constraint constraints_flow_in().
Note! If new Compressor types are created with different relationships between energy flow and pressure increase, this function should be updated to include the new type and relationship.
EnergyModelsGasNetworks.constraints_bidirectional_pressure — Function
" constraintsbidirectionalpressure(m, l::EMB.Link, ℒ, 𝒯, 𝒫) constraintsbidirectionalpressure(m, l::EMB.Direct, ℒ, 𝒯, 𝒫)
Ensure that parallel links defining bidirectionality cannot have flow at the same time. The link without flow will automatically have zero linkinpotential and linkoutpotential due to the constraints_balance_pressure constraints.
For pooling constraints:
EnergyModelsGasNetworks.constraints_proportion — Function
constraints_proportion(m, n::EMB.Source, ℒ::Vector{<:EMB.Link}, 𝒯, 𝒫::Vector{ResourcePooling})
constraints_proportion(m, n::EMB.Node, ℒ::Vector{<:EMB.Link}, 𝒯, 𝒫::Vector{ResourcePooling})Keeps track of the proportions of flows from sources at each node n. Source nodes have their proportions fixed to 1 for their own resource and 0 for others.
EnergyModelsGasNetworks.constraints_quality — Function
constraints_quality(m, n::EMB.Source, ℒ::Vector{<:EMB.Link}, 𝒯, 𝒫::Vector{<:ResourcePooling})
constraints_quality(m, n::EMB.Node, ℒ::Vector{<:EMB.Link}, 𝒯, 𝒫::Vector{<:ResourcePooling})Defines the maximum and minimum quality constraints for a node n based on the blending data. Sourcenodes do not have quality constraints.
EnergyModelsGasNetworks.constraints_proportion_source — Function
function constraints_proportion_source(m, 𝒩::Vector{<:EMB.Node}, ℒ::Vector{<:EMB.Link}, 𝒯, 𝒫::Vector{<:ResourcePooling})Set standard proportion_source values for all nodes. For nodes of type Source, the proportion source from itself is set to 1 and from other sources to 0. For other nodes, the proportion source from non-associated sources is set to 0. Non-associated sources are those that are not upstream of the node.
EnergyModelsGasNetworks.constraints_tracking — Function
constraints_tracking(m, n::EMB.Source, ℒ::Vector{<:EMB.Link}, 𝒯, 𝒫::Vector{<:ResourcePooling})
constraints_tracking(m, n::EMB.Node, ℒ::Vector{<:EMB.Link}, 𝒯, 𝒫::Vector{<:ResourcePooling})Tracking the proportion of subresources at node n. Required for linking with the pressure constraints. If n is a Source, the :proportiontrack variables are fixed to 1 for its own resources and 0 for others. For other node types, the :proportiontrack variables are defined based on the :proportion_source variables of upstream sources.
For unit conversion:
EnergyModelsBase.constraints_ext_data — Function
EMB.constraints_ext_data(m, n::Node, 𝒯, 𝒫, modeltype::EnergyModel, data::FlowToEnergyData)Function to convert flow rates to energy rates (e.g., Sm3/d to MWh/d). The time basis of the flow rates is preserved in the conversion.
Utils
General utils are:
EnergyModelsGasNetworks.nodes_upstream_of — Function
nodes_upstream_of(n::Node, ℒ::Vector{<:Link})Tracks all nodes associated with a given node n through the links in ℒ. We refer to associated to all the nodes that lead to n following the direction of the links.
EnergyModelsGasNetworks.sources_upstream_of — Function
sources_upstream_of(n::Node, ℒ::Vector{<:Link})
sources_upstream_of(n::EMB.Node, ℒ::Vector{<:EMB.Link}, resources::Vector{EMB.Resources})Tracks all nodes associated to n and filter by source nodes. If resources is provided, only sources which output any of the resources in sub_res are returned.
EnergyModelsGasNetworks.get_links_to_node_blend — Function
get_links_to_node_blend(n::Node, ℒ::Vector{<:EMB.Link}, sub_res, blend)Gets the links into node n which transport any of the resources in sub_res or the blend resource.
EnergyModelsGasNetworks.define_points_curve — Function
define_points_curve(x1, x2, x3)Defines the points (inlet and outlet pressures and proportion) for the surface for the PWA.
EnergyModelsGasNetworks.res_types — Function
res_types(𝒫::Array{<:Resource})Return the unique resource types in an Array of resources 𝒫.
EnergyModelsGasNetworks.res_types_seg — Function
res_types_seg(𝒫::Array{<:Resource})Return a Vector-of-Vectors of resources segmented by the sub-types.
EnergyModelsGasNetworks._get_optimizer — Function
Get optimizer; error if not set.
EnergyModelsBase.link_data — Function
link_data(l::CapDirect)Returns the [ExtensionData] array of link l.
It overwrites the EMB.link_data(l::Link) method, which returns an empty ExtensionData vector.
Specific utils to perform calculations on input data:
EnergyModelsGasNetworks.normalised_weymouth — Function
normalised_weymouth(weymouth, molar_fraction_hydrogen)Calculate the normalised flow constant with respect to the specific gravity using specific operating points.
EnergyModelsGasNetworks.calculate_flow_to_approximate — Function
calculate_flow_to_approximate(constant, x1, x2, x3)Calculates the flow of gas with the Weymouth equation using the normalised weymouth constant.
Typically, the constant in the Weymouth equation depends on the specific gravity of the gas. Here, we need instead a normalised it with respect to the specific gravity. This allows to calculate the flows considering the different proportions of the components.
Variables
- weymouth_ct::Float64 -> Normalised Weymouth constant
- x1::Float64 -> Inlet pressures
- x2::Float64 -> Outlet pressures
- x3::Float64 -> Proportion of tracking component
- molmass_other::Float64 -> Molar mass of the other component in the blend (e.g., for methane is 16.042 g/mol)
- molmass_track::Float64 -> Molar mass of the tracking component (e.g., for hydrogen is 2.016 g/mol)
EnergyModelsGasNetworks.get_step_pressure — Function
get_step_pressure()Return the current pressure step (in the same units as the inputs, e.g. bars) used when building piecewise-affine approximations of the Weymouth relation.
EnergyModelsGasNetworks.get_pwa — Function
function get_pwa(data_pressure::PressureLinkData, data_blend::BlendData, optimizer; resolution_prop=0.01)
function get_pwa(l::EMB.Link, optimizer; resolution_prop=0.01)Generates/retrieves the PWA functions for a link with blending and pressure data to calculate the Weymouth equation with blending.
EnergyModelsGasNetworks.get_specific_energy_content — Function
get_LHV(data::FlowToEnergyData)
get_LHV(data::FlowToEnergyData, p::EMB.Resource)Collects the resources if Dict{<:Resource,<:Real} (used for ResourcePooling) or the LHV if is a Real (for other types of resources) If the resource p is specified, retrieves the LHV for that specific resource from the dictionary.
EnergyModelsGasNetworks.resource_lhv — Function
resource_lhv(n::Node, 𝒫ˡʰᵛ::Vector{ResourcePooling}, data::FlowToEnergyData)
resource_lhv(n::EMB.Node, 𝒫ˡʰᵛ::Vector{Resource}, data::FlowToEnergyData)Function to calculate the LHV of the input resource for a given node with FlowToEnergyData. If the input resource is of type ResourcePooling, the LHV is calculated as the weighted average of the LHV of the individual resources in the blend. If the input resource is any other type of Resource, the LHV is simply retrieved from the data.
Scratch
EnergyModelsGasNetworks integrates the package Scratch.jl, which enables storing mutable containers of data. Specifically, it is applied to managing temporary storage of the piecewise-affine approximation data. In this way, the optimization used for finding the corresponding planes does not need to be performed again if the same conditions (i.e., Weymouth constants, maximum inlet pressure, minimum outlet pressure, pressure steps) are inputs for a link.
EnergyModelsGasNetworks.get_input_fn — Function
get_input_fn(x, y)Generate a unique filename in the cache directory for the given input parameters x and y.
EnergyModelsGasNetworks.read_from_json — Function
read_from_json(fn)Reads the PiecewiseAffineApprox.PWAFunc objects from a JSON file fn.
EnergyModelsGasNetworks.write_to_json — Function
write_to_json(fn, pwa)Writes the PiecewiseAffineApprox.PWAFunc object pwa to a JSON file fn.
All the functions are internally used by EnergyModelsGasNetworks, except delete_cache which can be called directly by the user if necessary.