# tessif/examples/data/fine/py_hard.py
"""
:mod:`~tessif.examples.data.fine.py_hard` is a :mod:`tessif` module for giving
examples on how to create an :class:`fine energy system
<fine.energySystemModel>`.
It collects minimum working examples, meaningful working
examples and full fledged use case wrappers for common scenarios.
"""
# 1.) Handle imports:
# standard library
import pathlib
import os
# third party
import shutil
import FINE as fn
import pandas as pd
import numpy as np
# local imports
import tessif.frused.namedtuples as nts
from tessif.frused.paths import write_dir
import tessif.write.tools as write_tools
[docs]def create_mwe(directory=None, filename=None, save=False):
r"""
Create a minimum working example using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~create_mwe.directory` as
:paramref:`~create_mwe.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/mwe will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``mwe_FINE``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet`.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": "GW_el", "gas": "GW_CH4"}
commodities = {"Electricity", "gas", }
numberOfTimeSteps = 4
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
verboseLogLevel=2,
)
# 2.) Adding Commodity Transmission to esM (not necessary for mwe)
uid = nts.Uid(
name='PowerLine', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 2.) Adding Commodity Transmission to esM (not necessary for mwe)
uid = nts.Uid(
name='CBET', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Bus', node_type='gas-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 3.) Adding Commodity Sink to esM representing the Demand
uid = nts.Uid(
name='Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink', node_type='Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10] * numberOfTimeSteps})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4.) Adding Commodity Source to esM representing renewable energy
uid = nts.Uid(
name='Renewable', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({uid.region: [1, 1, 0, 1]})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
operationRateMax=data_frame,
capacityMax=10,
opexPerOperation=1,
investPerCapacity=1,
)
)
# 6.) Adding Commodity Source to esM representing a gas import
uid = nts.Uid(
name='Gas Station', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Source', node_type='gas import')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 5.) Adding Commodity Conversion: gas -> elec
uid = nts.Uid(
name='Transformer', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Transformer', node_type='gas-powerplant')
uids.update({str(uid): uid})
# Transformer capacities are always related to inflow
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_CH4",
commodityConversionFactors={"gas": -1, "Electricity": 0.42},
opexPerOperation=2,
)
)
# 8.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
with write_tools.HideStdoutPrinting():
esM.optimize(solver='cbc')
# 9.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
f = "mwe_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
d = os.path.join(write_dir, 'fine', 'mwe')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 9b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 9c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 10.) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 11.) Return the mwe_FINE energy system
return esM
[docs]def create_expansion_example(directory=None, filename=None, save=False):
r"""
Create an expansion example using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~expansion_example.directory` as
:paramref:`~expansion_example.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/expansion_example will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``expansion_example_FINE``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet`.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": r"GW_el", "emissions": r'CO2/unit_Energy',
'electricity.unlimitted': 'MW_unlimitted'}
commodities = {"Electricity", "emissions", "electricity.unlimitted", }
numberOfTimeSteps = 4
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
simLimit = 20
yearlyLimit = 8760 * simLimit / numberOfTimeSteps
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
verboseLogLevel=2,
)
# 2.) Adding Commodity Transmission to esM (not necessary for mwe)
uid = nts.Uid(
name='PowerLine', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 3.) Adding Commodity Sink to esM representing the Demand
uid = nts.Uid(
name='Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10] * numberOfTimeSteps})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4a.) Adding Commodity Source to esM representing capped source with given bounds
uid = nts.Uid(
name='Capped Renewable', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
capacityMax=4,
capacityMin=2,
opexPerOperation=2,
investPerCapacity=1,
interestRate=0,
economicLifetime=numberOfTimeSteps / 8760
)
)
# 4b.) Adding Commodity Source to esM representing uncapped source but with invest costs if built
uid = nts.Uid(
name='Uncapped Renewable', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [1/3, 2/3, 3/3, 1/3]})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
operationRateMax=data_frame,
capacityMin=3,
investPerCapacity=2,
opexPerOperation=2,
interestRate=0,
economicLifetime=numberOfTimeSteps / 8760
)
)
# 5b.) Adding unlimitted Commodity Source to enable emission and commodity production in transformer
# this commodity is not any part in tessifs post processing, just that the transformer can do its job representing
# a source
esM.add(
fn.Source(
esM=esM,
name='Emitting Source.unlimitted',
commodity='electricity.unlimitted',
hasCapacityVariable=True,
)
)
# 5a.) Adding Commodity Conversion representing unlimitted source converting into commodity and emission
uid = nts.Uid(
name='Emitting Source', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='electricity',
component='Source')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit="GW_el",
commodityConversionFactors={
"electricity.unlimitted": -1, 'Electricity': 1, "emissions": 1},
hasCapacityVariable=True,
capacityMax=None,
interestRate=0,
economicLifetime=numberOfTimeSteps / 8760
)
)
# 6.) Adding global constraint for CO2, when a yearly limit is set
if yearlyLimit > 0:
esM.add(
fn.Sink(
esM=esM,
name='emissions',
commodity='emissions',
hasCapacityVariable=False,
commodityLimitID='emissions',
yearlyLimit=yearlyLimit
)
)
# 7.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
with write_tools.HideStdoutPrinting():
esM.optimize(solver='cbc')
# 8.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
f = "expansion_example_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
d = os.path.join(write_dir, 'fine', 'expansion_example')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 8b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 8c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 9.) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 10.) Return the mwe_FINE energy system
return esM
[docs]def emission_objective(directory=None, filename=None, save=False):
r"""
Create an emission constrain example using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~emission_objective.directory` as
:paramref:`~emission_objective.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/emission_objective will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``emission_objective_FINE``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet`.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": r"GW_el",
"gas": r"GW_CH4", 'CO2': r'CO2/unit_Energy'}
commodities = {"Electricity", "gas", "CO2"}
numberOfTimeSteps = 4
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
simLimit = 30
yearlyLimit = 8760 * simLimit / numberOfTimeSteps
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
lengthUnit="km",
verboseLogLevel=2,
)
# 2a.) Adding Commodity Transmission to esM for electricity
uid = nts.Uid(
name='Power Line', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
)
)
# 2b.) Adding Commodity Transmission to esM for electricity
uid = nts.Uid(
name='CBET', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Bus', node_type='Gas-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
)
)
# 3.) Adding Commodity Sink to esM representing the Demand
uid = nts.Uid(
name='Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink', node_type='AC-Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 10, 10, 10]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4.) Adding Commodity Source to esM representing a gas import
uid = nts.Uid(
name='CBE', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Source', node_type='Pipeline')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 5a.) Adding Commodity Conversion: gas -> elec
uid = nts.Uid(
name='Transformer', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Transformer', node_type='gas-powerplant')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_el",
commodityConversionFactors={
"Electricity": 0.42, 'CO2': 1, "gas": -1},
hasCapacityVariable=True,
capacityMax=10 / 0.42,
opexPerOperation=2
)
)
# 6.) Adding Commodity Source to esM representing renewable energy
uid = nts.Uid(
name='Renewable', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
opexPerOperation=5,
)
)
# 7.) Adding global constraint for CO2, when a yearly limit is set
if yearlyLimit > 0:
esM.add(
fn.Sink(
esM=esM,
name='emission',
commodity='CO2',
hasCapacityVariable=False,
commodityLimitID='emission',
yearlyLimit=yearlyLimit
)
)
# 7.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
with write_tools.HideStdoutPrinting():
esM.optimize(solver='cbc')
# 8.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
f = "emission_objective_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
d = os.path.join(write_dir, 'fine', 'emission_objective')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 8b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 8c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 9.a) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 9.b) Return the energy system
return esM
[docs]def chp_example(directory=None, filename=None, save=False):
r"""
Create a combined heat and power example using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~create_chp.directory` as
:paramref:`~create_chp.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/chp will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``chp_FINE``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet`.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": r"GW_el",
"gas": r"GW_CH4", 'Heat': r"GW_Heat", }
commodities = {"Electricity", "gas", "Heat"}
numberOfTimeSteps = 4
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
lengthUnit="km",
verboseLogLevel=2,
)
# 2a.) Adding Commodity Electricity Transmission to esM
uid = nts.Uid(
name='Power Line', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
)
)
# 2b.) Adding Commodity Heat Transmission to esM
uid = nts.Uid(
name='Heat Grid', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Bus', node_type='Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
)
)
# 2c.) Adding Commodity Gas Transmission to esM
uid = nts.Uid(
name='Gas Grid', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Bus', node_type='Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
)
)
# 3a.) Adding Commodity Sink to esM representing the Electricity Demand
uid = nts.Uid(
name='Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink', node_type='AC-Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 10, 10, 10]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 3b.) Adding Commodity Sink to esM representing the Heat Demand
uid = nts.Uid(
name='Heat Demand', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Sink', node_type='Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 10, 10, 10]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4a.) Adding Commodity Source to esM representing external back up
uid = nts.Uid(
name='Backup Power', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
opexPerOperation=10,
)
)
# 4b.) Adding Commodity Source to esM representing external back up
uid = nts.Uid(
name='Backup Heat', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Source', node_type='Heat-Source')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
opexPerOperation=10,
)
)
# 4c.) Adding Commodity Source to esM representing a gas import
uid = nts.Uid(
name='Gas Source', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Source', node_type='Pipeline')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 5a.) Adding Commodity Conversion: gas -> Electricity + Heat
uid = nts.Uid(
name='CHP', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Transformer', node_type='gas-powerplant')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_CH4",
commodityConversionFactors={
"gas": -1, "Electricity": 0.3, "Heat": 0.2},
hasCapacityVariable=True,
opexPerOperation=5 * 0.3 + 5 * 0.2
)
)
# 6.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
with write_tools.HideStdoutPrinting():
esM.optimize(solver='cbc')
# 7.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
f = "chp_example_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
d = os.path.join(write_dir, 'fine', 'chp_example')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 7b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 7c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 8.) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 9.) Return the energy system
return esM
[docs]def storage_example(directory=None, filename=None, save=False):
r"""
Create a storage example using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~storage_example.directory` as
:paramref:`~storage_example.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/storage_example will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``storage_example_FINE``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet`.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": r"GW_el"}
commodities = {"Electricity"}
numberOfTimeSteps = 5
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
lengthUnit="km",
verboseLogLevel=2,
)
# 2.) Adding Commodity Electricity Transmission to esM
uid = nts.Uid(
name='Power Line', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 3.) Adding Commodity Sink to esM representing the Electricity Demand
uid = nts.Uid(
name='Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink', node_type='AC-Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 10, 7, 10, 10]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4.) Adding Commodity Source to esM representing renewable energy
uid = nts.Uid(
name='Generator', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({uid.region: [1, 1, 0, 1, 0]})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
operationRateMax=data_frame,
opexPerOperation=2,
)
)
# 5.) Adding storage to esM representing a battery
uid = nts.Uid(
name='Storage', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Storage', node_type='AC-AC-Storage')
uids.update({str(uid): uid})
esM.add(
fn.Storage(
# Required Parameters
esM=esM,
name=str(uid),
commodity=uid.carrier,
opexPerDischargeOperation=1,
)
)
# 6.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
with write_tools.HideStdoutPrinting():
esM.optimize(solver='cbc')
# 7a.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
f = "storage_example_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
d = os.path.join(write_dir, 'fine', 'storage_example')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 7b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 8c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 9.) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 10.) Return the energy system
return esM
[docs]def create_multicommodity(directory=None, filename=None, save=False):
r"""
Create a multi flow grid example using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~multi_com.directory` as
:paramref:`~multi_com.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/multi_commodity will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``multi_commodity_FINE``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet`.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": r"GW_el", "gas": r"GW_CH4", 'CO2': r'CO2/unit_Energy', 'Heat': r"GW_Heat",
'H2': r'GW_H2'}
commodities = {"Electricity", "gas", "CO2", "Heat", "H2"}
numberOfTimeSteps = 4
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
simLimit = 30
yearlyLimit = 8760 * simLimit / numberOfTimeSteps
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
lengthUnit="km",
verboseLogLevel=2,
)
# 2a.) Adding Commodity Electricity Transmission to esM
uid = nts.Uid(
name='Power Line', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 2b.) Adding Commodity Heat Transmission to esM
uid = nts.Uid(
name='Heat Grid', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Bus', node_type='Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 2c.) Adding Commodity H2 Transmission to esM
uid = nts.Uid(
name='H2 Grid', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='H2',
component='Bus', node_type='Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 2d.) Adding Commodity Heat Transmission to esM
uid = nts.Uid(
name='Gas Grid', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Bus', node_type='Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
)
)
# 3a.) Adding Commodity Sink to esM representing the Electricity Demand
uid = nts.Uid(
name='Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink', node_type='AC-Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [6, 24, 10, 16]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 3b.) Adding Commodity Sink to esM representing the Heat Demand
uid = nts.Uid(
name='Heat Demand', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Sink', node_type='Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 12, 6, 12]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 3c.) Adding Commodity Sink to esM representing the Heat Demand
uid = nts.Uid(
name='H2 Demand', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='H2',
component='Sink', node_type='Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 50, 6, 15]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 3b.) Adding Commodity Sink to esM representing the Heat Demand
uid = nts.Uid(
name='Gas Demand', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='gas',
component='Sink', node_type='Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 12, 6, 12]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4a.) Adding Commodity Source to esM representing renewable energy
uid = nts.Uid(
name='Renewable', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({uid.region: [0.8, 0.4, 0.6, 1]})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
operationRateMax=data_frame,
capacityMax=30,
opexPerOperation=5,
)
)
# 4b.) Adding Commodity Source to esM representing renewable energy
uid = nts.Uid(
name='Back-up Heat', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Source', node_type='Heat-Source')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({uid.region: [0.8, 0.4, 0.6, 1]})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
operationRateMax=data_frame,
capacityMax=10,
opexPerOperation=5,
)
)
# 4c.) Adding Commodity Source to esM representing a gas import
uid = nts.Uid(
name='Gas Import', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Source', node_type='Pipeline')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 4d.) Adding Commodity Source to esM representing a Heat import
uid = nts.Uid(
name='Industry Heat', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Source', node_type='Pipeline')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({uid.region: [0, 0.8, 1, 0]})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
capacityMax=7.5,
operationRateMax=data_frame,
)
)
# 4e.) Adding Commodity Source to esM representing a H2 import
uid = nts.Uid(
name='H2 Import', latitude=53, longitude=10,
region='Germany', sector='Multi', carrier='H2',
component='Source', node_type='Pipeline')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({uid.region: [1, 0, 1, 1]})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
operationRateMax=data_frame,
)
)
# 5a.) Adding Commodity Conversion: gas -> Electricity + Heat
uid = nts.Uid(
name='CHP', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Transformer', node_type='gas-powerplant')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_CH4",
commodityConversionFactors={
"gas": -1, "Electricity": 0.42, "Heat": 0.42, "CO2": 2},
hasCapacityVariable=True,
capacityMax=10 / 0.42,
opexPerOperation=10
)
)
# 5b.) Adding Commodity Conversion: H2 -> Electricity + Heat
uid = nts.Uid(
name='H2-CHP', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='H2',
component='Transformer', node_type='gas-powerplant')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_CH4",
commodityConversionFactors={
"H2": -1, "Electricity": 0.8, "Heat": 0.4, "CO2": 0.1},
hasCapacityVariable=True,
opexPerOperation=20
)
)
# 5c.) Adding Commodity Conversion: H2 -> Electricity + Heat
uid = nts.Uid(
name='Electrolyzer', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='H2',
component='Transformer', node_type='H2-Electrolyzer')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_H2",
commodityConversionFactors={"Electricity": -1, "H2": 0.5},
hasCapacityVariable=True,
opexPerOperation=10
)
)
# 6a.) Storage components for electricity
uid = nts.Uid(
name='Batteries', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Storage', node_type='AC-AC-Storage')
uids.update({str(uid): uid})
esM.add(
fn.Storage(
esM=esM,
name=str(uid),
commodity=uid.carrier,
opexPerDischargeOperation=3
)
)
# 6b.) Storage components for H2
uid = nts.Uid(
name='H2-Caverns', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='H2',
component='Storage', node_type='AC-H2-Storage')
uids.update({str(uid): uid})
esM.add(
fn.Storage(
esM=esM,
name=str(uid),
commodity=uid.carrier,
capacityMax=30,
opexPerDischargeOperation=1
)
)
# 7.) Adding global constraint for CO2, when a yearly limit is set
if yearlyLimit > 0:
esM.add(
fn.Sink(
esM=esM,
name='co2_limit',
commodity='CO2',
hasCapacityVariable=False,
commodityLimitID='CO2 limit',
yearlyLimit=yearlyLimit
)
)
# 8.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
with write_tools.HideStdoutPrinting():
esM.optimize(solver='cbc')
# 9.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
f = "multi_commodity_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
d = os.path.join(write_dir, 'fine', 'multi_commodity')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 9b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 9c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 10.a) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 10.b) Return the energy system
return esM
[docs]def single_chp_emission_objective(directory=None, filename=None, save=False):
r"""
Create a single combined heat and power example with emissions constrained using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~single_chp_obj.directory` as
:paramref:`~single_chp_obj.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/single_chp_obj will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``single_chp_obj``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet`.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": r"GW_el", "gas": r"GW_CH4",
'Heat': r"GW_Heat", 'CO2': r'CO2/unit_Energy'}
commodities = {"Electricity", "gas", "Heat", "CO2"}
numberOfTimeSteps = 2
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
simLimit = 30
yearlyLimit = 8760 * simLimit / numberOfTimeSteps
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
lengthUnit="km",
verboseLogLevel=2,
)
# 2a.) Adding commodity electricity transmission to esM
uid = nts.Uid(
name='Power Line', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 2b.) Adding commodity heat transmission to esM
uid = nts.Uid(
name='Heat Grid', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Bus', node_type='Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 2c.) Adding commodity gas transmission to esM
uid = nts.Uid(
name='Gas Grid', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Bus', node_type='Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
)
)
# 3a.) Adding commodity sink to esM representing the electricity Demand
uid = nts.Uid(
name='Power Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink', node_type='AC-Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 10]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 3b.) Adding commodity sink to esM representing the heat demand
uid = nts.Uid(
name='Heat Demand', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Sink', node_type='Sink')
uids.update({str(uid): uid})
data_frame = pd.DataFrame({"Germany": [10, 10]})
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4a.) Adding commodity source to esM representing renewable energy
uid = nts.Uid(
name='Backup Power', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
capacityMax=10,
opexPerOperation=10,
)
)
# 4b.) Adding commodity source to esM representing renewable energy
uid = nts.Uid(
name='Backup Heat', latitude=53, longitude=10,
region='Germany', sector='Heat', carrier='Heat',
component='Source', node_type='Heat-Source')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
capacityMax=10,
opexPerOperation=10,
)
)
# 4c.) Adding Commodity Source to esM representing a gas import
uid = nts.Uid(
name='Gas Source', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Source', node_type='Pipeline')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 5a.) Adding Commodity Conversion: gas -> Electricity + Heat
uid = nts.Uid(
name='CHP', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Transformer', node_type='gas-powerplant')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_CH4",
commodityConversionFactors={
"gas": -1, "Electricity": 0.3, "Heat": 0.5, "CO2": 1},
hasCapacityVariable=True,
opexPerOperation=2
)
)
# 6.) Adding limiting constraint as sink
if yearlyLimit > 0:
esM.add(
fn.Sink(
esM=esM,
name='CO2_output',
commodity='CO2',
hasCapacityVariable=False,
commodityLimitID='CO2_cap',
yearlyLimit=yearlyLimit
)
)
# 7.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
with write_tools.HideStdoutPrinting():
esM.optimize(solver='cbc')
# 8.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
f = "single_chp_obj_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
d = os.path.join(write_dir, 'fine', 'single_chp_obj')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 9b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 9c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 11.a) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 11.b) Return the energy system
return esM
[docs]def tsa_one_year_example(directory=None, filename=None, save=False, tsa=False):
r"""
Create an one year timeseries example using :mod:`fine`.
Creates a simple energy system simulation to potentially
store it on disc in :paramref:`~one_year_mwe.directory` as
:paramref:`~one_year.filename`
Parameters
----------
directory : str, default=None
String path the created energy system is stored in.
If set to ``None`` (default)
:attr:`tessif.frused.paths.write_dir`/fine/one_year will be the chosen
directory.
filename : str, default=None
String name of the file the results are stored in.
If set to ``None`` (default) filename will be ``one_year_FINE``.
save : boolean, default=False
Specifies if the data should be stored to an excel spreadsheet.
tsa : boolean, default=False
Specifies if the data should be aggregated for faster optimization or not.
Return
------
optimized_es : fine energy system model
Energy system carrying the optimization results.
"""
# Specify the necessary parameters to create an energy system with fine
locations = {"Germany"}
commodityUnitDict = {"Electricity": r"GW_el",
"gas": r"GW_CH4", 'CO2': r'CO2/unit_Energy'}
commodities = {"Electricity", "gas", "CO2"}
numberOfTimeSteps = 8760
hoursPerTimeStep = 1
timesteps = pd.date_range('7/13/1990', periods=numberOfTimeSteps, freq='H')
yearlyLimit = 5000
uids = dict()
# 1.) Creating an energy system model instance
esM = fn.energySystemModel.EnergySystemModel(
locations=locations,
commodities=commodities,
numberOfTimeSteps=numberOfTimeSteps,
commodityUnitsDict=commodityUnitDict,
hoursPerTimeStep=hoursPerTimeStep,
costUnit="€",
lengthUnit="km",
verboseLogLevel=2,
)
# 2a.) Adding Commodity Transmission to esM for electricity
uid = nts.Uid(
name='Powerline', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Bus', node_type='AC-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 2b.) Adding Commodity Transmission to esM for electricity
uid = nts.Uid(
name='CBET', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Bus', node_type='Gas-Bus')
uids.update({str(uid): uid})
esM.add(
fn.Transmission(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 3.) Adding Commodity Sink to esM representing the Demand
uid = nts.Uid(
name='Demand', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Sink', node_type='AC-Sink')
uids.update({str(uid): uid})
dailyProfileSimple = [0.6, 0.6, 0.6, 0.6, 0.6, 0.7, 0.9,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9, 0.8]
data_frame = pd.DataFrame([[(u + 0.1 * np.random.rand()) * 50] for day in range(365) for u in dailyProfileSimple],
index=range(8760), columns=['Germany']).round(2)
esM.add(
fn.Sink(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=False,
operationRateFix=data_frame,
)
)
# 4.) Adding Commodity Source to esM representing a gas import
uid = nts.Uid(
name='CBE', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Source', node_type='Pipeline')
uids.update({str(uid): uid})
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
)
)
# 5.) Adding Commodity Conversion: gas -> elec
uid = nts.Uid(
name='Transformer', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='gas',
component='Transformer', node_type='gas-powerplant')
uids.update({str(uid): uid})
esM.add(
fn.Conversion(
esM=esM,
name=str(uid),
physicalUnit=r"GW_CH4",
commodityConversionFactors={
"Electricity": 0.63, 'CO2': 201 * 1e-6 / 0.63, "gas": -1},
hasCapacityVariable=True,
capacityMax=40 / 0.63,
opexPerOperation=2,
)
)
# 6) Adding Commodity Source to esM representing renewable energy
uid = nts.Uid(
name='Renewable', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Source', node_type='AC-Source')
uids.update({str(uid): uid})
data_frame = pd.DataFrame([[np.random.beta(a=2, b=5)] for t in range(8760)], index=range(8760),
columns=['Germany']).round(6)
esM.add(
fn.Source(
esM=esM,
name=str(uid),
commodity=uid.carrier,
hasCapacityVariable=True,
operationRateMax=data_frame,
capacityMin=0,
capacityMax=400,
opexPerOperation=1,
)
)
# 7.) Adding Storage to esM representing batteries
uid = nts.Uid(
name='Batteries', latitude=53, longitude=10,
region='Germany', sector='Power', carrier='Electricity',
component='Storage', node_type='AC-AC-Storage')
uids.update({str(uid): uid})
esM.add(
fn.Storage(
# Required Parameters
esM=esM,
name=str(uid),
commodity=uid.carrier,
opexPerDischargeOperation=0.000002,
)
)
# 8.) Adding global constraint for CO2, when a yearly limit is set
if yearlyLimit > 0:
esM.add(
fn.Sink(
esM=esM,
name='CO2',
commodity='CO2',
hasCapacityVariable=False,
commodityLimitID='CO2',
yearlyLimit=yearlyLimit
)
)
# 9.) Optimizing the esM with the cbc solver (default:gurobi) and hide output
# possible with or without time series aggregation
with write_tools.HideStdoutPrinting():
if tsa is True:
esM.cluster()
esM.optimize(timeSeriesAggregation=True, solver='cbc')
else:
esM.optimize(solver='cbc')
# 10 a.) Store results pumped energy system:
if save is True:
# Set default filename if necessary
if not filename:
if tsa is True:
f = "tsa_one_year_example_FINE"
else:
f = "one_year_example_FINE"
else:
f = filename
# Set default directory name of necessary
if not directory:
if tsa is True:
d = os.path.join(write_dir, 'fine', 'tsa_one_year_example')
else:
d = os.path.join(write_dir, 'fine', 'one_year_example')
else:
d = directory
# See if the targeted directory exists- if not: produce it
pathlib.Path(d).mkdir(parents=True, exist_ok=True)
# 10 b.) Use fine to save the data into an excel spreadsheet
fn.writeOptimizationOutputToExcel(
esM=esM, outputFileName=f, optSumOutputLevel=0)
# 10 c.) Moving the file to the correct destination in the tessif write dir
src = os.getcwd() # source folder
f = f + ".xlsx" # exact file name with ending
shutil.move(os.path.join(src, f), os.path.join(d, f))
# 11.a) Setting uids as additional attribute to esM to later use it
setattr(esM, 'uid_dict', uids)
setattr(esM, 'timesteps', timesteps)
# 11.b) Return the energy system
return esM