Skip to content

Instantly share code, notes, and snippets.

@henhuy
Created September 20, 2023 07:41
Show Gist options
  • Save henhuy/24fe9cd10880aa5af5a75adf9f4f8ab9 to your computer and use it in GitHub Desktop.
Save henhuy/24fe9cd10880aa5af5a75adf9f4f8ab9 to your computer and use it in GitHub Desktop.
Oemof.solph storage investment v1 as multi-period
# -*- coding: utf-8 -*-
"""
General description
-------------------
This example shows how to perform a capacity optimization for
an energy system with storage. The following energy system is modeled:
.. code-block:: text
input/output bgas bel
| | |
| | |
wind(FixedSource) |------------------>|
| | |
pv(FixedSource) |------------------>|
| | |
gas_resource |--------->| |
(Commodity) | | |
| | |
demand(Sink) |<------------------|
| | |
| | |
pp_gas(Converter) |<---------| |
|------------------>|
| | |
storage(Storage) |<------------------|
|------------------>|
The example exists in four variations. The following parameters describe
the main setting for the optimization variation 1:
- optimize wind, pv, gas_resource and storage
- set investment cost for wind, pv and storage
- set gas price for kWh
Results show an installation of wind and the use of the gas resource.
A renewable energy share of 51% is achieved.
.. tip::
Have a look at different parameter settings. There are four variations
of this example in the same folder.
Code
----
Download source code: :download:`v1_invest_optimize_all_technologies.py </../examples/storage_investment/v1_invest_optimize_all_technologies.py>`
.. dropdown:: Click to display code
.. literalinclude:: /../examples/storage_investment/v1_invest_optimize_all_technologies.py
:language: python
:lines: 80-
Data
----
Download data: :download:`storage_investment.csv </../examples/storage_investment/storage_investment.csv>`
Installation requirements
-------------------------
This example requires oemof.solph (v0.5.x), install by:
.. code:: bash
pip install oemof.solph[examples]
License
-------
`MIT license <https://github.com/oemof/oemof-solph/blob/dev/LICENSE>`_
"""
###############################################################################
# Imports
###############################################################################
import logging
import os
import pprint as pp
import warnings
import pandas as pd
from oemof.tools import economics
from oemof.tools import logger
from oemof import solph
def main():
# Read data file
filename = "/home/hendrik/RLI/oemof-solph/examples/storage_investment/storage_investment.csv"
try:
data = pd.read_csv(filename)
except FileNotFoundError:
msg = "Data file not found: {0}. Only one value used!"
warnings.warn(msg.format(filename), UserWarning)
data = pd.DataFrame(
{"pv": [0.3, 0.5], "wind": [0.6, 0.8], "demand_el": [500, 600]}
)
data = pd.concat([data, data], ignore_index=True)
##########################################################################
# Initialize the energy system and read/calculate necessary parameters
##########################################################################
logger.define_logging()
logging.info("Initialize the energy system")
t1 = pd.date_range("2022-01-01", periods=8760, freq="H")
t2 = pd.date_range("2023-01-01", periods=8760, freq="H")
tindex = t1.append(t2)
energysystem = solph.EnergySystem(
timeindex=tindex,
# timeincrement=[1] * len(tindex),
periods=[t1, t2],
infer_last_interval=False,
)
price_gas = 0.4
# If the period is one year the equivalent periodical costs (epc) of an
# investment are equal to the annuity. Use oemof's economic tools.
epc_wind = economics.annuity(capex=1000, n=20, wacc=0.05)
epc_pv = economics.annuity(capex=1000, n=20, wacc=0.05)
epc_storage = economics.annuity(capex=1000, n=20, wacc=0.05)
##########################################################################
# Create oemof objects
##########################################################################
logging.info("Create oemof objects")
# create natural gas bus
bgas = solph.Bus(label="natural_gas")
# create electricity bus
bel = solph.Bus(label="electricity")
energysystem.add(bgas, bel)
# create excess component for the electricity bus to allow overproduction
excess = solph.components.Sink(label="excess_bel", inputs={bel: solph.Flow()})
# create source object representing the gas commodity (annual limit)
gas_resource = solph.components.Source(
label="rgas", outputs={bgas: solph.Flow(variable_costs=price_gas)}
)
# create fixed source object representing wind power plants
wind = solph.components.Source(
label="wind",
outputs={
bel: solph.Flow(
fix=data["wind"],
investment=solph.Investment(ep_costs=epc_wind, lifetime=10),
)
},
)
# create fixed source object representing pv power plants
pv = solph.components.Source(
label="pv",
outputs={
bel: solph.Flow(
fix=data["pv"],
investment=solph.Investment(ep_costs=epc_pv, lifetime=10),
)
},
)
# create simple sink object representing the electrical demand
demand = solph.components.Sink(
label="demand",
inputs={bel: solph.Flow(fix=data["demand_el"], nominal_value=1)},
)
# create simple Converter object representing a gas power plant
pp_gas = solph.components.Converter(
label="pp_gas",
inputs={bgas: solph.Flow()},
outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=0)},
conversion_factors={bel: 0.58},
)
# create storage object representing a battery
storage = solph.components.GenericStorage(
label="storage",
inputs={bel: solph.Flow(variable_costs=0.0001)},
outputs={bel: solph.Flow()},
loss_rate=0.00,
lifetime_inflow=10,
lifetime_outflow=10,
invest_relation_input_capacity=1 / 6,
invest_relation_output_capacity=1 / 6,
inflow_conversion_factor=1,
outflow_conversion_factor=0.8,
investment=solph.Investment(ep_costs=epc_storage, lifetime=10),
)
energysystem.add(excess, gas_resource, wind, pv, demand, pp_gas, storage)
##########################################################################
# Optimise the energy system
##########################################################################
logging.info("Optimise the energy system")
# initialise the operational model
om = solph.Model(energysystem)
# if tee_switch is true solver messages will be displayed
logging.info("Solve the optimization problem")
om.solve(solver="cbc", solve_kwargs={"tee": True})
##########################################################################
# Check and plot the results
##########################################################################
# check if the new result object is working for custom components
results = solph.processing.results(om)
electricity_bus = solph.views.node(results, "electricity")
meta_results = solph.processing.meta_results(om)
pp.pprint(meta_results)
my_results = electricity_bus["scalars"]
# installed capacity of storage in GWh
my_results["storage_invest_GWh"] = (
results[(storage, None)]["scalars"]["invest"] / 1e6
)
# installed capacity of wind power plant in MW
my_results["wind_invest_MW"] = results[(wind, bel)]["scalars"]["invest"] / 1e3
# resulting renewable energy share
my_results["res_share"] = (
1
- results[(pp_gas, bel)]["sequences"].sum()
/ results[(bel, demand)]["sequences"].sum()
)
pp.pprint(my_results)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment