Connection
Caution
Proper transformation (from Julia docs to Python docs) of math mode rendering, and therefore the “detailed model reference”, is partially broken. Until this is fixed, please refer to the original Julia documentation for any math mode rendering.
Overview
Note
This section of the documentation is auto-generated from the code of the Julia-based core model. Refer to IESopt.jl and its documentation for any further details (which may require some familiarity with Julia).
A Connection
is used to model arbitrary flows of energy between Node
s. It allows for limits, costs, delays, …
Parameters
node_from
This Connection
models a flow from node_from
to node_to
(both are Node
s).
- Mandatory:
yes
- Values:
string
- Unit:
- Default:
node_to
This Connection
models a flow from node_from
to node_to
(both are Node
s).
- Mandatory:
yes
- Values:
string
- Unit:
- Default:
carrier
Carrier
of this Connection
. If not given, automatically picks the carrier
of the Node
s it connects. This parameter is not necessary, and only exists to allow for a more explicit definition.
- Mandatory:
no
- Values:
string
- Unit:
- Default:
capacity
The symmetric bound on this Connection
’s flow. Results in lb = -capacity
and ub = capacity
. Must not be specified if lb
, ub
, or both are explicitly stated.
- Mandatory:
no
- Values:
numeric,
col@file
,decision:value
- Unit:
power
- Default:
\(+\infty\)
lb
Lower bound of this Connection
’s flow.
- Mandatory:
no
- Values:
numeric,
col@file
,decision:value
- Unit:
power
- Default:
\(-\infty\)
ub
Upper bound of this Connection
’s flow.
- Mandatory:
no
- Values:
numeric,
col@file
,decision:value
- Unit:
power
- Default:
\(+\infty\)
cost
Cost of every unit of energy flow over this connection that is added to the model’s objective function. Keep in mind that negative flows will induce negative costs, which can be used to model revenues. Further, a bidirectional Connection
(if lb < 0
, which is the default, or if capacity
is used) with a positive cost
will lead to negative costs for the reverse flow. If you do not want this, split the Connection
into two separate ones, each being unidirectional (with lb: 0
). Remember, that these can share the same “capacity” (which is then set asub
), even when using decision:value
or col@file
as value.
- Mandatory:
no
- Values:
numeric
- Unit:
monetary (per energy)
- Default:
loss
Fractional loss when transfering energy. This loss occurs “at the destination”, which means that for a loss of 5%, set as loss: 0.05
, and considering a Snapshot
where the Connection
has a flow value of 100
, it will “extract” 100
from node_from
and “inject” 95
into node_to
. Since the flow variable is given as power, this would, e.g., translate to consuming 200 units of energy at node_from
and injecting 190 units at node_to
, if the Snapshot
duration is 2 hours.
- Mandatory:
no
- Values:
\(\in [0, 1]\)
- Unit:
- Default:
0
build_priority
Priority for the build order of components. Components with higher build_priority are built before. This can be useful for addons, that connect multiple components and rely on specific components being initialized before others.
- Mandatory:
no
- Values:
numeric
- Unit:
- Default:
0
Detailed model reference
Variables
flow
How to?
Access this variable by using:
# Julia
component(model, "your_connection").var.flow
# Python
model.get_component("your_connection").var.flow
You can find the full implementation and all details here: IESopt.jl
.
Add the variable representing the flow of this connection
to the model
. This can be accessed via connection.var.flow[t]
.
Additionally, the flow gets “injected” at the Node
s that the connection
is connecting, resulting in
$\(
\begin{aligned}
& \text{connection.node}_{from}\text{.injection}_t = \text{connection.node}_{from}\text{.injection}_t - \text{flow}_t, \qquad \forall t \in T \\
& \text{connection.node}_{to}\text{.injection}_t = \text{connection.node}_{to}\text{.injection}_t + \text{flow}_t, \qquad \forall t \in T
\end{aligned}
\)$
math
For “PF controlled”
Connection
s (ones that define the necessary power flow parameters), the flow variable may not be constructed (depending on specific power flow being used). The automatic result extraction will detect this and return the correct values either way. Accessing it manually can be done usingconnection.exp.pf_flow[t]
.
Expressions
pf_flow
How to?
Access this expression by using:
# Julia
component(model, "your_connection").exp.pf_flow
# Python
model.get_component("your_connection").exp.pf_flow
You can find the full implementation and all details here: IESopt.jl
.
Construct the JuMP.AffExpr
holding the PTDF based flow of this Connection
.
This needs the global addon Powerflow
with proper settings for mode
, as well as properly configured power flow parameters for this Connection
(pf_V
, pf_I
, pf_X
, …).
Constraints
flow_bounds
How to?
Access this constraint by using:
# Julia
component(model, "your_connection").con.flow_bounds
# Python
model.get_component("your_connection").con.flow_bounds
You can find the full implementation and all details here: IESopt.jl
.
Add the constraint defining the bounds of the flow (related to connection
) to the model
.
Specifiying capacity
will lead to symmetric bounds (\(\text{lb} := -capacity\) and \(\text{ub} := capacity\)), while asymmetric bounds can be set by explicitly specifiying lb
and ub
.
!!! note
Usage of etdf
is currently not fully tested, and not documented.
Upper and lower bounds can be “infinite” (by not setting them) resulting in the repective constraints not being added, and the flow variable therefore being (partially) unconstrained. Depending on the configuration the flow
is calculated differently:
if
connection.etdf
is set, it is based on an ETDF sum flow,if
connection.exp.pf_flow
is available, it equals thiselse it equal
connection.var.flow
This flow is then constrained:
\[\begin{split} > \begin{aligned} > & \text{flow}_t \geq \text{lb}, \qquad \forall t \in T \\ > & \text{flow}_t \leq \text{ub}, \qquad \forall t \in T > \end{aligned} > \end{split}\]math !!! note “Constraint safety” The lower and upper bound constraint are subject to penalized slacks.
Objectives
cost
How to?
Access this objective by using:
# Julia
component(model, "your_connection").obj.cost
# Python
model.get_component("your_connection").obj.cost
You can find the full implementation and all details here: IESopt.jl
.
Add the (potential) cost of this connection
to the global objective function.
The connection.cost
setting introduces a fixed cost of “transportation” to the flow of this Connection
. It is based on the directed flow. This means that flows in the “opposite” direction will lead to negative costs:
$\(
\sum_{t \in T} \text{flow}_t \cdot \text{cost}_t \cdot \omega_t
\)\(
math
Here \)\omega_t$ is the weight of Snapshot
t
.
!!! note “Costs for flows in both directions”
If you need to apply a cost term to the absolute value of the flow, consider splitting the Connection
into two different ones, in opposing directions, and including lb = 0
.