# Internals

## Index

`EnergyModelsBase.Formulation`

`EnergyModelsBase.Node`

`EnergyModelsBase.check_case_data`

`EnergyModelsBase.check_data`

`EnergyModelsBase.check_fixed_opex`

`EnergyModelsBase.check_model`

`EnergyModelsBase.check_node`

`EnergyModelsBase.check_node`

`EnergyModelsBase.check_node`

`EnergyModelsBase.check_node`

`EnergyModelsBase.check_node`

`EnergyModelsBase.check_node`

`EnergyModelsBase.check_node_data`

`EnergyModelsBase.check_node_data`

`EnergyModelsBase.check_profile`

`EnergyModelsBase.check_profile`

`EnergyModelsBase.check_representative_profile`

`EnergyModelsBase.check_scenario_profile`

`EnergyModelsBase.check_strategic_profile`

`EnergyModelsBase.check_time_structure`

`EnergyModelsBase.collect_types`

`EnergyModelsBase.compile_logs`

`EnergyModelsBase.constraints_emissions`

`EnergyModelsBase.constraints_level_aux`

`EnergyModelsBase.constraints_level_aux`

`EnergyModelsBase.constraints_level_sp`

`EnergyModelsBase.constraints_level_sp`

`EnergyModelsBase.constraints_level_sp`

`EnergyModelsBase.constraints_level_sp`

`EnergyModelsBase.constraints_links`

`EnergyModelsBase.constraints_node`

`EnergyModelsBase.create_link`

`EnergyModelsBase.is_network_node`

`EnergyModelsBase.is_resource_emit`

`EnergyModelsBase.is_sink`

`EnergyModelsBase.is_source`

`EnergyModelsBase.is_storage`

`EnergyModelsBase.link_res`

`EnergyModelsBase.link_sub`

`EnergyModelsBase.multiple`

`EnergyModelsBase.nodes_not_av`

`EnergyModelsBase.nodes_not_sub`

`EnergyModelsBase.nodes_sub`

`EnergyModelsBase.objective`

`EnergyModelsBase.res_em`

`EnergyModelsBase.res_not`

`EnergyModelsBase.res_sub`

`EnergyModelsBase.sort_types`

`EnergyModelsBase.variables_capacity`

`EnergyModelsBase.variables_capex`

`EnergyModelsBase.variables_emission`

`EnergyModelsBase.variables_flow`

`EnergyModelsBase.variables_nodes`

`EnergyModelsBase.variables_opex`

## Types

`EnergyModelsBase.Formulation`

— TypeDeclaration of the general type for formulation of links.

`EnergyModelsBase.Node`

— Type`Node`

as supertype for all technologies.

## Methods

`EnergyModelsBase.check_case_data`

— Method`check_case_data(case)`

Checks the `case`

dictionary is in the correct format.

**Checks**

- The dictionary requires the keys
`:T`

,`:nodes`

,`:links`

, and`:products`

. - The individual keys are of the correct type, that is
`:T::TimeStructure`

,`:nodes::Vector{<:Node}`

,`:links::Vector{<:Link}`

, and`:products::Vector{<:Resource}`

.

`EnergyModelsBase.check_data`

— Method`check_data(case, modeltype, check_timeprofiles::Bool)`

Check if the case data is consistent. Use the `@assert_or_log`

macro when testing. Currently only checking node data.

`EnergyModelsBase.check_fixed_opex`

— Method`check_fixed_opex(n::Node, 𝒯ᴵⁿᵛ, check_timeprofiles::Bool)`

Checks that the fixed opex value follows the given TimeStructure.

**Checks**

- The
`opex_fixed`

time profile cannot have a finer granulation than`StrategicProfile`

.

**Conditional checks (if check_timeprofiles=true)**

- The profiles in
`opex_fixed`

have to have the same length as the number of strategic periods.

`EnergyModelsBase.check_model`

— Method`check_model(case, modeltype::EnergyModel, check_timeprofiles::Bool)`

Checks the `modeltype`

.

**Checks**

- All
`ResourceEmit`

s require a corresponding value in the field`emission_limit`

. - The
`emission_limit`

time profiles cannot have a finer granulation than`StrategicProfile`

. - The
`emission_price`

time profiles cannot have a finer granulation than`StrategicProfile`

.

**Conditional checks (if check_timeprofiles=true)**

- The profiles in
`emission_limit`

have to have the same length as the number of strategic periods. - The profiles in
`emission_price`

have to have the same length as the number of strategic

periods.

`EnergyModelsBase.check_node`

— Method`check_node(n::Availability, 𝒯, modeltype::EnergyModel)`

This method checks that an `Availability`

node is valid. By default, that does not include any checks.

`EnergyModelsBase.check_node`

— Method`check_node(n::Node, 𝒯, modeltype::EnergyModel)`

Check that the fields of a `Node`

corresponds to required structure.

`EnergyModelsBase.check_node`

— Method`check_node(n::NetworkNode, 𝒯, modeltype::EnergyModel)`

This method checks that a `NetworkNode`

node is valid.

These checks are always performed, if the user is not creating a new method. Hence, it is important that a new `NetworkNode`

type includes at least the same fields as in the `RefNetworkNode`

node or that a new `NetworkNode`

type receives a new method for `check_node`

.

**Checks**

- The field
`cap`

is required to be non-negative. - The values of the dictionary
`input`

are required to be non-negative. - The values of the dictionary
`output`

are required to be non-negative. - The value of the field
`fixed_opex`

is required to be non-negative and accessible through a`StrategicPeriod`

as outlined in the function`check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)`

.

`EnergyModelsBase.check_node`

— Method`check_node(n::Sink, 𝒯, modeltype::EnergyModel)`

This method checks that a `Sink`

node is valid.

These checks are always performed, if the user is not creating a new method. Hence, it is important that a new `Sink`

type includes at least the same fields as in the `RefSink`

node or that a new `Source`

type receives a new method for `check_node`

.

**Checks**

- The field
`cap`

is required to be non-negative. - The values of the dictionary
`input`

are required to be non-negative. - The dictionary
`penalty`

is required to have the keys`:deficit`

and`:surplus`

. - The sum of the values
`:deficit`

and`:surplus`

in the dictionary`penalty`

has to be non-negative to avoid an infeasible model.

`EnergyModelsBase.check_node`

— Method`check_node(n::Source, 𝒯, modeltype::EnergyModel)`

This method checks that a `Source`

node is valid.

These checks are always performed, if the user is not creating a new method. Hence, it is important that a new `Source`

type includes at least the same fields as in the `RefSource`

node or that a new `Source`

type receives a new method for `check_node`

.

**Checks**

- The field
`cap`

is required to be non-negative. - The values of the dictionary
`output`

are required to be non-negative. - The value of the field
`fixed_opex`

is required to be non-negative and accessible through a`StrategicPeriod`

as outlined in the function`check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)`

.

`EnergyModelsBase.check_node`

— Method`check_node(n::Storage, 𝒯, modeltype::EnergyModel)`

This method checks that a `Storage`

node is valid.

These checks are always performed, if the user is not creating a new method. Hence, it is important that a new `Storage`

type includes at least the same fields as in the `RefStorage`

node or that a new `Storage`

type receives a new method for `check_node`

.

**Checks**

- The value of the field
`rate_cap`

is required to be non-negative. - The value of the field
`stor_cap`

is required to be non-negative. - The values of the dictionary
`input`

are required to be non-negative. - The values of the dictionary
`output`

are required to be non-negative. - The value of the field
`fixed_opex`

is required to be non-negative and accessible through a`StrategicPeriod`

as outlined in the function`check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)`

.

`EnergyModelsBase.check_node_data`

— Method`check_node_data(n::Node, data::Data, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)`

Check that the included `Data`

types of a `Node`

corresponds to required structure. This function will always result in a multiple error message, if several instances of the same supertype is loaded.

`EnergyModelsBase.check_node_data`

— Method`check_node_data(n::Node, data::EmissionsData, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)`

Check that the included `Data`

types of a `Node`

corresponds to required structure. This function will always result in a multiple error message, if several instances of the same supertype is loaded.

**Checks**

- Each node can only have a single
`EmissionsData`

. - Time profiles for process emissions, if present.
- The value of the field
`co2_capture`

is required to be in the range $[0, 1]$, if`CaptureData`

is used.

`EnergyModelsBase.check_profile`

— Method`check_profile(fieldname, value::TimeProfile, ts::TimeStructure, sp)`

Check that an individual `TimeProfile`

corresponds to the time structure `ts`

in strategic period sp. The function flow is designed to provide errors in all situations It currently does not include support for identifying `OperationalProfile`

s.

`EnergyModelsBase.check_profile`

— Method`check_profile(fieldname, value::TimeProfile, 𝒯)`

Check that an individual `TimeProfile`

corresponds to the time structure `𝒯`

. It currently does not include support for identifying `OperationalProfile`

s.

`EnergyModelsBase.check_representative_profile`

— Method`check_representative_profile(time_profile::TimeProfile, message::String)`

Function for checking that an individual `TimeProfile`

does not include the wrong type for representative periods indexing

**Input**

`time_profile`

- The time profile that should be checked.`message`

- A message that should be printed after the type of profile.

**Checks**

`TimeProfile`

s access in`RepresentativePeriod`

s cannot include`OperationalProfile`

or`ScenarioProfile`

as this is not allowed through indexing on the`TimeProfile`

.

`EnergyModelsBase.check_scenario_profile`

— Method`check_scenario_profile(time_profile::TimeProfile, message::String)`

Function for checking that an individual `TimeProfile`

does not include the wrong type for scenario indexing

**Checks**

`TimeProfile`

s access in`RepresentativePeriod`

s cannot include`OperationalProfile`

or`ScenarioProfile`

as this is not allowed through indexing on the`TimeProfile`

.

`EnergyModelsBase.check_strategic_profile`

— Method`check_strategic_profile(time_profile::TimeProfile, message::String)`

Function for checking that an individual `TimeProfile`

does not include the wrong type for strategic indexing

**Checks**

`TimeProfile`

s access in`StrategicPeriod`

s cannot include`OperationalProfile`

,`ScenarioProfile`

, or`RepresentativeProfile`

as this is not allowed through indexing on the`TimeProfile`

.

`EnergyModelsBase.check_time_structure`

— Method`check_time_structure(n::Node, 𝒯)`

Check that all fields of a `Node`

that are of type `TimeProfile`

correspond to the time structure `𝒯`

.

`EnergyModelsBase.collect_types`

— Method`collect_types(types_list)`

Return a Dict of all the give types_list and their supertypes. The keys in the dictionary are the types, and their corresponding value is the number in the type hierarchy.

E.g., `Node`

is at the top and will thus have the value 1. Types just below `Node`

will have value 2, and so on.

`EnergyModelsBase.compile_logs`

— Method`compile_logs(case, log_by_element)`

Simple method for showing all log messages.

`EnergyModelsBase.constraints_emissions`

— Method`constraints_emissions(m, 𝒩, 𝒯, 𝒫, modeltype::EnergyModel)`

Create constraints for the emissions accounting for both operational and strategic periods.

`EnergyModelsBase.constraints_level_aux`

— Method`constraints_level_aux(m, n::RefStorage{S}, 𝒯, 𝒫, modeltype::EnergyModel) where {S<:ResourceCarrier}`

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

resource.

`EnergyModelsBase.constraints_level_aux`

— Method`constraints_level_aux(m, n::RefStorage{S}, 𝒯, 𝒫, modeltype::EnergyModel) where {S<:ResourceEmit}`

Function for creating the Δ constraint for the level of a reference storage node with a `ResourceEmit`

resource.

`EnergyModelsBase.constraints_level_sp`

— Method```
constraints_level_sp(
m,
n::RefStorage{S},
t_inv::TS.StrategicPeriod{T, RepresentativePeriods{U, T, SimpleTimes{T}}},
𝒫,
modeltype::EnergyModel
) where {S<:ResourceCarrier, T, U}
```

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

resource when the operational `TimeStructure`

is given as `RepresentativePeriods`

.

`EnergyModelsBase.constraints_level_sp`

— Method```
constraints_level_sp(
m,
n::RefStorage{S},
t_inv::TS.StrategicPeriod{T, RepresentativePeriods{U, T, SimpleTimes{T}}},
𝒫,
modeltype::EnergyModel
) where {S<:ResourceEmit, T, U}
```

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

resource when the operational TimeStructure is given as `RepresentativePeriods`

.

`EnergyModelsBase.constraints_level_sp`

— Method```
constraints_level_sp(
m,
n::RefStorage{S},
t_inv::TS.StrategicPeriod{T, U},
𝒫,
modeltype::EnergyModel
) where {S<:ResourceCarrier, T, U<:SimpleTimes}
```

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

resource when the operational `TimeStructure`

is given as `SimpleTimes`

.

`EnergyModelsBase.constraints_level_sp`

— Method```
constraints_level_sp(
m,
n::RefStorage{S},
t_inv::TS.StrategicPeriod{T, U},
𝒫,
modeltype::EnergyModel
) where {S<:ResourceEmit, T, U<:SimpleTimes}
```

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

resource when the operational TimeStructure is given as `SimpleTimes`

.

`EnergyModelsBase.constraints_links`

— Method`constraints_links(m, 𝒩, 𝒯, 𝒫, ℒ, modeltype::EnergyModel)`

Call the function `create_link`

for link formulation

`EnergyModelsBase.constraints_node`

— Method`constraints_node(m, 𝒩, 𝒯, 𝒫, ℒ, modeltype::EnergyModel)`

Create link constraints for each `n ∈ 𝒩`

depending on its type and calling the function `create_node(m, n, 𝒯, 𝒫)`

for the individual node constraints.

Create constraints for fixed OPEX.

`EnergyModelsBase.create_link`

— Method`create_link(m, 𝒯, 𝒫, l, formulation::Formulation)`

Set the constraints for a simple `Link`

(input = output). Can serve as fallback option for all unspecified subtypes of `Link`

.

`EnergyModelsBase.is_network_node`

— Method`is_network_node(n::Node)`

Checks, whether node `n`

is a `NetworkNode`

node

`EnergyModelsBase.is_resource_emit`

— Method`is_resource_emit(p::Resource)`

Checks whether the Resource `p`

is of type `ResourceEmit`

.

`EnergyModelsBase.is_sink`

— Method`is_sink(n::Node)`

Checks, whether node `n`

is a `Sink`

node

`EnergyModelsBase.is_source`

— Method`is_source(n::Node)`

Checks, whether node `n`

is a `Source`

node

`EnergyModelsBase.is_storage`

— Method`is_storage(n::Node)`

Checks, whether node `n`

is a `Storage`

node

`EnergyModelsBase.link_res`

— Method`link_res(l::Link)`

Return the resources transported for a given link `l`

.

`EnergyModelsBase.link_sub`

— Method`link_sub(ℒ::Vector{<:Link}, n::Node)`

Return connected links for a given node `n`

.

`EnergyModelsBase.multiple`

— Method`multiple(t_inv, t)`

Provide a simplified function for returning the combination of the functions duration(t) * multiple*strat(t*inv, t) * probability(t)

`EnergyModelsBase.nodes_not_av`

— Method`nodes_not_av(𝒩::Array{<:Node})`

Return nodes that are not `Availability`

nodes for a given Array `𝒩::Array{<:Node}`

.

`EnergyModelsBase.nodes_not_sub`

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

Return nodes that are not of type `sub`

for a given Array `𝒩::Array{<:Node}`

.

`EnergyModelsBase.nodes_sub`

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

Return nodes that are of type `sub`

for a given Array `𝒩::Array{<:Node}`

.

`EnergyModelsBase.objective`

— Method`objective(m, 𝒩, 𝒯, 𝒫, modeltype::EnergyModel)`

Create the objective for the optimization problem for a given modeltype.

`EnergyModelsBase.res_em`

— Method`res_em(𝒫::Array{<:Resource})`

Returns all emission resources for a

- a given array
`::Array{<:Resource}`

.The output is in this case an`Array{<:Resource}`

- a given dictionary
`::Dict`

.The output is in this case a dictionary`Dict`

with the correct fields

`EnergyModelsBase.res_not`

— Method`res_not(𝒩::Array{<:Resource}, res_inst)`

Return all resources that are not `res_inst`

for

- a given array
`::Array{<:Resource}`

.The output is in this case an`Array{<:Resource}`

- a given dictionary
`::Dict`

.The output is in this case a dictionary`Dict`

with the correct fields

`EnergyModelsBase.res_sub`

— Function`res_sub(𝒫::Array{<:Resource}, sub = ResourceEmit)`

Return resources that are of type `sub`

for a given Array `::Array{Resource}`

.

`EnergyModelsBase.sort_types`

— Method`sort_types(types_list::Dict)`

Sort the result of `collect_types`

and return a vector where a supertype comes before all its subtypes.

`EnergyModelsBase.variables_capacity`

— Method`variables_capacity(m, 𝒩, 𝒯, modeltype::EnergyModel)`

Creation of different capacity variables for nodes `𝒩ⁿᵒᵗ`

that are neither `Storage`

nor `Availability`

nodes. These variables are:

`:cap_use`

- use of a technology node in each operational period`:cap_inst`

- installed capacity in each operational period in terms of either`:flow_in`

or `:flow_out`

(depending on node `n ∈ 𝒩`

)

Creation of different storage variables for `Storage`

nodes `𝒩ˢᵗᵒʳ`

. These variables are:

`:stor_level`

- storage level at the end of each operational period`:stor_level_Δ_op`

- storage level change in each operational period`:stor_level_Δ_rp`

- storage level change in each representative period`:stor_rate_use`

- storage rate use in each operational period`:stor_cap_inst`

- installed capacity for storage in each operational period, constrained

in the operational case to `n.stor_cap`

`:stor_rate_inst`

- installed rate for storage, e.g. power in each operational period,

constrained in the operational case to `n.rate_cap`

`EnergyModelsBase.variables_capex`

— Method`variables_capex(m, 𝒩, 𝒯, 𝒫, modeltype::EnergyModel)`

Declaration of the CAPEX variables of the model for each investment period `𝒯ᴵⁿᵛ ∈ 𝒯`

. Empty for operational models but required for multiple dispatch in investment model.

`EnergyModelsBase.variables_emission`

— Method`variables_emission(m, 𝒩, 𝒯, 𝒫, modeltype::EnergyModel)`

Declaration of emission variables per technology node with emissions `n ∈ 𝒩ᵉᵐ`

and emission resource `𝒫ᵉᵐ ∈ 𝒫`

.

The emission variables are differentiated in:

`:emissions_node`

- emissions of a node in an operational period,`:emissions_total`

- total emissions in an operational period, and`:emissions_strategic`

- total strategic emissions, constrained to an upper limit based on the field`emission_limit`

of the`EnergyModel`

.

`EnergyModelsBase.variables_flow`

— Method`variables_flow(m, 𝒩, 𝒯, 𝒫, ℒ, modeltype::EnergyModel)`

Declaration of the individual input (`:flow_in`

) and output (`:flow_out`

) flowrates for each technological node `n ∈ 𝒩`

and link `l ∈ ℒ`

(`:link_in`

and `:link_out`

).

`EnergyModelsBase.variables_nodes`

— Method`variables_nodes(m, 𝒩, 𝒯, modeltype::EnergyModel)`

Loop through all node types and create variables specific to each type. This is done by calling the method `variables_node`

on all nodes of each type.

The node type representing the widest cathegory will be called first. That is, `variables_node`

will be called on a `Node`

before it is called on `NetworkNode`

-nodes.

`EnergyModelsBase.variables_opex`

— Method`variables_opex(m, 𝒩, 𝒯, 𝒫, modeltype::EnergyModel)`

Declaration of the OPEX variables (`:opex_var`

and `:opex_fixed`

) of the model for each period `𝒯ᴵⁿᵛ ∈ 𝒯`

. Variable OPEX can be non negative to account for revenue streams.