# src/tessif_examples/scenarios/component_es.py
# pylint: disable=too-many-locals
# pylint: disable=duplicate-code
# pylint: disable=too-many-lines
"""Generic grid tessif energy system model example."""
import os
import numpy as np
import pandas as pd
import tessif.frused.namedtuples as nts
from tessif import components, system_model
from tessif_examples.paths import data_dir
[docs]def create_component_focused_msc(expansion_problem=False, periods=3):
"""Component-focused energy system model scenario combinations.
Developed by Max Reimer as part of his `Project Thesis
<https://tore.tuhh.de/handle/11420/11707>`_.
Create a model of a generic component based energy system using
:mod:`tessif's model <tessif.model>`.
Parameters
----------
expansion_problem : bool, default=False
Boolean which states whether a commitment problem (False)
or expansion problem (True) is to be solved
periods : int, default=3
Number of time steps of the evaluated timeframe
(one time step is one hour)
Return
------
:class:`tessif.system_model.AbstractEnergySystem`
Tessif energy system.
Examples
--------
Generic System Visualization:
.. image:: ../../_static/system_model_graphs/component_es_example.png
:align: center
:alt: Image showing the create_component_es energy system graph.
"""
# Create a simulation time frame
timeframe = pd.date_range("1/1/2019", periods=periods, freq="H")
# Initiate the global constraints depending on the scenario
if expansion_problem is False:
global_constraints = {
"name": "Commitment_Scenario",
"emissions": float("+inf"),
}
else:
global_constraints = {
"name": "Expansion_Scenario",
"emissions": 250000,
}
# Variables for timeseries of fluctuate wind, solar and demand
csv_data = pd.read_csv(
os.path.join(
data_dir,
"load_profiles",
"component_scenario_profiles.csv",
),
index_col=0,
sep=";",
)
# solar:
pv = csv_data["pv"].values.flatten()[0:periods]
# scale relative values with the installed pv power
pv = pv * 1100
# wind onshore:
wind_onshore = csv_data["wind_on"].values.flatten()[0:periods]
# scale relative values with installed onshore power
wind_onshore = wind_onshore * 1100
# wind offshore:
wind_offshore = csv_data["wind_off"].values.flatten()[0:periods]
# scale relative values with installed offshore power
wind_offshore = wind_offshore * 150
# electricity demand:
el_demand = csv_data["el_demand"].values.flatten()[0:periods]
max_el = np.max(el_demand)
# heat demand:
th_demand = csv_data["th_demand"].values.flatten()[0:periods]
max_th = np.max(th_demand)
# Creating the individual energy system components:
# ---------------- Sources (incl wind and solar) -----------------------
hard_coal_supply = components.Source(
name="Hard Coal Supply",
outputs=("Hard_Coal",),
sector="Power",
carrier="Hard_Coal",
node_type="source",
accumulated_amounts={"Hard_Coal": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"Hard_Coal": nts.MinMax(min=0, max=float("+inf"))},
flow_costs={"Hard_Coal": 0},
flow_emissions={"Hard_Coal": 0},
flow_gradients={
"Hard_Coal": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"Hard_Coal": nts.PositiveNegative(positive=0, negative=0)},
timeseries=None,
expandable={"Hard_Coal": False},
expansion_costs={"Hard_Coal": 0},
expansion_limits={"Hard_Coal": nts.MinMax(min=0, max=float("+inf"))},
)
lignite_supply = components.Source(
name="Lignite Supply",
outputs=("lignite",),
sector="Power",
carrier="Lignite",
node_type="source",
accumulated_amounts={"lignite": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"lignite": nts.MinMax(min=0, max=float("+inf"))},
flow_costs={"lignite": 0},
flow_emissions={"lignite": 0},
flow_gradients={
"lignite": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"lignite": nts.PositiveNegative(positive=0, negative=0)},
timeseries=None,
expandable={"lignite": False},
expansion_costs={"lignite": 0},
expansion_limits={"lignite": nts.MinMax(min=0, max=float("+inf"))},
)
fuel_supply = components.Source(
name="Gas Station",
outputs=("fuel",),
sector="Power",
carrier="Gas",
node_type="source",
accumulated_amounts={"fuel": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"fuel": nts.MinMax(min=0, max=float("+inf"))},
flow_costs={"fuel": 0},
flow_emissions={"fuel": 0},
flow_gradients={
"fuel": nts.PositiveNegative(positive=float("+inf"), negative=float("+inf"))
},
gradient_costs={"fuel": nts.PositiveNegative(positive=0, negative=0)},
timeseries=None,
expandable={"fuel": False},
expansion_costs={"fuel": 0},
expansion_limits={"fuel": nts.MinMax(min=0, max=float("+inf"))},
)
biogas_supply = components.Source(
name="Biogas Supply",
outputs=("biogas",),
sector="Power",
carrier="Biogas",
node_type="source",
accumulated_amounts={"biogas": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"biogas": nts.MinMax(min=0, max=float("+inf"))},
flow_costs={"biogas": 0},
flow_emissions={"biogas": 0},
flow_gradients={
"biogas": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"biogas": nts.PositiveNegative(positive=0, negative=0)},
timeseries=None,
expandable={"biogas": False},
expansion_costs={"biogas": 0},
expansion_limits={"biogas": nts.MinMax(min=0, max=float("+inf"))},
)
solar_panel = components.Source(
name="Solar Panel",
outputs=("electricity",),
sector="Power",
carrier="electricity",
node_type="Renewable",
accumulated_amounts={"electricity": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"electricity": nts.MinMax(min=0, max=1100)},
flow_costs={"electricity": 80},
flow_emissions={"electricity": 0.05},
flow_gradients={
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"electricity": nts.PositiveNegative(positive=0, negative=0)},
timeseries={
"electricity": nts.MinMax(min=np.array(periods * [0]), max=np.array(pv))
},
expandable={"electricity": expansion_problem},
expansion_costs={"electricity": 1000000},
expansion_limits={"electricity": nts.MinMax(min=1100, max=float("+inf"))},
)
onshore_wind_turbine = components.Source(
name="Onshore Wind Turbine",
outputs=("electricity",),
sector="Power",
carrier="electricity",
node_type="Renewable",
accumulated_amounts={"electricity": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"electricity": nts.MinMax(min=0, max=1100)},
flow_costs={"electricity": 60},
flow_emissions={"electricity": 0.02},
flow_gradients={
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"electricity": nts.PositiveNegative(positive=0, negative=0)},
timeseries={
"electricity": nts.MinMax(
min=np.array(periods * [0]), max=np.array(wind_onshore)
)
},
expandable={"electricity": expansion_problem},
expansion_costs={"electricity": 1750000},
expansion_limits={"electricity": nts.MinMax(min=1100, max=float("+inf"))},
)
offshore_wind_turbine = components.Source(
name="Offshore Wind Turbine",
outputs=("electricity",),
sector="Power",
carrier="electricity",
node_type="Renewable",
accumulated_amounts={"electricity": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"electricity": nts.MinMax(min=0, max=150)},
flow_costs={"electricity": 105},
flow_emissions={"electricity": 0.02},
flow_gradients={
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"electricity": nts.PositiveNegative(positive=0, negative=0)},
timeseries={
"electricity": nts.MinMax(
min=np.array(periods * [0]), max=np.array(wind_offshore)
)
},
expandable={"electricity": expansion_problem},
expansion_costs={"electricity": 3900000},
expansion_limits={"electricity": nts.MinMax(min=150, max=float("+inf"))},
)
# ---------------- Transformer -----------------------
hard_coal_chp = components.Transformer(
name="Hard Coal CHP",
inputs=("Hard_Coal",),
outputs=(
"electricity",
"hot_water",
),
conversions={
("Hard_Coal", "electricity"): 0.4,
("Hard_Coal", "hot_water"): 0.4,
},
sector="Coupled",
carrier="coupled",
node_type="transformer",
flow_rates={
"Hard_Coal": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=0, max=300),
"hot_water": nts.MinMax(min=0, max=300),
},
flow_costs={"Hard_Coal": 0, "electricity": 80, "hot_water": 6},
flow_emissions={"Hard_Coal": 0, "electricity": 0.8, "hot_water": 0.06},
flow_gradients={
"Hard_Coal": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"hot_water": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
},
gradient_costs={
"Hard_Coal": nts.PositiveNegative(positive=0, negative=0),
"electricity": nts.PositiveNegative(positive=0, negative=0),
"hot_water": nts.PositiveNegative(positive=0, negative=0),
},
timeseries=None,
expandable={
"Hard_Coal": False,
"electricity": expansion_problem,
"hot_water": expansion_problem,
},
expansion_costs={"Hard_Coal": 0, "electricity": 1750000, "hot_water": 131250},
expansion_limits={
"Hard_Coal": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=300, max=float("+inf")),
"hot_water": nts.MinMax(min=300, max=float("+inf")),
},
)
hard_coal_power_plant = components.Transformer(
name="Hard Coal PP",
inputs=("Hard_Coal",),
outputs=("electricity",),
conversions={("Hard_Coal", "electricity"): 0.43},
sector="Power",
carrier="electricity",
node_type="transformer",
flow_rates={
"Hard_Coal": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=0, max=500),
},
flow_costs={"Hard_Coal": 0, "electricity": 80},
flow_emissions={"Hard_Coal": 0, "electricity": 0.8},
flow_gradients={
"Hard_Coal": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
},
gradient_costs={
"Hard_Coal": nts.PositiveNegative(positive=0, negative=0),
"electricity": nts.PositiveNegative(positive=0, negative=0),
},
timeseries=None,
expandable={"Hard_Coal": False, "electricity": expansion_problem},
expansion_costs={"Hard_Coal": 0, "electricity": 1650000},
expansion_limits={
"Hard_Coal": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=500, max=float("+inf")),
},
)
combined_cycle_power_plant = components.Transformer(
name="Combined Cycle PP",
inputs=("fuel",),
outputs=("electricity",),
conversions={("fuel", "electricity"): 0.6},
sector="Power",
carrier="electricity",
node_type="transformer",
flow_rates={
"fuel": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=0, max=600),
},
flow_costs={"fuel": 0, "electricity": 90},
flow_emissions={"fuel": 0, "electricity": 0.35},
flow_gradients={
"fuel": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
},
gradient_costs={
"fuel": nts.PositiveNegative(positive=0, negative=0),
"electricity": nts.PositiveNegative(positive=0, negative=0),
},
timeseries=None,
expandable={"fuel": False, "electricity": expansion_problem},
expansion_costs={"fuel": 0, "electricity": 950000},
expansion_limits={
"fuel": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=600, max=float("+inf")),
},
)
lignite_power_plant = components.Transformer(
name="Lignite Power Plant",
inputs=("lignite",),
outputs=("electricity",),
conversions={("lignite", "electricity"): 0.4},
sector="Power",
carrier="electricity",
node_type="transformer",
flow_rates={
"lignite": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=0, max=500),
},
flow_costs={"lignite": 0, "electricity": 65},
flow_emissions={"lignite": 0, "electricity": 1},
flow_gradients={
"lignite": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
},
gradient_costs={
"lignite": nts.PositiveNegative(positive=0, negative=0),
"electricity": nts.PositiveNegative(positive=0, negative=0),
},
timeseries=None,
expandable={"lignite": False, "electricity": expansion_problem},
expansion_costs={"lignite": 0, "electricity": 1900000},
expansion_limits={
"lignite": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=500, max=float("+inf")),
},
)
biogas_chp = components.Transformer(
name="Biogas CHP",
inputs=("biogas",),
outputs=(
"electricity",
"hot_water",
),
conversions={("biogas", "electricity"): 0.4, ("biogas", "hot_water"): 0.5},
sector="Coupled",
carrier="coupled",
node_type="transformer",
flow_rates={
"biogas": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=0, max=200),
"hot_water": nts.MinMax(min=0, max=250),
},
flow_costs={"biogas": 0, "electricity": 150, "hot_water": 11.25},
flow_emissions={"biogas": 0, "electricity": 0.25, "hot_water": 0.01875},
flow_gradients={
"biogas": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"hot_water": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
},
gradient_costs={
"biogas": nts.PositiveNegative(positive=0, negative=0),
"electricity": nts.PositiveNegative(positive=0, negative=0),
"hot_water": nts.PositiveNegative(positive=0, negative=0),
},
timeseries=None,
expandable={
"biogas": False,
"electricity": expansion_problem,
"hot_water": expansion_problem,
},
expansion_costs={"biogas": 0, "electricity": 3500000, "hot_water": 262500},
expansion_limits={
"biogas": nts.MinMax(min=0, max=float("+inf")),
"electricity": nts.MinMax(min=200, max=float("+inf")),
"hot_water": nts.MinMax(min=250, max=float("+inf")),
},
)
heat_plant = components.Transformer(
name="Heat Plant",
inputs=("fuel",),
outputs=("hot_water",),
conversions={("fuel", "hot_water"): 0.9},
sector="Power",
carrier="hot_water",
node_type="transformer",
flow_rates={
"fuel": nts.MinMax(min=0, max=float("+inf")),
"hot_water": nts.MinMax(min=0, max=450),
},
flow_costs={"fuel": 0, "hot_water": 35},
flow_emissions={"fuel": 0, "hot_water": 0.23},
flow_gradients={
"fuel": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"hot_water": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
},
gradient_costs={
"fuel": nts.PositiveNegative(positive=0, negative=0),
"hot_water": nts.PositiveNegative(positive=0, negative=0),
},
timeseries=None,
expandable={"fuel": False, "hot_water": expansion_problem},
expansion_costs={"fuel": 0, "hot_water": 390000},
expansion_limits={
"fuel": nts.MinMax(min=0, max=float("+inf")),
"hot_water": nts.MinMax(min=450, max=float("+inf")),
},
)
power_to_heat = components.Transformer(
name="Power To Heat",
inputs=("electricity",),
outputs=("hot_water",),
conversions={("electricity", "hot_water"): 0.99},
sector="Coupled",
carrier="coupled",
node_type="transformer",
flow_rates={
"electricity": nts.MinMax(min=0, max=float("+inf")),
"hot_water": nts.MinMax(min=0, max=100),
},
flow_costs={"electricity": 0, "hot_water": 20},
flow_emissions={"electricity": 0, "hot_water": 0.0007},
flow_gradients={
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
"hot_water": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
),
},
gradient_costs={
"electricity": nts.PositiveNegative(positive=0, negative=0),
"hot_water": nts.PositiveNegative(positive=0, negative=0),
},
timeseries=None,
expandable={"electricity": False, "hot_water": expansion_problem},
expansion_costs={"electricity": 0, "hot_water": 100000},
expansion_limits={
"electricity": nts.MinMax(min=0, max=float("+inf")),
"hot_water": nts.MinMax(min=100, max=float("+inf")),
},
)
# ---------------- Storages -----------------------
storage = components.Storage(
name="Battery",
input="electricity",
output="electricity",
capacity=100,
initial_soc=0,
sector="Power",
carrier="electricity",
node_type="storage",
idle_changes=nts.PositiveNegative(positive=0, negative=0.5),
flow_rates={"electricity": nts.MinMax(min=0, max=33)},
flow_efficiencies={"electricity": nts.InOut(inflow=0.95, outflow=0.95)},
flow_costs={"electricity": 400},
flow_emissions={"electricity": 0.06},
flow_gradients={
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"electricity": nts.PositiveNegative(positive=0, negative=0)},
timeseries=None,
expandable={"capacity": expansion_problem, "electricity": expansion_problem},
fixed_expansion_ratios={"electricity": expansion_problem},
expansion_costs={"capacity": 1630000, "electricity": 0},
expansion_limits={
"capacity": nts.MinMax(min=100, max=float("+inf")),
"electricity": nts.MinMax(min=33, max=float("+inf")),
},
)
heat_storage = components.Storage(
name="Heat Storage",
input="hot_water",
output="hot_water",
capacity=50,
initial_soc=0,
sector="Heat",
carrier="hot_water",
node_type="storage",
idle_changes=nts.PositiveNegative(positive=0, negative=0.25),
flow_rates={"hot_water": nts.MinMax(min=0, max=10)},
flow_efficiencies={"hot_water": nts.InOut(inflow=0.95, outflow=0.95)},
flow_costs={"hot_water": 20},
flow_emissions={"hot_water": 0},
flow_gradients={
"hot_water": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"hot_water": nts.PositiveNegative(positive=0, negative=0)},
timeseries=None,
expandable={"capacity": expansion_problem, "hot_water": expansion_problem},
fixed_expansion_ratios={"hot_water": expansion_problem},
expansion_costs={"capacity": 4500, "hot_water": 0},
expansion_limits={
"capacity": nts.MinMax(min=50, max=float("+inf")),
"hot_water": nts.MinMax(min=10, max=float("+inf")),
},
)
# ---------------- Sinks -----------------------
el_demand = components.Sink(
name="El Demand",
inputs=("electricity",),
sector="Power",
carrier="electricity",
node_type="demand",
accumulated_amounts={"electricity": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"electricity": nts.MinMax(min=0, max=max_el)},
flow_costs={"electricity": 0},
flow_emissions={"electricity": 0},
flow_gradients={
"electricity": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"electricity": nts.PositiveNegative(positive=0, negative=0)},
timeseries={
"electricity": nts.MinMax(min=np.array(el_demand), max=np.array(el_demand))
},
expandable={"electricity": False},
expansion_costs={"electricity": 0},
expansion_limits={"electricity": nts.MinMax(min=0, max=float("+inf"))},
)
heat_demand = components.Sink(
name="Heat Demand",
inputs=("hot_water",),
sector="Heat",
carrier="hot_water",
node_type="demand",
accumulated_amounts={"hot_water": nts.MinMax(min=0, max=float("+inf"))},
flow_rates={"hot_water": nts.MinMax(min=0, max=max_th)},
flow_costs={"hot_water": 0},
flow_emissions={"hot_water": 0},
flow_gradients={
"hot_water": nts.PositiveNegative(
positive=float("+inf"), negative=float("+inf")
)
},
gradient_costs={"hot_water": nts.PositiveNegative(positive=0, negative=0)},
timeseries={
"hot_water": nts.MinMax(min=np.array(th_demand), max=np.array(th_demand))
},
expandable={"hot_water": False},
expansion_costs={"hot_water": 0},
expansion_limits={"hot_water": nts.MinMax(min=0, max=float("+inf"))},
)
# ---------------- Busses -----------------------
fuel_supply_line = components.Bus(
name="Gas Line",
inputs=("Gas Station.fuel",),
outputs=("Combined Cycle PP.fuel", "Heat Plant.fuel"),
sector="Coupled",
carrier="Gas",
node_type="bus",
)
biogas_supply_line = components.Bus(
name="Biogas Line",
inputs=("Biogas Supply.biogas",),
outputs=("Biogas CHP.biogas",),
sector="Coupled",
carrier="Biogas",
node_type="bus",
)
hard_coal_supply_line = components.Bus(
name="Hard Coal Supply Line",
inputs=("Hard Coal Supply.Hard_Coal",),
outputs=(
"Hard Coal PP.Hard_Coal",
"Hard Coal CHP.Hard_Coal",
),
sector="Coupled",
carrier="Hard_Coal",
node_type="bus",
)
lignite_supply_line = components.Bus(
name="Lignite Supply Line",
inputs=("Lignite Supply.lignite",),
outputs=("Lignite Power Plant.lignite",),
sector="Power",
carrier="Lignite",
node_type="bus",
)
electricity_line = components.Bus(
name="Powerline",
inputs=(
"Combined Cycle PP.electricity",
"Battery.electricity",
"Lignite Power Plant.electricity",
"Hard Coal PP.electricity",
"Hard Coal CHP.electricity",
"Solar Panel.electricity",
"Offshore Wind Turbine.electricity",
"Biogas CHP.electricity",
"Onshore Wind Turbine.electricity",
),
outputs=(
"El Demand.electricity",
"Battery.electricity",
"Power To Heat.electricity",
),
sector="Power",
carrier="electricity",
node_type="bus",
)
heat_line = components.Bus(
name="Heatline",
inputs=(
"Heat Plant.hot_water",
"Hard Coal CHP.hot_water",
"Biogas CHP.hot_water",
"Power To Heat.hot_water",
"Heat Storage.hot_water",
),
outputs=("Heat Demand.hot_water", "Heat Storage.hot_water"),
sector="Heat",
carrier="hot_water",
node_type="bus",
)
# Creating the actual energy system:
if expansion_problem:
uid = "Component Focused MSC (Expansion Problem)"
else:
uid = "Component Focused MSC (Commitment Problem)"
explicit_es = system_model.AbstractEnergySystem(
uid=uid,
busses=(
fuel_supply_line,
electricity_line,
hard_coal_supply_line,
lignite_supply_line,
biogas_supply_line,
heat_line,
),
sinks=(el_demand, heat_demand),
sources=(
fuel_supply,
solar_panel,
onshore_wind_turbine,
hard_coal_supply,
lignite_supply,
offshore_wind_turbine,
biogas_supply,
),
transformers=(
combined_cycle_power_plant,
hard_coal_power_plant,
lignite_power_plant,
biogas_chp,
heat_plant,
power_to_heat,
hard_coal_chp,
),
storages=(storage, heat_storage),
timeframe=timeframe,
global_constraints=global_constraints,
)
return explicit_es
# pylint: enable=too-many-locals
# pylint: enable=duplicate-code