Spaces:
Runtime error
Runtime error
# %% | |
# -*- coding: utf-8 -*- | |
""" | |
Spyder Editor | |
This is a temporary script file. | |
""" | |
from numpy import arange | |
import xarray as xr | |
import highspy | |
import linopy | |
import openpyxl | |
from linopy import Model, EQUAL | |
import pandas as pd | |
import plotly.express as px | |
##import gurobipy | |
import streamlit as st | |
# %% | |
#url_excel = r'Input_Jahr_2021.xlsx' | |
url_excel = st.file_uploader(label = 'Excel Upload') | |
if url_excel == None: | |
url_excel = r'Input_Jahr_2021.xlsx' | |
# # %% | |
# # Slider for gas price [€/MWh_th] | |
price_gas = st.slider(value=10, min_value=0, max_value=400, label="Natural gas price [€/MWh]", step=10) | |
# Slider for CO2 price [€/t] | |
price_co2 = st.slider(value=80, min_value=0, max_value=400, label="CO2 price [€/t CO2eq]", step=10) | |
# Slider for CO2 limit [mio. t] | |
limit_co2 = st.slider(value=400, min_value=0, max_value=750, label="CO2 limit [mio. t]", step=50) | |
# Slider for H2 price / usevalue [€/MWH_th] | |
price_h2 = st.slider(value=100, min_value=0, max_value=300, label="Hydrogen price [€/MWh]", step=10) | |
# %% | |
# %% [markdown] | |
# Read Sets | |
# %% | |
## Define all sets for the model | |
# Timesteps | |
df_excel= pd.read_excel(url_excel, sheet_name = 'Timesteps_All', header=None) | |
t = pd.Index(df_excel.iloc[:,0], name = 't')[1:168] | |
#t = pd.Index(df_excel.iloc[:,0], name = 't') | |
# Technologies | |
df_excel = pd.read_excel(url_excel, sheet_name = 'Technologies') | |
i = pd.Index(df_excel.iloc[:,0], name = 'i') | |
i | |
df_excel = pd.read_excel(url_excel, sheet_name = 'Technologies') | |
iConv = pd.Index(df_excel.iloc[0:7,2], name = 'iConv') | |
df_excel = pd.read_excel(url_excel, sheet_name = 'Technologies') | |
iRes = pd.Index(df_excel.iloc[0:4,4], name = 'iRes') | |
df_excel = pd.read_excel(url_excel, sheet_name = 'Technologies') | |
iSto = pd.Index(df_excel.iloc[0:2,6], name = 'iSto') | |
df_excel = pd.read_excel(url_excel, sheet_name = 'Technologies') | |
iPtG = pd.Index(df_excel.iloc[0:1,8], name = 'iPtG') | |
df_excel = pd.read_excel(url_excel, sheet_name = 'Technologies') | |
iHyRes = pd.Index(df_excel.iloc[0:1,10], name = 'iHyRes') | |
# %% | |
### Parameters | |
# CO2 limit (from slider) | |
l_co2 = limit_co2 | |
p_co2 = price_co2 | |
# length of timesteps | |
dt = 1 | |
# Demand | |
df_excel= pd.read_excel(url_excel, sheet_name = 'Demand') | |
#df_melt = pd.melt(df_excel, id_vars='Zeit') | |
df_excel = df_excel.rename(columns = {'Timesteps':'t', 'Unnamed: 1':'Demand'}) | |
#df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('t') | |
D_t = df_excel.iloc[:,0].to_xarray() | |
## Efficiencies | |
df_excel = pd.read_excel(url_excel, sheet_name = 'Efficiency') | |
df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'Efficiency'}) | |
df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('i') | |
eff_i = df_excel.iloc[:,0].to_xarray() | |
## Variable costs | |
# Fuel costs | |
df_excel = pd.read_excel(url_excel, sheet_name = 'FuelCosts') | |
df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'FuelCosts'}) | |
df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('i') | |
c_fuel_i = df_excel.iloc[:,0].to_xarray() | |
# Apply slider value | |
c_fuel_i.loc[dict(i = 'Fossil Gas')] = price_gas | |
c_fuel_i.loc[dict(i = 'H2')] = price_h2 | |
# Other var. costs | |
df_excel = pd.read_excel(url_excel, sheet_name = 'OtherVarCosts') | |
df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'OtherVarCosts'}) | |
df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('i') | |
c_other_i = df_excel.iloc[:,0].to_xarray() | |
# Investment costs | |
df_excel = pd.read_excel(url_excel, sheet_name = 'InvCosts') | |
df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'InvCosts'}) | |
df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('i') | |
c_inv_i = df_excel.iloc[:,0].to_xarray() | |
# Emission factor | |
df_excel = pd.read_excel(url_excel, sheet_name = 'EmFactor') | |
df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'EmFactor'}) | |
df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('i') | |
co2_factor_i = df_excel.iloc[:,0].to_xarray() | |
## Calculation of variable costs | |
c_var_i = (c_fuel_i.sel(i = iConv) + p_co2 * co2_factor_i.sel(i = iConv)) / eff_i.sel(i = iConv) + c_other_i.sel(i = iConv) | |
# RES capacity factors | |
#df_excel = pd.read_excel(url_excel, sheet_name = 'RES',header=[0,1]) | |
#df_excel = pd.read_excel(url_excel, sheet_name = 'RES', index_col=['Timesteps'], columns=['PV', 'WindOn', 'WindOff', 'RoR']) | |
df_excel = pd.read_excel(url_excel, sheet_name = 'RES') | |
df_excel = df_excel.set_index(['Timesteps']) | |
df_test = df_excel | |
df_excel = df_excel.stack() | |
#df_excel = df_excel.rename(columns={'PV', 'WindOn', 'WindOff', 'RoR'}) | |
df_test2 = df_excel | |
#df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
#df_excel = df_excel.fillna(0) | |
#df_test = df_excel.set_index(['Timesteps', 'PV', 'WindOn', 'WindOff', 'RoR']).stack([0]) | |
#df_test.index = df_test.index.set_names(['t','i']) | |
s_t_r_iRes = df_excel.to_xarray().rename({'level_1': 'i','Timesteps':'t'}) | |
#s_t_r_iRes = df_excel.iloc[:,0].to_xarray() | |
# Base capacities | |
df_excel = pd.read_excel(url_excel, sheet_name = 'InstalledCap') | |
df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'InstalledCap'}) | |
df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('i') | |
K_0_i = df_excel.iloc[:,0].to_xarray() | |
# Energy-to-power ratio storages | |
df_excel = pd.read_excel(url_excel, sheet_name = 'E2P') | |
df_excel = df_excel.rename(columns = {'Storage':'i', 'Unnamed: 1':'E2P ratio'}) | |
#df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left') | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('i') | |
e2p_iSto = df_excel.iloc[:,0].to_xarray() | |
# Inflow for hydro reservoir | |
df_excel = pd.read_excel(url_excel, sheet_name = 'HydroInflow') | |
df_excel = df_excel.rename(columns = {'Timesteps':'t', 'Hydro Water Reservoir':'Inflow'}) | |
df_excel = df_excel.fillna(0) | |
df_excel = df_excel.set_index('t') | |
h_t = df_excel.iloc[:,0].to_xarray() | |
# %% | |
### Variables | |
m = Model() | |
C_tot = m.add_variables(name = 'C_tot') # Total costs | |
C_op = m.add_variables(name = 'C_op', lower = 0) # Operational costs | |
C_inv = m.add_variables(name = 'C_inv', lower = 0) # Investment costs | |
K = m.add_variables(coords = [i], name = 'K', lower = 0) # Endogenous capacity | |
y = m.add_variables(coords = [t,i], name = 'y', lower = 0) # Electricity production --> für Elektrolyseure ausschließen | |
y_ch = m.add_variables(coords = [t,i], name = 'y_ch', lower = 0) # Electricity consumption --> für alles außer Elektrolyseure und Speicher ausschließen | |
l = m.add_variables(coords = [t,i], name = 'l', lower = 0) # Storage filling level | |
w = m.add_variables(coords = [t], name = 'w', lower = 0) # RES curtailment | |
### Model | |
## Objective function | |
C_tot = C_op + C_inv | |
m.add_objective(C_tot) | |
## Costs terms for objective function | |
# Operational costs minus revenue for produced hydrogen | |
C_op_sum = m.add_constraints((y * c_var_i * dt).sum() - ((y_ch.sel(i = iPtG) / eff_i.sel(i = iPtG)) * price_h2 * dt).sum() == C_op, name = 'C_op_sum') | |
# Investment costs | |
C_inv_sum = m.add_constraints((K * c_inv_i).sum() == C_inv, name = 'C_inv_sum') | |
## Load serving | |
loadserve_t = m.add_constraints(((y * dt).sum(dims = 'i') - (w * dt) == D_t.sel(t = t) * dt), name = 'load') | |
## Maximum capacity limit | |
maxcap_i_t = m.add_constraints((y - K <= K_0_i), name = 'max_cap') | |
## Maximum storage charging and discharging | |
maxcha_iSto_t = m.add_constraints((y.sel(i = iSto) + y_ch.sel(i = iSto) - K.sel(i = iSto) <= K_0_i.sel(i = iSto)), name = 'max_cha') | |
## Maximum electrolyzer capacity | |
ptg_prod_iPtG_t = m.add_constraints((y_ch.sel(i = iPtG) - K.sel(i = iPtG)<= K_0_i.sel(i = iPtG)), name = 'max_cha_ptg') | |
## Infeed of renewables | |
infeed_iRes_t = m.add_constraints((y.sel(i = iRes) - s_t_r_iRes.sel(i = iRes).sel(t = t) * K.sel(i = iRes) <= s_t_r_iRes.sel(i = iRes).sel(t = t) * K_0_i.sel(i = iRes)), name = 'infeed') | |
## Maximum filling level restriction storage power plant --> Energy-to-Power-Ratio eingeführt. (JR) | |
maxcapsto_iSto_t = m.add_constraints((l.sel(i = iSto) - K.sel(i = iSto) * e2p_iSto.sel(i = iSto) <= K_0_i.sel(i = iSto) * e2p_iSto.sel(i = iSto)), name = 'max_sto_filling') | |
## Filling level restriction hydro reservoir --> Ist Kreisbedingung erfüllt? (JR) | |
filling_iHydro_t = m.add_constraints(l.sel(i = iHyRes) - l.sel(i = iHyRes).roll(t = -1) + y.sel(i = iHyRes) * dt == h_t.sel(t = t) * dt, name = 'filling_level_hydro') | |
## Filling level restriction other storages --> Ist Kreisbedingung erfüllt? (JR) | |
filling_iSto_t = m.add_constraints(l.sel(i = iSto) - (l.sel(i = iSto).roll(t = -1) - (y.sel(i = iSto) / eff_i.sel(i = iSto)) * dt + y_ch.sel(i = iSto) * eff_i.sel(i = iSto) * dt) == 0, name = 'filling_level') | |
## CO2 limit --> ggf. hier auch mit Subset arbeiten (Technologien, die Brennstoff verbrauchen). (JR) | |
CO2_limit = m.add_constraints(((y / eff_i) * co2_factor_i * dt).sum() <= l_co2, name = 'CO2_limit') | |
m.solve(solver_name = 'highs') | |
# %% | |
# Read Objective from solution | |
m.objective_value | |
pd.options.plotting.backend = "plotly" | |
# Read dual values and plot | |
df = loadserve_t.dual.to_dataframe().reset_index() | |
#df['t'] = pd.to_datetime(df['t']) | |
df | |
# %% | |
# Read values | |
Productionlevels = m.solution['y'].to_dataframe().reset_index() | |
df = Productionlevels | |
df | |
# %% | |
#pandas gui | |
# Create Line plot | |
fig = px.line(df, x=df['t'], y=df['y'], color = df['i']) | |
fig | |
# %% | |