Wir betrachten Energienetzwerke, deren Flüsse (=Leistungen auf den Kanten) sich im Zeitverlauf ändern können. Dabei verwenden wir gesampelte Leistungen und Energien, d. h. wir betrachten diskrete Zeitperioden und Zeitpunkte. Die Leistungen (typischerweise in kW) sind über eine Periode konstant, und die Energien (typischerweise in kWh) werden zu den Zeitpunkten, die die Perioden begrenzen, betrachtet. Für die Implementierung unter Python bietet sich folgende Konvention der Indexierung der Zeitpunkte und -perioden an:
Samplingintervall \(\Delta t\), typischerweise in h
\(n\) Zeitperioden (=Intervalle)
Gesamtdauer \(T = \Delta t \cdot n\), typischerweise in h
Zeitpunkte \(t_i = \Delta t \cdot i\) für Indizes \(i = 0, 1, 2, \ldots, n\)
Energien zu den Zeitpunkten: \(E_i\) für Indizes \(i = 0, 1, 2, \ldots, n\), typischerweise in kWh
Lade den Energieinhalt \(E_i\) von \(E_{\text{start}}\) auf \(E_{\text{end}}\) in \(n\) Zeitperioden:
Die Energien sind begrenzt durch \(0 \leq E_i \leq E_{\max} \quad \forall i = 0, 1, 2, \ldots, n.\)
Die Ladeleistungen \(p_j\) sind begrenzt durch \(0 \leq p_j \leq p_{\max} \quad \forall j = 0, 1, 2, \ldots, n - 1.\)
Update des Energieinhalts: \(E_{i+1} = E_i + p_i \Delta t \quad \forall i = 0, 1, 2, \ldots, n - 1.\)
Anfangs- und Endenergie: \(E_0 = E_{\text{start}}\) und \(E_n = E_{\text{end}}\).
Ladeverluste
Der Update des Energieinhalts ändert sich zu \[E_{i+1} = E_i + \eta p_i \Delta t \quad \forall i = 0, 1, 2, \ldots, n - 1,\] wobei \(0 < \eta < 1\) der Ladewirkungsgrad ist.
Minimale Ladeleistung
Eine Größe \(p\), wie z. B. die Ladeleistung eines E-Mobils während eines bestimmten Zeitintervalls, kann der Einschränkung unterworfen sein, dass sie entweder Null oder im Intervall \([l, u]\) liegt. Um diese Nebenbedingung zu implementieren, führen wir die binäre Variable \(\lambda \in\{0, 1\}\) ein und formulieren die Nebenbedingung als \[
l\lambda \leq p \leq u\lambda.
\] Die binäre Variable \(\lambda\) ist 1, wenn das E-Mobil geladen wird und 0, wenn nicht.
Batterie
Verlustfreie Batterie
Entscheidungsvariablen:
\(E_i\) … Energieinhalt der Batterie zum \(i\)-ten Zeitpunkt, \(i = 0, 1, 2, \ldots, n\)
\(p_j\) … Ladeleistung der Batterie während der \(j\)-ten Zeitperiode, \(j = 0, 1, 2, \ldots, n-1\)
Nebenbedingungen:
Die Energien sind begrenzt durch \(0 \leq E_i \leq E_{\max} \; \forall i = 0, 1, 2, \ldots, n.\)
Die Ladeleistungen \(p_j\) sind begrenzt durch \(p_{\min} \leq p_j \leq p_{\max} \; \forall j = 0, 1, 2, \ldots, n - 1\), wobei \(p_{\min} < 0\).
Update des Energieinhalts: \(E_{i+1} = E_i + p_i \Delta t \; \forall i = 0, 1, 2, \ldots, n - 1.\)
Anfangs- und Endenergie: \(E_0 = E_{\text{start}}\) und \(E_n = E_{\text{end}}\).
Lade- und Entladeverluste
In Abbildung Abbildung 2 sind die Lade- und Entladeverluste einer Batterie berücksichtigt.
Entscheidungsvariablen:
\(p_{\text{in},j}\): Ladeleistung in kW während der Zeitperioden \(j\), \(0 \leq p_{\text{in},j} \leq p_{\text{in,max}}\)
\(p_{\text{out},j}\): Entladeleistung in kW während der Zeitperioden \(j\), \(0 \leq p_{\text{out},j} \leq p_{\text{out,max}}\)
\(E_i\): Energieinhalt der Batterie in kWh zu den Zeitpunkten \(i\)
\(b_{\text{in},j}\): binäre Variable, die angibt, ob die Batterie in der Zeitperiode \(j\) geladen wird (\(b_{\text{in},j} = 1\)) oder nicht (\(b_{\text{in},j} = 0\))
\(b_{\text{out},j}\): binäre Variable, die angibt, ob die Batterie in der Zeitperiode \(j\) entladen wird (\(b_{\text{in},j} = 1\)) oder nicht (\(b_{\text{in},j} = 0\))
Nebenbedingungen:
Anfangs- und Endenergie: \(E_0 = E_{\text{start}}\) und \(E_n = E_{\text{end}}\).
Die Energien sind begrenzt durch \(0 \leq E_i \leq E_{\max} \; \forall i = 0, 1, 2, \ldots, n.\)
zeitliche Änderung der Energie der Batterie: \[
E_{i+1} = E_i + (\eta_\text{in} p_{\text{in},i} - \frac{p_{\text{out},i}}{\eta_\text{out}}) \Delta t \quad \forall i = 0, 1, 2, \ldots, n-1
\]
Kein gleichzeitiges Laden und Entladen der Batterie:
\(p_{\text{in},j} \leq p_{\text{max}} b_{\text{in},j}\) für alle \(j = 0, 1, 2, \ldots, n-1\)
\(p_{\text{out},j} \leq p_{\text{max}} b_{\text{out},j}\) für alle \(j = 0, 1, 2, \ldots, n-1\)
\(b_{\text{in},j} + b_{\text{out},j} \leq 1\) für alle \(j = 0, 1, 2, \ldots, n-1\)
Verschiebbare Lasten
Eine verschiebbare Last habe den Lastgang \(l_k\) in kW über \(m\) Perioden mit Indizes \(k = 0, 1, 2, \ldots, m-1\). Wir betrachten \(n\) Zeitperioden mit Indizes \(j = 0, 1, 2, \ldots, n-1\) und \(n > m\). Der Startzeitpunkt \(i\) der verschiebbaren Last mit \(0 \leq i \leq n - m\) sei frei wählbar. Um den resultierenden flexiblen Lastgang \(p_j\) über alle \(j = 0, 1, \ldots, n-1\) zu beschreiben, führen wir die binären Variablen \(s_i\) für \(i = 0, 1, \ldots, n - m\) ein, die angeben, dass die Last zum Zeitpunkt \(i\) gestartet wird, falls \(s_i = 1\). Mit den folgenden Nebenbedingungen lässt sich dann der Lastgang \(p_j\) beschreiben:
\(\sum_{i=0}^{n - m} s_i = 1\): Die Last wird genau einmal gestartet.
\(p_j = \sum_{k=0}^{m - 1} l_k s_{j - k}\) für alle \(j = 0, 1, \ldots, n - 1\), falls \(j - k \leq n - m\): Falls die Last zum Zeitpunkt \(j - k\) gestartet wurde, dann hat sie in der Zeitperiode \(j\) die Leistungsaufnahme \(l_k\).
Thermische Speicher
Wir betrachten einen elektrisch betriebenen Warmwasserboiler mit einem Volumen von 150 Litern. Das Wasser hat daher eine Masse \(m\) von ca. 150 kg. Die spezifische Wärmekapazität von Wasser beträgt ca. \(c_p = 4.2\) kJ/(kg K). Die Wärmekapazität des Wassers beträgt daher \(c = m c_p = 630\) kJ/K, was 0.175 kWh/K entspricht. Die Energiebilanz des Wassers lautet \[
c\dot{T}(t) = P_\text{el}(t) - P_\text{loss}(t) - P_\text{dem}(t).
\] Dabei ist \(T(t)\) die Temperatur des Wassers in °C, \(P_\text{el}(t)\) die elektrische Leistung in kW, die beim Aufheizen in das Wasser eingebracht wird, \(P_\text{loss}(t)\) die Leistung in kW, die das Wasser an die Umgebung verliert, und \(P_\text{dem}(t)\) die Leistung in kW, die durch Austausch von warmem mit kaltem Wasser an die Verbraucher abgegeben wird. Die Verluste an die Umgebung sind wegen Netwons Abkühlgesetz gegeben durch \[
P_\text{loss}(t) = k(T(t) - T_\text{env}),
\] wobei \(k = 1.2\) W/K die Wärmeübertragungseigenschaften (Konvektion und Konduktion) beschreibt, und \(T_\text{env}\) die Umgebungstemperatur in °C angibt. Einsetzen von \(P_\text{loss}(t)\) liefert die lineare Differentialgleichung erster Ordnung \[
c\dot{T}(t) + k(T(t) - T_\text{env})= P_\text{el}(t) - P_\text{dem}(t).
\] Wir definieren \(E(t) = c T(t)\) als Energieinhalt des Wassers in kWh. Dann lautet die Differentialgleichung für \(E(t)\)\[
\dot{E}(t) + \frac{k}{c}(E(t) - c T_\text{env})= P_\text{el}(t) - P_\text{dem}(t).
\] Wenn die Umgebungstemperatur, die elektrische Leistung und der Verbrauch während einer Dauer \(\Delta t\) konstant sind, dann ist \[
E(t + \Delta t) = E(t)e^{-\frac{k}{c}\Delta t} + \frac{c}{k}(1 - e^{-\frac{k}{c}\Delta t})(P_\text{el} - P_\text{dem} + k T_\text{env}),
\] siehe z. B. Ingenieurmathematik: Lineare DGL 1. Ordnung.
Plausibilitätschecks:
Für \(\Delta t = 0\) h ist \(E(t + \Delta t) = E(t)\).
Für kleine \(\Delta t\) ist \(E(t + \Delta t) \approx E(t)(1 - \frac{k}{c}\Delta t) + \Delta t (P_\text{el} - P_\text{dem} + k T_\text{env}),\) da dann \(e^{-\frac{k}{c}\Delta t} \simeq 1 - \frac{k}{c}\Delta t\).
Für große \(\Delta t\) und \(P_\text{el} = P_\text{dem} = 0\) ist \(E(t + \Delta t) \approx c T_\text{env}\), da dann \(e^{-\frac{k}{c}\Delta t} \simeq 0\). Das heißt, ohne Aufheizen und Verbrauch ist für große \(\Delta t\) die Temperatur des Wassers gleich der Umgebungstemperatur.
Für die oben angegebenen Werte von \(c\), \(k\) sowie eine Umgebungstemperatur \(T_\text{env} = 15\) °C und eine Dauer \(\Delta t = 0.25\) h ist \[
E(t + \Delta t) = 0.9983 E(t) + 0.2498(P_\text{el} - P_\text{dem} + 0.0012 T_\text{env}).
\] In Abbildung Abbildung 3 ist für dieses Setting und \(P_\text{el} = P_\text{dem} = 0\) die Temperatur des Wassers über eine Woche dargestellt.
Code
import numpy as npimport matplotlib.pyplot as pltdt =0.25# hc =0.175# kWh/Kk =0.0012# kW/KT_env =15# °CT =24*7# htimes = np.arange(0, T + dt, dt) # hE = np.zeros_like(times)E[0] = c*70.0# 70 °Cfor i inrange(0, len(times)-1): E[i+1] = E[i]*np.exp(-k/c*dt) + c/k*(1- np.exp(-k/c*dt))*k*T_envplt.figure(figsize=(5, 3))plt.plot(times/24, E/c)plt.xlabel("time (d)")plt.ylabel("temperature (°C)")plt.grid()
Gegeben sind Energiepreise \(c_j\), die während der Zeitperioden mit Indizes \(j = 0, 1, 2, \ldots, n-1\) für die Leistungen \(p_j\) gelten - unabhängig vom Vorzeichen der Leistungen. Zielfunktion: \[
\min \sum_{j=0}^{n-1} c_j p_j \Delta t.
\]
Bezugskosten und Einspeisevergütung
Wir betrachten der Einfachheit halber nur eine Zeitperiode: Wenn sich die Bezugspreise \(c_{\text{Bezug}}\) in EUR/kWh und die Einspeisevergütung \(c_{\text{Einsp.}}\) in EUR/kWh unterscheiden, dann ist die Kostenfunktion nicht-linear. Falls, wie üblich, \(c_{\text{Bezug}} \geq c_{\text{einsp.}}\), dann ist die Kostenfunktion konvex und kann als Maximum zweier linearer Funktionen geschrieben werden: \[
c(E) = \max\{ c_{\text{Bezug}}E, c_{\text{Einsp.}}E \}.
\] Dabei ist \(E\) die bezogene (\(E > 0\)) bzw. eingespeiste (\(E < 0\)) Energie in kWh, siehe Abbildung Abbildung 4.
Die Minimierung einer solchen Zielfunktion lässt sich in einem LP mit einer zusätzlichen Variablen \(K\) umsetzen: \[
\begin{aligned}
\min \; & K \\
\text{s. t.}\; & c_{\text{Bezug}} E \leq K \\
& c_{\text{Einsp.}} E \leq K
\end{aligned}
\]
Eigenverbrauchsanteil und Autarkiegrad
Fixe Produktion und fixer Verbrauch
Wir betrachten den Fall eines fixen (bekannten, unflexiblen) Produktionsverlaufs in kW (z. B. einer PV-Anlage) und eines fixen (bekannten, unflexiblen) Verbrauchsverlaufs in kW (z. B. eines Haushalts) über eine fixierte Anzahl an Zeitperioden. Der Produktionsüberschuss werde ins Netz eingespeist und bei Bedarf aus dem Netz bezogen. Siehe Abbildung Abbildung 5.
Eigenverbrauch: Die eigenverbrauchte Leistung ist das Minimum aus der Produktionsleistung und der Verbrauchsleistung. Der Eigenverbrauch ist die Summe der eigenverbrauchten Leistungen mal dem Zeitintervall über alle Zeitperioden. Der Eigenverbrauch kann auch berechnet werden als produzierte Energie minus ins Netz eingespeiste Energie.
Eigenverbrauchsanteil: Der Eigenverbrauchsanteil (auch Eigenverbrauchsquote genannte) ist definiert als der Eigenverbrauch dividiert durch die produzierte Energie. Der Eingenverbrauchsanteil gibt an, wie viel der selbst produzierten Energie man selbst verbraucht hat.
Autarkiegrad: Der Autarkiegrad ist definiert als der Eigenverbrauch dividiert durch die verbrauchte Energie. Der Autarkiegrad gibt an, wie viel der gesamt verbrauchten Energie von der eigenen PV-Anlage gedeckt wurde.
Da die Größen produzierte Energie und verbrauchte Energie fixiert sind, ist die Maximierung des Eigenverbrauchsanteils und die Maximierung des Autarkiegrads äquivalent
zur Maximierung des Eigenverbrauchs und
zur Minimierung der ins Netz eingespeisten Energie.
Fixe Produktion und variabler Verbrauch
Durch den variablen Verbrauch ist auch die Einspeisung variabel. Für diesen Fall definieren wir den Eigenverbrauch als produzierte Energie minus ins Netz eingespeiste Energie.
Die Maximierung des Eingenverbrauchs entspricht daher der Minimierung der ins Netz eingespeisten Energie. Wenn die ins Netz eingespeiste Energie als negativer Anteil der Leistung \(g_j\) in kW definiert ist, d. h. als \(\max(-g_j, 0)\), dann lautet die Minimierung der ins Netz eingespeisten Energie: \[
\min \sum_{j=0}^{n-1} \max(-g_j, 0) \Delta t.
\] Diese Zielfunktion ist aufgrund des Maximumoperators nicht-linear. Sie lässt sich jedoch in einem LP mit einer zusätzlichen Variablen \(f_j\) (in kW, für feed in) umsetzen: \[
\begin{aligned}
\min \; & \sum_{j=0}^{n-1} f_j \Delta t \\
\text{s. t.}\; -g_j & \leq f_j \quad \forall j = 0, 1, 2, \ldots, n-1 \\
0 & \leq f_j \quad \forall j = 0, 1, 2, \ldots, n-1
\end{aligned}
\]
Spitzenlast
Die Spitzenlast ist die maximale Leistung \(\max_{j\in J} p_j\), die während der Zeitperioden \(J\) auftritt. Aufgrund des Maximumoperators ist die Zielfunktion nicht-linear von den \(p_j\) abhängig. Die Minimierung der Spitzenlast kann allerdings durch die Minimierung einer zusätzlichen Variablen \(m > 0\) in Kombination mit den folgenden zusätzlichen Nebenbedingung linear modelliert werden: \[
\begin{aligned}
\min \; & m \\
\text{s. t.}\; & p_j \leq m \quad \forall j \in J. \\
& \ldots
\end{aligned}
\] Wie erwähnen hier die dazu verwandte Variante der Minimierung der \(l_\infty\) (Chebyshev) Norm: Die \(l_\infty\) (Chebyshev) Norm eines Vektors \(y\in\mathbb{R}^n\) ist definiert als das Maximum der Absolutbeträge seiner Komponenten: \[||y||_\infty = \max_{i=1,\ldots,n} |y_i|\] Die Minimierung der Zielfunktion \(||y||_\infty\) lässt sich in einem LP mit einer zusätzlichen Variablen \(t\) und \(2n\) zusätzlichen Nebenbedingungen umsetzen: \[
\begin{aligned}
\text{min.} \; & t \\
\text{s. t.}\; & -t \leq y_i \leq t, i = 1,\ldots,n
\end{aligned}
\]
Variation
Die Variation eines Leistungsverlaufs ist gegeben durch die absoluten Änderungen der Leistungen zwischen den Zeitperioden: \(|p_j - p_{j-1}|\) für alle \(j = 1, 2, \dots, n-1.\)
Die Minimierung der Variationssumme\(\min \sum_{j=1}^{n-1} |p_j - p_{j-1}|\) lässt sich als LP mit \(n-1\) zusätzlichen Variablen \(v_j \geq 0\) und \(2n-2\) zusätzlichen Nebenbedingungen umsetzen: \[
\begin{aligned}
\text{min.} \; & \sum_{j=1}^{n-1} v_j \\
\text{s. t.}\; & -v_j \leq p_j - p_{j-1} \leq v_j, j = 1,\ldots,n-1
\end{aligned}
\] Die Minimierung der Variationsspitze\(\min \max\limits_{j=1,\ldots,n-1} |p_j - p_{j-1}|\) lässt sich als LP mit einer zusätzlichen Variablen \(m \geq 0\) und \(2n-2\) zusätzlichen Nebenbedingungen umsetzen: \[
\begin{aligned}
\text{min.} \; & m \\
\text{s. t.}\; & -m \leq p_j - p_{j-1} \leq m, j = 1,\ldots,n-1
\end{aligned}
\]
Tracking
Beim Tracking wird ein vorgegebener Leistungsverlauf \(q_j\) von einem flexiblen Leistungsverlauf \(p_j\) in kW möglichst gut nachgefahren. Der Unterschied zwischen den Leistungen \(p_j\) und \(q_j\) kann auch unterschiedliche Weisen quantifiziert werden.
Summe der absoluten Abweichungen
Die Summe der absoluten Abweichungen von \(p_j\) und \(q_j\) ist gegeben durch \[
\sum_{j=0}^{n-1} |p_j - q_j|
\] Die Minimierung dieser Zielfunktion lässt sich in einem LP mit \(n\) zusätzlichen Variablen \(a_j\) und \(2n\) zusätzlichen Nebenbedingungen umsetzen: \[
\begin{aligned}
\min \; & \sum_{j=0}^{n-1} a_j \\
\text{s. t.}\; & -a_j \leq p_j - q_j \leq a_j, j = 0, 1, \ldots, n - 1
\end{aligned}
\]
Maximale absolute Abweichung
Die maximale absolute Abweichung von \(p_j\) und \(q_j\) ist gegeben durch \[
\max_{j=0, 1, \ldots, n-1} |p_j - q_j|
\] Die Minimierung dieser Zielfunktion lässt sich in einem LP mit einer zusätzlichen Variablen \(m\) und \(2n\) zusätzlichen Nebenbedingungen umsetzen: \[
\begin{aligned}
\min \; & m \\
\text{s. t.}\; & -m \leq p_j - q_j \leq m, j = 0, 1, \ldots, n - 1
\end{aligned}
\]
Summe der quadratischen Abweichungen
Die Summe der quadratischen Abweichungen von \(p_j\) und \(q_j\) ist gegeben durch \[
\sum_{j=0}^{n-1} (p_j - q_j)^2
\] Die Minimierung dieser Zielfunktion kann nicht als LP formuliert werden. Diese Problemstellung wird als Regression oder Quadratic Programming bezeichnet, für die es eigene Lösungsmethoden gibt.
Sioshansi, Ramteen; Conejo, Antonio J. (2017): Optimization in Engineering: Models and Algorithms. Springer. Kapitel 3 “Mixed-Integer Linear Optimization” insbesondere Abschnitt 3.3 “Linearizing Nonlinearities Using Binary Variables”.
Williams, H. Paul (2013): Model Building in Mathematical Programming. 5. Auflage, Wiley. Kapitel 8 “Integer programming”, Abschnitt 8.2 “The applicability of integer programming”
Vandenberghe, Lieven: lecture notes on Linear Programming insbesondere “Lecture 2 Piecewise-linear optimization”