FINE
Following sections give detailed instructions on how to create ready-to-use energy systems using FINE Energy System Model
Concept
FINE aims to be a free software toolbox simulating and optimizing energy supply systems with multiple regions, commodities and time steps. Using the time series aggregation module TSAM , the time series under investigation can be divided into periods to reduce the memory requirement and computation time. This is particularly useful for larger amounts of data under investigation.
It is developed by the Forschungszentrum Jülich with the Helmholtz Association as partner in the context of Energy System 2050 - Central platform of the Research Field Energy.
Purpose
Within the context of tessif, FINE serves another pyomo solver interface. The goal of optimization it’s is to minimize the costs incurred by the energy system. Thereby it is possible to formulate emission restrictions, that will be respected.
Using FINE through tessif is somewhat of a challenge The clear technical parameterization allows an efficient transformation of the energy system from Tessif to FINE. In addition, the components are designed in order to allow flexible use. This enables components to be implemented that are not actually part of the predefined FINE structure .
Examples
Minimum Working Example
Note
The exact same energy system can be accessed using
tessif.examples.data.fine.py_hard.create_mwe().
Import the needed packages:
# standard library import os import pathlib # third party import FINE as fn # local import tessif.frused.namedtuples as nts from tessif.frused.paths import write_dir import tessif.write.tools as write_tools
Create an energy system model instance
esM = fine.energySystemModel.EnergySystemModel( locations={"Germany"}, commodities={"Electricity", "gas"}, numberOfTimeSteps=2, commodityUnitsDict={"Electricity": "GW_el", "gas": "GW_CH4"}, hoursPerTimeStep=1, costUnit="€",)
Add an
Uidcontainer to the energy system model for utilizing Tessif’s Labeling Concept:setattr(esM, 'uid_dict', dict())
Do the modular arrangement of all components:
Add a
Transmissionas ideal power line with predefined UID:# create uid transmission_uid = nts.Uid( name='Power Line', latitude=53, longitude=10, region='Germany', sector='Power', carrier='Electricity', component='Bus', node_type='AC_Bus') # create component esM.add( fn.Transmission( esM=esM, hasCapacityVariable=True, name=str(transmission_uid), commodity=transmission_uid.carrier,) ) # add the UID to the container: esM.uid_dict.update({str(transmission_uid): transmission_uid})
Add a
Transmissionas ideal chemical bound energy transmission with predefined UID:# create uid gas_transmission_uid = nts.Uid( name='CBET', latitude=53, longitude=10, region='Germany', sector='Power', carrier='gas', component='Bus', node_type='gas-Bus') # create component esM.add( fn.Transmission( esM=esM, hasCapacityVariable=True, name=str(gas_transmission_uid), commodity=gas_transmission_uid.carrier,) ) # add the UID to the container: esM.uid_dict.update({str(gas_transmission_uid): gas_transmission_uid})
Add a
Demandas sink needing 10 energy units per timestep:# create uid demand_uid = nts.Uid( name='Demand', latitude=53, longitude=10, region='Germany', sector='Power', carrier='Electricity', component='Sink', node_type='Sink') # create component esM.add( fn.Sink( esM=esM, hasCapacityVariable=False, name=str(demand_uid), commodity=demand_uid.carrier, operationRateFix=pd.DataFrame({"Germany": [10, 10]}), ) ) # add the UID to the container: esM.uid_dict.update({str(demand_uid): demand_uid})
Add a renewable
Sourceproducing 8 and 2 energy units with a cost of 9:# create uid renewable_uid = nts.Uid( name='Renewable', latitude=53, longitude=10, region='Germany', sector='Power', carrier='Electricity', component='Source', node_type='AC-Source') # create component esM.add( fn.Source( esM=esM, name=str(renewable_uid), commodity=renewable_uid.carrier, hasCapacityVariable=True, operationRateMax=pd.DataFrame({'Germany': [0.8, 0.2]}), capacityMax=10, opexPerOperation=9, ) ) # add the UID to the container: esM.uid_dict.update({str(conversion_uid): conversion_uid})
Add a chemical bound energy source
Source:# create uid CBE_uid = nts.Uid( name='Gas Station', latitude=53, longitude=10, region='Germany', sector='Power', carrier='gas', component='Source', node_type='gas import') # create component esM.add( fn.Source( esM=esM, name=str(CBE_uid), commodity=CBE_uid.carrier, hasCapacityVariable=True, ) ) # add the UID to the container: esM.uid_dict.update({str(conversion_uid): conversion_uid})
Add a conventional engergy
Conversionproducing up to 10 energy units for a cost of 10:# create uid conversion_uid = nts.Uid( name='Transformer', latitude=53, longitude=10, region='Germany', sector='Power', carrier='gas', component='Transformer', node_type='gas-powerplant' ) # create component # Transformer parameters are related to inflow -> devide outflow related params with efficiency esM.add( fn.Conversion( esM=esM, name=str(conversion_uid), physicalUnit="GW_el", commodityConversionFactors={"gas": -1, "Electricity": 0.42}, opexPerOperation=10/0.42, ) ) # add the UID to the container: esM.uid_dict.update({str(conversion_uid): conversion_uid})
Optimize the energy system model instance:
esM.optimize()
Store the energy system into
tessif/src/tessf/write/fine/mwe:import os import pathlib from tessif.frused.paths import write_dir # Use fine to save the data into an excel spreadsheet fn.writeOptimizationOutputToExcel(esM=esM, outputFileName=f, optSumOutputLevel=0) # 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))
Using this newly generated energy system in a different python context by importing it:
Note
The code of steps 1 to 5 is wrapped in a
create_mwe() function for
convenience meaning it is copy pastable.
Import the wrapper functionality:
>>> from tessif.examples.data.fine.py_hard import create_mwe >>> esys = create_mwe()Confirm the expected output:
>>> for model in esys.componentModelingDict: ... for node in esys.componentModelingDict[model].componentsDict: ... print(node) PowerLine CBET Demand Renewable Gas Station Transformer
For examples on how to extract result information out ouf the optimized energy system using tessif, see
tessif.transform.es2mapping.fine