Code Base

Following section display the code snippets that were used to create the CompC/E results and diagrams.

System-Model-Scenario-Combination Creation Code

Following code snippet shows how to create the CompC/E combinations

import os

import numpy as np
import pandas as pd

import tessif.frused.namedtuples as nts
from tessif.frused.paths import example_dir
from tessif.model import components, energy_system


def create_compcne_es(expansion=False, periods=3):
    """
    Create a model of a generic component based energy system using
    :mod:`tessif's model <tessif.model>`.

    Parameters
    ----------
    expansion : 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)

    Returns
    -------
    energy_supply_system_model_scenario_combination
        The created CompC combination.
    """
    # 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 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(
            example_dir,
            "data",
            "tsf",
            "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},
        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},
        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},
        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,
            "hot_water": expansion,
        },
        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},
        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},
        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},
        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,
            "hot_water": expansion,
        },
        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},
        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},
        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,
                    "electricity": expansion},
        fixed_expansion_ratios={"electricity": expansion},
        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,
                    "hot_water": expansion},
        fixed_expansion_ratios={"hot_water": expansion},
        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:

    explicit_es = energy_system.AbstractEnergySystem(
        uid="Component_es",
        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

Generic Graph

import matplotlib.pyplot as plt

import tessif.visualize.nxgrph as nxv
import tessif.examples.data.tsf.py_hard as tsf_py

tsf_es = tsf_py.create_component_es()
grph = tsf_es.to_nxgrph()
drawing_data = nxv.draw_graph(
    grph,
    node_color={
        'Hard Coal Supply': '#666666',
        'Hard Coal Supply Line': '#666666',
        'Hard Coal PP': '#666666',
        'Hard Coal CHP': '#666666',
        'Solar Panel': '#FF7700',
        'Heat Storage': '#cc0033',
        'Heat Demand': 'Red',
        'Heat Plant': '#cc0033',
        'Heatline': 'Red',
        'Power To Heat': '#cc0033',
        'Biogas CHP': '#006600',
        'Biogas Line': '#006600',
        'Biogas Supply': '#006600',
        'Onshore Wind Turbine': '#99ccff',
        'Offshore Wind Turbine': '#00ccff',
        'Gas Station': '#336666',
        'Gas Line': '#336666',
        'Combined Cycle PP': '#336666',
        'El Demand': '#ffe34d',
        'Battery': '#ffe34d',
        'Powerline': '#ffcc00',
        'Lignite Supply': '#993300',
        'Lignite Supply Line': '#993300',
        'Lignite Power Plant': '#993300',
    },
    node_size={
        'Powerline': 5000,
        'Heatline': 5000
    },
    title='Component Based Example Energy System Graph',
)

plt.show()

Optimization Results

Shown below, is the code to generate the CompC and CompE results. Use the PERIODS constant to adjust the simulated time span. And the Expansion constant to switch between CompC and CompE.

Results displayed were created using PERIODS = 24.

Optimize and Post Process via Tessif

Following script uses the CompC/E creation skript above to generate and tessif internally post-process the optimization results, ready for further analysis.

import pandas as pd

import json
import importlib
import os
from pathlib import Path

from tessif.analyze import ComparativeResultier
from tessif import parse
from tessif.frused.paths import doc_dir
import tessif.examples.data.tsf.py_hard as tsf_examples
import tessif.simulate as optimize
from tessif.transform.es2mapping import compile_result_data_representation
import tessif.visualize.dcgrph as dcv
from tessif.frused.hooks.tsf import reparameterize_components

# PERIODS = 3
PERIODS = 8760
# EXPANSION = False
EXPANSION = True


FOLDER = "commitment_results"
# FOLDER = "expansion_results"
FOLDER = "modified_expansion_results"

FOLDER = "trivia_results"
# FOLDER = "avs_results"
# FOLDER = "test_results"

# define the softwares to be used
SOFTWARES = ['cllp', 'fine', 'omf', 'ppsa', ]
# use this in case you are just testing out the water
SOFTWARES = ['ppsa', ]
SOFTWARES = ['omf', ]
HOOK_PYPSA = True

CYTOSCAPE_ADVANCED_GRAPH = True
MATPLOTLIB_ADVANCED_GRAPH = False
ADVANCED_GRAPH_ON = "omf"

PARENT = os.path.join(
    doc_dir,
    "source",
    "getting_started",
    "examples",
    "application",
    "phd",
    "field_study",
    "CompCnE",
)


def reparam_ppsa(tessif_es):
    reparameterized_es = reparameterize_components(
        es=tessif_es,
        components={
            'Hard Coal CHP': {
                'flow_emissions': {'Hard_Coal': 0, 'electricity': 0, 'hot_water': 0},
            },
            'Hard Coal Supply': {
                'flow_emissions': {'Hard_Coal': 0.8 * 0.4 + 0.06 * 0.4},
            },
            'Biogas CHP': {
                'flow_emissions': {'biogas': 0, 'electricity': 0, 'hot_water': 0},
            },
            'Biogas Supply': {
                'flow_emissions': {'biogas': 0.25 * 0.4 + 0.01875 * 0.5},
            },

        },

    )
    return reparameterized_es


# create dispatch problem aka TransC or TransE combination
creation_module_path = os.path.join(PARENT, "creation.py")

creation_module = parse.python_file(creation_module_path)
tessif_CompCnE = creation_module.create_compcne_es(
    periods=PERIODS, expansion=EXPANSION,)


# dynamically access the tessif transform utilities based on requested
# softwares above. Store them in a dictionairy for
# ease of access.
transformers = {}
for software in SOFTWARES:
    transformers[software] = importlib.import_module(
        '.'.join(['tessif.transform.es2es', software]))

# Do the tessif -> software transformations and store them in a dictionairy for
# ease of access
transformed_CompCnE_combinations = {}
for software in SOFTWARES:
    # local copy of the tessif es:
    copied_es = tessif_CompCnE.duplicate(suffix='')
    if software == 'ppsa' and HOOK_PYPSA:
        copied_es = reparam_ppsa(copied_es)

    transformed_CompCnE_combinations[software] = transformers[
        software].transform(copied_es)


# Perform the software specific optimizations
optimized_CompCnE_combinations = {}
for software in SOFTWARES:
    optimizer = getattr(optimize, "_".join([software, "from_es"]))
    optimized_CompCnE_combinations[software] = optimizer(
        transformed_CompCnE_combinations[software])

# post process the allresultiers:
all_resultiers = {}
for software in SOFTWARES:
    post_processor = importlib.import_module(
        '.'.join(['tessif.transform.es2mapping', software]))
    all_resultiers[software] = post_processor.AllResultier(
        optimized_CompCnE_combinations[software])

# post process the comparative results using the constructed all-resultiers:
comparatier = ComparativeResultier(all_resultiers)


data_storage_path = os.path.join(PARENT, FOLDER)

# store the all_loads results
for software in SOFTWARES:

    result_id = f"{software}_all_loads"
    storage_location = os.path.join(data_storage_path, result_id)
    result_df = comparatier.all_loads[software]
    result_df.to_csv(".".join([storage_location, "csv"]))

# store the all_socs results
result_id = f"all_socs"
storage_location = os.path.join(data_storage_path, result_id)
result_df = comparatier.all_socs
result_df.to_csv(".".join([storage_location, "csv"]))

# store the rest of the all_* results:
for rtype in [
        "all_capacities",
        "all_original_capacities",
        "all_net_energy_flows",
        "all_costs_incurred",
        "all_emissions_caused",
]:
    result_id = rtype
    storage_location = os.path.join(data_storage_path, result_id)
    result_df = getattr(comparatier, rtype)
    result_df.to_csv(".".join([storage_location, "csv"]))


result_types = ['Load', 'Capacity', 'IntegratedGlobal', ]
post_processed_data = {}
for software in SOFTWARES:
    post_processor = importlib.import_module(
        '.'.join(['tessif.transform.es2mapping', software]))
    post_processed_data[software] = {}
    for result_type in result_types:
        post_processed_data[software][result_type] = getattr(
            post_processor, "".join([result_type, "Resultier"]))(
                optimized_CompCnE_combinations[software])

wanted_results = {
    'Load': 'node_load',
    'Capacity': 'node_installed_capacity',
    'IntegratedGlobal': 'global_results',
}
nodes_of_interest = {
    'Load': ['Powerline', 'Heatline'],
    'Capacity': [],
    'IntegratedGlobal': [],
}


for software in SOFTWARES:
    for rtype in result_types:
        if nodes_of_interest[rtype]:
            for node in nodes_of_interest[rtype]:
                result_id = f"{software}_{rtype}_{node}"
                storage_location = os.path.join(data_storage_path, result_id)
                res = getattr(post_processed_data[software][rtype], wanted_results[rtype])[
                    node]
                if rtype == 'Load':
                    # store timeseries results
                    res.name = f"{software}_timeseries_{rtype}_{node}"
                    timeseries_storage_location = storage_location.replace(
                        rtype, "timeseries_"+rtype)
                    res.to_json(
                        ".".join([timeseries_storage_location, "json"]),
                        orient="split",
                    )

                    # store regular loads as summed loads
                    res = res.sum()
                    res.name = result_id
                    res.to_json(
                        ".".join([storage_location, "json"]), orient="split")

        else:
            result_id = f"{software}_{rtype}"
            storage_location = os.path.join(data_storage_path, result_id)
            res = getattr(
                post_processed_data[software][rtype], wanted_results[rtype])
            res = pd.Series(res.values(), index=res.keys())
            res.name = result_id
            res.to_json(
                ".".join([storage_location, "json"]), orient="split")


# draw advanced graphs
advanced_graphs = {}
if CYTOSCAPE_ADVANCED_GRAPH:
    if ADVANCED_GRAPH_ON in SOFTWARES:

        reference_capacity = all_resultiers[
            ADVANCED_GRAPH_ON].node_installed_capacity["El Demand"]
        reference_net_energy_flow = all_resultiers[
            ADVANCED_GRAPH_ON].edge_net_energy_flow[("Powerline", "El Demand")]
        reference_emissions = all_resultiers[
            ADVANCED_GRAPH_ON].edge_specific_emissions[("Solar Panel", "Powerline")]

        app = dcv.draw_advanced_graph(
            optimized_es=optimized_CompCnE_combinations[ADVANCED_GRAPH_ON],
            layout='cose',
            # layout_nodeDimensionsIncludeLabels=True,
            node_shape="circle",
            node_color={
                'Hard Coal Supply': '#666666',
                'Hard Coal Supply Line': '#666666',
                'Hard Coal PP': '#666666',
                'Hard Coal CHP': '#666666',
                'Solar Panel': '#FF7700',
                'Heat Storage': '#cc0033',
                'Heat Demand': 'Red',
                'Heat Plant': '#cc0033',
                'Heatline': 'Red',
                'Power To Heat': '#cc0033',
                'Biogas CHP': '#006600',
                'Biogas Line': '#006600',
                'Biogas Supply': '#006600',
                'Onshore Wind Turbine': '#99ccff',
                'Offshore Wind Turbine': '#00ccff',
                'Gas Station': '#336666',
                'Gas Line': '#336666',
                'Combined Cycle PP': '#336666',
                'El Demand': '#ffe34d',
                'Battery': '#ffe34d',
                'Powerline': '#ffcc00',
                'Lignite Supply': '#993300',
                'Lignite Supply Line': '#993300',
                'Lignite Power Plant': '#993300',
            },
            reference_node_width=reference_capacity,
            reference_edge_width=reference_net_energy_flow/13,
            reference_edge_blackness=reference_emissions,
            node_border_width=0.1,
            node_fill_border_width=1.5,
            # edge_minimum_grey=0.15,
            nodes_to_remove=[
                "Hard Coal Supply",
                "Hard Coal Supply Line",
                "Hard Coal PP",
                "Hard Coal CHP",

                "Lignite Supply",
                "Lignite Supply Line",
                "Lignite Power Plant",

                "Biogas Supply",
                "Biogas Line",

                "Gas Station",
                "Gas Line",

                "Heat Plant"
            ],
        )

    app.run_server()


if MATPLOTLIB_ADVANCED_GRAPH:
    if ADVANCED_GRAPH_ON in SOFTWARES:
        from tessif.transform.es2mapping import omf as tomf
        from tessif.transform import nxgrph as nxt
        import matplotlib.pyplot as plt
        import tessif.visualize.nxgrph as nxv

        es = optimized_CompCnE_combinations[software]
        formatier = tomf.AllFormatier(es, cgrp='all')
        grph = nxt.Graph(tomf.FlowResultier(es))

        for key, value in formatier.edge_data()['edge_width'].items():
            formatier.edge_data()['edge_width'][key] = 4 * value

        nxv.draw_graphical_representation(
            formatier=formatier, colored_by='sector')

        figure = plt.gcf()
        figure.show()

# Use this in case you want to see the result representation of certain nodes
# rdrs = {}
# for software in SOFTWARES:
#     rdrs[software] = compile_result_data_representation(
#         optimized_es=optimized_CompCnE_combinations[software],
#         software=software,
#         node="Heatline",
#     )
# # print(rdrs['fine'])

Aggregate, Compare, and Store Representative Results

Following script takes the stored results from the optimization process above and turns them into representative csv files shown in the results section.

import pandas as pd
from numpy import int_

import os
from collections import defaultdict
import numbers

from tessif.frused.paths import doc_dir

FOLDER = "commitment_results"
# FOLDER = "expansion_results"
# FOLDER = "modified_expansion_results"

FOLDER = "trivia_results"

# locate the storage directory
cp = os.path.join(
    doc_dir, "source", "getting_started", "examples", "application",
    "phd", "field_study", "CompCnE", FOLDER
)

softwares = ['cllp', 'fine', 'omf', 'ppsa', ]
# use this in case you are just testing out the water
softwares = ['omf', ]

load_nodes = ["Powerline", "Heatline"]

# Result dicts for convenience access
globalesque_results = {}
load_results = {}
timeseries_results = {}
for software in softwares:
    load_results[software] = {}
    timeseries_results[software] = {}
    for node in load_nodes:
        load_result_file = f"{software}_Load_{node}"
        timeseries_load_result_file = f"{software}_timeseries_Load_{node}"

        storage_path = os.path.join(cp, ".".join([load_result_file, "json"]))
        ser = pd.read_json(
            storage_path, orient="split", typ="series")
        ser.name = load_result_file
        load_results[software][node] = ser

        timeseries_storage_path = os.path.join(cp, ".".join(
            [timeseries_load_result_file, "json"]))
        df = pd.read_json(
            timeseries_storage_path, orient="split", typ="frame")
        df.name = timeseries_load_result_file
        timeseries_results[software][node] = df

    globalesque_results[software] = {}
    for rtype in ["Capacity", "IntegratedGlobal"]:
        result_file = f"{software}_{rtype}"
        storage_path = os.path.join(cp, ".".join([result_file, "json"]))
        ser = pd.read_json(
            storage_path, orient="split", typ="series")
        ser.name = result_file
        globalesque_results[software][rtype] = ser

# flatten capacity and igr results for better readability:
capacity_results = {}
integrated_global_results = {}
for software in softwares:
    capacity_results[software] = globalesque_results[software]["Capacity"]
    integrated_global_results[software] = globalesque_results[software]["IntegratedGlobal"]

# aggregate software results into one dataframe for ease of comparison
load_by_node = defaultdict(dict)
timeseries_by_node = defaultdict(dict)
for software in softwares:
    for node in load_nodes:
        load_by_node[node][software] = load_results[software][node]
        timeseries_by_node[node][software] = timeseries_results[software][node]

labels = [
    "Capacity",
    "IGR",
    "Load-Powerline",
    "Load-Heatline",
    "Timeseries-Powerline",
    "Timeseries-Heatline",
]
dimensions = ["MW or MWh", "€ or t_CO2", "MW", "MW", "MW", "MW"]

for pos, dct in enumerate([
    capacity_results,
    integrated_global_results,
    load_by_node["Powerline"],
    load_by_node["Heatline"],

    timeseries_by_node["Powerline"],
    timeseries_by_node["Heatline"],
]):

    df = pd.concat(
        dct.values(),
        keys=dct.keys(),
        axis='columns')

    # drop all zero  columns
    # df = df.loc[:, (df != 0).any(axis=0)]

    # give dataframe a name for higher recognition value
    df.index.name = labels[pos] + f" [{dimensions[pos]}]"
    # sort dataframe for index
    df = df.sort_index()

    # change None to "variable" since that is what it means
    df = df.fillna("variable")
    # cast values into integers, since they are deemed to provide enough
    # information
    df = df.applymap(
        lambda x: int_(x) if isinstance(x, numbers.Number) else x,
        # na_action="ignore",
    )

    # dynamically create the filename using the df.index name
    storage_path = os.path.join(cp, ".".join([labels[pos], "csv"]))

    # store the result dfs as csv for convenient access
    df.to_csv(storage_path)

IGR Bar Plot Code

The CompC/E “Integrated Global Result” bar plots are created using following code:

import pandas as pd


from pathlib import Path

from tessif.frused.paths import doc_dir
from tessif.visualize import igr

mpl_config = {
    "title": "Integrated Global Results Relative to 'Oemof'",
    "ylabel": "",
    "xlabel": "Result Values",
    "rot": 0,
}

for result in [
    # "commitment_results",
    "expansion_results",
    "modified_expansion_results",
    # "trivia_results",
]:
    igr_results_csv_path = (
        Path(doc_dir)
        / "source"
        / "getting_started"
        / "examples"
        / "application"
        / "phd"
        / "field_study"
        / "CompCnE"
        / result
        / "IGR.csv"
    )

    result_df = pd.read_csv(igr_results_csv_path, index_col=0)

    # make results relative to oemof
    result_df = result_df.div(result_df['omf'], axis='index')
    # mpl_config["ylim"] = [
    #     math.floor(10*result_df.min().min())/10,
    #     math.ceil(10*result_df.max().max())/10,
    # ]

    handle = igr.plot(
        igr_df=result_df,
        plt_config=mpl_config,
        ptype="bar",
    )

    # for category in ["costs", "non_costs"]:
    #     figure_storage_path = igr_results_csv_path.parents[0] / "_".join(
    #         [category, "IGR.png"])

    # handle[category].savefig(figure_storage_path)
    handle["costs"].gca().grid('on', which='major', axis='y')
    handle["costs"].show()
    handle["non_costs"].gca().grid('on', which='major', axis='y')
    handle["non_costs"].show()


plexp_config = {
    "title": "Integrated Global Results Relative to 'Oemof (omf)'",
    "barmode": "group",
    "text_auto": True,
}


handle = igr.plot(
    igr_df=result_df,
    plt_config=plexp_config,
    ptype="bar",
    draw_util="plexp",
)
handle["costs"].show()
handle["non_costs"].show()

Installed Compfer Grid Capacity

The CompC/E “Installed Compfer Grid Capacities” bar plots are created using following code:

import os

from tessif.frused.paths import doc_dir

import pandas as pd
import plotly.express as px

PARENT = "CompCnE"

FOLDERS = [
    # "commitment_results",
    "expansion_results",
    # "modified_expansion_results",
]

# FOLDERS = ["trivia_results", ]

FILE = "Capacity.csv"

SOFTWARES = [
    # 'cllp',
    # 'fine',
    'omf',
    # 'ppsa',
]
NOT_NODES = [
    "Biogas Line",
    "Gas Line",
    "Hard Coal Supply Line",
    "Heatline",
    "Lignite Supply Line",
    "Powerline",
]

PLOTLY = False
MATPLOTLIB = True

# locate the storage directory
parent_folder = os.path.join(
    doc_dir,
    "source",
    "getting_started",
    "examples",
    "application",
    "phd",
    "field_study",
    PARENT,
)

# cp = os.path.join(parent_folder, FOLDER)

for folder in FOLDERS:
    capacities_path = os.path.join(parent_folder, folder, FILE)

    df = pd.read_csv(capacities_path, index_col=0)

    # only keep nodes in NOT_NODES
    keepers = [node for node in df.index if node not in NOT_NODES]
    df = df.loc[keepers]

    # rename df cols and rows for increased verbosity
    df.columns.name = "Softwares"
    df.index.name = "Nodes"

    print(df)

    # original df holds "variable" strings so data needs to be parsed to numeric
    df = df.apply(pd.to_numeric, errors='coerce')

    # store the df as csv for reference
    write_path = os.path.join(
        parent_folder, folder, "Installed_Capacities.csv")
    df.to_csv(write_path)

    folder_title = " ".join(
        [part.capitalize() for part in folder.split("_")])

    if PLOTLY:
        figure = px.bar(
            df,
            barmode="group",
            text_auto=True,
            title="Installed Capacities in MWh " + folder_title,
            template="simple_white",
        )
        figure.show()

    if MATPLOTLIB:
        ax = df.plot(
            kind="bar",
            title="Installed Capacities " + folder_title,
            xlabel="Nodes",
            ylabel="Installed Capacities in MWh",
            rot=45,
        )
        ax.grid(axis='y')
        figure = ax.figure
        figure.show()

Summed Load Bar Plots

The CompC/E summed load bar plots are created using following code:

import plotly.express as px
import os
from collections import defaultdict

from tessif.frused.paths import doc_dir
import matplotlib.pyplot as plt


import pandas as pd

PARENT = "CompCnE"

FOLDER = "commitment_results"
FOLDER = "expansion_results"
FOLDER = "modified_expansion_results"

# FOLDER = "trivia_results"

NODES = [
    "Powerline",
    "Heatline",
]

# locate the storage directory
parent_folder = os.path.join(
    doc_dir,
    "source",
    "getting_started",
    "examples",
    "application",
    "phd",
    "field_study",
    PARENT,
)

cp = os.path.join(parent_folder, FOLDER)


for node in NODES:
    summed_loads_file = f"Load-{node}.csv"
    summed_loads_path = os.path.join(parent_folder, FOLDER, summed_loads_file)

    df = pd.read_csv(summed_loads_path, index_col=0)
    # drop all zero rows
    df = df.loc[(df != 0).any(axis=1)]
    df.columns.name = "softwares"
    # print(node)
    print(df)

    if not df.empty:
        figure = px.bar(
            df,
            barmode="group",
            text_auto=True,
            title=f"{node} Summed Loads",
            template="simple_white",
        )

        ax = df.plot(
            kind="bar",
            title=f"{node} Summed Loads",
            xlabel="Connecting Nodes",
            ylabel="Summed Loads in MW",
            rot=45,
        )
        ax.grid(axis='y')
        figure = ax.figure
        figure.show()

Load Probile Plots

The CompC/E load profile plots are created using following code:

import os
from collections import defaultdict

from tessif.frused.paths import doc_dir
import matplotlib.pyplot as plt
from tessif.visualize import component_loads

import pandas as pd

PARENT = "CompCnE"

FOLDER = "commitment_results"
# FOLDER = "expansion_results"
# FOLDER = "modified_expansion_results"

# FOLDER = "trivia_results"


SOFTWARES = [
    'cllp',
    'fine',
    'omf',
    'ppsa',
]
NODES = [
    "Powerline",
    "Heatline",
]

# locate the storage directory
parent_folder = os.path.join(
    doc_dir,
    "source",
    "getting_started",
    "examples",
    "application",
    "phd",
    "field_study",
    PARENT,
)

cp = os.path.join(parent_folder, FOLDER)


load_results = {}
for software in SOFTWARES:
    load_results[software] = {}
    for node in NODES:
        load_result_file = f"{software}_timeseries_Load_{node}"
        storage_path = os.path.join(cp, ".".join([load_result_file, "json"]))
        df = pd.read_json(
            storage_path, orient="split", typ="frame")
        df.name = load_result_file
        load_results[software][node] = df

        # store the df as csv for reference
        df.columns.name = "Softwares"
        write_path = os.path.join(cp, ".".join([load_result_file, "csv"]))
        df.to_csv(write_path)


# aggregate software results into one dataframe for ease of comparison
load_by_node = defaultdict(dict)
for software in SOFTWARES:
    for node in NODES:
        load_by_node[node][software] = load_results[software][node]

for software in SOFTWARES:
    for node in NODES:

        df = load_by_node[node][software]
        # drop all zero  columns
        df = df.loc[:, (df != 0).any(axis=0)]

        figure = component_loads.bar_lines(
            df,
            component_type='bus',
        )

        title = f"{node} Load Profile Results of Software: '{software}'"
        figure.axes[0].set_title(title)

        figure.show()

Computational Results

Computational Ressources Estimation Code

The computational ressources bar plots are created using following code:

# change spellings_logging_level to debug to declutter output
import pandas as pd
import os
from tessif.frused.paths import doc_dir, write_dir
import tessif.analyze
from tessif import parse
from tessif.frused.hooks.tsf import reparameterize_components


import tessif.frused.configurations as configurations
configurations.spellings_logging_level = 'debug'

PARENT = "CompCnE"
SOFTWARES = ('cllp', 'fine', 'omf', 'ppsa', )
# SOFTWARES = ('cllp',)

PERIODS = 8760
EXPANSION = False

FOLDER = "commitment_results"
# FOLDER = "expansion_results"
# FOLDER = "modified_expansion_results"

# FOLDER = "trivia_results"

if FOLDER == "modified_expansion_results":
    HOOK_PYPSA = True
else:
    HOOK_PYPSA = False


def reparam_ppsa(tessif_es):
    reparameterized_es = reparameterize_components(
        es=tessif_es,
        components={
            'Hard Coal CHP': {
                'flow_emissions': {'Hard_Coal': 0, 'electricity': 0, 'hot_water': 0},
            },
            'Hard Coal Supply': {
                'flow_emissions': {'Hard_Coal': 0.8 * 0.4 + 0.06 * 0.4},
            },
            'Biogas CHP': {
                'flow_emissions': {'biogas': 0, 'electricity': 0, 'hot_water': 0},
            },
            'Biogas Supply': {
                'flow_emissions': {'biogas': 0.25 * 0.4 + 0.01875 * 0.5},
            },

        },

    )
    return reparameterized_es


hook = None
if HOOK_PYPSA:
    hook = reparam_ppsa

# locate the storage directory
parent_location = os.path.join(
    doc_dir, "source", "getting_started", "examples", "application",
    "phd", "field_study", PARENT
)

result_path = os.path.join(parent_location, FOLDER)
creation_path = os.path.join(parent_location, "creation.py")

creation_module = parse.python_file(creation_path)
tessif_CompCnE = creation_module.create_compcne_es(
    periods=PERIODS, expansion=EXPANSION)

output_msg = tessif_CompCnE.to_hdf5(
    directory=os.path.join(write_dir, 'tsf'),
    filename='es_to_compare.hdf5',
)


# let the comparatier do the auto comparison:
memory_results = {}
for software in SOFTWARES:

    dct = tessif.analyze.trace_memory(
        path=os.path.join(write_dir, 'tsf', 'es_to_compare.hdf5'),
        parser=tessif.parse.hdf5,
        model=software,
        hook=hook,
    )

    memory_df = pd.DataFrame(
        data=dct.values(), index=dct.keys(), columns=(software,))
    memory_df = memory_df.divide(1e6).round(0)
    memory_df.index.name = "Memory [MB]"
    memory_df.rename(index={'simulation': 'optimization'}, inplace=True)
    csv_path = os.path.join(result_path, "_".join(
        [software, "memory_results.csv"]))
    memory_df.to_csv(csv_path)

print("memory results obtianed")

timing_results = {}
for software in SOFTWARES:

    dct = tessif.analyze.stop_time(
        path=os.path.join(write_dir, 'tsf', 'es_to_compare.hdf5'),
        parser=tessif.parse.hdf5,
        model=software,
        measurement='wall',
        hook=hook,
    )

    timings_df = pd.DataFrame(
        data=dct.values(), index=dct.keys(), columns=(software,))
    timings_df = timings_df.round(1)
    timings_df.index.name = "Timings [s]"
    timings_df.rename(index={'simulation': 'optimization'}, inplace=True)
    csv_path = os.path.join(result_path, "_".join(
        [software, "timings_results.csv"]))
    timings_df.to_csv(csv_path)

print("timing results obtianed")

Computational Ressources Plots

The computational ressources bar plots are created using following code:

from tessif.frused.paths import doc_dir  # nopep8
import os  # nopep8
import pandas as pd  # nopep8


SOFTWARES = ('cllp', 'fine', 'omf', 'ppsa', )

PARENT = "CompCnE"

FOLDER = "commitment_results"
# FOLDER = "expansion_results"
# FOLDER = "modified_expansion_results"

# FOLDER = "trivia_results"


# locate the storage directory
parent_location = os.path.join(
    doc_dir, "source", "getting_started", "examples", "application",
    "phd", "model_scenario_combinations", PARENT
)


# locate the storage directory
result_path = os.path.join(parent_location, FOLDER)

memory_results = {}
for software in SOFTWARES:
    csv_path = os.path.join(result_path, "_".join(
        [software, "memory_results.csv"]))
    memory_results[software] = pd.read_csv(
        csv_path, index_col=0).to_dict()[software]

memory_df = pd.DataFrame(memory_results)
memory_df.index.name = "Memory [MB]"
csv_path = os.path.join(result_path, "memory_results.csv")
plot_path = os.path.join(result_path, "memory_results.png")
memory_df.to_csv(csv_path)
memory_df.plot(kind="bar", rot=0, figsize=(10, 5)).figure.savefig(plot_path)

timings_results = {}
for software in SOFTWARES:
    csv_path = os.path.join(result_path, "_".join(
        [software, "timings_results.csv"]))
    timings_results[software] = pd.read_csv(
        csv_path, index_col=0).to_dict()[software]

timings_df = pd.DataFrame(timings_results)
timings_df.index.name = "Time [s]"
csv_path = os.path.join(result_path, "timings_results.csv")
plot_path = os.path.join(result_path, "timings_results.png")
timings_df.to_csv(csv_path)
timings_df.plot(kind="bar", rot=0, figsize=(10, 5)).figure.savefig(plot_path)