Linear optimal power flow (lopf)¶
Three-Bus system¶
General description¶
This script shows how to do a linear optimal powerflow (lopf) calculation based on custom oemof components. The example is based on the PyPSA simple lopf example.
Note: As oemof currently does not support models with one timesteps, therefore there are two.
Code¶
Download source code: lopf.py
Click to display code
import networkx as nx
import pandas as pd
from matplotlib import pyplot as plt
from oemof.network.graph import create_nx_graph
from oemof.solph import EnergySystem
from oemof.solph import Investment
from oemof.solph import Model
from oemof.solph import processing
from oemof.solph import views
from oemof.solph.buses.experimental import ElectricalBus
from oemof.solph.components import Sink
from oemof.solph.components import Source
from oemof.solph.flows import Flow
from oemof.solph.flows.experimental import ElectricalLine
try:
import pygraphviz as pygz
except ModuleNotFoundError:
pygz = None
def draw_graph(
grph,
edge_labels=True,
node_color="#AFAFAF",
edge_color="#CFCFCF",
plot=True,
node_size=2000,
with_labels=True,
arrows=True,
layout="neato",
):
"""
Draw a graph. This function will be removed in future versions.
Parameters
----------
grph : networkxGraph
A graph to draw.
edge_labels : boolean
Use nominal values of flow as edge label
node_color : dict or string
Hex color code oder matplotlib color for each node. If string, all
colors are the same.
edge_color : string
Hex color code oder matplotlib color for edge color.
plot : boolean
Show matplotlib plot.
node_size : integer
Size of nodes.
with_labels : boolean
Draw node labels.
arrows : boolean
Draw arrows on directed edges. Works only if an optimization_model has
been passed.
layout : string
networkx graph layout, one of: neato, dot, twopi, circo, fdp, sfdp.
"""
if isinstance(node_color, dict):
node_color = [node_color.get(g, "#AFAFAF") for g in grph.nodes()]
# set drawing options
options = {
# "prog": "dot",
"with_labels": with_labels,
"node_color": node_color,
"edge_color": edge_color,
"node_size": node_size,
"arrows": arrows,
}
# draw graph
pos = nx.drawing.nx_agraph.graphviz_layout(grph, prog=layout)
nx.draw(grph, pos=pos, **options)
# add edge labels for all edges
if edge_labels is True and plt:
labels = nx.get_edge_attributes(grph, "weight")
nx.draw_networkx_edge_labels(grph, pos=pos, edge_labels=labels)
# show output
if plot is True:
plt.show()
def main():
datetimeindex = pd.date_range("1/1/2017", periods=2, freq="H")
es = EnergySystem(timeindex=datetimeindex)
b_el0 = ElectricalBus(label="b_0", v_min=-1, v_max=1)
b_el1 = ElectricalBus(label="b_1", v_min=-1, v_max=1)
b_el2 = ElectricalBus(label="b_2", v_min=-1, v_max=1)
es.add(b_el0, b_el1, b_el2)
es.add(
ElectricalLine(
input=b_el0,
output=b_el1,
reactance=0.0001,
investment=Investment(ep_costs=10),
min=-1,
max=1,
)
)
es.add(
ElectricalLine(
input=b_el1,
output=b_el2,
reactance=0.0001,
nominal_value=60,
min=-1,
max=1,
)
)
es.add(
ElectricalLine(
input=b_el2,
output=b_el0,
reactance=0.0001,
nominal_value=60,
min=-1,
max=1,
)
)
es.add(
Source(
label="gen_0",
outputs={b_el0: Flow(nominal_value=100, variable_costs=50)},
)
)
es.add(
Source(
label="gen_1",
outputs={b_el1: Flow(nominal_value=100, variable_costs=25)},
)
)
es.add(
Sink(label="load", inputs={b_el2: Flow(nominal_value=100, fix=[1, 1])})
)
m = Model(energysystem=es)
# m.write('lopf.lp', io_options={'symbolic_solver_labels': True})
m.solve(solver="cbc", solve_kwargs={"tee": True, "keepfiles": False})
m.results()
graph = create_nx_graph(es)
if pygz is not None:
draw_graph(
graph,
plot=True,
layout="neato",
node_size=3000,
node_color={"b_0": "#cd3333", "b_1": "#7EC0EE", "b_2": "#eeac7e"},
)
results = processing.results(m)
print(views.node(results, "gen_0")["sequences"])
Installation requirements¶
This example requires oemof.solph (v0.5.x), install by:
pip install oemof.solph[examples]
To draw the graph pygraphviz is required, installed by:
pip install pygraphviz
License¶
Simon Hilpert - 12.12.2017 - simon.hilpert@uni-flensburg.de