Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ Here is a template for new release sections
### Added
-
### Changed
-
-
### Removed
-
```
## [Unreleased]

### Added
- oemof workshop by @smartie2076 (from https://github.com/smartie2076/oemof_workshop) to rli oemof workshop repro into new folder 3-day-workshop
- csv file with overview over workshops in oemof folder

### Changed

Expand Down Expand Up @@ -50,4 +52,4 @@ Here is a template for new release sections
- CHANGELOG.md
- requirements.txt
### Changed
- README.md
- README.md
772 changes: 772 additions & 0 deletions oemof/3_day_workshop/Day_1_Oemof_Basics/1a_tutorial_dispatch.ipynb

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions oemof/3_day_workshop/Day_1_Oemof_Basics/1b_task_dispatch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python

"""
Edited based on https://github.com/rl-institut/workshop

This script includes the basic sections necessary for optimizing the operation of an energy system in oemof. Tasks:

1) Load input data with pandas from input_data.csv
2) To complete the model,
a) create all necessary components of the energy system (compare file energysystem.png)
b) parameterize the components
c) add the components to the energy system
"""


import pandas as pd
import matplotlib.pyplot as plt

from oemof.solph import Sink, Source, Transformer, Bus, Flow, EnergySystem, Model
from oemof.solph.components import GenericStorage
import oemof.outputlib as outputlib

# ## Specify solver
solver = 'cbc'

# ## Create an energy system and load data
datetimeindex = pd.date_range('1/1/2016', periods=24*365, freq='H')
energysystem = EnergySystem(timeindex=datetimeindex)

filename = ''
data = pd.read_csv(filename, sep=",")
# ## Create Buses


# ## Create components


# ## Add all to the energysystem
energysystem.add()


# ## Create an Optimization Model and solve it
# create optimization model based on energy_system
optimization_model = Model(energysystem=energysystem)

# solve problem
optimization_model.solve(solver=solver)

# ## Get results
results_main = outputlib.processing.results(optimization_model)
results_meta = outputlib.processing.meta_results(optimization_model)
params = outputlib.processing.parameter_as_dict(energysystem)

# ## Pass results to energysystem.results object before saving
energysystem.results['main'] = results_main
energysystem.results['meta'] = results_meta
energysystem.params = params

# ## Save results - Dump the energysystem (to ~/home/user/.oemof by default)
# Specify path and filename if you do not want to overwrite
energysystem.dump(dpath=None, filename=None)

print(results_meta)

sequences_el = outputlib.views.node(results_main, 'electricity')['sequences']
print(sequences_el.head())
105 changes: 105 additions & 0 deletions oemof/3_day_workshop/Day_1_Oemof_Basics/1c_task_dispatch_solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/env python

import pandas as pd
import matplotlib.pyplot as plt

from oemof.solph import Sink, Source, Transformer, Bus, Flow, EnergySystem, Model, Investment
from oemof.solph.components import GenericStorage
import oemof.outputlib as outputlib

# ## Specify solver
solver = 'cbc'


# ## Create an energy system and load data
datetimeindex = pd.date_range('1/1/2016', periods=24*365, freq='H')
energysystem = EnergySystem(timeindex=datetimeindex)

filename = 'input_data.csv'
data = pd.read_csv(filename, sep=",")
data = data.dropna(axis=1)
print(data.head())

# ## Create Buses

# resource buses
bus_gas = Bus(label='gas')
bus_coal = Bus(label='coal')

# electricity and heat buses
bus_el = Bus(label='electricity')
bus_th = Bus(label='heat')

# ## Create components
source_gas = Source(label='source_gas', outputs={bus_gas: Flow(variable_costs=30)})
source_coal = Source(label='source_coal', outputs={bus_coal: Flow(variable_costs=30)})

# Renewable feedin
wind = Source(label='wind', outputs={bus_el: Flow(
actual_value=data['wind'], nominal_value=66.3, fixed=True)})

pv = Source(label='pv', outputs={bus_el: Flow(
actual_value=data['pv'], nominal_value=65.3, fixed=True)})

# Electricity demand
demand_el = Sink(label='demand_el', inputs={bus_el: Flow(
nominal_value=85, actual_value=data['demand_el'], fixed=True)})


# power plants
pp_coal = Transformer(label='pp_coal',
inputs={bus_coal: Flow()},
outputs={bus_el: Flow(nominal_value=40,
emission_factor=0.335)},
conversion_factors={bus_el: 0.39})

storage_el = GenericStorage(label='storage_el',
invest=Investment(ep_cost=412),
inputs={bus_el: Flow(nominal_value=200)},
outputs={bus_el: Flow(nominal_value=200)},
loss_rate=0.01,
initial_storage_level=0,
max_storage_level=0.9,
inflow_conversion_factor=0.9,
outflow_conversion_factor=0.9)

# an excess and a shortage variable can help to avoid infeasible problems
excess_el = Sink(label='excess_el', inputs={bus_el: Flow()})

shortage_el = Source(label='shortage_el',
outputs={bus_el: Flow(variable_costs=100000)})


# ## Add all to the energysystem
energysystem.add(bus_coal, bus_gas, bus_el,
source_gas, source_coal,
wind, pv, demand_el,
pp_coal, storage_el,
excess_el, shortage_el)


# ## Create an Optimization Model and solve it
# create optimization model based on energy_system
optimization_model = Model(energysystem=energysystem)

# solve problem
optimization_model.solve(solver=solver)

# ## Get results
results_main = outputlib.processing.results(optimization_model)
results_meta = outputlib.processing.meta_results(optimization_model)
params = outputlib.processing.parameter_as_dict(energysystem)

# ## Pass results to energysystem.results object before saving
energysystem.results['main'] = results_main
energysystem.results['meta'] = results_meta
energysystem.params = params

# ## Save results - Dump the energysystem (to ~/home/user/.oemof by default)
# Specify path and filename if you do not want to overwrite
energysystem.dump(dpath=None, filename=None)

print(results_meta)

sequences_el = outputlib.views.node(results_main, 'electricity')['sequences']
print(sequences_el.head())

Large diffs are not rendered by default.

113 changes: 113 additions & 0 deletions oemof/3_day_workshop/Day_1_Oemof_Basics/2b_task_investment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env python

"""
Edited based on https://github.com/rl-institut/workshop

This script provides the basic structure for perfoming an investment optimization with oemof. Tasks

1) Read input data with pandas
2) Complete the model by
a) Modifying installed capacities manually while avoiding shortage
b) Inluding an invest-object to each fossil fuelled power plant to optimize their capacity

"""

import pandas as pd
import matplotlib.pyplot as plt

from oemof.solph import (Sink, Source, Transformer, Bus, Flow, Model,
EnergySystem, Investment, NonConvex)
import oemof.outputlib as outputlib
from oemof.tools import economics

solver = 'cbc'

# initialize energysytem
datetimeindex = pd.date_range('1/1/2016', periods=24*365, freq='H')
energysystem = EnergySystem(timeindex=datetimeindex)

# load data
filename = ''
data = pd.read_csv()
print(data.head())

# create buses
bus_coal = Bus(label='coal', balanced=False)
bus_gas = Bus(label='gas', balanced=False)
bus_el = Bus(label='electricity')

# create sources
wind = Source(label='wind',
outputs={bus_el: Flow(actual_value=data['wind'],
nominal_value=1,
fixed=True)})

pv = Source(label='pv',
outputs={bus_el: Flow(actual_value=data['pv'],
nominal_value=1,
fixed=True)})

# create excess and shortage to avoid infeasibilies
excess = Sink(label='excess_el',
inputs={bus_el: Flow()})

shortage = Source(label='shortage_el',
outputs={bus_el: Flow(variable_costs=1e12)})

# create demand
demand_el = Sink(label='demand_el',
inputs={bus_el: Flow(nominal_value=1,
actual_value=data['demand_el'],
fixed=True)})

epc_coal = economics.annuity(capex=1500000, n=50, wacc=0.05)
epc_gas = economics.annuity(capex=900000, n=20, wacc=0.05)

# create power plants
pp_coal = Transformer(label='pp_coal',
inputs={bus_coal: Flow()},
outputs={bus_el: Flow(nominal_value=5000,
variable_costs=25)},
conversion_factors={bus_el: 0.39})

pp_gas = Transformer(label='pp_gas',
inputs={bus_gas: Flow()},
outputs={bus_el: Flow(nominal_value=2000,
variable_costs=40)},
conversion_factors={bus_el: 0.50})

# add all components to energysystem
energysystem.add(bus_coal, bus_gas, bus_el,
wind, pv, excess, shortage, demand_el,
pp_coal, pp_gas)


# create optimization model based on energy_system
optimization_model = Model(energysystem=energysystem)

# solve problem
optimization_model.solve(solver=solver,
solve_kwargs={'tee': False, 'keepfiles': False})


# postprocessing
results = outputlib.processing.results(optimization_model)
string_results = outputlib.processing.convert_keys_to_strings(results)

results_investment = pd.DataFrame({key: value['scalars'] for key, value in string_results.items() if hasattr(value['scalars'], 'invest')})
print(results_investment)

el_sequences = outputlib.views.node(results, 'electricity')['sequences']

sorted_sequences = pd.DataFrame()
for column in el_sequences.columns:
sorted_sequences[column]=sorted(el_sequences[column], reverse=True)

fig, ax = plt.subplots(figsize=(8,3))
sorted_sequences.plot(ax=ax, linewidth=3)
ax.set_ylabel('Power in kW')
ax.set_xlabel('Sorted hours')
ax.set_title('Electricity: Annual load duration curve')
legend = plt.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)) # place legend outside of plot
plt.tight_layout()
plt.show()
Loading