LoadShiftingNode
LoadShiftingNode
is a specialized Sink
node that allows for batch-wise load shifting. It is designed for demand profiles where discrete production batches can be rescheduled within defined working shifts. This flexibility allows modeling of industrial processes that can shift load within operational constraints. LoadShiftingNode
s introduce integer and continuous variables to allow demand shifting across time, subject to batching, balance, and capacity constraints.
This node is designed for uniform timestep durations. Irregular durations may cause misalignment of shifted loads.
The node is experimental and has in its current version a lot of prerequisites:
- This node is designed for uniform timestep durations. Irregular durations may cause misalignment of shifted loads.
- The node utilizes the indices of the operational period. It cannot be used with
OperationalScenarios
andRepresentativePeriods
.
Its application should be carefully evaluated.
Introduced type and its fields
The LoadShiftingNode
extends the basic Sink
with load shifting logic based on indexed operational periods and discrete batch shifts.
The fields of a LoadShiftingNode
are:
id
:
Identifier for the node.cap::TimeProfile
:
The original, unshifted demand profile.penalty::Dict{Symbol,<:TimeProfile}
:
Penalties for:surplus
and:deficit
, though not actively used in the load shifting formulation.input::Dict{<:Resource,<:Real}
:
Resource inputs and their conversion factors.load_shift_times::Vector{<:Int}
:
Indices of time steps where batches may be shifted from/to.load_shifts_per_period::Int
:
Maximum number of batch shifts allowed within each load shifting group.load_shift_duration::Int
:
Number of consecutive periods each load shift lasts.load_shift_magnitude::Real
:
The magnitude of demand shifted per period in a batch.load_shift_times_per_period::Int
:
Number of time steps per shift group in which shifts may occur.data::Vector{Data}
:
Optional metadata (e.g., emissions, investment data).
This node is designed for uniform timestep durations. Irregular durations may cause misalignment of shifted loads.
Mathematical description
In the following mathematical equations, we use the name for variables and functions used in the model. Variables are in general represented as
$\texttt{var\_example}[index_1, index_2]$
with square brackets, while functions are represented as
$func\_example(index_1, index_2)$
with paranthesis.
Variables
In addition to standard Sink
variables:
- $\texttt{opex\_var}$
- $\texttt{opex\_fixed}$
- $\texttt{cap\_use}$
- $\texttt{cap\_inst}$
- $\texttt{flow\_out}$
- $\texttt{sink\_surplus}$
- $\texttt{sink\_deficit}$
- $\texttt{emissions\_node}$ if
EmissionsData
is added to the fielddata
the node introduces:
- $\texttt{load\_shift\_from}[n, t]$:
Integer variable for number of batches shifted away from operational period $t$. This variable is only defined for the operational periods given by the vectorload_shift_times
. - $\texttt{load\_shift\_to}[n, t]$:
Integer variable for number of batches shifted to operational period $t$. This variable is only defined for the operational periods given by the vectorload_shift_times
. - $\texttt{load\_shifted}[n, t]$:
Continuous variable representing the net capacity added or removed via load shifting at operational period $t$.
Constraints
The following sections omit the direct inclusion of the vector of LoadShiftingNode
nodes. Instead, it is implicitly assumed that the constraints are valid $\forall n ∈ N$ for all LoadShiftingNode
types if not stated differently. In addition, all constraints are valid $\forall t \in T$ (that is in all operational periods) or $\forall t_{inv} \in T^{Inv}$ (that is in all investment periods).
Standard constraints
Load shifting nodes nodes utilize in general the standard constraints described on Constraint functions. In fact, they use the same create_node
function as a RefSource
node. These standard constraints are:
constraints_flow_in
:\[\texttt{flow\_in}[n, t, p] = inputs(n, p) \times \texttt{cap\_use}[n, t] \qquad \forall p \in inputs(n)\]
constraints_opex_fixed
:
The current implementation fixes the fixed operating expenses of a sink to 0.\[\texttt{opex\_fixed}[n, t_{inv}] = 0\]
constraints_opex_var
:\[\begin{aligned} \texttt{opex\_var}[n, t_{inv}] = & \\ \sum_{t \in t_{inv}} & surplus\_penalty(n, t) \times \texttt{sink\_surplus}[n, t] + \\ & deficit\_penalty(n, t) \times \texttt{sink\_deficit}[n, t] \times \\ & scale\_op\_sp(t_{inv}, t) \end{aligned}\]
The function `scale_op_sp` The function $scale\_op\_sp(t_{inv}, t)$ calculates the scaling factor between operational and investment periods. It also takes into account potential operational scenarios and their probability as well as representative periods.
constraints_data
:
This function is only called for specified additional data, see above.
The function constraints_capacity
receives a new method to handle the load shifting constraints:
constraints_capacity
Group-level limits on load shifts:
For each group of $n.load\_shift\_times\_per\_period$ steps:
\[\sum \texttt{load\_shift\_from}[n, \text{group}] \leq n.load\_shifts\_per\_period\]
\[\sum \texttt{load\_shift\_to}[n, \text{group}] \leq n.load\_shifts\_per\_period\]
\[\sum \texttt{load\_shift\_from}[n, \text{group}] = \sum \texttt{load\_shift\_to}[n, \text{group}]\]
This ensures no net addition or removal of demand—only rescheduling.
Define shifted load across duration:
For each time $t$ in $n.load\_shift\_times$, and for each period $t+i$ in $n.load\_shift\_duration$:
\[\texttt{load\_shifted}[n, t+i] = n.load\_shift\_magnitude \times (\texttt{load\_shift\_to}[n, t] - \texttt{load\_shift\_from}[n, t])\]
Zero shifted load outside batch duration periods:
\[\texttt{load\_shifted}[n, t] = 0 \qquad \forall t \notin \text{shifted batch times}\]
Final demand with shifted load:
\[\texttt{cap\_use}[n, t] = \texttt{cap\_inst}[n, t] + \texttt{load\_shifted}[n, t]\]