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
Index
EnergyModelsBase.Accumulating
EnergyModelsBase.AccumulatingEmissions
EnergyModelsBase.Availability
EnergyModelsBase.Cyclic
EnergyModelsBase.CyclicRepresentative
EnergyModelsBase.CyclicStrategic
EnergyModelsBase.GenAvailability
EnergyModelsBase.NetworkNode
EnergyModelsBase.RefNetworkNode
EnergyModelsBase.RefSink
EnergyModelsBase.RefSource
EnergyModelsBase.RefStorage
EnergyModelsBase.Sink
EnergyModelsBase.Source
EnergyModelsBase.StorCap
EnergyModelsBase.StorCapOpex
EnergyModelsBase.StorCapOpexFixed
EnergyModelsBase.StorCapOpexVar
EnergyModelsBase.StorOpexVar
EnergyModelsBase.Storage
EnergyModelsBase.UnionCapacity
EnergyModelsBase.UnionOpexFixed
EnergyModelsBase.UnionOpexVar
EnergyModelsBase.capacity
EnergyModelsBase.charge
EnergyModelsBase.deficit_penalty
EnergyModelsBase.discharge
EnergyModelsBase.has_charge
EnergyModelsBase.has_discharge
EnergyModelsBase.has_emissions
EnergyModelsBase.has_input
EnergyModelsBase.has_output
EnergyModelsBase.inputs
EnergyModelsBase.is_unidirectional
EnergyModelsBase.level
EnergyModelsBase.node_data
EnergyModelsBase.nodes_emissions
EnergyModelsBase.nodes_input
EnergyModelsBase.nodes_output
EnergyModelsBase.opex_fixed
EnergyModelsBase.opex_var
EnergyModelsBase.outputs
EnergyModelsBase.storage_resource
EnergyModelsBase.surplus_penalty
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
— TypeSource
node with only output.
EnergyModelsBase.NetworkNode
— TypeNetworkNode
node with both input and output.
EnergyModelsBase.Sink
— TypeSink
node with only input.
EnergyModelsBase.Storage
— TypeStorage
node with level.
EnergyModelsBase.Availability
— TypeAvailability
node as routing node.
Reference node types
The following composite types are implemented 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
— TypeRefSource <: Source
A reference Source
node. The reference Source
node allows for a time varying capacity which is normalized to a conversion value of 1 in the field input
. Note, that if you include investments, you can only use as TimeProfile
a FixedProfile
or StrategicProfile
.
Fields
id
is the name/identifier of the node.cap::TimeProfile
is the installed capacity.opex_var::TimeProfile
is the variable operating expense per per capacity usage through the variable:cap_use
.opex_fixed::TimeProfile
is the fixed operating expense per installed capacity through the variable:cap_inst
.output::Dict{<:Resource,<:Real}
are the generatedResource
s with conversion valueReal
.data::Vector{<:Data}
is the additional data (e.g., for investments). The fielddata
is conditional through usage of a constructor.
EnergyModelsBase.RefNetworkNode
— TypeRefNetworkNode <: NetworkNode
A reference NetworkNode
node. The RefNetworkNode
utilizes a linear, time independent conversion rate of the input
Resource
s to the output Resource
s, subject to the available capacity. The capacity is hereby normalized to a conversion value of 1 in the fields input
and output
.
Fields
id
is the name/identifier of the node.cap::TimeProfile
is the installed capacity.opex_var::TimeProfile
is the variable operating expense per per capacity usage through the variable:cap_use
.opex_fixed::TimeProfile
is the fixed operating expense per installed capacity through the variable:cap_inst
.input::Dict{<:Resource,<:Real}
are the inputResource
s with conversion valueReal
.output::Dict{<:Resource,<:Real}
are the generatedResource
s with conversion valueReal
.data::Vector{Data}
is the additional data (e.g., for investments). The fielddata
is conditional through usage of a constructor.
EnergyModelsBase.RefSink
— TypeRefSink <: Sink
A reference Sink
node. This node corresponds to a demand given by the field cap
. The penalties introduced in the field penalty
affect the variable OPEX for both a surplus and deficit.
Fields
id
is the name/identifier of the node.cap::TimeProfile
is the demand.penalty::Dict{Symbol,<:TimeProfile}
are penalties for surplus or deficits. The dictionary requires the fields:surplus
and:deficit
.input::Dict{<:Resource,<:Real}
are the inputResource
s with conversion valueReal
.data::Vector{<:Data}
is the additional data (e.g., for investments). The fielddata
is conditional through usage of a constructor.
EnergyModelsBase.RefStorage
— TypeRefStorage{T} <: Storage{T}
A reference Storage
node.
This node is designed to store either a ResourceCarrier
or a ResourceEmit
. It is designed as a parametric type through the type parameter T
to differentiate between different cyclic behaviours. Note that the parameter T
is only used for dispatching, but does not carry any other information. Hence, it is simple to fast switch between different StorageBehavior
s.
The current implemented cyclic behaviours are CyclicRepresentative
, CyclicStrategic
, and AccumulatingEmissions
.
Fields
id
is the name/identifier of the node.charge::AbstractStorageParameters
are the charging parameters of theStorage
node. Depending on the chosen type, the charge parameters can include variable OPEX, fixed OPEX, and/or a capacity.level::AbstractStorageParameters
are the level parameters of theStorage
node. Depending on the chosen type, the charge parameters can include variable OPEX and/or fixed OPEX.stor_res::Resource
is the storedResource
.input::Dict{<:Resource,<:Real}
are the inputResource
s with conversion valueReal
.output::Dict{<:Resource,<:Real}
are the generatedResource
s with conversion valueReal
. Only relevant for linking and the storedResource
as the output value is not utilized in the calculations.data::Vector{<:Data}
is the additional data (e.g., for investments). The fielddata
is conditional through usage of a constructor.
EnergyModelsBase.GenAvailability
— TypeGenAvailability <: Availability
A reference Availability
node. The reference Availability
node solves the energy balance for all connected flows.
Fields
id
is the name/identifier of the node.inputs::Vector{<:Resource}
are the inputResource
s.output::Vector{<:Resource}
are the outputResource
s.
A constructor is provided so that only a single array can be provided with the fields:
id
is the name/identifier of the node.𝒫::Vector{<:Resource}
are the[
Resource`](@ref)s.
Storage behaviours
EnergyModelsBase
provides several different storage behaviours for calculating the level balance of a Storage
node. In general, the concrete storage behaviours are ready to use and should account for all eventualities.
EnergyModelsBase.Accumulating
— TypeAccumulating <: StorageBehavior
Accumulating
as supertype for an accumulating storage level.
Accumulating storage behaviour implies that the change in the overall storage level in a strategic period can be both positive or negative.
Examples for potential usage of Accumulating
are CO₂ storages in which the CO₂ is permanently stored or multi year hydropower magazines.
EnergyModelsBase.AccumulatingEmissions
— TypeAccumulatingEmissions <: Accumulating
StorageBehavior
which accumulates all inflow witin a strategic period. AccumulatingEmissions
allows as well to serve as a ResourceEmit
emission point to represent a soft constraint on storing the captured emissions.
EnergyModelsBase.Cyclic
— TypeCyclic <: StorageBehavior
Cyclic
as supertype for a cyclic storage level.
Cyclic storage behaviour implies that the change in the overall storage level in a strategic period behaves cyclic.
EnergyModelsBase.CyclicRepresentative
— TypeCyclicRepresentative <: Cyclic
StorageBehavior
in which cyclic behaviour is achieved within the lowest time structure excluding operational times.
In the case of TwoLevel{SimpleTimes}
, this approach is similar to CyclicStrategic
. In the case of TwoLevel{RepresentativePeriods{SimpleTimes}}
, this approach differs from CyclicStrategic
as the cyclic constraint is enforeced within each representative period.
EnergyModelsBase.CyclicStrategic
— TypeCyclicStrategic <: Cyclic
StorageBehavior
in which the the cyclic behaviour is achieved within a strategic period. This implies that the initial level in individual representative periods can be different when using RepresentativePeriods
.
We have not yet supported upper and lower bound constraints in the case of using OperationalScenarios
. While the calculation of the overall level balance and the operational costs is consistent, it can happen that the upper and lower bound of the storage level is violated.
This impacts specifically CyclicStrategic
.
Storage parameters
Storage parameters are used for describing different parameters for the individual capacities of a Storage
node. In practice, Storage
nodes can have three different capacities:
- charge, that is a capacity for charging the
Storage
node, - level, that is the amount of energy/mass that can be stored, and
- discharge, that is a capacity for discharging the
Storage
node.
In general, each of the individual capacities can have an assigned capacity, variable OPEX, and fixed OPEX. Furthermore, it is possible to only have a variable OPEX. To this end, multiple composite types are defined.
EnergyModelsBase.StorCapOpex
— TypeStorCapOpex <: AbstractStorageParameters
A storage parameter type for including a capacity as well as variable and fixed operational expenditures.
Fields
capacity::TimeProfile
is the installed capacity.opex_var::TimeProfile
is the variable operating expense per capacity usage through the variable:cap_use
.opex_fixed::TimeProfile
is the fixed operating expense per installed capacity through the variable:cap_inst
.
EnergyModelsBase.StorCap
— TypeStorCap <: AbstractStorageParameters
A storage parameter type for including only a capacity. This implies that neither the usage of the Storage
, nor the installed capacity have a direct impact on the objective function.
Fields
capacity::TimeProfile
is the installed capacity.
EnergyModelsBase.StorCapOpexVar
— TypeStorCap <: AbstractStorageParameters
A storage parameter type for including a capacity and variable operational expenditures. This implies that the installed capacity has no direct impact on the objective function.
Fields
capacity::TimeProfile
is the installed capacity.opex_var::TimeProfile
is the variable operating expense per capacity usage through the variable:cap_use
.
EnergyModelsBase.StorCapOpexFixed
— TypeStorCapOpexFixed <: AbstractStorageParameters
A storage parameter type for including a capacity and fixed operational expenditures. This implies that the installed capacity has no direct impact on the objective function.
Fields
capacity::TimeProfile
is the installed capacity.opex_fixed::TimeProfile
is the fixed operating expense per installed capacity through the variable:cap_inst
.
EnergyModelsBase.StorOpexVar
— TypeStorCap <: AbstractStorageParameters
A storage parameter type for including variable operational expenditures. This implies that the charge or discharge rate do not have a capacity and the Storage
level can be used within a single TimePeriod
.
This type can only be used for the fields charge
and discharge
.
Fields
opex_var::TimeProfile
is the variable operating expense per capacity usage through the variable:cap_use
.
When dispatching on the individual type, it is also possible to use the following unions:
EnergyModelsBase.UnionOpexFixed
— TypeUnionOpexFixed
Union for simpler dispatching for storage parameters that include fixed OPEX.
EnergyModelsBase.UnionOpexVar
— TypeUnionOpexVar
Union for simpler dispatching for storage parameters that include variable OPEX.
EnergyModelsBase.UnionCapacity
— TypeUnionCapacity
Union for simpler dispatching for storage parameters that include a capacity.
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
— Functioncapacity(n::Node)
capacity(n::Node, t)
Returns the capacity of a node n
as TimeProfile
or in operational period t
.
The capacity is not directly defined for Storage
nodes. Instead, it is necessary to call the function on the respective field, see capacity(stor_par::AbstractStorageParameters)
.
capacity(stor_par::AbstractStorageParameters)
capacity(stor_par::AbstractStorageParameters, t)
Returns the capacity of storage parameter stor_par
as TimeProfile
or in operational period t
.
The individual storage parameters of a Storage
node can be accessed through the functions charge(n)
, level(n)
, and discharge(n)
.
EnergyModelsBase.opex_var
— Functionopex_var(n::Node)
opex_var(n::Node, t)
Returns the variable OPEX of a node n
as TimeProfile
or in operational period t
.
The variable OPEX is not directly defined for Storage
nodes. Instead, it is necessary to call the function on the respective field, see opex_var(stor_par::AbstractStorageParameters)
.
opex_var(stor_par::UnionOpexVar)
opex_var(stor_par::UnionOpexVar, t)
Returns the variable OPEX of storage parameter stor_par
as TimeProfile
or in operational period t
.
The individual storage parameters of a Storage
node can be accessed through the functions charge(n)
, level(n)
, and discharge(n)
.
EnergyModelsBase.opex_fixed
— Functionopex_fixed(n::Node)
opex_fixed(n::Node, t_inv)
Returns the fixed OPEX of a node node n
as TimeProfile
or in strategic period t_inv
.
The fixed OPEX is not directly defined for Storage
nodes. Instead, it is necessary to call the function on the respective field, see opex_fixed(stor_par::AbstractStorageParameters)
.
opex_fixed(stor_par::UnionOpexFixed)
opex_fixed(stor_par::UnionOpexFixed, t_inv)
Returns the fixed OPEX of storage parameter stor_par
as TimeProfile
or in strategic period t_inv
.
The individual storage parameters of a Storage
node can be accessed through the functions charge(n)
, level(n)
, and discharge(n)
.
EnergyModelsBase.inputs
— Methodinputs(n::Node)
inputs(n::Node, p::Resource)
Returns the input resources of a node n
, specified via the field input
.
If the resource p
is specified, it returns the value (1 in the case of Availability
, nothing in the case of a Source
)
EnergyModelsBase.outputs
— Methodoutputs(n::Node)
outputs(n::Node, p::Resource)
Returns the output resources of a node n
, specified via the field output
.
If the resource p
is specified, it returns the value (1 in the case of Availability
, nothing in the case of a Sink
)
EnergyModelsBase.node_data
— Functionnode_data(n::Node)
Returns the Data
array of node n
.
EnergyModelsBase.charge
— Functioncharge(n::Storage)
Returns the parameter type of the charge
field of the node. If the node has no field charge
, it returns nothing
.
EnergyModelsBase.level
— Functionlevel(n::Storage)
Returns the parameter type of the level
field of the node.
EnergyModelsBase.discharge
— Functiondischarge(n::Storage)
Returns the parameter type of the discharge
field of the node. If the node has no field discharge
, it returns nothing
.
EnergyModelsBase.storage_resource
— Functionstorage_resource(n::Storage)
Returns the storage resource of Storage
node n
.
EnergyModelsBase.surplus_penalty
— Functionsurplus_penalty(n::Sink)
surplus_penalty(n::Sink, t)
Returns the surplus penalty of sink n
as TimeProfile
or in operational period t
.
EnergyModelsBase.deficit_penalty
— Functiondeficit_penalty(n::Sink)
deficit_penalty(n::Sink, t)
Returns the deficit penalty of sink n
as TimeProfile
or in 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
— Functionnodes_input(𝒩::Array{<:Node}, sub)
Returns nodes that have an input, i.e., Sink
and NetworkNode
nodes.
EnergyModelsBase.nodes_output
— Functionnodes_output(𝒩::Array{<:Node})
Returns nodes that have an output, i.e., Source
and NetworkNode
nodes.
EnergyModelsBase.nodes_emissions
— Functionhas_emissions(𝒩::Array{<:Node})
Returns nodes that have emission data for a given Array ::Array{<:Node}
.
EnergyModelsBase.has_input
— Functionhas_input(n::Node)
Returns logic whether the node is an input node, i.e., Sink
and NetworkNode
nodes.
EnergyModelsBase.has_output
— Functionhas_output(n::Node)
Returns logic whether the node is an output node, i.e., Source
and NetworkNode
nodes.
EnergyModelsBase.has_emissions
— Methodhas_emissions(n::Node)
Checks whether node n
has emissions.
EnergyModelsBase.has_charge
— Functionhas_charge(n::Storage)
Returns logic whether the node has a charge
field allowing for restrictions and/or costs on the (installed) charging rate.
EnergyModelsBase.has_discharge
— Functionhas_discharge(n::Storage)
Returns logic whether the node has a discharge
field allowing for restrictions and/or costs on the (installed) discharging rate.
EnergyModelsBase.is_unidirectional
— Methodis_unidirectional(n::Node)
Returns logic whether the node n
can be used bidirectional or only unidirectional.
In the current stage, EnergyModelsBase
does not include any nodes which can be used bidirectional, that is with flow reversal.
If you plan to use bidirectional flow, you have to declare your own nodes and links that support this. You can then dispatch on this function for the incorporation.