# Public interface

## Module

`EnergyModelsBase`

— ModuleMain module for `EnergyModelsBase`

a framework for building flexible energy system models.

It exports several types and associated functions for accessing fields. In addition, all required functions for creaeting and running the model are exported.

You can find the exported types and functions below or on the pages *Constraint functions* and *Data functions*.

## Resources

`Resource`

s correspond to the mass/energy that is converted or transported within an energy system. `Resource`

s are discrete, that is they do not have as default additional variables, *e.g.* pressure or temperature, associated with them. Instead, they are implemented through flows and levels, as explained in *Optimization variables*.

`Resource`

types

The following resources are implemented in `EnergyModelsBase`

. `EnergyModelsBase`

differentiates between `ResourceCarrier`

and `ResourceEmit`

resources. The key difference between both is that `ResourceEmit`

resources can have emissions, *e.g.*, CO₂ or methane. Emissions are accounted for and can have either a cap and/or a price associated with them.

One important field for a resource is the CO₂ intensity (`co2_int`

). CO₂ is handled differently than other emissions as the emissions are fundamental properties of a fuel based on the carbon content.

`EnergyModelsBase.Resource`

— TypeGeneral resource supertype to be used for the declaration of subtypes.

`EnergyModelsBase.ResourceCarrier`

— Type`ResourceCarrier{T<:Real} <: Resource`

Resources that can be transported and converted. These resources cannot be included as resources that are emitted, *e.g*, in the variable `emissions_strategic`

.

**Fields**

is the name/identifyer of the resource.`id`

is the the CO₂ intensity,`co2_int::T`

*e.g.*, t/MWh.

`EnergyModelsBase.ResourceEmit`

— Type`ResourceEmit{T<:Real} <: Resource`

Resources that can can be emitted (e.g., CO₂, CH₄, NOₓ).

These resources can be included as resources that are emitted, *e.g*, in the variable `emissions_strategic`

.

**Fields**

is the name/identifyer of the resource.`id`

is the the CO₂ intensity,`co2_int::T`

*e.g.*, t/MWh.

### Functions for accessing fields of `Resource`

types

The following functions are declared for accessing fields from a `Resource`

type. If you want to introduce new `Resource`

types, it is important that this function are either functional for your new types or you have to declare a corresponding function.

`EnergyModelsBase.co2_int`

— Function`co2_int(p::Resource)`

Returns the CO₂ intensity of resource `p`

## Nodes

`Node`

s are used in `EnergyModelsBase`

to convert `Resource`

s. They are coupled to the rest of the system through the *Flow variables*. Nodes are the key types for extending `EnergyModelsBase`

through dispatch. You can find an introduction of the different node types on the page *Creating a new node*

### Abstract `Node`

types

The following abstract node types are implemented in the `EnergyModelsBase`

. These abstract types are relevant for dispatching in individual functions.

`EnergyModelsBase.Source`

— Type`Source`

node with only output.

`EnergyModelsBase.NetworkNode`

— Type`NetworkNode`

node with both input and output.

`EnergyModelsBase.Sink`

— Type`Sink`

node with only input.

`EnergyModelsBase.Storage`

— Type`Storage`

node with level.

`EnergyModelsBase.Availability`

— Type`Availability`

node as routing node.

### Reference node types

The following composite types are inmplemented in the `EnergyModelsBase`

. They can be used for describing a simple energy system without any non-linear or binary based expressions. Hence, there are, *e.g.*, no operation point specific efficiencies implemented.

`EnergyModelsBase.RefSource`

— TypeA reference `Source`

node.

**Fields**

is the name/identifier of the node.`id`

is the installed capacity.`cap::TimeProfile`

is the variational operational costs per energy unit produced.`opex_var::TimeProfile`

is the fixed operational costs.`opex_fixed::TimeProfile`

are the generated`output::Dict{<:Resource, <:Real}`

`Resource`

s with conversion value`Real`

.is the additional data (e.g. for investments). The field`data::Vector{Data}`

`data`

is conditional through usage of a constructor.

`EnergyModelsBase.RefNetworkNode`

— TypeA reference `NetworkNode`

node.

**Fields**

is the name/identifier of the node.`id`

is the installed capacity.`cap::TimeProfile`

is the variational operational costs per energy unit produced.`opex_var::TimeProfile`

is the fixed operational costs.`opex_fixed::TimeProfile`

are the input`input::Dict{<:Resource, <:Real}`

`Resource`

s with conversion value`Real`

.are the generated`output::Dict{<:Resource, <:Real}`

`Resource`

s with conversion value`Real`

.is the additional data (e.g. for investments). The field`data::Vector{Data}`

`data`

is conditional through usage of a constructor.

`EnergyModelsBase.RefSink`

— TypeA reference `Sink`

node.

This node corresponds to a demand given by the field `cap`

.

**Fields**

is the name/identifier of the node.`id`

is the Demand.`cap::TimeProfile`

are penalties for surplus or deficits. Requires the fields`penalty::Dict{Any, TimeProfile}`

`:surplus`

and`:deficit`

.are the input`input::Dict{<:Resource, <:Real}`

`Resource`

s with conversion value`Real`

.is the additional data (e.g. for investments). The field`data::Vector{Data}`

`data`

is conditional through usage of a constructor.

`EnergyModelsBase.RefStorage`

— TypeA reference `Storage`

node.

This node is designed to store either a `ResourceCarrier`

or a `ResourceEmit`

. It is designed as a composite type to automatically distinguish between these two.

**Fields**

is the name/identifier of the node.`id`

is the installed rate capacity, that is e.g. power or mass flow.`rate_cap::TimeProfile`

is the installed storage capacity, that is e.g. energy or mass.`stor_cap::TimeProfile`

is the variational operational costs per energy unit stored.`opex_var::TimeProfile`

is the fixed operational costs.`opex_fixed::TimeProfile`

is the stored`stor_res::T`

`Resource`

.are the input`input::Dict{<:Resource, <:Real}`

`Resource`

s with conversion value`Real`

.are the generated`output::Dict{<:Resource, <:Real}`

`Resource`

s with conversion value`Real`

. Only relevant for linking and the stored`Resource`

.is the additional data (e.g. for investments). The field`data::Vector{<:Data}`

`data`

is conditional through usage of a constructor.

`EnergyModelsBase.GenAvailability`

— TypeA reference `Availability`

node.

**Fields**

is the name/identifier of the node.`id`

are the input`inputs::Vector{<:Resource}`

`Resource`

s.are the output`output::Vector{<:Resource}`

`Resource`

s.

A constructor is provided so that only a single array can be provided with the fields:

is the name/identifier of the node.`id`

are the`𝒫::Vector{<:Resource}`

`Resource`

s.

### Functions for accessing fields of `Node`

types

The following functions are declared for accessing fields from a `Node`

type.

If you want to introduce new `Node`

types, it is important that these functions are either functional for your new types or you have to declare corresponding functions. The first approach can be achieved through using the same name for the respective fields.

The functions `storage_resource`

is only required for `Storage`

nodes, when you plan to use the implemented constraint function `constraints_flow_in`

. The functions `surplus_penalty`

and `deficit_penalty`

are only required for `Sink`

nodes if you plan to use the implemented constraint function `constraints_opex_var`

.

`EnergyModelsBase.capacity`

— Function`capacity(n::Node)`

Returns the capacity of a node `n`

as `TimeProfile`

. In the case of a `Storage`

node, the capacity is returned as `NamedTuple`

with the fields `level`

and `rate`

.

`capacity(n::Node, t)`

Returns the capacity of a node `n`

at operational period `t`

. In the case of a `Storage`

node, the capacity is returned as `NamedTuple`

with the fields `level`

and `rate`

.

`EnergyModelsBase.opex_var`

— Function`opex_var(n::Node)`

Returns the variable OPEX of a node `n`

as `TimeProfile`

.

`opex_var(n::Node, t)`

Returns the variable OPEX of a node `n`

in operational period `t`

`EnergyModelsBase.opex_fixed`

— Function`opex_fixed(n::Node)`

Returns the fixed OPEX of a node `n`

as `TimeProfile`

.

`opex_fixed(n::Node, t_inv)`

Returns the fixed OPEX of a node `n`

at strategic period `t_inv`

`EnergyModelsBase.inputs`

— Function`inputs(n::Node)`

Returns the input resources of a node `n`

. These resources are specified via the field `input`

.

`inputs(n::Node, p::Resource)`

Returns the value of an input resource `p`

of a node `n`

.

`EnergyModelsBase.outputs`

— Function`outputs(n::Node)`

Returns the output resources of a node `n`

. These resources are specified via the field `output`

.

`outputs(n::Node, p::Resource)`

Returns the value of an output resource `p`

of a node `n`

.

`EnergyModelsBase.node_data`

— Function`node_data(n::Node)`

Returns the `Data`

array of node `n`

.

`EnergyModelsBase.storage_resource`

— Function`storage_resource(n::Storage)`

Returns the storage resource of `Storage`

node `n`

.

`EnergyModelsBase.surplus_penalty`

— Function`surplus_penalty(n::Sink)`

Returns the surplus penalty of sink `n`

as `TimeProfile`

.

`surplus_penalty(n::Sink, t)`

Returns the surplus penalty of sink `n`

at operational period `t`

`EnergyModelsBase.deficit_penalty`

— Function`deficit_penalty(n::Sink)`

Returns the deficit penalty of sink `n`

as `TimeProfile`

.

`deficit_penalty(n::Sink, t)`

Returns the deficit penalty of sink `n`

at operational period `t`

### Functions for identifying `Node`

s

The following functions are declared for filtering on `Node`

types.

If you want to introduce new `Node`

types, it is important that the functions `has_input`

, `has_output`

, and `has_emissions`

are either functional for your new types or you have to declare corresponding functions. The first approach can be achieved through using the same name for the respective fields.

The functions `nodes_input`

, `nodes_output`

, and `nodes_emissions`

are not used in the model as they are replaced by the build in filter function as, *e.g.*, `filter(has_input, 𝒩)`

. In practice, they provide a pre-defined approach for filtering nodes and do not require additional modifications. They can be used in potential extensions.

`EnergyModelsBase.nodes_input`

— Function`nodes_input(𝒩::Array{<:Node}, sub)`

Return nodes that have an input, i.e., `Sink`

and `NetworkNode`

nodes.

`EnergyModelsBase.nodes_output`

— Function`nodes_output(𝒩::Array{<:Node})`

Return nodes that have an output, i.e., `Source`

and `NetworkNode`

nodes.

`EnergyModelsBase.nodes_emissions`

— Function`has_emissions(𝒩::Array{<:Node})`

Return nodes that have emission data for a given Array `::Array{<:Node}`

.

`EnergyModelsBase.has_input`

— Function`has_input(n::Node)`

Return logic whether the node is an input node, i.e., `Sink`

and `NetworkNode`

nodes.

`EnergyModelsBase.has_output`

— Function`has_output(n::Node)`

Return logic whether the node is an output node, i.e., `Source`

and `NetworkNode`

nodes.

`EnergyModelsBase.has_emissions`

— Function`has_emissions(n::Node)`

Checks whether the Node `n`

has emissions.

### Legacy constructors

The following legacy constructors are implemented to avoid changing each individual model after updates in the core structure. It is however uncertain, how long they will remain in the model. To this end, it is suggest to adjust them with the reference nodes described above.

`EnergyModelsBase.RefNetwork`

— FunctionLegacy constructor for a `RefNetwork`

node. This version will be discontinued in the near future. its new name is given by RefNetworkNode.

`EnergyModelsBase.RefNetworkEmissions`

— FunctionLegacy constructor for a `RefNetworkEmissions`

node. This version will be discontinued in the near future and replaced with the new implementation of `data`

and the application of `RefNetworkNode`

.

See the documentation for further information. In this case, the emission data can be implemented by the new `EmissionsData`

type `CaptureEnergyEmissions`

.

`EnergyModelsBase.RefStorageEmissions`

— FunctionLegacy constructor for a `RefStorageEmissions`

. This version will be discontinued in the near future and replaced with the new version of `RefStorage`

.

See the documentation for further information. In this case, the key difference is that it uses now a parametric type instead of a standard composite type to differentiate between the storage of `ResourceCarrier`

or `ResourceEmit`

## Links

`Link`

s are connecting the individual `Node`

s for the exchange of energy/mass. `Link`

s are directional, that is transport of mass/energy is only allowed in a single direction.

`Link`

types

The following types for links are implemented in `EnergyModelsBase`

. The thought process is to dispatch on the `EMB.Formulation`

of a link as additional option. This is in the current stage not implemented.

`EnergyModelsBase.Link`

— TypeDeclaration of the general type for links connecting nodes.

`EnergyModelsBase.Direct`

— Type`Direct <: Link`

A direct link between two nodes.

**Fields**

is the name/identifier of the link.`id`

is node from which there is flow into the link.`from::Node`

is node to which there is flow out of the link.`to::Node`

is the used formulation of links. If not specified, a`formulation::Formulation`

`Linear`

link is assumed.

`EnergyModelsBase.Linear`

— TypeLinear `Formulation`

, that is input equals output.

### Functions for accessing fields of `Link`

types

The following functions are declared for accessing fields from a `Link`

type.

If you want to introduce new `Link`

types, it is important that the function `formulation`

is either functional for your new types or you have to declare a corresponding function. The first approach can be achieved through using the same name for the respective fields.

`EnergyModelsBase.formulation`

— Function`formulation(l::Link)`

Return the formulation of a Link ´l´.

## Model and data

`EnergyModel`

and `Data`

types

The type `EnergyModel`

is used for creating the global parameters of a model. It can be as well used for extending `EnergyModelsBase`

as described in the section *Extensions to the model*. `EnergyModelsBase`

only provides an `OperationalModel`

while `InvestmentModel`

is added through the extension `EnergyModelsInvestments`

`EnergyModelsBase.EnergyModel`

— TypeAbstract type for differentation between types of models (investment, operational, ...).

`EnergyModelsBase.OperationalModel`

— TypeOperational Energy Model without investments.

**Fields**

is a dictionary with individual emission limits as`emission_limit::Dict{<:ResourceEmit, <:TimeProfile}`

`TimeProfile`

for each emission resource`ResourceEmit`

.are the prices for the different emissions types considered.`emission_price::Dict{<:ResourceEmit, <:TimeProfile}`

is a`co2_instance`

`ResourceEmit`

and corresponds to the type used for CO₂.

In addition, the following `Data`

types are introduced for introducing additional parameters, variables, and constraints to the `Node`

s. The approach of using the `data`

field of `Node`

s is explained on the page *Data functions*. `EmptyData`

is no longer relevant for the modelling, but it is retained for avoiding any problems with existing models.

`EnergyModelsBase.Data`

— TypeAbstract type used to define concrete struct containing the package specific elements to add to the composite type defined in this package.

`EnergyModelsBase.EmptyData`

— TypeEmpty composite type for `Data`

### Functions for accessing fields of `EnergyModel`

types

The following functions are declared for accessing fields from a `EnergyModel`

type.

If you want to introduce new `EnergyModel`

types, it is important that the functions `emission_limit`

, `emission_price`

, and `co2_instance`

are either functional for your new types or you have to declare corresponding functions. The first approach can be achieved through using the same name for the respective fields.

`EnergyModelsBase.emission_limit`

— Function`emission_limit(model::EnergyModel)`

Returns the emission limit of EnergyModel `model`

as dictionary with `TimeProfile`

s for each `ResourceEmit`

.

`emission_limit(model::EnergyModel, p::ResourceEmit)`

Returns the emission limit of EnergyModel `model`

and ResourceEmit `p`

as `TimeProfile`

.

`emission_limit(model::EnergyModel, p::ResourceEmit, t_inv::TS.StrategicPeriod)`

Returns the emission limit of EnergyModel `model`

and ResourceEmit `p`

in strategic period period `t_inv`

.

`EnergyModelsBase.emission_price`

— Function`emission_price(model::EnergyModel)`

Returns the emission price of EnergyModel `model`

as dictionary with `TimeProfile`

s for each `ResourceEmit`

.

`emission_price(model::EnergyModel, p::ResourceEmit)`

Returns the emission price of EnergyModel `model`

and ResourceEmit `p`

as `TimeProfile`

. If no emission price is specified for the ResourceEmit `p`

, the function returns 0

`emission_price(model::EnergyModel, p::ResourceEmit, t_inv::TS.StrategicPeriod)`

Returns the emission price of EnergyModel `model`

and ResourceEmit `p`

in strategic period `t_inv`

. If no emission price is specified for the ResourceEmit `p`

, the function returns 0

`EnergyModelsBase.co2_instance`

— Function`co2_instance(model::EnergyModel)`

Returns the CO₂ instance used in modelling.

## Functions for running the model

The following functions are provided for both creating a model using `EnergyModelsBase`

and solving said model. Both functions have the input `case`

and `model`

. `run_model`

calls `create_model`

in the function, hence, it is not necessary to call the function beforehand.

The `case`

dictionary has to follow a certain outline. In this case, it is simplest to look at the provided *examples*.

We are currently debating to replace the dictionary used for `case`

as well with a composite type.

This will lead to breacking changes, but should be simple to adjust for.

`EnergyModelsBase.create_model`

— Function`create_model(case, modeltype::EnergyModel, m::JuMP.Model; check_timeprofiles::Bool=true)`

Create the model and call all required functions.

**Input**

`case`

- The case dictionary requiring the keys`:T`

,`:nodes`

,`:links`

, and`products`

. If the input is not provided in the correct form, the checks will identify the problem.`modeltype`

- Used modeltype, that is a subtype of the type`EnergyModel`

.`m`

- the empty`JuMP.Model`

instance. If it is not provided, then it is assumed that the input is a standard`JuMP.Model`

.

**Conditional input**

`check_timeprofiles=true`

- A boolean indicator whether the time profiles of the individual nodes should be checked or not. It is advised to not deactivate the check, except if you are testing new components. It may lead to unexpected behaviour and potential inconsistencies in the input data, if the time profiles are not checked.

`EnergyModelsBase.run_model`

— Function`run_model(case::Dict, model::EnergyModel, optimizer)`

Take the `case`

data as a dictionary and the `model`

and build and optimize the model. Returns the solved JuMP model.

The dictionary requires the keys:

`:nodes::Vector{Node}`

`:links::Vector{Link}`

`:products::Vector{Resource}`

`:T::TimeStructure`

## Functions for extending the model

The following functions are used for developing new nodes. See the page *Creating a new node* for a detailed explanation on how to create a new node.

`EnergyModelsBase.variables_node`

— Function" variables_node(m, 𝒩ˢᵘᵇ::Vector{<:Node}, 𝒯, modeltype::EnergyModel)

Default fallback method when no function is defined for a node type.

`variables_node(m, 𝒩ˢⁱⁿᵏ::Vector{<:Sink}, 𝒯, modeltype::EnergyModel)`

Declaration of both surplus (`:sink_surplus`

) and deficit (`:sink_deficit`

) variables for `Sink`

nodes `𝒩ˢⁱⁿᵏ`

to quantify when there is too much or too little energy for satisfying the demand.

`EnergyModelsBase.create_node`

— Function`create_node(m, n::Source, 𝒯, 𝒫, modeltype::EnergyModel)`

Set all constraints for a `Source`

. Can serve as fallback option for all unspecified subtypes of `Source`

.

`create_node(m, n::NetworkNode, 𝒯, 𝒫, modeltype::EnergyModel)`

Set all constraints for a `NetworkNode`

. Can serve as fallback option for all unspecified subtypes of `NetworkNode`

.

`create_node(m, n::Storage, 𝒯, 𝒫, modeltype::EnergyModel)`

Set all constraints for a `Storage`

. Can serve as fallback option for all unspecified subtypes of `Storage`

.

`create_node(m, n::Sink, 𝒯, 𝒫, modeltype::EnergyModel)`

Set all constraints for a `Sink`

. Can serve as fallback option for all unspecified subtypes of `Sink`

.

`create_node(m, n::Availability, 𝒯, 𝒫, modeltype::EnergyModel)`

Set all constraints for a `Availability`

. Can serve as fallback option for all unspecified subtypes of `Availability`

.

Availability nodes can be seen as routing nodes. It is not necessary to have more than one available node except if one wants to include as well transport between different `Availability`

nodes with associated costs (not implemented at the moment).

## Constraint functions

The following functions can be used in new developed nodes to include constraints. See the pages *Constraint functions* and *Data functions* for a detailed explanation on their usage.

The function `constraints_capacity_installed`

should not be changed. It is used for the inclusion of investments through `EnergyModelsInvestments`

. It also has to be called, if you create a new function `constraints_capacity`

.

`EnergyModelsBase.constraints_flow_in`

— Function`constraints_flow_in(m, n, 𝒯::TimeStructure, modeltype::EnergyModel)`

Function for creating the constraint on the inlet flow to a generic `Node`

. This function serves as fallback option if no other function is specified for a `Node`

.

`constraints_flow_in(m, n::Storage, 𝒯::TimeStructure, modeltype::EnergyModel)`

Function for creating the constraint on the inlet flow to a generic `Storage`

. This function serves as fallback option if no other function is specified for a `Storage`

.

`EnergyModelsBase.constraints_flow_out`

— Function`constraints_flow_out(m, n, 𝒯::TimeStructure, modeltype::EnergyModel)`

Function for creating the constraint on the outlet flow from a generic `Node`

. This function serves as fallback option if no other function is specified for a `Node`

.

`EnergyModelsBase.constraints_capacity`

— Function`constraints_capacity(m, n::Node, 𝒯::TimeStructure, modeltype::EnergyModel)`

Function for creating the constraint on the maximum capacity of a generic `Node`

. This function serves as fallback option if no other function is specified for a `Node`

.

`constraints_capacity(m, n::Storage, 𝒯::TimeStructure, modeltype::EnergyModel)`

Function for creating the constraint on the maximum level of a generic `Storage`

. This function serves as fallback option if no other function is specified for a `Storage`

.

`constraints_capacity(m, n::Sink, 𝒯::TimeStructure, modeltype::EnergyModel)`

Function for creating the constraint on the maximum capacity of a generic `Sink`

. This function serves as fallback option if no other function is specified for a `Sink`

.

`EnergyModelsBase.constraints_capacity_installed`

— Function`constraints_capacity_installed(m, n, 𝒯::TimeStructure, modeltype::EnergyModel)`

In general, it is prefered to have the capacity as a function of a variable given with a value of 1 in the field `n.Cap`

.

`EnergyModelsBase.constraints_level`

— Function`constraints_level(m, n::Storage, 𝒯, 𝒫, modeltype::EnergyModel)`

Function for creating the level constraint for a reference storage node with a `ResourceCarrier`

resource.

`EnergyModelsBase.constraints_opex_var`

— Function`constraints_opex_var(m, n::Node, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)`

Function for creating the constraint on the variable OPEX of a generic `Node`

. This function serves as fallback option if no other function is specified for a `Node`

.

`constraints_opex_var(m, n::Storage, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)`

Function for creating the constraint on the variable OPEX of a generic `Storage`

. This function serves as fallback option if no other function is specified for a `Storage`

.

`constraints_opex_var(m, n::RefStorage{T}, 𝒯ᴵⁿᵛ, modeltype::EnergyModel) where {T<:ResourceEmit}`

Function for creating the constraint on the variable OPEX of a `RefStorage{ResourceEmit}`

.

`constraints_opex_var(m, n::Sink, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)`

Function for creating the constraint on the variable OPEX of a generic `Sink`

. This function serves as fallback option if no other function is specified for a `Sink`

.

`EnergyModelsBase.constraints_opex_fixed`

— Function`constraints_opex_fixed(m, n::Node, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)`

Function for creating the constraint on the fixed OPEX of a generic `Node`

. This function serves as fallback option if no other function is specified for a `Node`

.

`constraints_opex_fixed(m, n::Storage, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)`

Function for creating the constraint on the fixed OPEX of a generic `Storage`

. This function serves as fallback option if no other function is specified for a `Storage`

.

`constraints_opex_fixed(m, n::Storage, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)`

Function for creating the constraint on the fixed OPEX of a generic `Storage`

. This function serves as fallback option if no other function is specified for a `Storage`

.

`constraints_opex_fixed(m, n::Sink, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)`

Function for creating the constraint on the fixed OPEX of a generic `Sink`

. This function serves as fallback option if no other function is specified for a `Sink`

.

`EnergyModelsBase.constraints_data`

— Function`constraints_data(m, n::Node, 𝒯, 𝒫, modeltype, data::DataEmissions)`

Constraints functions for calculating both the emissions and amount of CO₂ captured in the process.

There exist several configurations:

: Only energy usage related emissions.`EmissionsEnergy`

: Both process and energy usage related emissions.`EmissionsProcess`

: Capture of energy usage related emissions, can include process emissions.`CaptureEnergyEmissions`

: Capture of process emissions.`CaptureProcessEmissions`

: Capture of both process and energy usage related`CaptureProcessEnergyEmissions`

emissions.

`constraints_data(m, n::Node, 𝒯, 𝒫, modeltype, data::Data)`

Fallback option when data is specified, but it is not desired to add the constraints through this function. This is, e.g., the case for `EnergyModelsInvestments`

as the capacity constraint has to be replaced

## Emission data

Emission data are used to provide the individual nodes with potential emissions. The approach is also explained on the page *Data functions*.

`Emission`

types

The thought process with `EmissionData`

is to provide the user with options for each individual node to include emissions and potentially capture or not. The individual types can be used for all included *reference Nodes*, although capture is not possible for

`Sink`

nodes due to the lack of an output.`EnergyModelsBase.EmissionsData`

— Type`EmissionsData`

as supertype for all `Data`

types for emissions.

`EnergyModelsBase.CaptureData`

— Type`CaptureData`

as supertype for all `EmissionsData`

that include CO₂ capture.

`EnergyModelsBase.EmissionsEnergy`

— TypeNo capture, no process emissions are present. Does not require `co2_capture`

or `emissions`

as input, but accepts it and will ignore it, if provided.

`EnergyModelsBase.EmissionsProcess`

— TypeNo capture, but process emissions are present. Does not require `co2_capture`

as input, but accepts it and will ignore it, if provided.

**Fields**

: emissions per unit produced.`emissions::Dict{ResourceEmit, T}`

`EnergyModelsBase.CaptureEnergyEmissions`

— TypeCapture the energy usage related emissions, but not the process emissions. Does not require `emissions`

as input, but can be supplied.

**Fields**

: emissions per unit produced.`emissions::Dict{ResourceEmit, T}`

is the CO₂ capture rate.`co2_capture::Float64`

`EnergyModelsBase.CaptureProcessEmissions`

— TypeCapture the process emissions, but not the energy usage related emissions.

**Fields**

: emissions per unit produced.`emissions::Dict{ResourceEmit, T}`

is the CO₂ capture rate.`co2_capture::Float64`

`EnergyModelsBase.CaptureProcessEnergyEmissions`

— TypeCapture both the process emissions and the energy usage related emissions.

**Fields**

: emissions per unit produced.`emissions::Dict{ResourceEmit, T}`

is the CO₂ capture rate.`co2_capture::Float64`

### Functions for accessing fields of `EmissionsData`

types

The following functions are declared for accessing fields from a `EmissionsData`

type.

If you want to introduce new `EmissionsData`

types, it is important that the functions `co2_capture`

and `process_emissions`

are either functional for your new types or you have to declare corresponding functions. The first approach can be achieved through using the same name for the respective fields.

`EnergyModelsBase.co2_capture`

— Function`co2_capture(data::CaptureData)`

Returns the CO₂ capture rate of the `data`

.

`EnergyModelsBase.process_emissions`

— Function`process_emissions(data::EmissionsData)`

Returns the `ResourceEmit`

s that have process emissions in the `data`

.

`process_emissions(data::EmissionsData{T}, p::ResourceEmit)`

Returns the the process emissions of resource `p`

in the `data`

as `TimeProfile`

. If the process emissions are provided as `Float64`

, it returns a FixedProfile(x). If there are no process emissions, it returns a FixedProfile(0).

`process_emissions(data::EmissionsData{T}, p:ResourceEmit, t)`

Returns the the process emissions of resource `p`

in the `data`

at operational period t. If there are no process emissions, it returns a value of 0.

## Miscellaneous functions/macros

`EnergyModelsBase.@assert_or_log`

— Macro`assert_or_log(ex, msg)`

Macro that extends the behaviour of the `@assert`

macro. The switch `ASSERTS_AS_LOG`

, controls if the macro should act as a logger or a normal `@assert`

. This macro is designed to be used to check whether the data provided is consistent.