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() | |
| # %% | |
| # Slider for gas price [€/MWh_th] | |
| price_gas = st.slider(value=10, min=0, max=400, label="Natural gas price [€/MWh]", step=10) | |
| # Slider for CO2 price [€/t] | |
| price_co2 = st.slider(value=80, min=0, max=400, label="CO2 price [€/t CO2eq]", step=10) | |
| # Slider for CO2 limit [mio. t] | |
| limit_co2 = st.slider(value=400, min=0, max=750, label="CO2 limit [mio. t]", step=50) | |
| # Slider for H2 price / usevalue [€/MWH_th] | |
| price_h2 = st.slider(value=100, min=0, max=300, label="Hydrogen price [€/MWh]", step=10) | |
| # %% | |
| # Set input file | |
| url_excel = r'Input_Jahr_2021.xlsx' | |
| # %% [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.value | |
| p_co2 = price_co2.value | |
| # 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.value | |
| c_fuel_i.loc[dict(i = 'H2')] = price_h2.value | |
| # 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.value * 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') | |
| # %% [markdown] | |
| # Results | |
| # %% | |
| # %% | |
| m.solve(solver_name = 'highs',presolve = 'off',run_crossover = 'off',solver = 'ipm') | |
| # %% | |
| #m.solve(solver_name = 'highs', solver = 'ipm', log_file = 'solverlog.txt',run_crossover = 'off' ) | |
| # %% | |
| # 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'].sel(r = 'DE').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 | |
| # %% | |
| #Productionlevels | |