### Full Example Setup Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/nametuple.md Imports necessary libraries and defines the oemof.solph environment for running energy system models, including components and data handling. ```python import logging import os import warnings from collections import namedtuple import pandas as pd from oemof.tools import logger from oemof.solph import EnergySystem from oemof.solph import Model from oemof.solph import buses from oemof.solph import components as comp from oemof.solph import create_time_index from oemof.solph import flows from oemof.solph import helpers from oemof.solph import processing # Subclass of the named tuple with its own __str__ method. # You can add as many tags as you like ``` -------------------------------- ### Install Optional Visualization Tools Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/variable_chp.md Install the oemof_visio package from its GitHub repository. This is optional and required only if you want to view the input/output balance plot for the example. ```bash pip install git+https://github.com/oemof/oemof_visio.git ``` -------------------------------- ### Successful Installation Test Output Source: https://github.com/oemof/oemof-solph/blob/dev/README.rst Example output indicating a successful installation of oemof.solph and its solvers. ```console ********* Solver installed with oemof: glpk: working cplex: not working cbc: working gurobi: not working ********* oemof.solph successfully installed. ``` -------------------------------- ### Install oemof.solph Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/time_index.md Install the oemof.solph library, version 0.5 or higher, using pip. This is a prerequisite for running the energy system modeling examples. ```bash pip install oemof.solph>=0.5 ``` -------------------------------- ### Install oemof.solph Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/flow_gradient.md This command installs the oemof.solph library, which is required to run the flow gradient example. Ensure you have version 0.6.4 or higher. ```bash pip install oemof.solph>=0.6.4 ``` -------------------------------- ### Basic Equidistant Time Index Example Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/time_index.md This snippet demonstrates the creation of a basic energy system with equidistant time steps. It sets up a source, a sink, and a generic storage, then optimizes the system and visualizes the results. Ensure oemof.solph is installed with 'pip install oemof.solph>=0.5'. ```python import matplotlib.pyplot as plt from oemof import solph def main(optimize=True): solver = "cbc" # 'glpk', 'gurobi',... solver_verbose = False # show/hide solver output date_time_index = solph.create_time_index(2000, interval=0.25, number=8) energy_system = solph.EnergySystem( timeindex=date_time_index, infer_last_interval=False ) bus = solph.buses.Bus(label="bus") source = solph.components.Source( label="source", outputs={ bus: solph.flows.Flow( nominal_capacity=2, variable_costs=0.2, maximum=[0, 0, 0, 0, 1, 0.25, 0.75, 1], ) }, ) storage = solph.components.GenericStorage( label="storage", inputs={bus: solph.flows.Flow()}, outputs={bus: solph.flows.Flow()}, nominal_capacity=4, initial_storage_level=0.5, ) sink = solph.components.Sink( label="sink", inputs={ bus: solph.flows.Flow( nominal_capacity=2, variable_costs=0.1, fix=[1, 1, 0.5, 0.5, 0, 0, 0, 0], ) }, ) energy_system.add(bus, source, sink, storage) ########################################################################## # Optimise the energy system ########################################################################## if optimize is False: return energy_system model = solph.Model(energy_system) model.solve(solver=solver, solve_kwargs={"tee": solver_verbose}) results = solph.processing.results(model) results_df = results[(storage, None)]["sequences"].copy() results_df["storage_inflow"] = results[(bus, storage)]["sequences"]["flow"] results_df["storage_outflow"] = results[(storage, bus)]["sequences"][ "flow" ] print(results_df) if plt is not None: plt.plot( results[(bus, storage)]["sequences"], drawstyle="steps-post", label="Storage inflow", ) plt.plot( results[(storage, None)]["sequences"], label="Storage content" ) plt.plot( results[(storage, bus)]["sequences"], drawstyle="steps-post", label="Storage outflow", ) plt.legend(loc="lower left") plt.show() if __name__ == "__main__": main() ``` -------------------------------- ### Complete Home PV and Battery System Setup Source: https://github.com/oemof/oemof-solph/blob/dev/docs/introductory_tutorials/home_pv_battery_system.md This comprehensive Python script sets up an energy system with PV, a grid connection, and a battery storage. It includes data loading, component definition, model creation, and solving the optimization problem. Use this as a complete example for a home energy system simulation. ```python # -*- coding: utf-8 -*- """ SPDX-FileCopyrightText: Patrik Schönfeldt SPDX-FileCopyrightText: Daniel Niederhöfer SPDX-FileCopyrightText: DLR e.V. SPDX-License-Identifier: MIT """ # %%[imports] import os import matplotlib.pyplot as plt import networkx as nx import numpy as np import pandas as pd from oemof import solph # %%[input_data] file_path = os.path.dirname(__file__) filename = os.path.join(file_path, "pv_example_data.csv") input_data = pd.read_csv( filename, index_col="timestep", parse_dates=["timestep"] ) # %%[energy_system] energy_system = solph.EnergySystem( timeindex=input_data.index, infer_last_interval=True, ) # %%[dispatch_model] el_bus = solph.Bus(label="electricity") demand = solph.components.Sink( label="demand", inputs={ el_bus: solph.Flow( nominal_capacity=1, fix=input_data["electricity demand (kW)"], ) }, ) energy_system.add(el_bus, demand) grid = solph.Bus( label="grid", inputs={el_bus: solph.Flow(variable_costs=-0.06)}, outputs={el_bus: solph.Flow(variable_costs=0.3)}, balanced=False, ) energy_system.add(grid) pv_specific_costs = 1500 # €/kW pv_lifetime = 20 # years pv_epc = pv_specific_costs / pv_lifetime pv_system = solph.components.Source( label="PV", outputs={ el_bus: solph.Flow( nominal_capacity=solph.Investment(ep_costs=pv_epc, maximum=10), maximum=input_data["pv yield (kW/kW)"], ) }, ) energy_system.add(pv_system) # %%[battery] battery_specific_costs = 1000 # €/kW battery_lifetime = 10 # years battery_epc = battery_specific_costs / battery_lifetime battery_size = 10 # kWh battery = solph.components.GenericStorage( label="Battery", nominal_capacity=battery_size, inputs={el_bus: solph.Flow()}, outputs={el_bus: solph.Flow()}, inflow_conversion_factor=0.9, loss_rate=0.01, ) energy_system.add(battery) # %%[graph_plotting] plt.figure() graph = energy_system.to_networkx() nx.draw(graph, with_labels=True, font_size=8) # %%[model_optimisation] model = solph.Model(energy_system) results = model.solve(solver="cbc", solve_kwargs={"tee": True}) # %%[results] # Potentially, there are more points in time to invest. ``` -------------------------------- ### Install oemof.solph and Matplotlib Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/storage_level_constraint.md Install the necessary libraries for running the oemof.solph storage level constraint example. This includes oemof.solph version 0.5.0 or higher and matplotlib for plotting. ```bash pip install oemof.solph>=0.5 matplotlib ``` -------------------------------- ### Full Code Example for Step 2 Source: https://github.com/oemof/oemof-solph/blob/dev/docs/introductory_tutorials/home_pv_battery_system.md This is the complete, uncommented Python code for the second step of the tutorial, which includes adding a fixed-size PV system and analyzing the results. ```python # -*- coding: utf-8 -*- """ SPDX-FileCopyrightText: Patrik Schönfeldt SPDX-FileCopyrightText: Daniel Niederhöfer SPDX-FileCopyrightText: DLR e.V. SPDX-License-Identifier: MIT """ ``` -------------------------------- ### Run Installation Test Source: https://github.com/oemof/oemof-solph/blob/dev/docs/installation.md Execute the installation test command to verify that oemof.solph and its solvers are correctly installed. ```console oemof_installation_test ``` -------------------------------- ### Install oemof.solph Source: https://github.com/oemof/oemof-solph/blob/dev/README.rst Install the oemof.solph package using pip within a virtual environment. ```console (venv) pip install oemof.solph ``` -------------------------------- ### Run oemof.solph Installation Test Source: https://github.com/oemof/oemof-solph/blob/dev/README.rst Execute the oemof_installation_test command to verify the installation of oemof.solph and its compatible solvers. ```console (venv) oemof_installation_test ``` -------------------------------- ### Initialize and Solve Energy System Model Source: https://github.com/oemof/oemof-solph/blob/dev/docs/reference/oemof.solph.results.md This snippet demonstrates the basic setup for an oemof.solph energy system, including model creation, solving, and initializing the Results object. ```python from oemof import solph energysystem = solph.EnergySystem(timeindex=[1,2,3]) energysystem_model = solph.Model(energysystem) _ = energysystem_model.solve() results = solph.Results(energysystem_model) ``` -------------------------------- ### Import Libraries for CHP Example Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/variable_chp.md Imports necessary libraries for the CHP example, including logging, os, warnings, matplotlib, pandas, and oemof.solph. ```python import logging import os import warnings import matplotlib.pyplot as plt import pandas as pd from oemof.tools import logger from oemof import solph ``` -------------------------------- ### Instantiate GenericCAES Component Source: https://github.com/oemof/oemof-solph/blob/dev/docs/reference/oemof.solph.components.md Example of how to instantiate the GenericCAES component with specific parameters for a compressed air energy storage plant. Requires defining input and output buses. ```python from oemof import solph bel = solph.buses.Bus(label='bel') bth = solph.buses.Bus(label='bth') bgas = solph.buses.Bus(label='bgas') # dictionary with parameters for a specific CAES plant concept = { 'cav_e_in_b': 0, 'cav_e_in_m': 0.6457267578, 'cav_e_out_b': 0, 'cav_e_out_m': 0.3739636077, 'cav_eta_temp': 1.0, 'cav_level_max': 211.11, 'cmp_p_max_b': 86.0918959849, 'cmp_p_max_m': 0.0679999932, 'cmp_p_min': 1, 'cmp_q_out_b': -19.3996965679, 'cmp_q_out_m': 1.1066036114, 'cmp_q_tes_share': 0, 'exp_p_max_b': 46.1294016678, 'exp_p_max_m': 0.2528340303, 'exp_p_min': 1, 'exp_q_in_b': -2.2073411014, 'exp_q_in_m': 1.129249765, 'exp_q_tes_share': 0, 'tes_eta_temp': 1.0, 'tes_level_max': 0.0} # generic compressed air energy storage (caes) plant caes = solph.components.experimental.GenericCAES( label='caes', electrical_input={bel: solph.flows.Flow()}, fuel_input={bgas: solph.flows.Flow()}, electrical_output={bel: solph.flows.Flow()}, params=concept) type(caes) ``` -------------------------------- ### Import Libraries and Setup Energy System Source: https://github.com/oemof/oemof-solph/blob/dev/docs/introductory_tutorials/ev_charging.md Imports necessary libraries including matplotlib, networkx, numpy, pandas, and oemof.solph. It also sets up the time index and the energy system for the simulation. ```python # %%[imports_start] import matplotlib.pyplot as plt import networkx as nx import numpy as np import pandas as pd from helpers import plot_results from oemof.network.graph import create_nx_graph # %%[imports_end] # %%[create_time_index_set_up_energysystem_start] import oemof.solph as solph time_index = pd.date_range( start="2025-01-01", end="2025-01-02", freq="5min", inclusive="both", ) ev_energy_system = solph.EnergySystem( timeindex=time_index, infer_last_interval=False, ) # %%[create_time_index_set_up_energysystem_end] ``` -------------------------------- ### Instantiating OffsetConverter Source: https://github.com/oemof/oemof-solph/blob/dev/docs/reference/oemof.solph.components.md Example of creating an OffsetConverter instance with specified inputs, outputs, conversion factors, and normed offsets. ```python >>> ostf = solph.components.OffsetConverter( ... label='ostf', ... inputs={bel: solph.flows.Flow()}, ... outputs={bth: solph.flows.Flow( ... nominal_capacity=l_nominal, minimum=l_min, maximum=l_max, ... nonconvex=solph.NonConvex())}, ... conversion_factors={bel: slope}, ... normed_offsets={bel: offset}, ... ) >>> type(ostf) ``` -------------------------------- ### Initialize ExtractionTurbineCHP Component Source: https://github.com/oemof/oemof-solph/blob/dev/docs/reference/oemof.solph.components.md Example of initializing an ExtractionTurbineCHP component with input and output buses, and defining conversion factors for electricity and heat. ```python from oemof import solph bel = solph.buses.Bus(label='electricityBus') bth = solph.buses.Bus(label='heatBus') bgas = solph.buses.Bus(label='commodityBus') et_chp = solph.components.ExtractionTurbineCHP( label='variable_chp_gas', inputs={bgas: solph.flows.Flow(nominal_capacity=10e10)}, outputs={bel: solph.flows.Flow(), bth: solph.flows.Flow()}, conversion_factors={bel: 0.3, bth: 0.5}, conversion_factor_full_condensation={bel: 0.5}) ``` -------------------------------- ### Initialize Energy System and Parameters Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/storage_investment.md Sets up the energy system, creates a time index, and calculates economic parameters like equivalent periodical costs for investments. ```python 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(optimize=True): # Read data file filename = os.path.join( os.path.dirname(__file__), "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]} ) number_timesteps = len(data) ########################################################################## # Initialize the energy system and read/calculate necessary parameters ########################################################################## logger.define_logging() logging.info("Initialize the energy system") date_time_index = solph.create_time_index(2012, number=number_timesteps) energysystem = solph.EnergySystem( timeindex=date_time_index, infer_last_interval=False ) price_gas = 0.04 # If the period is one year the equivalent periodical costs (epc) of an # investment are equal to the annuity. Use oemof's economic tools. # It is assumed that the investment object in storage capacity entails the # costs for investment into both input and output capacity 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 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"], nominal_capacity=1000000)}, ) # create fixed source object representing pv power plants pv = solph.components.Source( label="pv", outputs={bel: solph.Flow(fix=data["pv"], nominal_capacity=600000)}, ) # create simple sink object representing the electrical demand demand = solph.components.Sink( label="demand", inputs={bel: solph.Flow(fix=data["demand_el"], nominal_capacity=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_capacity=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, nominal_capacity=solph.Investment() ) }, outputs={bel: solph.Flow(nominal_capacity=solph.Investment())}, loss_rate=0.00, initial_storage_level=0, invest_relation_input_capacity=1 / 6, # c-rate of 1/6 invest_relation_output_capacity=1 / 6, inflow_conversion_factor=1, outflow_conversion_factor=0.8, nominal_capacity=solph.Investment(ep_costs=epc_storage), ) energysystem.add(excess, gas_resource, wind, pv, demand, pp_gas, storage) ########################################################################## # Optimise the energy system ########################################################################## if optimize is False: return energysystem 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) ``` -------------------------------- ### Home PV System Setup and Optimization Source: https://github.com/oemof/oemof-solph/blob/dev/docs/introductory_tutorials/home_pv_battery_system.md This script sets up an energy system with a PV source, electricity demand, and grid connection. It then optimizes the system to determine the optimal PV size and calculates associated costs and revenues. Finally, it visualizes the energy flows. ```python # -*- coding: utf-8 -*- """ SPDX-FileCopyrightText: Patrik Schönfeldt SPDX-FileCopyrightText: Daniel Niederhöfer SPDX-FileCopyrightText: DLR e.V. SPDX-License-Identifier: MIT """ # %%[imports] import os import matplotlib.pyplot as plt import networkx as nx import numpy as np import pandas as pd from oemof import solph # %%[input_data] file_path = os.path.dirname(__file__) filename = os.path.join(file_path, "pv_example_data.csv") input_data = pd.read_csv( filename, index_col="timestep", parse_dates=["timestep"] ) # %%[energy_system] energy_system = solph.EnergySystem( timeindex=input_data.index, infer_last_interval=True, ) # %%[dispatch_model] el_bus = solph.Bus(label="electricity") demand = solph.components.Sink( label="demand", inputs={ el_bus: solph.Flow( nominal_capacity=1, fix=input_data["electricity demand (kW)"], ) }, ) energy_system.add(el_bus, demand) # %%[grid_conection] grid = solph.Bus( label="grid", inputs={el_bus: solph.Flow(variable_costs=-0.06)}, outputs={el_bus: solph.Flow(variable_costs=0.3)}, balanced=False, ) # %%[add_grid] energy_system.add(grid) # %%[pv_system] pv_specific_costs = 1500 # €/kW pv_lifetime = 20 # years pv_epc = pv_specific_costs / pv_lifetime pv_system = solph.components.Source( label="PV", outputs={ el_bus: solph.Flow( nominal_capacity=solph.Investment(ep_costs=pv_epc, maximum=10), maximum=input_data["pv yield (kW/kW)"], ) }, ) energy_system.add(pv_system) # %%[graph_plotting] plt.figure() graph = energy_system.to_networkx() nx.draw(graph, with_labels=True, font_size=8) # %%[model_optimisation] model = solph.Model(energy_system) results = model.solve(solver="cbc", solve_kwargs={"tee": True}) # %%[result_pv] # Potentially, there are more points in time to invest. # For upfront invest, we need to select the initial. pv_size = results["invest"][(pv_system, el_bus)][0] # %%[results] pv_annuity = pv_epc * pv_size annual_grid_supply = results["flow"][(grid, el_bus)].sum() el_costs = 0.3 * annual_grid_supply el_revenue = 0.1 * results["flow"][(el_bus, grid)].sum() tce = results["objective"] # %%[result_plotting] print(f"The optimal PV size is {pv_size:.2f} kW.") print(f"The annual costs for grid electricity are {el_costs:.2f} €.") print(f"The annual revenue from feed-in is {el_revenue:.2f} €.") print(f"The annuity for the PV system is {pv_annuity:.2f} €.") print(f"The total annual costs are {tce:.2f} €.") annual_demand = input_data["electricity demand (kW)"].sum() print( f"Autarky is 1 - {annual_grid_supply:.2f} kWh / {annual_demand:.2f} kWh" + f" = {100 - 100 * annual_grid_supply / annual_demand:.2f} %." ) flows = results["flow"] baseline = np.zeros(len(flows)) plt.figure() mode = "light" # mode = "dark" if mode == "dark": plt.style.use("dark_background") plt.fill_between( flows.index, baseline, baseline + flows[("grid", "electricity")], step="pre", label="Grid supply", ) baseline += flows[("grid", "electricity")] plt.fill_between( flows.index, baseline, baseline + flows[("PV", "electricity")], step="pre", label="PV supply", ) plt.step( flows.index, flows[("electricity", "demand")], "-", color="darkgrey", label="Electricity demand", ) plt.step( flows.index, flows[("electricity", "demand")] + flows[("electricity", "grid")], ":", color="darkgrey", label="Feed-In", ) plt.legend() plt.ylabel("Power (kW)") plt.xlim(pd.Timestamp("2020-02-21 00:00"), pd.Timestamp("2020-02-28 00:00")) plt.gcf().autofmt_xdate() plt.savefig(f"home_pv_result-3_{{mode}}.svg") plt.show() ``` -------------------------------- ### Initialize Energy System and Parameters Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/invest_nonconvex.md Sets up the simulation time, date range, and imports necessary data for the energy system. This includes reading solar generation and demand data from a CSV file. ```python __copyright__ = "oemof developer group" __license__ = "MIT" import os import time import warnings from datetime import datetime from datetime import timedelta import numpy as np import pandas as pd from oemof import solph try: import matplotlib.pyplot as plt except ImportError: plt = None def main(optimize=True): ########################################################################## # Initialize the energy system and calculate necessary parameters ########################################################################## # Start time for calculating the total elapsed time. start_simulation_time = time.time() start = "2022-01-01" # The maximum number of days depends on the given *.csv file. n_days = 10 n_days_in_year = 365 # Create date and time objects. start_date_obj = datetime.strptime(start, "%Y-%m-%d") start_date = start_date_obj.date() start_datetime = datetime.combine( start_date_obj.date(), start_date_obj.time() ) end_datetime = start_datetime + timedelta(days=n_days) # Import data. filename = os.path.join(os.path.dirname(__file__), "solar_generation.csv") data = pd.read_csv(filename) # Change the index of data to be able to select data based on the time # range. data.index = pd.date_range(start="2022-01-01", periods=len(data), freq="h") # Choose the range of the solar potential and demand # based on the selected simulation period. solar_potential = data.SolarGen.loc[start_datetime:end_datetime] hourly_demand = data.Demand.loc[start_datetime:end_datetime] peak_solar_potential = solar_potential.max() peak_demand = hourly_demand.max() # Create the energy system. date_time_index = solph.create_time_index( number=n_days * 24, start=start_date ) energysystem = solph.EnergySystem( timeindex=date_time_index, infer_last_interval=False ) # -------------------- BUSES -------------------- # Create electricity and diesel buses. b_el_ac = solph.buses.Bus(label="electricity_ac") b_el_dc = solph.buses.Bus(label="electricity_dc") b_diesel = solph.buses.Bus(label="diesel") # -------------------- SOURCES -------------------- diesel_cost = 0.65 # currency/l diesel_density = 0.846 # kg/l diesel_lhv = 11.83 # kWh/kg diesel_source = solph.components.Source( label="diesel_source", outputs={ b_diesel: solph.flows.Flow( variable_costs=diesel_cost / diesel_density / diesel_lhv ) }, ) # EPC stands for the equivalent periodical costs. epc_pv = 152.62 # currency/kW/year pv = solph.components.Source( label="pv", outputs={ b_el_dc: solph.flows.Flow( fix=solar_potential / peak_solar_potential, nominal_capacity=solph.Investment( ep_costs=epc_pv * n_days / n_days_in_year ), variable_costs=0, ) }, ) # -------------------- CONVERTERS -------------------- # The diesel genset assumed to have a fixed efficiency of 33%. # The output power of the diesel genset can only vary between # the given minimum and maximum loads, which represent the fraction # of the optimal capacity obtained from the optimization. epc_diesel_genset = 84.80 # currency/kW/year variable_cost_diesel_genset = 0.045 # currency/kWh min_load = 0.2 max_load = 1.0 diesel_genset = solph.components.Converter( label="diesel_genset", inputs={b_diesel: solph.flows.Flow()}, outputs={ b_el_ac: solph.flows.Flow( variable_costs=variable_cost_diesel_genset, minimum=min_load, maximum=max_load, nominal_capacity=solph.Investment( ep_costs=epc_diesel_genset * n_days / n_days_in_year, maximum=2 * peak_demand, ), nonconvex=solph.NonConvex(), ) }, conversion_factors={b_el_ac: 0.33}, ) # The rectifier assumed to have a fixed efficiency of 98%. epc_rectifier = 62.35 # currency/kW/year rectifier = solph.components.Converter( label="rectifier", inputs={ b_el_ac: solph.flows.Flow( nominal_capacity=solph.Investment( ep_costs=epc_rectifier * n_days / n_days_in_year ), variable_costs=0, ) }, outputs={b_el_dc: solph.flows.Flow()}, conversion_factors={ b_el_dc: 0.98, }, ) # The inverter assumed to have a fixed efficiency of 98%. epc_inverter = 62.35 # currency/kW/year inverter = solph.components.Converter( label="inverter", inputs={ b_el_dc: solph.flows.Flow( ``` -------------------------------- ### Initialize Energy System and Parameters Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/storage_investment.md Sets up the energy system, creates a time index, and calculates economic parameters like equivalent periodical costs (epc) for investments. It handles data loading from a CSV file or uses default data if the file is not found. ```python 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(optimize=True): # Read data file filename = os.path.join( os.path.dirname(__file__), "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.5], "demand_el": [500, 400]} ) number_timesteps = len(data) ########################################################################## # Initialize the energy system and read/calculate necessary parameters ########################################################################## logger.define_logging() logging.info("Initialize the energy system") date_time_index = solph.create_time_index(2012, number=number_timesteps) energysystem = solph.EnergySystem( timeindex=date_time_index, infer_last_interval=False ) fossil_share = 0.2 consumption_total = data["demand_el"].sum() # 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) # It is assumed that the investment object in storage capacity entails the # costs for investment into both input and output capacity 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 representing the natural gas commodity (with annual limit) gas_resource = solph.components.Source( label="rgas", outputs={ bgas: solph.Flow( nominal_capacity=fossil_share * consumption_total / 0.58 * number_timesteps / 8760, full_load_time_max=1, ) }, ) # create fixed source object representing wind power plants wind = solph.components.Source( label="wind", outputs={ bel: solph.Flow( fix=data["wind"], nominal_capacity=solph.Investment(ep_costs=epc_wind), ) }, ) # create fixed source object representing pv power plants pv = solph.components.Source( label="pv", outputs={ bel: solph.Flow( fix=data["pv"], nominal_capacity=solph.Investment(ep_costs=epc_pv), ) }, ) # create simple sink object representing the electrical demand demand = solph.components.Sink( label="demand", inputs={bel: solph.Flow(fix=data["demand_el"], nominal_capacity=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_capacity=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, nominal_capacity=solph.Investment() ) }, outputs={bel: solph.Flow(nominal_capacity=solph.Investment())}, loss_rate=0.00, initial_storage_level=0, invest_relation_input_capacity=1 / 6, # c-rate of 1/6 invest_relation_output_capacity=1 / 6, inflow_conversion_factor=1, outflow_conversion_factor=0.8, nominal_capacity=solph.Investment(ep_costs=epc_storage), ) energysystem.add(excess, gas_resource, wind, pv, demand, pp_gas, storage) ########################################################################## # Optimise the energy system ########################################################################## if optimize is False: return energysystem logging.info("Optimise the energy system") # initialise the operational model om = solph.Model(energysystem) ``` -------------------------------- ### Initialize Energy System and Define Parameters Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/storage_investment.md Sets up the energy system, creates a time index, and calculates economic parameters like annuity for storage investment costs. It handles potential file not found errors for input data. ```python 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(optimize=True): # Read data file filename = os.path.join( os.path.dirname(__file__), "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.4], "wind": [0.6, 0.5], "demand_el": [500, 400]} ) number_timesteps = len(data) ########################################################################## # Initialize the energy system and read/calculate necessary parameters ########################################################################## logger.define_logging() logging.info("Initialize the energy system") date_time_index = solph.create_time_index(2012, number=number_timesteps) energysystem = solph.EnergySystem( timeindex=date_time_index, infer_last_interval=False ) fossil_share = 0.2 consumption_total = data["demand_el"].sum() # If the period is one year the equivalent periodical costs (epc) of an # investment are equal to the annuity. Use oemof's economic tools. # It is assumed that the investment object in storage capacity entails the # costs for investment into both input and output capacity 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 (with annual limit) gas_resource = solph.components.Source( label="rgas", outputs={ bgas: solph.Flow( nominal_capacity=fossil_share * consumption_total / 0.58 * number_timesteps / 8760, full_load_time_max=1, ) }, ) # create fixed source object representing wind power plants wind = solph.components.Source( label="wind", outputs={bel: solph.Flow(fix=data["wind"], nominal_capacity=1000000)}, ) # create fixed source object representing pv power plants pv = solph.components.Source( label="pv", outputs={bel: solph.Flow(fix=data["pv"], nominal_capacity=600000)}, ) # create simple sink object representing the electrical demand demand = solph.components.Sink( label="demand", inputs={bel: solph.Flow(fix=data["demand_el"], nominal_capacity=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_capacity=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, nominal_capacity=solph.Investment() ) }, outputs={bel: solph.Flow(nominal_capacity=solph.Investment())}, loss_rate=0.00, initial_storage_level=0, invest_relation_input_capacity=1 / 6, # c-rate of 1/6 invest_relation_output_capacity=1 / 6, inflow_conversion_factor=1, outflow_conversion_factor=0.8, nominal_capacity=solph.Investment(ep_costs=epc_storage), ) energysystem.add(excess, gas_resource, wind, pv, demand, pp_gas, storage) ########################################################################## # Optimise the energy system ########################################################################## if optimize is False: return energysystem 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 ``` -------------------------------- ### Define New Wind Power Plant with Existing Capacity Source: https://github.com/oemof/oemof-solph/blob/dev/docs/optimization/dispatch_vs_invest.md This example shows how to define a new wind power plant while accounting for existing capacity. The 'existing' parameter specifies the pre-installed capacity, and 'maximum' defines the limit for new installations. ```python solph.components.Source(label='new_wind_pp', outputs={electricity: solph.flows.Flow( fix=wind_power_time_series, nominal_capacity=solph.Investment(ep_costs=epc, maximum=30000, existing=20000))}) ``` -------------------------------- ### Initialize Energy System and Define Parameters Source: https://github.com/oemof/oemof-solph/blob/dev/docs/examples/storage_investment.md Sets up the energy system, creates a time index, and calculates economic parameters like equivalent periodical costs (epc) for investments using oemof's economic tools. ```python 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(optimize=True): # Read data file filename = os.path.join( os.path.dirname(__file__), "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]} ) number_timesteps = len(data) ########################################################################## # Initialize the energy system and read/calculate necessary parameters ########################################################################## logger.define_logging() logging.info("Initialize the energy system") date_time_index = solph.create_time_index(2012, number=number_timesteps) energysystem = solph.EnergySystem( timeindex=date_time_index, infer_last_interval=False ) price_gas = 0.04 # 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) # It is assumed that the investment object in storage capacity entails the # costs for investment into both input and output capacity 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 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"], nominal_capacity=solph.Investment(ep_costs=epc_wind), ) }, ) # create fixed source object representing pv power plants pv = solph.components.Source( label="pv", outputs={ bel: solph.Flow( fix=data["pv"], nominal_capacity=solph.Investment(ep_costs=epc_pv), ) }, ) # create simple sink object representing the electrical demand demand = solph.components.Sink( label="demand", inputs={bel: solph.Flow(fix=data["demand_el"], nominal_capacity=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_capacity=10e10, variable_costs=0)}, conversion_factors={bel: 0.58}, ) # create storage object representing a battery, allow for investment storage = solph.components.GenericStorage( label="storage", inputs={ bel: solph.Flow( variable_costs=0.0001, nominal_capacity=solph.Investment() ) }, outputs={bel: solph.Flow(nominal_capacity=solph.Investment())}, loss_rate=0.00, initial_storage_level=0, invest_relation_input_capacity=1 / 6, # c-rate of 1/6 invest_relation_output_capacity=1 / 6, inflow_conversion_factor=1, outflow_conversion_factor=0.8, nominal_capacity=solph.Investment(ep_costs=epc_storage), ) energysystem.add(excess, gas_resource, wind, pv, demand, pp_gas, storage) ########################################################################## # Optimise the energy system ########################################################################## if optimize is False: return energysystem 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 ```